2 * Copyright (C) 2009, 2010 Daniel Borkmann <daniel@netsniff-ng.org> and
3 * Emmanuel Roullit <emmanuel@netsniff-ng.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
29 #include <sys/ioctl.h>
30 #include <sys/socket.h>
32 #include <arpa/inet.h>
34 #include <netinet/in.h>
35 #include <netinet/ether.h>
36 #include <arpa/inet.h>
40 #include <linux/socket.h>
41 #include <linux/types.h>
43 #include <linux/if_ether.h>
44 #include <linux/if_packet.h>
45 #include <linux/filter.h>
46 #include <linux/sockios.h>
47 #include <linux/ethtool.h>
48 #include <linux/wireless.h>
57 # define PACKET_LOSS 14
59 #define wop_entry(x, i) (wop_mode[(x) % (sizeof(wop_mode)/sizeof(wop_mode[0]))][(i)])
61 static const char *const wop_mode
[][2] = {
63 {"adhoc", "single cell net"},
64 {"infra", "multi cell net"},
65 {"master", "sync master or AP"},
66 {"repeat", "forwarder"},
67 {"second", "secondary master"},
68 {"monitor", "passive mode"},
69 {"mesh", "mesh net (IEEE 802.11s)"},
73 static inline void assert_dev_name(const char *dev
)
76 assert(strlen(dev
) < IFNAMSIZ
);
79 static int get_af_socket(int af
)
83 assert(af
== AF_INET
|| af
== AF_INET6
);
85 sock
= socket(af
, SOCK_DGRAM
, 0);
95 * get_pf_socket - Allocates a raw PF_PACKET socket
97 int get_pf_socket(void)
99 int sock
= socket(PF_PACKET
, SOCK_RAW
, 0);
101 err("Allocation of pf socket");
109 * get_wireless_bitrate - Returns wireless bitrate in Mb/s
110 * @ifname: device name
112 static int get_wireless_bitrate(const char *ifname
)
117 assert_dev_name(ifname
);
119 memset(&iwr
, 0, sizeof(iwr
));
120 strlcpy(iwr
.ifr_name
, ifname
, sizeof(iwr
.ifr_name
) - 1);
122 sock
= get_af_socket(AF_INET
);
124 ret
= ioctl(sock
, SIOCGIWRATE
, &iwr
);
131 return (iwr
.u
.bitrate
.value
/ 1000000);
134 static int get_wireless_ssid(const char *ifname
, char *ssid
)
142 sock
= get_af_socket(AF_INET
);
144 memset(&iwr
, 0, sizeof(iwr
));
145 strlcpy(iwr
.ifr_name
, ifname
, sizeof(iwr
.ifr_name
) - 1);
147 iwr
.u
.essid
.pointer
= ssid
;
148 iwr
.u
.essid
.length
= IW_ESSID_MAX_SIZE
;
150 ret
= ioctl(sock
, SIOCGIWESSID
, &iwr
);
152 ret
= iwr
.u
.essid
.length
;
162 static inline int adjust_dbm_level(int dbm_val
)
169 static int dbm_to_mwatt(const int in
)
171 /* From Jean Tourrilhes <jt@hpl.hp.com> (iwlib.c) */
178 for (k
= 0; k
< ip
; k
++)
180 for (k
= 0; k
< fp
; k
++)
181 res
*= 1.25892541179; /* LOG10_MAGIC */
185 static int get_wireless_tx_power(const char *ifname
)
192 sock
= get_af_socket(AF_INET
);
194 memset(&iwr
, 0, sizeof(iwr
));
195 strlcpy(iwr
.ifr_name
, ifname
, sizeof(iwr
.ifr_name
) - 1);
197 ret
= ioctl(sock
, SIOCGIWTXPOW
, &iwr
);
199 ret
= iwr
.u
.txpower
.value
;
209 static int get_wireless_sigqual(const char *ifname
, struct iw_statistics
*stats
)
217 sock
= get_af_socket(AF_INET
);
219 memset(&iwr
, 0, sizeof(iwr
));
221 strlcpy(iwr
.ifr_name
, ifname
, sizeof(iwr
.ifr_name
) - 1);
222 iwr
.u
.data
.pointer
= (caddr_t
) stats
;
223 iwr
.u
.data
.length
= sizeof(*stats
);
224 iwr
.u
.data
.flags
= 1;
226 ret
= ioctl(sock
, SIOCGIWSTATS
, &iwr
);
236 static int get_wireless_rangemax_sigqual(const char *ifname
)
240 struct iw_range iwrange
;
244 sock
= get_af_socket(AF_INET
);
246 memset(&iwr
, 0, sizeof(iwr
));
247 memset(&iwrange
, 0, sizeof(iwrange
));
249 strlcpy(iwr
.ifr_name
, ifname
, sizeof(iwr
.ifr_name
) - 1);
250 iwr
.u
.data
.pointer
= (caddr_t
) & iwrange
;
251 iwr
.u
.data
.length
= sizeof(iwrange
);
252 iwr
.u
.data
.flags
= 0;
254 ret
= ioctl(sock
, SIOCGIWRANGE
, &iwr
);
261 return iwrange
.max_qual
.qual
;
265 * get_ethtool_bitrate - Returns non-wireless bitrate in Mb/s (via ethtool)
266 * @ifname: device name
268 static int get_ethtool_bitrate(const char *ifname
)
272 struct ethtool_cmd ecmd
;
274 assert_dev_name(ifname
);
276 memset(&ifr
, 0, sizeof(ifr
));
277 memset(&ecmd
, 0, sizeof(ecmd
));
278 ecmd
.cmd
= ETHTOOL_GSET
;
280 strlcpy(ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
) - 1);
282 sock
= get_af_socket(AF_INET
);
284 ifr
.ifr_data
= (char *)&ecmd
;
286 ret
= ioctl(sock
, SIOCETHTOOL
, &ifr
);
292 switch (ecmd
.speed
) {
309 * get_ethtool_drvinf - Returns driver info of ethtool supported dev
310 * @ifname: device name
312 static int get_ethtool_drvinf(const char *ifname
, struct ethtool_drvinfo
*di
)
316 struct ethtool_drvinfo __di
;
319 assert_dev_name(ifname
);
321 memset(&ifr
, 0, sizeof(ifr
));
322 memset(&__di
, 0, sizeof(__di
));
324 __di
.cmd
= ETHTOOL_GDRVINFO
;
326 strlcpy(ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
) - 1);
328 sock
= get_af_socket(AF_INET
);
330 ifr
.ifr_data
= (char *)&__di
;
332 ret
= ioctl(sock
, SIOCETHTOOL
, &ifr
);
336 memcpy(di
, &__di
, sizeof(*di
));
344 * get_device_bitrate_generic - Returns bitrate in Mb/s
345 * @ifname: device name
347 int get_device_bitrate_generic(const char *ifname
)
349 int speed_c
, speed_w
;
351 /* Probe for speed rates */
352 speed_c
= get_ethtool_bitrate(ifname
);
353 speed_w
= get_wireless_bitrate(ifname
);
355 return (speed_c
== 0 ? speed_w
: speed_c
);
359 * get_device_bitrate_generic_cable - Returns bitrate in Mb/s
360 * @ifname: device name
362 int get_device_bitrate_generic_cable(const char *ifname
)
364 return get_ethtool_bitrate(ifname
);
368 * get_mtu - Get MTU of a device
369 * @sock: socket descriptor
370 * @ifname: device name
372 int get_mtu(const char *dev
)
377 assert_dev_name(dev
);
379 sock
= get_af_socket(AF_INET
);
381 memset(&ifr
, 0, sizeof(ifr
));
382 strlcpy(ifr
.ifr_name
, dev
, sizeof(ifr
.ifr_name
) - 1);
384 if (ioctl(sock
, SIOCGIFMTU
, &ifr
) < 0) {
385 err("Doing iotcl(SIOCGIFMTU)");
390 return (ifr
.ifr_mtu
);
393 static int get_nic_irq_number_proc(const char *dev
)
395 /* Since fetching IRQ numbers from SIOCGIFMAP is deprecated and not
396 supported anymore, we need to grab them from procfs */
398 /* XXX Mhh... I think it would cleverer to read our
399 * info from /sys/class/net/eth0/device/irq
404 char buff
[128] = { 0 };
406 assert_dev_name(dev
);
409 if (!strncmp("lo", dev
, strlen("lo")))
412 FILE *fp
= fopen("/proc/interrupts", "r");
414 err("Cannot open /proc/interrupts");
418 memset(buff
, 0, sizeof(buff
));
420 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
421 buff
[sizeof(buff
) - 1] = 0;
422 if (strstr(buff
, dev
) == NULL
)
425 while (*buffp
!= ':') {
436 int get_nic_irq_number(const char *dev
)
438 return get_nic_irq_number_proc(dev
);
441 int bind_nic_interrupts_to_cpu(int intr
, int cpu
)
444 char buff
[128] = { 0 };
445 char file
[128] = { 0 };
447 /* XXX Mhh... I think it would cleverer to read our
448 * info from /sys/class/net/eth0/device/local_cpulist
451 /* Note: first CPU begins with CPU 0 */
452 if (intr
< 0 || cpu
< 0)
455 /* smp_affinity starts counting with CPU 1, 2, ... */
458 sprintf(file
, "/proc/irq/%d/smp_affinity", intr
);
459 FILE *fp
= fopen(file
, "w");
461 err("Cannot open %s", file
);
465 sprintf(buff
, "%d", cpu
);
466 ret
= fwrite(buff
, sizeof(buff
), 1, fp
);
469 return (ret
> 0 ? 0 : ret
);
473 * get_nic_flags - Fetches device flags
476 short get_nic_flags(const char *dev
)
482 assert_dev_name(dev
);
484 sock
= get_af_socket(AF_INET
);
486 memset(ðreq
, 0, sizeof(ethreq
));
487 strlcpy(ethreq
.ifr_name
, dev
, sizeof(ethreq
.ifr_name
) - 1);
489 ret
= ioctl(sock
, SIOCGIFFLAGS
, ðreq
);
491 err("ioctl: cannot determine dev number for %s",
498 return (ethreq
.ifr_flags
);
502 * set_nic_flags - Set flags attached to a network device
506 void set_nic_flags(const char *dev
, const short nic_flags
)
512 assert_dev_name(dev
);
514 sock
= get_af_socket(AF_INET
);
516 memset(ðreq
, 0, sizeof(ethreq
));
517 strlcpy(ethreq
.ifr_name
, dev
, sizeof(ethreq
.ifr_name
) - 1);
518 ethreq
.ifr_flags
= nic_flags
;
520 ret
= ioctl(sock
, SIOCSIFFLAGS
, ðreq
);
522 err("ioctl: cannot determine dev number for %s",
532 * get_nic_mac - Fetches device MAC address
534 * @mac: Output buffer
536 static int get_nic_mac(const char *dev
, uint8_t * mac
)
542 assert_dev_name(dev
);
545 sock
= get_af_socket(AF_INET
);
547 memset(&ifr
, 0, sizeof(ifr
));
548 strlcpy(ifr
.ifr_name
, dev
, sizeof(ifr
.ifr_name
) - 1);
550 ret
= ioctl(sock
, SIOCGIFHWADDR
, &ifr
);
552 err("Doing ioctl(SIOCGIFHWADDR)");
557 memcpy(mac
, ifr
.ifr_hwaddr
.sa_data
, ETH_ALEN
);
562 static char *get_nic_mac_str(const char *dev
)
564 uint8_t mac
[ETH_ALEN
] = { 0 };
565 get_nic_mac(dev
, mac
);
566 return (ether_ntoa((const struct ether_addr
*)mac
));
569 static int get_interface_conf(struct ifconf
*ifconf
)
574 assert(ifconf
->ifc_buf
);
575 assert(ifconf
->ifc_len
);
577 sock
= get_af_socket(AF_INET
);
579 if (ioctl(sock
, SIOCGIFCONF
, ifconf
) < 0) {
580 err("Doing ioctl(SIOCGIFCONF)");
588 static int get_interface_address(const char *dev
, struct in_addr
*in
,
589 struct in6_addr
*in6
)
594 struct in_addr
*tmp_in
;
596 struct sockaddr_in6
*sa6
;
600 assert_dev_name(dev
);
602 memset(in
, 0, sizeof(*in
));
603 memset(in6
, 0, sizeof(*in6
));
604 memset(&ifr
, 0, sizeof(ifr
));
606 strlcpy(ifr
.ifr_name
, dev
, sizeof(ifr
.ifr_name
) - 1);
608 sock
= get_af_socket(AF_INET
);
610 if (ioctl(sock
, SIOCGIFADDR
, &ifr
) < 0) {
611 err("Doing ioctl(SIOCGIFADDR)");
616 sa
= (struct sockaddr
*)&ifr
.ifr_addr
;
618 switch (sa
->sa_family
) {
620 tmp_in
= &(((struct sockaddr_in
*)&ifr
.ifr_addr
)->sin_addr
);
621 memcpy(in
, tmp_in
, sizeof(*in
));
625 sa6
= (struct sockaddr_in6
*)&ifr
.ifr_addr
;
626 memcpy(in6
, &sa6
->sin6_addr
, sizeof(*in6
));
630 return (sa
->sa_family
);
634 * print_device_info - Prints infos of netdevs
636 void print_device_info(void)
638 int i
= 0, ret
= 0, speed
= 0, txp
= 0;
641 char essid
[IW_ESSID_MAX_SIZE
] = { 0 };
642 char tmp_ip
[INET6_ADDRSTRLEN
] = { 0 };
644 struct ifreq
*ifr_elem
= NULL
;
645 struct ifreq
*ifr_buffer
= NULL
;
646 struct ifconf ifc
= { 0 };
647 struct in_addr ipv4
= { 0 };
648 struct in6_addr ipv6
= IN6ADDR_ANY_INIT
;
649 struct ethtool_drvinfo di
= { 0 };
650 struct iw_statistics ws
= { 0 };
652 size_t if_buffer_len
= sizeof(*ifr_buffer
) * MAX_NUMBER_OF_NICS
;
654 ifr_buffer
= xzmalloc(if_buffer_len
);
656 ifc
.ifc_len
= if_buffer_len
;
657 ifc
.ifc_req
= ifr_buffer
;
659 get_interface_conf(&ifc
);
661 info("Networking devs\n");
663 for (i
= 0; i
< (ifc
.ifc_len
/ sizeof(*ifr_buffer
)); i
++) {
664 ifr_elem
= &ifc
.ifc_req
[i
];
669 switch (get_interface_address(ifr_elem
->ifr_name
, &ipv4
, &ipv6
)) {
671 inet_ntop(AF_INET
, (const void *)&ipv4
, tmp_ip
,
675 inet_ntop(AF_INET6
, (const void *)&ipv6
, tmp_ip
,
681 * Basic info as name, HW addr, IP addr
683 info(" (%03d) %s%s%s => %s\n", i
, colorize_start(bold
),
684 ifr_elem
->ifr_name
, colorize_end(), tmp_ip
);
685 info(" hw: %s\n", get_nic_mac_str(ifr_elem
->ifr_name
));
688 * Driver name (for non-wireless)
690 ret
= get_ethtool_drvinf(ifr_elem
->ifr_name
, &di
);
692 info(" driver: %s %s\n", di
.driver
, di
.version
);
696 * General device flags
698 nic_flags
= get_nic_flags(ifr_elem
->ifr_name
);
699 info(" stat:%s%s%s%s\n",
700 (((nic_flags
& IFF_UP
) == IFF_UP
) ? " up" : " not up"),
701 (((nic_flags
& IFF_RUNNING
) ==
702 IFF_RUNNING
) ? " running" : ""),
703 (((nic_flags
& IFF_LOOPBACK
) ==
704 IFF_LOOPBACK
) ? ", loops back" : ""),
705 (((nic_flags
& IFF_POINTOPOINT
) ==
706 IFF_POINTOPOINT
) ? ", point-to-point link" : ""));
708 info(" mtu: %d Byte\n", get_mtu(ifr_elem
->ifr_name
));
710 get_nic_irq_number(ifr_elem
->ifr_name
));
715 speed
= get_device_bitrate_generic(ifr_elem
->ifr_name
);
717 info(" bitrate: %d Mb/s\n", speed
);
721 * Wireless information
723 /* XXX: a better way to test for a wireless dev!? */
724 if (get_wireless_bitrate(ifr_elem
->ifr_name
)) {
726 adjust_dbm_level(get_wireless_tx_power
727 (ifr_elem
->ifr_name
));
729 if (get_wireless_ssid(ifr_elem
->ifr_name
, essid
) > 0)
730 info(" connected to ssid: %s\n", essid
);
731 if (get_wireless_sigqual(ifr_elem
->ifr_name
, &ws
) >= 0) {
732 info(" link quality: %d/%d\n",
734 get_wireless_rangemax_sigqual(ifr_elem
->
736 info(" signal level: %d dBm\n",
737 adjust_dbm_level(ws
.qual
.level
));
738 info(" noise level: %d dBm\n",
739 adjust_dbm_level(ws
.qual
.noise
));
740 info(" tx-power: %d dBm (%d mW)\n", txp
,
742 info(" operation mode: %s (%d) %s\n",
743 wop_entry(ws
.status
, 0), ws
.status
,
744 wop_entry(ws
.status
, 1));
745 info(" pkg discarded:\n");
746 info(" rx invalid nwid: %d\n",
748 info(" rx invalid crypt: %d\n",
750 info(" rx invalif frag: %d\n",
751 ws
.discard
.fragment
);
752 info(" tx excessive retries: %d\n", ws
.discard
.retries
);
753 info(" invalid misc reasons: %d\n", ws
.discard
.misc
);
762 * inject_kernel_bpf - Binds filter code to socket
764 * @bpf: Berkeley Packet Filter code
766 void inject_kernel_bpf(int sock
, struct sock_fprog
*bpf
)
772 ret
= setsockopt(sock
, SOL_SOCKET
, SO_ATTACH_FILTER
, bpf
, sizeof(*bpf
));
774 err("setsockopt: filter cannot be injected");
781 * reset_kernel_bpf - Resets filter code from socket
784 void reset_kernel_bpf(int sock
)
789 ret
= setsockopt(sock
, SOL_SOCKET
, SO_DETACH_FILTER
, &foo
, sizeof(foo
));
791 err("setsockopt: cannot reset filter");
798 * ethdev_to_ifindex - Translates device name into device number
801 int ethdev_to_ifindex(const char *dev
)
809 sock
= get_af_socket(AF_INET
);
811 memset(ðreq
, 0, sizeof(ethreq
));
812 strlcpy(ethreq
.ifr_name
, dev
, sizeof(ethreq
.ifr_name
) - 1);
814 ret
= ioctl(sock
, SIOCGIFINDEX
, ðreq
);
816 err("ioctl: cannot determine dev number for %s",
823 return (ethreq
.ifr_ifindex
);
827 * net_stat - Grabs and prints current socket statistics
830 void net_stat(int sock
)
833 struct tpacket_stats kstats
;
834 socklen_t slen
= sizeof(kstats
);
836 memset(&kstats
, 0, sizeof(kstats
));
838 ret
= getsockopt(sock
, SOL_PACKET
, PACKET_STATISTICS
, &kstats
, &slen
);
840 info("\r%d frames incoming\n", kstats
.tp_packets
);
841 info("\r%d frames passed filter\n",
842 kstats
.tp_packets
- kstats
.tp_drops
);
843 info("\r%d frames failed filter (due to out of space)\n",
849 * parse_rules - Parses a BPF rulefile
850 * @rulefile: path to rulefile
854 int parse_rules(char *rulefile
, struct sock_fprog
*bpf
)
857 char buff
[128] = { 0 };
859 struct sock_filter sf_single
;
864 FILE *fp
= fopen(rulefile
, "r");
866 err("Cannot read rulefile");
870 memset(buff
, 0, sizeof(buff
));
872 info("Parsing rulefile %s\n", rulefile
);
874 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
875 /* We're using evil sscanf, so we have to assure
876 that we don't get into a buffer overflow ... */
877 buff
[sizeof(buff
) - 1] = 0;
879 /* A comment. Skip this line */
880 if (buff
[0] != '{') {
884 memset(&sf_single
, 0, sizeof(sf_single
));
886 ret
= sscanf(buff
, "{ 0x%x, %d, %d, 0x%08x },",
887 (unsigned int *)((void *)&(sf_single
.code
)),
888 (int *)((void *)&(sf_single
.jt
)),
889 (int *)((void *)&(sf_single
.jf
)), &(sf_single
.k
));
891 /* No valid bpf opcode format or a syntax error */
897 (struct sock_filter
*)realloc(bpf
->filter
,
898 bpf
->len
* sizeof(sf_single
));
900 memcpy(&bpf
->filter
[bpf
->len
- 1], &sf_single
,
903 memset(buff
, 0, sizeof(buff
));
908 /* bpf_validate() returns 0 on failiure */
909 return (bpf_validate(bpf
));