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>
25 #include <sys/socket.h>
26 #include <sys/ioctl.h>
27 #include <sys/resource.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>
45 if (unlikely(af
!= AF_INET
&& af
!= AF_INET6
)) {
46 whine("Wrong AF socket type! Falling back to AF_INET\n");
49 sock
= socket(af
, SOCK_DGRAM
, 0);
50 if (unlikely(sock
< 0))
51 panic("Creation AF socket failed!\n");
55 int af_raw_socket(int af
, int proto
)
58 if (unlikely(af
!= AF_INET
&& af
!= AF_INET6
)) {
59 whine("Wrong AF socket type! Falling back to AF_INET\n");
62 sock
= socket(af
, SOCK_RAW
, proto
);
63 if (unlikely(sock
< 0))
64 panic("Creation AF socket failed!\n");
70 int sock
= socket(PF_PACKET
, SOCK_RAW
, htons(ETH_P_ALL
));
71 if (unlikely(sock
< 0))
72 panic("Creation of PF socket failed!\n");
76 int set_nonblocking(int fd
)
78 int ret
= fcntl(fd
, F_SETFL
, fcntl(fd
, F_GETFD
, 0) | O_NONBLOCK
);
79 if (unlikely(ret
< 0))
80 panic("Cannot fcntl!\n");
84 int set_nonblocking_sloppy(int fd
)
86 return fcntl(fd
, F_SETFL
, fcntl(fd
, F_GETFD
, 0) | O_NONBLOCK
);
89 int set_reuseaddr(int fd
)
92 ret
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &one
, sizeof (one
));
93 if (unlikely(ret
< 0))
94 panic("Cannot reuse addr!\n");
98 int wireless_bitrate(const char *ifname
)
100 int sock
, ret
, rate_in_mbit
;
102 sock
= af_socket(AF_INET
);
103 memset(&iwr
, 0, sizeof(iwr
));
104 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
105 ret
= ioctl(sock
, SIOCGIWRATE
, &iwr
);
107 rate_in_mbit
= iwr
.u
.bitrate
.value
/ 1000000;
114 int wireless_essid(const char *ifname
, char *essid
)
116 int ret
, sock
, essid_len
;
118 sock
= af_socket(AF_INET
);
119 memset(&iwr
, 0, sizeof(iwr
));
120 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
121 iwr
.u
.essid
.pointer
= essid
;
122 iwr
.u
.essid
.length
= IW_ESSID_MAX_SIZE
;
123 ret
= ioctl(sock
, SIOCGIWESSID
, &iwr
);
125 essid_len
= iwr
.u
.essid
.length
;
132 int adjust_dbm_level(int dbm_val
)
139 int dbm_to_mwatt(const int in
)
141 /* From Jean Tourrilhes <jt@hpl.hp.com> (iwlib.c) */
146 for (k
= 0; k
< ip
; k
++)
148 for (k
= 0; k
< fp
; k
++)
149 res
*= 1.25892541179; /* LOG10_MAGIC */
153 int wireless_tx_power(const char *ifname
)
155 int ret
, sock
, tx_power
;
157 sock
= af_socket(AF_INET
);
158 memset(&iwr
, 0, sizeof(iwr
));
159 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
160 ret
= ioctl(sock
, SIOCGIWTXPOW
, &iwr
);
162 tx_power
= iwr
.u
.txpower
.value
;
169 int wireless_sigqual(const char *ifname
, struct iw_statistics
*stats
)
173 sock
= af_socket(AF_INET
);
174 memset(&iwr
, 0, sizeof(iwr
));
175 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
176 iwr
.u
.data
.pointer
= (caddr_t
) stats
;
177 iwr
.u
.data
.length
= sizeof(*stats
);
178 iwr
.u
.data
.flags
= 1;
179 ret
= ioctl(sock
, SIOCGIWSTATS
, &iwr
);
184 int wireless_rangemax_sigqual(const char *ifname
)
186 int ret
, sock
, sigqual
;
188 struct iw_range iwrange
;
189 sock
= af_socket(AF_INET
);
190 memset(&iwrange
, 0, sizeof(iwrange
));
191 memset(&iwr
, 0, sizeof(iwr
));
192 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
193 iwr
.u
.data
.pointer
= (caddr_t
) &iwrange
;
194 iwr
.u
.data
.length
= sizeof(iwrange
);
195 iwr
.u
.data
.flags
= 0;
196 ret
= ioctl(sock
, SIOCGIWRANGE
, &iwr
);
198 sigqual
= iwrange
.max_qual
.qual
;
205 int ethtool_bitrate(const char *ifname
)
207 int ret
, sock
, bitrate
;
209 struct ethtool_cmd ecmd
;
210 sock
= af_socket(AF_INET
);
211 memset(&ecmd
, 0, sizeof(ecmd
));
212 memset(&ifr
, 0, sizeof(ifr
));
213 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
214 ecmd
.cmd
= ETHTOOL_GSET
;
215 ifr
.ifr_data
= (char *) &ecmd
;
216 ret
= ioctl(sock
, SIOCETHTOOL
, &ifr
);
221 switch (ecmd
.speed
) {
226 bitrate
= ecmd
.speed
;
237 int ethtool_drvinf(const char *ifname
, struct ethtool_drvinfo
*drvinf
)
241 sock
= af_socket(AF_INET
);
242 memset(drvinf
, 0, sizeof(*drvinf
));
243 memset(&ifr
, 0, sizeof(ifr
));
244 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
245 drvinf
->cmd
= ETHTOOL_GDRVINFO
;
246 ifr
.ifr_data
= (char *) drvinf
;
247 ret
= ioctl(sock
, SIOCETHTOOL
, &ifr
);
252 int device_bitrate(const char *ifname
)
254 int speed_c
, speed_w
;
255 speed_c
= ethtool_bitrate(ifname
);
256 speed_w
= wireless_bitrate(ifname
);
257 return (speed_c
== 0 ? speed_w
: speed_c
);
260 int device_ifindex(const char *ifname
)
262 int ret
, sock
, index
;
264 if (!strncmp("any", ifname
, strlen("any")))
266 sock
= af_socket(AF_INET
);
267 memset(&ifr
, 0, sizeof(ifr
));
268 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
269 ret
= ioctl(sock
, SIOCGIFINDEX
, &ifr
);
271 index
= ifr
.ifr_ifindex
;
278 int device_address(const char *ifname
, int af
, struct sockaddr_storage
*ss
)
284 if (!strncmp("any", ifname
, strlen("any")))
286 sock
= af_socket(af
);
287 memset(&ifr
, 0, sizeof(ifr
));
288 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
289 ifr
.ifr_addr
.sa_family
= af
;
290 ret
= ioctl(sock
, SIOCGIFADDR
, &ifr
);
292 memcpy(ss
, &ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
297 int device_mtu(const char *ifname
)
301 sock
= af_socket(AF_INET
);
302 memset(&ifr
, 0, sizeof(ifr
));
303 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
304 ret
= ioctl(sock
, SIOCGIFMTU
, &ifr
);
313 short device_get_flags(const char *ifname
)
315 /* Really, it's short! Look at struct ifreq */
319 sock
= af_socket(AF_INET
);
320 memset(&ifr
, 0, sizeof(ifr
));
321 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
322 ret
= ioctl(sock
, SIOCGIFFLAGS
, &ifr
);
324 flags
= ifr
.ifr_flags
;
331 void device_set_flags(const char *ifname
, const short flags
)
335 sock
= af_socket(AF_INET
);
336 memset(&ifr
, 0, sizeof(ifr
));
337 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
338 ifr
.ifr_flags
= flags
;
339 ret
= ioctl(sock
, SIOCSIFFLAGS
, &ifr
);
341 panic("Cannot set NIC flags!\n");
345 int device_irq_number(const char *ifname
)
348 * Since fetching IRQ numbers from SIOCGIFMAP is deprecated and not
349 * supported anymore, we need to grab them from procfs
355 if (!strncmp("lo", ifname
, strlen("lo")))
357 FILE *fp
= fopen("/proc/interrupts", "r");
359 whine("Cannot open /proc/interrupts!\n");
362 memset(buff
, 0, sizeof(buff
));
363 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
364 buff
[sizeof(buff
) - 1] = 0;
365 if (strstr(buff
, ifname
) == NULL
)
368 while (*buffp
!= ':')
372 memset(buff
, 0, sizeof(buff
));
378 * Try sysfs as fallback. Probably wireless devices will be found
379 * here. We return silently if it fails ...
381 slprintf(sysname
, sizeof(sysname
), "/sys/class/net/%s/device/irq",
383 fp
= fopen(sysname
, "r");
386 memset(buff
, 0, sizeof(buff
));
387 if(fgets(buff
, sizeof(buff
), fp
) != NULL
) {
388 buff
[sizeof(buff
) - 1] = 0;
395 int device_bind_irq_to_cpu(int irq
, int cpu
)
400 /* Note: first CPU begins with CPU 0 */
401 if (irq
< 0 || cpu
< 0)
403 memset(file
, 0, sizeof(file
));
404 memset(buff
, 0, sizeof(buff
));
405 /* smp_affinity starts counting with CPU 1, 2, ... */
407 sprintf(file
, "/proc/irq/%d/smp_affinity", irq
);
408 FILE *fp
= fopen(file
, "w");
410 whine("Cannot open file %s!\n", file
);
413 sprintf(buff
, "%d", cpu
);
414 ret
= fwrite(buff
, sizeof(buff
), 1, fp
);
416 return (ret
> 0 ? 0 : ret
);
419 void sock_print_net_stats(int sock
)
422 struct tpacket_stats kstats
;
423 socklen_t slen
= sizeof(kstats
);
424 memset(&kstats
, 0, sizeof(kstats
));
425 ret
= getsockopt(sock
, SOL_PACKET
, PACKET_STATISTICS
, &kstats
, &slen
);
427 printf("\r%12d frames incoming\n",
429 printf("\r%12d frames passed filter\n",
430 kstats
.tp_packets
- kstats
.tp_drops
);
431 printf("\r%12d frames failed filter (out of space)\n",
433 if (kstats
.tp_packets
> 0)
434 printf("\r%12.4f%% frame droprate\n", 1.f
*
435 kstats
.tp_drops
/ kstats
.tp_packets
* 100.f
);
439 void register_signal(int signal
, void (*handler
)(int))
442 struct sigaction saction
;
443 sigfillset(&block_mask
);
444 saction
.sa_handler
= handler
;
445 saction
.sa_mask
= block_mask
;
446 saction
.sa_flags
= SA_RESTART
;
447 sigaction(signal
, &saction
, NULL
);
450 void register_signal_f(int signal
, void (*handler
)(int), int flags
)
453 struct sigaction saction
;
454 sigfillset(&block_mask
);
455 saction
.sa_handler
= handler
;
456 saction
.sa_mask
= block_mask
;
457 saction
.sa_flags
= flags
;
458 sigaction(signal
, &saction
, NULL
);
461 int get_tty_size(void)
464 struct ttysize ts
= {0};
465 int ret
= ioctl(0, TIOCGSIZE
, &ts
);
466 return (ret
== 0 ? ts
.ts_cols
: DEFAULT_TTY_SIZE
);
467 #elif defined(TIOCGWINSZ)
469 memset(&ts
, 0, sizeof(ts
));
470 int ret
= ioctl(0, TIOCGWINSZ
, &ts
);
471 return (ret
== 0 ? ts
.ws_col
: DEFAULT_TTY_SIZE
);
473 return DEFAULT_TTY_SIZE
;
477 void check_for_root_maybe_die(void)
479 if (geteuid() != 0 || geteuid() != getuid())
480 panic("Uhhuh, not root?!\n");
483 short enter_promiscuous_mode(char *ifname
)
485 if (!strncmp("any", ifname
, strlen("any")))
487 short ifflags
= device_get_flags(ifname
);
488 device_set_flags(ifname
, ifflags
| IFF_PROMISC
);
492 void leave_promiscuous_mode(char *ifname
, short oldflags
)
494 if (!strncmp("any", ifname
, strlen("any")))
496 device_set_flags(ifname
, oldflags
);
499 int device_up(char *ifname
)
503 if (!strncmp("any", ifname
, strlen("any")))
505 return (device_get_flags(ifname
) & IFF_UP
) == IFF_UP
;
508 int device_running(char *ifname
)
512 if (!strncmp("any", ifname
, strlen("any")))
514 return (device_get_flags(ifname
) & IFF_RUNNING
) == IFF_RUNNING
;
517 int device_up_and_running(char *ifname
)
521 if (!strncmp("any", ifname
, strlen("any")))
523 return (device_get_flags(ifname
) & (IFF_UP
| IFF_RUNNING
)) ==
524 (IFF_UP
| IFF_RUNNING
);
527 int poll_error_maybe_die(int sock
, struct pollfd
*pfd
)
529 if ((pfd
->revents
& (POLLHUP
| POLLRDHUP
| POLLERR
| POLLNVAL
)) == 0)
530 return POLL_NEXT_PKT
;
531 if (pfd
->revents
& (POLLHUP
| POLLRDHUP
))
532 panic("Hangup on socket occured!\n");
533 if (pfd
->revents
& POLLERR
) {
536 if (recv(sock
, &tmp
, sizeof(tmp
), MSG_PEEK
) >= 0)
537 return POLL_NEXT_PKT
;
538 if (errno
== ENETDOWN
)
539 panic("Interface went down!\n");
540 return POLL_MOVE_OUT
;
542 if (pfd
->revents
& POLLNVAL
) {
543 whine("Invalid polling request on socket!\n");
544 return POLL_MOVE_OUT
;
546 return POLL_NEXT_PKT
;
549 static inline char *next_token(char *q
, int sep
)
554 * glibc defines this as a macro and gcc throws a false
555 * positive ``logical ‘&&’ with non-zero constant will
556 * always evaluate as true'' in older versions. See:
557 * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36513
564 int set_cpu_affinity(char *str
, int inverted
)
568 cpu_set_t cpu_bitmask
;
570 cpus
= get_number_cpus();
571 CPU_ZERO(&cpu_bitmask
);
572 for (i
= 0; inverted
&& i
< cpus
; ++i
)
573 CPU_SET(i
, &cpu_bitmask
);
574 while (p
= q
, q
= next_token(q
, ','), p
) {
575 unsigned int a
; /* Beginning of range */
576 unsigned int b
; /* End of range */
577 unsigned int s
; /* Stride */
579 if (sscanf(p
, "%u", &a
) < 1)
583 c1
= next_token(p
, '-');
584 c2
= next_token(p
, ',');
585 if (c1
!= NULL
&& (c2
== NULL
|| c1
< c2
)) {
586 if (sscanf(c1
, "%u", &b
) < 1)
588 c1
= next_token(c1
, ':');
589 if (c1
!= NULL
&& (c2
== NULL
|| c1
< c2
))
590 if (sscanf(c1
, "%u", &s
) < 1)
597 CPU_CLR(a
, &cpu_bitmask
);
599 CPU_SET(a
, &cpu_bitmask
);
603 ret
= sched_setaffinity(getpid(), sizeof(cpu_bitmask
),
606 panic("Can't set this cpu affinity!\n");
610 char *get_cpu_affinity(char *cpu_string
, size_t len
)
613 cpu_set_t cpu_bitmask
;
614 if (len
!= get_number_cpus() + 1)
616 CPU_ZERO(&cpu_bitmask
);
617 ret
= sched_getaffinity(getpid(), sizeof(cpu_bitmask
),
620 whine("Can't fetch cpu affinity!\n");
623 for (i
= 0, cpu_string
[len
- 1] = 0; i
< len
- 1; ++i
) {
624 cpu
= CPU_ISSET(i
, &cpu_bitmask
);
625 cpu_string
[i
] = (cpu
? '1' : '0');
630 int set_proc_prio(int priority
)
633 * setpriority() is clever, even if you put a nice value which
634 * is out of range it corrects it to the closest valid nice value
636 int ret
= setpriority(PRIO_PROCESS
, getpid(), priority
);
638 panic("Can't set nice val to %i!\n", priority
);
642 int set_sched_status(int policy
, int priority
)
644 int ret
, min_prio
, max_prio
;
645 struct sched_param sp
;
646 max_prio
= sched_get_priority_max(policy
);
647 min_prio
= sched_get_priority_min(policy
);
648 if (max_prio
== -1 || min_prio
== -1)
649 whine("Cannot determine scheduler prio limits!\n");
650 else if (priority
< min_prio
)
652 else if (priority
> max_prio
)
654 memset(&sp
, 0, sizeof(sp
));
655 sp
.sched_priority
= priority
;
656 ret
= sched_setscheduler(getpid(), policy
, &sp
);
658 whine("Cannot set scheduler policy!\n");
661 ret
= sched_setparam(getpid(), &sp
);
663 whine("Cannot set scheduler prio!\n");
669 int set_timeout(struct timeval
*timeval
, unsigned int msec
)
674 timeval
->tv_usec
= 0;
676 timeval
->tv_usec
= msec
* 1000;
679 timeval
->tv_sec
= (long) (msec
/ 1000);
680 timeval
->tv_usec
= (long) ((msec
- (timeval
->tv_sec
* 1000)) * 1000);