2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2009, 2010 Daniel Borkmann.
5 * Copyright 2009, 2010 Emmanuel Roullit.
6 * Subject to the GPL, version 2.
18 #include <arpa/inet.h>
24 #include <sys/socket.h>
25 #include <sys/ioctl.h>
26 #include <sys/resource.h>
27 #include <sys/epoll.h>
30 #include <linux/socket.h>
31 #include <linux/types.h>
33 #include <linux/if_ether.h>
34 #include <linux/if_packet.h>
35 #include <linux/sockios.h>
36 #include <netinet/tcp.h>
37 #include <netinet/udp.h>
50 if (unlikely(af
!= AF_INET
&& af
!= AF_INET6
)) {
51 whine("Wrong AF socket type! Falling back to AF_INET\n");
55 sock
= socket(af
, SOCK_DGRAM
, 0);
56 if (unlikely(sock
< 0))
57 panic("Creation AF socket failed!\n");
64 int sock
= socket(PF_PACKET
, SOCK_RAW
, htons(ETH_P_ALL
));
65 if (unlikely(sock
< 0))
66 panic("Creation of PF socket failed!\n");
71 void set_udp_cork(int fd
)
74 setsockopt(fd
, IPPROTO_UDP
, UDP_CORK
, &state
, sizeof(state
));
77 void set_udp_uncork(int fd
)
80 setsockopt(fd
, IPPROTO_UDP
, UDP_CORK
, &state
, sizeof(state
));
83 void set_tcp_cork(int fd
)
86 setsockopt(fd
, IPPROTO_TCP
, TCP_CORK
, &state
, sizeof(state
));
89 void set_tcp_uncork(int fd
)
92 setsockopt(fd
, IPPROTO_TCP
, TCP_CORK
, &state
, sizeof(state
));
95 void set_sock_cork(int fd
, int udp
)
103 void set_sock_uncork(int fd
, int udp
)
111 int set_nonblocking(int fd
)
113 int ret
= fcntl(fd
, F_SETFL
, fcntl(fd
, F_GETFD
, 0) | O_NONBLOCK
);
114 if (unlikely(ret
< 0))
115 panic("Cannot fcntl!\n");
120 int set_nonblocking_sloppy(int fd
)
122 return fcntl(fd
, F_SETFL
, fcntl(fd
, F_GETFD
, 0) | O_NONBLOCK
);
125 void set_socket_keepalive(int fd
)
128 setsockopt(fd
, SOL_SOCKET
, SO_KEEPALIVE
, &one
, sizeof(one
));
131 void set_tcp_nodelay(int fd
)
134 setsockopt(fd
, IPPROTO_TCP
, TCP_NODELAY
, &one
, sizeof(one
));
137 int set_ipv6_only(int fd
)
140 return setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &one
, sizeof(one
));
143 int set_reuseaddr(int fd
)
147 ret
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &one
, sizeof (one
));
148 if (unlikely(ret
< 0))
149 panic("Cannot reuse addr!\n");
154 void set_mtu_disc_dont(int fd
)
156 int mtu
= IP_PMTUDISC_DONT
;
157 setsockopt(fd
, SOL_IP
, IP_MTU_DISCOVER
, &mtu
, sizeof(mtu
));
160 void set_epoll_descriptor(int fd_epoll
, int action
, int fd_toadd
, int events
)
163 struct epoll_event ev
;
165 memset(&ev
, 0, sizeof(ev
));
167 ev
.data
.fd
= fd_toadd
;
169 ret
= epoll_ctl(fd_epoll
, action
, fd_toadd
, &ev
);
171 panic("Cannot add socket for epoll!\n");
174 int set_epoll_descriptor2(int fd_epoll
, int action
, int fd_toadd
, int events
)
176 struct epoll_event ev
;
178 memset(&ev
, 0, sizeof(ev
));
180 ev
.data
.fd
= fd_toadd
;
182 return epoll_ctl(fd_epoll
, action
, fd_toadd
, &ev
);
185 int wireless_bitrate(const char *ifname
)
187 int sock
, ret
, rate_in_mbit
;
190 sock
= af_socket(AF_INET
);
192 memset(&iwr
, 0, sizeof(iwr
));
193 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
195 ret
= ioctl(sock
, SIOCGIWRATE
, &iwr
);
197 rate_in_mbit
= iwr
.u
.bitrate
.value
/ 1000000;
206 int adjust_dbm_level(int dbm_val
)
213 int wireless_sigqual(const char *ifname
, struct iw_statistics
*stats
)
218 sock
= af_socket(AF_INET
);
220 memset(&iwr
, 0, sizeof(iwr
));
221 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
223 iwr
.u
.data
.pointer
= (caddr_t
) stats
;
224 iwr
.u
.data
.length
= sizeof(*stats
);
225 iwr
.u
.data
.flags
= 1;
227 ret
= ioctl(sock
, SIOCGIWSTATS
, &iwr
);
234 int wireless_rangemax_sigqual(const char *ifname
)
236 int ret
, sock
, sigqual
;
238 struct iw_range iwrange
;
240 sock
= af_socket(AF_INET
);
242 memset(&iwrange
, 0, sizeof(iwrange
));
244 memset(&iwr
, 0, sizeof(iwr
));
245 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
247 iwr
.u
.data
.pointer
= (caddr_t
) &iwrange
;
248 iwr
.u
.data
.length
= sizeof(iwrange
);
249 iwr
.u
.data
.flags
= 0;
251 ret
= ioctl(sock
, SIOCGIWRANGE
, &iwr
);
253 sigqual
= iwrange
.max_qual
.qual
;
262 int ethtool_bitrate(const char *ifname
)
264 int ret
, sock
, bitrate
;
266 struct ethtool_cmd ecmd
;
268 sock
= af_socket(AF_INET
);
270 memset(&ecmd
, 0, sizeof(ecmd
));
272 memset(&ifr
, 0, sizeof(ifr
));
273 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
275 ecmd
.cmd
= ETHTOOL_GSET
;
276 ifr
.ifr_data
= (char *) &ecmd
;
278 ret
= ioctl(sock
, SIOCETHTOOL
, &ifr
);
284 switch (ecmd
.speed
) {
289 bitrate
= ecmd
.speed
;
301 int ethtool_drvinf(const char *ifname
, struct ethtool_drvinfo
*drvinf
)
306 sock
= af_socket(AF_INET
);
308 memset(drvinf
, 0, sizeof(*drvinf
));
310 memset(&ifr
, 0, sizeof(ifr
));
311 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
313 drvinf
->cmd
= ETHTOOL_GDRVINFO
;
314 ifr
.ifr_data
= (char *) drvinf
;
316 ret
= ioctl(sock
, SIOCETHTOOL
, &ifr
);
323 int device_bitrate(const char *ifname
)
325 int speed_c
, speed_w
;
327 speed_c
= ethtool_bitrate(ifname
);
328 speed_w
= wireless_bitrate(ifname
);
330 return (speed_c
== 0 ? speed_w
: speed_c
);
333 int device_ifindex(const char *ifname
)
335 int ret
, sock
, index
;
338 if (!strncmp("any", ifname
, strlen("any")))
341 sock
= af_socket(AF_INET
);
343 memset(&ifr
, 0, sizeof(ifr
));
344 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
346 ret
= ioctl(sock
, SIOCGIFINDEX
, &ifr
);
348 index
= ifr
.ifr_ifindex
;
357 int device_address(const char *ifname
, int af
, struct sockaddr_storage
*ss
)
364 if (!strncmp("any", ifname
, strlen("any")))
367 sock
= af_socket(af
);
369 memset(&ifr
, 0, sizeof(ifr
));
370 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
372 ifr
.ifr_addr
.sa_family
= af
;
374 ret
= ioctl(sock
, SIOCGIFADDR
, &ifr
);
376 memcpy(ss
, &ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
383 int device_mtu(const char *ifname
)
388 sock
= af_socket(AF_INET
);
390 memset(&ifr
, 0, sizeof(ifr
));
391 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
393 ret
= ioctl(sock
, SIOCGIFMTU
, &ifr
);
404 short device_get_flags(const char *ifname
)
406 /* Really, it's short! Look at struct ifreq */
411 sock
= af_socket(AF_INET
);
413 memset(&ifr
, 0, sizeof(ifr
));
414 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
416 ret
= ioctl(sock
, SIOCGIFFLAGS
, &ifr
);
418 flags
= ifr
.ifr_flags
;
427 void device_set_flags(const char *ifname
, const short flags
)
432 sock
= af_socket(AF_INET
);
434 memset(&ifr
, 0, sizeof(ifr
));
435 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
437 ifr
.ifr_flags
= flags
;
439 ret
= ioctl(sock
, SIOCSIFFLAGS
, &ifr
);
441 panic("Cannot set NIC flags!\n");
446 int device_irq_number(const char *ifname
)
449 * Since fetching IRQ numbers from SIOCGIFMAP is deprecated and not
450 * supported anymore, we need to grab them from procfs
457 if (!strncmp("lo", ifname
, strlen("lo")))
460 FILE *fp
= fopen("/proc/interrupts", "r");
462 whine("Cannot open /proc/interrupts!\n");
466 memset(buff
, 0, sizeof(buff
));
467 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
468 buff
[sizeof(buff
) - 1] = 0;
470 if (strstr(buff
, ifname
) == NULL
)
474 while (*buffp
!= ':')
479 memset(buff
, 0, sizeof(buff
));
487 * Try sysfs as fallback. Probably wireless devices will be found
488 * here. We return silently if it fails ...
490 slprintf(sysname
, sizeof(sysname
), "/sys/class/net/%s/device/irq",
493 fp
= fopen(sysname
, "r");
497 memset(buff
, 0, sizeof(buff
));
498 if(fgets(buff
, sizeof(buff
), fp
) != NULL
) {
499 buff
[sizeof(buff
) - 1] = 0;
508 int device_bind_irq_to_cpu(int irq
, int cpu
)
514 /* Note: first CPU begins with CPU 0 */
515 if (irq
< 0 || cpu
< 0)
518 memset(file
, 0, sizeof(file
));
519 memset(buff
, 0, sizeof(buff
));
521 /* smp_affinity starts counting with CPU 1, 2, ... */
523 sprintf(file
, "/proc/irq/%d/smp_affinity", irq
);
525 FILE *fp
= fopen(file
, "w");
527 whine("Cannot open file %s!\n", file
);
531 sprintf(buff
, "%d", cpu
);
532 ret
= fwrite(buff
, sizeof(buff
), 1, fp
);
535 return (ret
> 0 ? 0 : ret
);
538 void sock_print_net_stats(int sock
)
541 struct tpacket_stats kstats
;
543 socklen_t slen
= sizeof(kstats
);
545 memset(&kstats
, 0, sizeof(kstats
));
547 ret
= getsockopt(sock
, SOL_PACKET
, PACKET_STATISTICS
, &kstats
, &slen
);
549 printf("\r%12d frames incoming\n",
551 printf("\r%12d frames passed filter\n",
552 kstats
.tp_packets
- kstats
.tp_drops
);
553 printf("\r%12d frames failed filter (out of space)\n",
555 if (kstats
.tp_packets
> 0)
556 printf("\r%12.4f%% frame droprate\n", 1.f
*
557 kstats
.tp_drops
/ kstats
.tp_packets
* 100.f
);
561 void register_signal(int signal
, void (*handler
)(int))
564 struct sigaction saction
;
566 sigfillset(&block_mask
);
568 saction
.sa_handler
= handler
;
569 saction
.sa_mask
= block_mask
;
570 saction
.sa_flags
= SA_RESTART
;
571 sigaction(signal
, &saction
, NULL
);
574 void register_signal_f(int signal
, void (*handler
)(int), int flags
)
577 struct sigaction saction
;
579 sigfillset(&block_mask
);
581 saction
.sa_handler
= handler
;
582 saction
.sa_mask
= block_mask
;
583 saction
.sa_flags
= flags
;
584 sigaction(signal
, &saction
, NULL
);
587 int get_tty_size(void)
590 struct ttysize ts
= {0};
591 int ret
= ioctl(0, TIOCGSIZE
, &ts
);
592 return (ret
== 0 ? ts
.ts_cols
: DEFAULT_TTY_SIZE
);
593 #elif defined(TIOCGWINSZ)
595 memset(&ts
, 0, sizeof(ts
));
596 int ret
= ioctl(0, TIOCGWINSZ
, &ts
);
597 return (ret
== 0 ? ts
.ws_col
: DEFAULT_TTY_SIZE
);
599 return DEFAULT_TTY_SIZE
;
603 void check_for_root_maybe_die(void)
605 if (geteuid() != 0 || geteuid() != getuid())
606 panic("Uhhuh, not root?!\n");
609 short enter_promiscuous_mode(char *ifname
)
613 if (!strncmp("any", ifname
, strlen("any")))
616 ifflags
= device_get_flags(ifname
);
617 device_set_flags(ifname
, ifflags
| IFF_PROMISC
);
622 void leave_promiscuous_mode(char *ifname
, short oldflags
)
624 if (!strncmp("any", ifname
, strlen("any")))
626 device_set_flags(ifname
, oldflags
);
629 int device_up(char *ifname
)
633 if (!strncmp("any", ifname
, strlen("any")))
635 return (device_get_flags(ifname
) & IFF_UP
) == IFF_UP
;
638 int device_running(char *ifname
)
642 if (!strncmp("any", ifname
, strlen("any")))
644 return (device_get_flags(ifname
) & IFF_RUNNING
) == IFF_RUNNING
;
647 int device_up_and_running(char *ifname
)
651 if (!strncmp("any", ifname
, strlen("any")))
653 return (device_get_flags(ifname
) & (IFF_UP
| IFF_RUNNING
)) ==
654 (IFF_UP
| IFF_RUNNING
);
657 int poll_error_maybe_die(int sock
, struct pollfd
*pfd
)
659 if ((pfd
->revents
& (POLLHUP
| POLLRDHUP
| POLLERR
| POLLNVAL
)) == 0)
660 return POLL_NEXT_PKT
;
661 if (pfd
->revents
& (POLLHUP
| POLLRDHUP
))
662 panic("Hangup on socket occured!\n");
663 if (pfd
->revents
& POLLERR
) {
666 if (recv(sock
, &tmp
, sizeof(tmp
), MSG_PEEK
) >= 0)
667 return POLL_NEXT_PKT
;
668 if (errno
== ENETDOWN
)
669 panic("Interface went down!\n");
670 return POLL_MOVE_OUT
;
672 if (pfd
->revents
& POLLNVAL
) {
673 whine("Invalid polling request on socket!\n");
674 return POLL_MOVE_OUT
;
676 return POLL_NEXT_PKT
;
679 static inline char *next_token(char *q
, int sep
)
684 * glibc defines this as a macro and gcc throws a false
685 * positive ``logical ‘&&’ with non-zero constant will
686 * always evaluate as true'' in older versions. See:
687 * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36513
694 int set_cpu_affinity(char *str
, int inverted
)
698 cpu_set_t cpu_bitmask
;
702 cpus
= get_number_cpus();
704 CPU_ZERO(&cpu_bitmask
);
706 for (i
= 0; inverted
&& i
< cpus
; ++i
)
707 CPU_SET(i
, &cpu_bitmask
);
709 while (p
= q
, q
= next_token(q
, ','), p
) {
710 unsigned int a
; /* Beginning of range */
711 unsigned int b
; /* End of range */
712 unsigned int s
; /* Stride */
714 if (sscanf(p
, "%u", &a
) < 1)
718 c1
= next_token(p
, '-');
719 c2
= next_token(p
, ',');
720 if (c1
!= NULL
&& (c2
== NULL
|| c1
< c2
)) {
721 if (sscanf(c1
, "%u", &b
) < 1)
723 c1
= next_token(c1
, ':');
724 if (c1
!= NULL
&& (c2
== NULL
|| c1
< c2
))
725 if (sscanf(c1
, "%u", &s
) < 1)
732 CPU_CLR(a
, &cpu_bitmask
);
734 CPU_SET(a
, &cpu_bitmask
);
738 ret
= sched_setaffinity(getpid(), sizeof(cpu_bitmask
),
741 panic("Can't set this cpu affinity!\n");
745 int set_proc_prio(int priority
)
748 * setpriority() is clever, even if you put a nice value which
749 * is out of range it corrects it to the closest valid nice value
751 int ret
= setpriority(PRIO_PROCESS
, getpid(), priority
);
753 panic("Can't set nice val to %i!\n", priority
);
757 int set_sched_status(int policy
, int priority
)
759 int ret
, min_prio
, max_prio
;
760 struct sched_param sp
;
762 max_prio
= sched_get_priority_max(policy
);
763 min_prio
= sched_get_priority_min(policy
);
765 if (max_prio
== -1 || min_prio
== -1)
766 whine("Cannot determine scheduler prio limits!\n");
767 else if (priority
< min_prio
)
769 else if (priority
> max_prio
)
772 memset(&sp
, 0, sizeof(sp
));
773 sp
.sched_priority
= priority
;
775 ret
= sched_setscheduler(getpid(), policy
, &sp
);
777 whine("Cannot set scheduler policy!\n");
781 ret
= sched_setparam(getpid(), &sp
);
783 whine("Cannot set scheduler prio!\n");
790 int set_timeout(struct timeval
*timeval
, unsigned int msec
)
796 timeval
->tv_usec
= 0;
799 timeval
->tv_usec
= msec
* 1000;
803 timeval
->tv_sec
= (long) (msec
/ 1000);
804 timeval
->tv_usec
= (long) ((msec
- (timeval
->tv_sec
* 1000)) * 1000);