proto_ipv4: don't trim length of pkt_buff
[netsniff-ng.git] / src / xsys.c
blob4cf6038e07ddb36cadd7c8c52034fb80afe69b6f
1 /*
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 * Copyright 2010 Marek Polacek.
7 * Subject to the GPL, version 2.
8 */
10 #define _GNU_SOURCE
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stdint.h>
14 #include <fcntl.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <errno.h>
18 #include <signal.h>
19 #include <arpa/inet.h>
20 #include <time.h>
21 #include <sched.h>
22 #include <limits.h>
23 #include <stdbool.h>
24 #include <sys/time.h>
25 #include <sys/socket.h>
26 #include <sys/ioctl.h>
27 #include <sys/resource.h>
28 #include <sys/epoll.h>
29 #include <sys/syscall.h>
30 #include <asm/unistd.h>
31 /* Kernel < 2.6.26 */
32 #include <linux/if.h>
33 #include <linux/socket.h>
34 #include <linux/types.h>
35 /* Kernel < 2.6.26 */
36 #include <linux/if_ether.h>
37 #include <linux/if_packet.h>
38 #include <linux/sockios.h>
39 #include <netinet/tcp.h>
40 #include <netinet/udp.h>
42 #include "die.h"
43 #include "xsys.h"
44 #include "xstring.h"
45 #include "ring.h"
46 #include "tprintf.h"
47 #include "built_in.h"
49 #define IOPRIO_CLASS_SHIFT 13
51 enum {
52 ioprio_class_none,
53 ioprio_class_rt,
54 ioprio_class_be,
55 ioprio_class_idle,
58 enum {
59 ioprio_who_process = 1,
60 ioprio_who_pgrp,
61 ioprio_who_user,
64 static const char *const to_prio[] = {
65 "none", "realtime", "best-effort", "idle", };
67 int af_socket(int af)
69 int sock;
71 if (unlikely(af != AF_INET && af != AF_INET6)) {
72 whine("Wrong AF socket type! Falling back to AF_INET\n");
73 af = AF_INET;
76 sock = socket(af, SOCK_DGRAM, 0);
77 if (unlikely(sock < 0))
78 panic("Creation AF socket failed!\n");
80 return sock;
83 int pf_socket(void)
85 int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
86 if (unlikely(sock < 0))
87 panic("Creation of PF socket failed!\n");
89 return sock;
92 void set_udp_cork(int fd)
94 int state = 1;
95 setsockopt(fd, IPPROTO_UDP, UDP_CORK, &state, sizeof(state));
98 void set_udp_uncork(int fd)
100 int state = 0;
101 setsockopt(fd, IPPROTO_UDP, UDP_CORK, &state, sizeof(state));
104 void set_tcp_cork(int fd)
106 int state = 1;
107 setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
110 void set_tcp_uncork(int fd)
112 int state = 0;
113 setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
116 void set_sock_cork(int fd, int udp)
118 if (!!udp)
119 set_udp_cork(fd);
120 else
121 set_tcp_cork(fd);
124 void set_sock_uncork(int fd, int udp)
126 if (!!udp)
127 set_udp_uncork(fd);
128 else
129 set_tcp_uncork(fd);
132 int set_nonblocking(int fd)
134 int ret = fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
135 if (unlikely(ret < 0))
136 panic("Cannot fcntl!\n");
138 return 0;
141 int set_nonblocking_sloppy(int fd)
143 return fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
146 void set_socket_keepalive(int fd)
148 int one = 1;
149 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one));
152 void set_tcp_nodelay(int fd)
154 int one = 1;
155 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
158 int set_ipv6_only(int fd)
160 int one = 1;
161 return setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
164 int set_reuseaddr(int fd)
166 int ret, one = 1;
168 ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (one));
169 if (unlikely(ret < 0))
170 panic("Cannot reuse addr!\n");
172 return 0;
175 void set_mtu_disc_dont(int fd)
177 int mtu = IP_PMTUDISC_DONT;
178 setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu));
181 void set_epoll_descriptor(int fd_epoll, int action, int fd_toadd, int events)
183 int ret;
184 struct epoll_event ev;
186 memset(&ev, 0, sizeof(ev));
187 ev.events = events;
188 ev.data.fd = fd_toadd;
190 ret = epoll_ctl(fd_epoll, action, fd_toadd, &ev);
191 if (ret < 0)
192 panic("Cannot add socket for epoll!\n");
195 int set_epoll_descriptor2(int fd_epoll, int action, int fd_toadd, int events)
197 struct epoll_event ev;
199 memset(&ev, 0, sizeof(ev));
200 ev.events = events;
201 ev.data.fd = fd_toadd;
203 return epoll_ctl(fd_epoll, action, fd_toadd, &ev);
206 int wireless_bitrate(const char *ifname)
208 int sock, ret, rate_in_mbit;
209 struct iwreq iwr;
211 sock = af_socket(AF_INET);
213 memset(&iwr, 0, sizeof(iwr));
214 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
216 ret = ioctl(sock, SIOCGIWRATE, &iwr);
217 if (!ret)
218 rate_in_mbit = iwr.u.bitrate.value / 1000000;
219 else
220 rate_in_mbit = 0;
222 close(sock);
224 return rate_in_mbit;
227 int adjust_dbm_level(int dbm_val)
229 if (dbm_val >= 64)
230 dbm_val -= 0x100;
231 return dbm_val;
234 int wireless_sigqual(const char *ifname, struct iw_statistics *stats)
236 int ret, sock;
237 struct iwreq iwr;
239 sock = af_socket(AF_INET);
241 memset(&iwr, 0, sizeof(iwr));
242 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
244 iwr.u.data.pointer = (caddr_t) stats;
245 iwr.u.data.length = sizeof(*stats);
246 iwr.u.data.flags = 1;
248 ret = ioctl(sock, SIOCGIWSTATS, &iwr);
250 close(sock);
252 return ret;
255 int wireless_rangemax_sigqual(const char *ifname)
257 int ret, sock, sigqual;
258 struct iwreq iwr;
259 struct iw_range iwrange;
261 sock = af_socket(AF_INET);
263 memset(&iwrange, 0, sizeof(iwrange));
265 memset(&iwr, 0, sizeof(iwr));
266 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
268 iwr.u.data.pointer = (caddr_t) &iwrange;
269 iwr.u.data.length = sizeof(iwrange);
270 iwr.u.data.flags = 0;
272 ret = ioctl(sock, SIOCGIWRANGE, &iwr);
273 if (!ret)
274 sigqual = iwrange.max_qual.qual;
275 else
276 sigqual = 0;
278 close(sock);
280 return sigqual;
283 int ethtool_bitrate(const char *ifname)
285 int ret, sock, bitrate;
286 struct ifreq ifr;
287 struct ethtool_cmd ecmd;
289 sock = af_socket(AF_INET);
291 memset(&ecmd, 0, sizeof(ecmd));
293 memset(&ifr, 0, sizeof(ifr));
294 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
296 ecmd.cmd = ETHTOOL_GSET;
297 ifr.ifr_data = (char *) &ecmd;
299 ret = ioctl(sock, SIOCETHTOOL, &ifr);
300 if (ret) {
301 bitrate = 0;
302 goto out;
305 switch (ecmd.speed) {
306 case SPEED_10:
307 case SPEED_100:
308 case SPEED_1000:
309 case SPEED_10000:
310 bitrate = ecmd.speed;
311 break;
312 default:
313 bitrate = 0;
314 break;
316 out:
317 close(sock);
319 return bitrate;
322 int ethtool_drvinf(const char *ifname, struct ethtool_drvinfo *drvinf)
324 int ret, sock;
325 struct ifreq ifr;
327 sock = af_socket(AF_INET);
329 memset(drvinf, 0, sizeof(*drvinf));
331 memset(&ifr, 0, sizeof(ifr));
332 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
334 drvinf->cmd = ETHTOOL_GDRVINFO;
335 ifr.ifr_data = (char *) drvinf;
337 ret = ioctl(sock, SIOCETHTOOL, &ifr);
339 close(sock);
341 return ret;
344 int device_bitrate(const char *ifname)
346 int speed_c, speed_w;
348 speed_c = ethtool_bitrate(ifname);
349 speed_w = wireless_bitrate(ifname);
351 return (speed_c == 0 ? speed_w : speed_c);
354 int device_ifindex(const char *ifname)
356 int ret, sock, index;
357 struct ifreq ifr;
359 if (!strncmp("any", ifname, strlen("any")))
360 return 0;
362 sock = af_socket(AF_INET);
364 memset(&ifr, 0, sizeof(ifr));
365 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
367 ret = ioctl(sock, SIOCGIFINDEX, &ifr);
368 if (!ret)
369 index = ifr.ifr_ifindex;
370 else
371 index = -1;
373 close(sock);
375 return index;
378 int device_address(const char *ifname, int af, struct sockaddr_storage *ss)
380 int ret, sock;
381 struct ifreq ifr;
383 if (!ss)
384 return -EINVAL;
385 if (!strncmp("any", ifname, strlen("any")))
386 return -EINVAL;
388 sock = af_socket(af);
390 memset(&ifr, 0, sizeof(ifr));
391 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
393 ifr.ifr_addr.sa_family = af;
395 ret = ioctl(sock, SIOCGIFADDR, &ifr);
396 if (!ret)
397 memcpy(ss, &ifr.ifr_addr, sizeof(ifr.ifr_addr));
399 close(sock);
401 return ret;
404 int device_mtu(const char *ifname)
406 int ret, sock, mtu;
407 struct ifreq ifr;
409 sock = af_socket(AF_INET);
411 memset(&ifr, 0, sizeof(ifr));
412 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
414 ret = ioctl(sock, SIOCGIFMTU, &ifr);
415 if (!ret)
416 mtu = ifr.ifr_mtu;
417 else
418 mtu = 0;
420 close(sock);
422 return mtu;
425 short device_get_flags(const char *ifname)
427 /* Really, it's short! Look at struct ifreq */
428 short flags;
429 int ret, sock;
430 struct ifreq ifr;
432 sock = af_socket(AF_INET);
434 memset(&ifr, 0, sizeof(ifr));
435 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
437 ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
438 if (!ret)
439 flags = ifr.ifr_flags;
440 else
441 flags = 0;
443 close(sock);
445 return flags;
448 void device_set_flags(const char *ifname, const short flags)
450 int ret, sock;
451 struct ifreq ifr;
453 sock = af_socket(AF_INET);
455 memset(&ifr, 0, sizeof(ifr));
456 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
458 ifr.ifr_flags = flags;
460 ret = ioctl(sock, SIOCSIFFLAGS, &ifr);
461 if (ret < 0)
462 panic("Cannot set NIC flags!\n");
464 close(sock);
467 int device_irq_number(const char *ifname)
470 * Since fetching IRQ numbers from SIOCGIFMAP is deprecated and not
471 * supported anymore, we need to grab them from procfs
473 int irq = 0;
474 char *buffp;
475 char buff[512];
476 char sysname[512];
478 if (!strncmp("lo", ifname, strlen("lo")))
479 return 0;
481 FILE *fp = fopen("/proc/interrupts", "r");
482 if (!fp) {
483 whine("Cannot open /proc/interrupts!\n");
484 return -ENOENT;
487 memset(buff, 0, sizeof(buff));
488 while (fgets(buff, sizeof(buff), fp) != NULL) {
489 buff[sizeof(buff) - 1] = 0;
491 if (strstr(buff, ifname) == NULL)
492 continue;
494 buffp = buff;
495 while (*buffp != ':')
496 buffp++;
497 *buffp = 0;
498 irq = atoi(buff);
500 memset(buff, 0, sizeof(buff));
503 fclose(fp);
505 if (irq != 0)
506 return irq;
508 * Try sysfs as fallback. Probably wireless devices will be found
509 * here. We return silently if it fails ...
511 slprintf(sysname, sizeof(sysname), "/sys/class/net/%s/device/irq",
512 ifname);
514 fp = fopen(sysname, "r");
515 if (!fp)
516 return -ENOENT;
518 memset(buff, 0, sizeof(buff));
519 if(fgets(buff, sizeof(buff), fp) != NULL) {
520 buff[sizeof(buff) - 1] = 0;
521 irq = atoi(buff);
524 fclose(fp);
526 return irq;
529 int device_bind_irq_to_cpu(int irq, int cpu)
531 int ret;
532 char buff[256];
533 char file[256];
535 /* Note: first CPU begins with CPU 0 */
536 if (irq < 0 || cpu < 0)
537 return -EINVAL;
539 memset(file, 0, sizeof(file));
540 memset(buff, 0, sizeof(buff));
542 /* smp_affinity starts counting with CPU 1, 2, ... */
543 cpu = cpu + 1;
544 sprintf(file, "/proc/irq/%d/smp_affinity", irq);
546 FILE *fp = fopen(file, "w");
547 if (!fp) {
548 whine("Cannot open file %s!\n", file);
549 return -ENOENT;
552 sprintf(buff, "%d", cpu);
553 ret = fwrite(buff, sizeof(buff), 1, fp);
555 fclose(fp);
556 return (ret > 0 ? 0 : ret);
559 void sock_print_net_stats(int sock, unsigned long skipped)
561 int ret;
562 struct tpacket_stats kstats;
564 socklen_t slen = sizeof(kstats);
566 memset(&kstats, 0, sizeof(kstats));
568 ret = getsockopt(sock, SOL_PACKET, PACKET_STATISTICS, &kstats, &slen);
569 if (ret > -1) {
570 printf("\r%12ld frames incoming\n",
571 1UL * kstats.tp_packets);
572 printf("\r%12ld frames passed filter\n",
573 1UL * kstats.tp_packets - kstats.tp_drops - skipped);
574 printf("\r%12ld frames failed filter (out of space)\n",
575 1UL * kstats.tp_drops + skipped);
576 if (kstats.tp_packets > 0)
577 printf("\r%12.4f%% frame droprate\n", 1.f *
578 kstats.tp_drops / kstats.tp_packets * 100.f);
582 void register_signal(int signal, void (*handler)(int))
584 sigset_t block_mask;
585 struct sigaction saction;
587 sigfillset(&block_mask);
589 saction.sa_handler = handler;
590 saction.sa_mask = block_mask;
591 saction.sa_flags = SA_RESTART;
592 sigaction(signal, &saction, NULL);
595 void register_signal_f(int signal, void (*handler)(int), int flags)
597 sigset_t block_mask;
598 struct sigaction saction;
600 sigfillset(&block_mask);
602 saction.sa_handler = handler;
603 saction.sa_mask = block_mask;
604 saction.sa_flags = flags;
605 sigaction(signal, &saction, NULL);
608 int get_tty_size(void)
610 #ifdef TIOCGSIZE
611 struct ttysize ts = {0};
612 int ret = ioctl(0, TIOCGSIZE, &ts);
613 return (ret == 0 ? ts.ts_cols : DEFAULT_TTY_SIZE);
614 #elif defined(TIOCGWINSZ)
615 struct winsize ts;
616 memset(&ts, 0, sizeof(ts));
617 int ret = ioctl(0, TIOCGWINSZ, &ts);
618 return (ret == 0 ? ts.ws_col : DEFAULT_TTY_SIZE);
619 #else
620 return DEFAULT_TTY_SIZE;
621 #endif
624 void check_for_root_maybe_die(void)
626 if (geteuid() != 0 || geteuid() != getuid())
627 panic("Uhhuh, not root?!\n");
630 short enter_promiscuous_mode(char *ifname)
632 short ifflags;
634 if (!strncmp("any", ifname, strlen("any")))
635 return 0;
637 ifflags = device_get_flags(ifname);
638 device_set_flags(ifname, ifflags | IFF_PROMISC);
640 return ifflags;
643 void leave_promiscuous_mode(char *ifname, short oldflags)
645 if (!strncmp("any", ifname, strlen("any")))
646 return;
648 device_set_flags(ifname, oldflags);
651 int device_up(char *ifname)
653 if (!ifname)
654 return -EINVAL;
655 if (!strncmp("any", ifname, strlen("any")))
656 return 1;
658 return (device_get_flags(ifname) & IFF_UP) == IFF_UP;
661 int device_running(char *ifname)
663 if (!ifname)
664 return -EINVAL;
665 if (!strncmp("any", ifname, strlen("any")))
666 return 1;
668 return (device_get_flags(ifname) & IFF_RUNNING) == IFF_RUNNING;
671 int device_up_and_running(char *ifname)
673 if (!ifname)
674 return -EINVAL;
675 if (!strncmp("any", ifname, strlen("any")))
676 return 1;
678 return (device_get_flags(ifname) & (IFF_UP | IFF_RUNNING)) ==
679 (IFF_UP | IFF_RUNNING);
682 int poll_error_maybe_die(int sock, struct pollfd *pfd)
684 if ((pfd->revents & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL)) == 0)
685 return POLL_NEXT_PKT;
686 if (pfd->revents & (POLLHUP | POLLRDHUP))
687 panic("Hangup on socket occured!\n");
688 if (pfd->revents & POLLERR) {
689 int tmp;
691 errno = 0;
692 if (recv(sock, &tmp, sizeof(tmp), MSG_PEEK) >= 0)
693 return POLL_NEXT_PKT;
694 if (errno == ENETDOWN)
695 panic("Interface went down!\n");
697 return POLL_MOVE_OUT;
699 if (pfd->revents & POLLNVAL) {
700 whine("Invalid polling request on socket!\n");
702 return POLL_MOVE_OUT;
705 return POLL_NEXT_PKT;
708 static inline char *next_token(char *q, int sep)
710 if (q)
711 q = strchr(q, sep);
713 * glibc defines this as a macro and gcc throws a false
714 * positive ``logical ‘&&’ with non-zero constant will
715 * always evaluate as true'' in older versions. See:
716 * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36513
718 if (q)
719 q++;
720 return q;
723 int set_cpu_affinity(char *str, int inverted)
725 int ret, i, cpus;
726 char *p, *q;
727 cpu_set_t cpu_bitmask;
729 q = str;
731 cpus = get_number_cpus();
733 CPU_ZERO(&cpu_bitmask);
735 for (i = 0; inverted && i < cpus; ++i)
736 CPU_SET(i, &cpu_bitmask);
738 while (p = q, q = next_token(q, ','), p) {
739 unsigned int a; /* Beginning of range */
740 unsigned int b; /* End of range */
741 unsigned int s; /* Stride */
742 char *c1, *c2;
744 if (sscanf(p, "%u", &a) < 1)
745 return -EINVAL;
747 b = a;
748 s = 1;
750 c1 = next_token(p, '-');
751 c2 = next_token(p, ',');
753 if (c1 != NULL && (c2 == NULL || c1 < c2)) {
754 if (sscanf(c1, "%u", &b) < 1)
755 return -EINVAL;
757 c1 = next_token(c1, ':');
759 if (c1 != NULL && (c2 == NULL || c1 < c2))
760 if (sscanf(c1, "%u", &s) < 1)
761 return -EINVAL;
764 if (!(a <= b))
765 return -EINVAL;
767 while (a <= b) {
768 if (inverted)
769 CPU_CLR(a, &cpu_bitmask);
770 else
771 CPU_SET(a, &cpu_bitmask);
772 a += s;
776 ret = sched_setaffinity(getpid(), sizeof(cpu_bitmask),
777 &cpu_bitmask);
778 if (ret)
779 panic("Can't set this cpu affinity!\n");
781 return 0;
784 int set_proc_prio(int priority)
787 * setpriority() is clever, even if you put a nice value which
788 * is out of range it corrects it to the closest valid nice value
790 int ret = setpriority(PRIO_PROCESS, getpid(), priority);
791 if (ret)
792 panic("Can't set nice val to %i!\n", priority);
794 return 0;
797 int set_sched_status(int policy, int priority)
799 int ret, min_prio, max_prio;
800 struct sched_param sp;
802 max_prio = sched_get_priority_max(policy);
803 min_prio = sched_get_priority_min(policy);
805 if (max_prio == -1 || min_prio == -1)
806 whine("Cannot determine scheduler prio limits!\n");
807 else if (priority < min_prio)
808 priority = min_prio;
809 else if (priority > max_prio)
810 priority = max_prio;
812 memset(&sp, 0, sizeof(sp));
813 sp.sched_priority = priority;
815 ret = sched_setscheduler(getpid(), policy, &sp);
816 if (ret) {
817 whine("Cannot set scheduler policy!\n");
818 return -EINVAL;
821 ret = sched_setparam(getpid(), &sp);
822 if (ret) {
823 whine("Cannot set scheduler prio!\n");
824 return -EINVAL;
827 return 0;
830 static inline int ioprio_set(int which, int who, int ioprio)
832 return syscall(SYS_ioprio_set, which, who, ioprio);
835 static inline int ioprio_get(int which, int who)
837 return syscall(SYS_ioprio_get, which, who);
840 static void ioprio_setpid(pid_t pid, int ioprio, int ioclass)
842 int ret = ioprio_set(ioprio_who_process, pid,
843 ioprio | ioclass << IOPRIO_CLASS_SHIFT);
844 if (ret < 0)
845 panic("Failed to set io prio for pid!\n");
848 void ioprio_print(void)
850 int ioprio = ioprio_get(ioprio_who_process, getpid());
851 if (ioprio < 0)
852 panic("Failed to fetch io prio for pid!\n");
853 else {
854 int ioclass = ioprio >> IOPRIO_CLASS_SHIFT;
855 if (ioclass != ioprio_class_idle) {
856 ioprio &= 0xff;
857 printf("%s: prio %d\n", to_prio[ioclass], ioprio);
858 } else
859 printf("%s\n", to_prio[ioclass]);
863 void set_ioprio_rt(void)
865 ioprio_setpid(getpid(), 4, ioprio_class_rt);
868 void set_ioprio_be(void)
870 ioprio_setpid(getpid(), 4, ioprio_class_be);
873 int set_timeout(struct timeval *timeval, unsigned int msec)
875 if (msec == 0)
876 return -EINVAL;
878 timeval->tv_sec = 0;
879 timeval->tv_usec = 0;
881 if (msec < 1000) {
882 timeval->tv_usec = msec * 1000;
883 return 0;
886 timeval->tv_sec = (long) (msec / 1000);
887 timeval->tv_usec = (long) ((msec - (timeval->tv_sec * 1000)) * 1000);
889 return 0;