dissectors: lldp: check for all mandatory TLVs at correct position
[netsniff-ng.git] / xutils.c
blobb70fca397abfcead077452a6381ac9083428075a
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 <stdarg.h>
19 #include <ctype.h>
20 #include <signal.h>
21 #include <arpa/inet.h>
22 #include <time.h>
23 #include <sched.h>
24 #include <limits.h>
25 #include <stdbool.h>
26 #include <netdb.h>
27 #include <ifaddrs.h>
28 #include <sys/time.h>
29 #include <sys/socket.h>
30 #include <sys/ioctl.h>
31 #include <sys/mman.h>
32 #include <sys/resource.h>
33 #include <sys/epoll.h>
34 #include <sys/syscall.h>
35 #include <asm/unistd.h>
36 #include <linux/if.h>
37 #include <linux/socket.h>
38 #include <linux/types.h>
39 #include <linux/if_ether.h>
40 #include <linux/if_packet.h>
41 #include <linux/sockios.h>
42 #include <netinet/tcp.h>
43 #include <netinet/udp.h>
45 #include "die.h"
46 #include "xutils.h"
47 #include "ring.h"
48 #include "tprintf.h"
49 #include "built_in.h"
51 #define IOPRIO_CLASS_SHIFT 13
53 enum {
54 ioprio_class_none,
55 ioprio_class_rt,
56 ioprio_class_be,
57 ioprio_class_idle,
60 enum {
61 ioprio_who_process = 1,
62 ioprio_who_pgrp,
63 ioprio_who_user,
66 enum {
67 sock_rmem_max = 0,
68 sock_rmem_def,
69 sock_wmem_max,
70 sock_wmem_def,
73 #define SMEM_SUG_MAX 104857600
74 #define SMEM_SUG_DEF 4194304
76 static const char *const to_prio[] = {
77 "none",
78 "realtime",
79 "best-effort",
80 "idle",
83 static const char *const sock_mem[] = {
84 "/proc/sys/net/core/rmem_max",
85 "/proc/sys/net/core/rmem_default",
86 "/proc/sys/net/core/wmem_max",
87 "/proc/sys/net/core/wmem_default",
90 int af_socket(int af)
92 int sock;
94 if (unlikely(af != AF_INET && af != AF_INET6))
95 panic("Wrong AF socket type! Falling back to AF_INET\n");
97 sock = socket(af, SOCK_DGRAM, 0);
98 if (unlikely(sock < 0))
99 panic("Creation AF socket failed!\n");
101 return sock;
104 int pf_socket(void)
106 int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
107 if (unlikely(sock < 0))
108 panic("Creation of PF socket failed!\n");
110 return sock;
113 void set_sock_prio(int fd, int prio)
115 int val = prio;
116 setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
119 void set_udp_cork(int fd)
121 int state = 1;
122 setsockopt(fd, IPPROTO_UDP, UDP_CORK, &state, sizeof(state));
125 void set_udp_uncork(int fd)
127 int state = 0;
128 setsockopt(fd, IPPROTO_UDP, UDP_CORK, &state, sizeof(state));
131 void set_tcp_cork(int fd)
133 int state = 1;
134 setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
137 void set_tcp_uncork(int fd)
139 int state = 0;
140 setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
143 void set_sock_cork(int fd, int udp)
145 if (!!udp)
146 set_udp_cork(fd);
147 else
148 set_tcp_cork(fd);
151 void set_sock_uncork(int fd, int udp)
153 if (!!udp)
154 set_udp_uncork(fd);
155 else
156 set_tcp_uncork(fd);
159 int set_nonblocking(int fd)
161 int ret = fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
162 if (unlikely(ret < 0))
163 panic("Cannot fcntl!\n");
165 return 0;
168 int set_nonblocking_sloppy(int fd)
170 return fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
173 void set_socket_keepalive(int fd)
175 int one = 1;
176 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one));
179 void set_tcp_nodelay(int fd)
181 int one = 1;
182 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
185 int set_ipv6_only(int fd)
187 int one = 1;
188 return setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
191 int set_reuseaddr(int fd)
193 int ret, one = 1;
195 ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (one));
196 if (unlikely(ret < 0))
197 panic("Cannot reuse addr!\n");
199 return 0;
202 void set_mtu_disc_dont(int fd)
204 int mtu = IP_PMTUDISC_DONT;
205 setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu));
208 void set_epoll_descriptor(int fd_epoll, int action, int fd_toadd, int events)
210 int ret;
211 struct epoll_event ev;
213 memset(&ev, 0, sizeof(ev));
214 ev.events = events;
215 ev.data.fd = fd_toadd;
217 ret = epoll_ctl(fd_epoll, action, fd_toadd, &ev);
218 if (ret < 0)
219 panic("Cannot add socket for epoll!\n");
222 int set_epoll_descriptor2(int fd_epoll, int action, int fd_toadd, int events)
224 struct epoll_event ev;
226 memset(&ev, 0, sizeof(ev));
227 ev.events = events;
228 ev.data.fd = fd_toadd;
230 return epoll_ctl(fd_epoll, action, fd_toadd, &ev);
233 u32 wireless_bitrate(const char *ifname)
235 int sock, ret, rate_in_mbit;
236 struct iwreq iwr;
238 sock = af_socket(AF_INET);
240 memset(&iwr, 0, sizeof(iwr));
241 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
243 ret = ioctl(sock, SIOCGIWRATE, &iwr);
244 if (!ret)
245 rate_in_mbit = iwr.u.bitrate.value / 1000000;
246 else
247 rate_in_mbit = 0;
249 close(sock);
251 return rate_in_mbit;
254 int adjust_dbm_level(int in_dbm, int dbm_val)
256 if (!in_dbm)
257 return dbm_val;
259 return dbm_val - 0x100;
262 void drop_privileges(bool enforce, uid_t uid, gid_t gid)
264 if (enforce) {
265 if (uid == getuid())
266 panic("Uid cannot be the same as the current user!\n");
267 if (gid == getgid())
268 panic("Gid cannot be the same as the current user!\n");
270 if (setgid(gid) != 0)
271 panic("Unable to drop group privileges: %s!\n", strerror(errno));
272 if (setuid(uid) != 0)
273 panic("Unable to drop user privileges: %s!\n", strerror(errno));
276 int get_system_socket_mem(int which)
278 int fd, val = -1;
279 ssize_t ret;
280 const char *file = sock_mem[which];
281 char buff[64];
283 fd = open(file, O_RDONLY);
284 if (fd < 0)
285 return val;
287 ret = read(fd, buff, sizeof(buff));
288 if (ret > 0)
289 val = atoi(buff);
291 close(fd);
292 return val;
295 void set_system_socket_mem(int which, int val)
297 int fd;
298 const char *file = sock_mem[which];
299 ssize_t ret;
300 char buff[64];
302 fd = open(file, O_WRONLY);
303 if (fd < 0)
304 return;
306 memset(buff, 0, sizeof(buff));
307 slprintf(buff, sizeof(buff), "%d", val);
309 ret = write(fd, buff, strlen(buff));
310 ret = ret;
312 close(fd);
315 int wireless_sigqual(const char *ifname, struct iw_statistics *stats)
317 int ret, sock;
318 struct iwreq iwr;
320 sock = af_socket(AF_INET);
322 memset(&iwr, 0, sizeof(iwr));
323 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
325 iwr.u.data.pointer = (caddr_t) stats;
326 iwr.u.data.length = sizeof(*stats);
327 iwr.u.data.flags = 1;
329 ret = ioctl(sock, SIOCGIWSTATS, &iwr);
331 close(sock);
333 return ret;
336 int wireless_rangemax_sigqual(const char *ifname)
338 int ret, sock, sigqual;
339 struct iwreq iwr;
340 struct iw_range iwrange;
342 sock = af_socket(AF_INET);
344 memset(&iwrange, 0, sizeof(iwrange));
346 memset(&iwr, 0, sizeof(iwr));
347 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
349 iwr.u.data.pointer = (caddr_t) &iwrange;
350 iwr.u.data.length = sizeof(iwrange);
351 iwr.u.data.flags = 0;
353 ret = ioctl(sock, SIOCGIWRANGE, &iwr);
354 if (!ret)
355 sigqual = iwrange.max_qual.qual;
356 else
357 sigqual = 0;
359 close(sock);
361 return sigqual;
364 u32 ethtool_bitrate(const char *ifname)
366 int ret, sock, bitrate;
367 struct ifreq ifr;
368 struct ethtool_cmd ecmd;
370 sock = af_socket(AF_INET);
372 memset(&ecmd, 0, sizeof(ecmd));
374 memset(&ifr, 0, sizeof(ifr));
375 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
377 ecmd.cmd = ETHTOOL_GSET;
378 ifr.ifr_data = (char *) &ecmd;
380 ret = ioctl(sock, SIOCETHTOOL, &ifr);
381 if (ret) {
382 bitrate = 0;
383 goto out;
386 switch (ecmd.speed) {
387 case SPEED_10:
388 case SPEED_100:
389 case SPEED_1000:
390 case SPEED_2500:
391 case SPEED_10000:
392 bitrate = ecmd.speed;
393 break;
394 default:
395 bitrate = 0;
396 break;
398 out:
399 close(sock);
401 return bitrate;
404 int ethtool_link(const char *ifname)
406 int ret, sock;
407 struct ifreq ifr;
408 struct ethtool_value ecmd;
410 sock = af_socket(AF_INET);
412 memset(&ecmd, 0, sizeof(ecmd));
414 memset(&ifr, 0, sizeof(ifr));
415 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
417 ecmd.cmd = ETHTOOL_GLINK;
418 ifr.ifr_data = (char *) &ecmd;
420 ret = ioctl(sock, SIOCETHTOOL, &ifr);
421 if (ret)
422 ret = -EINVAL;
423 else
424 ret = !!ecmd.data;
426 close(sock);
427 return ret;
430 int ethtool_drvinf(const char *ifname, struct ethtool_drvinfo *drvinf)
432 int ret, sock;
433 struct ifreq ifr;
435 sock = af_socket(AF_INET);
437 memset(drvinf, 0, sizeof(*drvinf));
439 memset(&ifr, 0, sizeof(ifr));
440 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
442 drvinf->cmd = ETHTOOL_GDRVINFO;
443 ifr.ifr_data = (char *) drvinf;
445 ret = ioctl(sock, SIOCETHTOOL, &ifr);
447 close(sock);
449 return ret;
452 u32 device_bitrate(const char *ifname)
454 u32 speed_c, speed_w;
456 speed_c = ethtool_bitrate(ifname);
457 speed_w = wireless_bitrate(ifname);
459 return (speed_c == 0 ? speed_w : speed_c);
462 int device_ifindex(const char *ifname)
464 int ret, sock, index;
465 struct ifreq ifr;
467 if (!strncmp("any", ifname, strlen("any")))
468 return 0;
470 sock = af_socket(AF_INET);
472 memset(&ifr, 0, sizeof(ifr));
473 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
475 ret = ioctl(sock, SIOCGIFINDEX, &ifr);
476 if (!ret)
477 index = ifr.ifr_ifindex;
478 else
479 index = -1;
481 close(sock);
483 return index;
486 static int __device_address6(const char *ifname, struct sockaddr_storage *ss)
488 int ret, family, found = -EINVAL;
489 struct ifaddrs *ifaddr, *ifa;
491 ret = getifaddrs(&ifaddr);
492 if (ret < 0)
493 panic("Cannot get device addresses for IPv6!\n");
495 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
496 family = ifa->ifa_addr->sa_family;
497 if (family != AF_INET6)
498 continue;
499 if (strcmp(ifa->ifa_name, ifname))
500 continue;
502 memcpy(ss, ifa->ifa_addr, sizeof(*ss));
503 found = 0;
504 break;
507 freeifaddrs(ifaddr);
508 return found;
511 int device_address(const char *ifname, int af, struct sockaddr_storage *ss)
513 int ret, sock;
514 struct ifreq ifr;
516 if (!ss)
517 return -EINVAL;
518 if (!strncmp("any", ifname, strlen("any")))
519 return -EINVAL;
520 if (af == AF_INET6)
521 return __device_address6(ifname, ss);
523 sock = af_socket(af);
525 memset(&ifr, 0, sizeof(ifr));
526 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
528 ifr.ifr_addr.sa_family = af;
530 ret = ioctl(sock, SIOCGIFADDR, &ifr);
531 if (!ret)
532 memcpy(ss, &ifr.ifr_addr, sizeof(ifr.ifr_addr));
534 close(sock);
536 return ret;
539 int device_mtu(const char *ifname)
541 int ret, sock, mtu;
542 struct ifreq ifr;
544 sock = af_socket(AF_INET);
546 memset(&ifr, 0, sizeof(ifr));
547 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
549 ret = ioctl(sock, SIOCGIFMTU, &ifr);
550 if (!ret)
551 mtu = ifr.ifr_mtu;
552 else
553 mtu = 0;
555 close(sock);
557 return mtu;
560 short device_get_flags(const char *ifname)
562 /* Really, it's short! Look at struct ifreq */
563 short flags;
564 int ret, sock;
565 struct ifreq ifr;
567 sock = af_socket(AF_INET);
569 memset(&ifr, 0, sizeof(ifr));
570 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
572 ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
573 if (!ret)
574 flags = ifr.ifr_flags;
575 else
576 flags = 0;
578 close(sock);
580 return flags;
583 void device_set_flags(const char *ifname, const short flags)
585 int ret, sock;
586 struct ifreq ifr;
588 sock = af_socket(AF_INET);
590 memset(&ifr, 0, sizeof(ifr));
591 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
593 ifr.ifr_flags = flags;
595 ret = ioctl(sock, SIOCSIFFLAGS, &ifr);
596 if (ret < 0)
597 panic("Cannot set NIC flags!\n");
599 close(sock);
602 int device_irq_number(const char *ifname)
605 * Since fetching IRQ numbers from SIOCGIFMAP is deprecated and not
606 * supported anymore, we need to grab them from procfs
608 int irq = 0;
609 char *buffp;
610 char buff[512];
611 char sysname[512];
612 FILE *fp;
614 if (!strncmp("lo", ifname, strlen("lo")))
615 return 0;
617 fp = fopen("/proc/interrupts", "r");
618 if (!fp)
619 panic("Cannot open /proc/interrupts!\n");
621 memset(buff, 0, sizeof(buff));
622 while (fgets(buff, sizeof(buff), fp) != NULL) {
623 buff[sizeof(buff) - 1] = 0;
625 if (strstr(buff, ifname) == NULL)
626 continue;
628 buffp = buff;
629 while (*buffp != ':')
630 buffp++;
631 *buffp = 0;
632 irq = atoi(buff);
634 memset(buff, 0, sizeof(buff));
637 fclose(fp);
639 if (irq != 0)
640 return irq;
642 * Try sysfs as fallback. Probably wireless devices will be found
643 * here. We return silently if it fails ...
645 slprintf(sysname, sizeof(sysname), "/sys/class/net/%s/device/irq",
646 ifname);
648 fp = fopen(sysname, "r");
649 if (!fp)
650 return -ENOENT;
652 memset(buff, 0, sizeof(buff));
653 if(fgets(buff, sizeof(buff), fp) != NULL) {
654 buff[sizeof(buff) - 1] = 0;
655 irq = atoi(buff);
658 fclose(fp);
660 return irq;
663 int device_set_irq_affinity_list(int irq, unsigned long from, unsigned long to)
665 int ret, fd;
666 char file[256], list[64];
668 slprintf(file, sizeof(file), "/proc/irq/%d/smp_affinity_list", irq);
669 slprintf(list, sizeof(list), "%lu-%lu\n", from, to);
671 fd = open(file, O_WRONLY);
672 if (fd < 0)
673 return -ENOENT;
675 ret = write(fd, list, strlen(list));
677 close(fd);
678 return ret;
681 int device_bind_irq_to_cpu(int irq, int cpu)
683 int ret;
684 char buff[256];
685 char file[256];
686 FILE *fp;
688 /* Note: first CPU begins with CPU 0 */
689 if (irq < 0 || cpu < 0)
690 return -EINVAL;
692 memset(file, 0, sizeof(file));
693 memset(buff, 0, sizeof(buff));
695 /* smp_affinity starts counting with CPU 1, 2, ... */
696 cpu = cpu + 1;
697 sprintf(file, "/proc/irq/%d/smp_affinity", irq);
699 fp = fopen(file, "w");
700 if (!fp)
701 return -ENOENT;
703 sprintf(buff, "%d", cpu);
704 ret = fwrite(buff, sizeof(buff), 1, fp);
706 fclose(fp);
707 return (ret > 0 ? 0 : ret);
710 void sock_print_net_stats(int sock, unsigned long skipped)
712 int ret;
713 struct tpacket_stats kstats;
715 socklen_t slen = sizeof(kstats);
717 memset(&kstats, 0, sizeof(kstats));
718 ret = getsockopt(sock, SOL_PACKET, PACKET_STATISTICS, &kstats, &slen);
719 if (ret > -1) {
720 uint64_t packets = kstats.tp_packets;
721 uint64_t drops = kstats.tp_drops;
723 printf("\r%12ld packets incoming\n", packets);
724 printf("\r%12ld packets passed filter\n", packets - drops - skipped);
725 printf("\r%12ld packets failed filter (out of space)\n", drops + skipped);
726 if (kstats.tp_packets > 0)
727 printf("\r%12.4lf%\% packet droprate\n", (1.0 * drops / packets) * 100.0);
731 void register_signal(int signal, void (*handler)(int))
733 sigset_t block_mask;
734 struct sigaction saction;
736 sigfillset(&block_mask);
738 saction.sa_handler = handler;
739 saction.sa_mask = block_mask;
740 saction.sa_flags = SA_RESTART;
742 sigaction(signal, &saction, NULL);
745 void register_signal_f(int signal, void (*handler)(int), int flags)
747 sigset_t block_mask;
748 struct sigaction saction;
750 sigfillset(&block_mask);
752 saction.sa_handler = handler;
753 saction.sa_mask = block_mask;
754 saction.sa_flags = flags;
756 sigaction(signal, &saction, NULL);
759 int get_tty_size(void)
761 #ifdef TIOCGSIZE
762 struct ttysize ts = {0};
764 return (ioctl(0, TIOCGSIZE, &ts) == 0 ? ts.ts_cols : DEFAULT_TTY_SIZE);
765 #elif defined(TIOCGWINSZ)
766 struct winsize ts;
768 return (ioctl(0, TIOCGWINSZ, &ts) == 0 ? ts.ws_col : DEFAULT_TTY_SIZE);
769 #else
770 return DEFAULT_TTY_SIZE;
771 #endif
774 short enter_promiscuous_mode(char *ifname)
776 short ifflags;
778 if (!strncmp("any", ifname, strlen("any")))
779 return 0;
781 ifflags = device_get_flags(ifname);
782 device_set_flags(ifname, ifflags | IFF_PROMISC);
784 return ifflags;
787 void leave_promiscuous_mode(char *ifname, short oldflags)
789 if (!strncmp("any", ifname, strlen("any")))
790 return;
792 device_set_flags(ifname, oldflags);
795 int device_up(char *ifname)
797 if (!ifname)
798 return -EINVAL;
799 if (!strncmp("any", ifname, strlen("any")))
800 return 1;
802 return (device_get_flags(ifname) & IFF_UP) == IFF_UP;
805 int device_running(char *ifname)
807 if (!ifname)
808 return -EINVAL;
809 if (!strncmp("any", ifname, strlen("any")))
810 return 1;
812 return (device_get_flags(ifname) & IFF_RUNNING) == IFF_RUNNING;
815 int device_up_and_running(char *ifname)
817 if (!ifname)
818 return -EINVAL;
819 if (!strncmp("any", ifname, strlen("any")))
820 return 1;
822 return (device_get_flags(ifname) & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING);
825 int poll_error_maybe_die(int sock, struct pollfd *pfd)
827 if ((pfd->revents & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL)) == 0)
828 return POLL_NEXT_PKT;
829 if (pfd->revents & (POLLHUP | POLLRDHUP))
830 panic("Hangup on socket occured!\n");
831 if (pfd->revents & POLLERR) {
832 int tmp;
834 errno = 0;
835 if (recv(sock, &tmp, sizeof(tmp), MSG_PEEK) >= 0)
836 return POLL_NEXT_PKT;
837 if (errno == ENETDOWN)
838 panic("Interface went down!\n");
840 return POLL_MOVE_OUT;
842 if (pfd->revents & POLLNVAL) {
843 printf("Invalid polling request on socket!\n");
845 return POLL_MOVE_OUT;
848 return POLL_NEXT_PKT;
851 void cpu_affinity(int cpu)
853 int ret;
854 cpu_set_t cpu_bitmask;
856 CPU_ZERO(&cpu_bitmask);
857 CPU_SET(cpu, &cpu_bitmask);
859 ret = sched_setaffinity(getpid(), sizeof(cpu_bitmask),
860 &cpu_bitmask);
861 if (ret)
862 panic("Can't set this cpu affinity!\n");
865 int set_proc_prio(int priority)
867 int ret = setpriority(PRIO_PROCESS, getpid(), priority);
868 if (ret)
869 panic("Can't set nice val to %i!\n", priority);
871 return 0;
874 int set_sched_status(int policy, int priority)
876 int ret, min_prio, max_prio;
877 struct sched_param sp;
879 max_prio = sched_get_priority_max(policy);
880 min_prio = sched_get_priority_min(policy);
882 if (max_prio == -1 || min_prio == -1)
883 printf("Cannot determine scheduler prio limits!\n");
884 else if (priority < min_prio)
885 priority = min_prio;
886 else if (priority > max_prio)
887 priority = max_prio;
889 memset(&sp, 0, sizeof(sp));
890 sp.sched_priority = priority;
892 ret = sched_setscheduler(getpid(), policy, &sp);
893 if (ret) {
894 printf("Cannot set scheduler policy!\n");
895 return -EINVAL;
898 ret = sched_setparam(getpid(), &sp);
899 if (ret) {
900 printf("Cannot set scheduler prio!\n");
901 return -EINVAL;
904 return 0;
907 static inline int ioprio_set(int which, int who, int ioprio)
909 return syscall(SYS_ioprio_set, which, who, ioprio);
912 static inline int ioprio_get(int which, int who)
914 return syscall(SYS_ioprio_get, which, who);
917 static void ioprio_setpid(pid_t pid, int ioprio, int ioclass)
919 int ret = ioprio_set(ioprio_who_process, pid,
920 ioprio | ioclass << IOPRIO_CLASS_SHIFT);
921 if (ret < 0)
922 panic("Failed to set io prio for pid!\n");
925 void ioprio_print(void)
927 int ioprio = ioprio_get(ioprio_who_process, getpid());
928 if (ioprio < 0)
929 panic("Failed to fetch io prio for pid!\n");
930 else {
931 int ioclass = ioprio >> IOPRIO_CLASS_SHIFT;
932 if (ioclass != ioprio_class_idle) {
933 ioprio &= 0xff;
934 printf("%s: prio %d\n", to_prio[ioclass], ioprio);
935 } else
936 printf("%s\n", to_prio[ioclass]);
940 void set_ioprio_rt(void)
942 ioprio_setpid(getpid(), 4, ioprio_class_rt);
945 void set_ioprio_be(void)
947 ioprio_setpid(getpid(), 4, ioprio_class_be);
950 void xlockme(void)
952 if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0)
953 panic("Cannot lock pages!\n");
956 void xunlockme(void)
958 munlockall();
961 int set_timeout(struct timeval *timeval, unsigned int msec)
963 if (msec == 0)
964 return -EINVAL;
966 timeval->tv_sec = 0;
967 timeval->tv_usec = 0;
969 if (msec < 1000) {
970 timeval->tv_usec = msec * 1000;
971 return 0;
974 timeval->tv_sec = (long) (msec / 1000);
975 timeval->tv_usec = (long) ((msec - (timeval->tv_sec * 1000)) * 1000);
977 return 0;
980 size_t strlcpy(char *dest, const char *src, size_t size)
982 size_t ret = strlen(src);
984 if (size) {
985 size_t len = (ret >= size) ? size - 1 : ret;
987 memcpy(dest, src, len);
988 dest[len] = '\0';
991 return ret;
994 static inline int vslprintf(char *dst, size_t size, const char *fmt, va_list ap)
996 int ret;
998 ret = vsnprintf(dst, size, fmt, ap);
999 dst[size - 1] = '\0';
1001 return ret;
1004 int slprintf(char *dst, size_t size, const char *fmt, ...)
1006 int ret;
1007 va_list ap;
1009 va_start(ap, fmt);
1010 ret = vslprintf(dst, size, fmt, ap);
1011 va_end(ap);
1013 return ret;
1016 int slprintf_nocheck(char *dst, size_t size, const char *fmt, ...)
1018 int ret;
1019 va_list ap;
1021 va_start(ap, fmt);
1022 ret = vslprintf(dst, size, fmt, ap);
1023 va_end(ap);
1025 return ret;
1028 noinline void *xmemset(void *s, int c, size_t n)
1030 size_t i;
1031 uint8_t *ptr = s;
1033 for (i = 0; i < n; ++i)
1034 ptr[i] = (uint8_t) c;
1036 return ptr;
1039 char *strtrim_right(register char *p, register char c)
1041 register char *end;
1042 register int len;
1044 len = strlen(p);
1045 while (*p && len) {
1046 end = p + len - 1;
1047 if (c == *end)
1048 *end = 0;
1049 else
1050 break;
1051 len = strlen(p);
1054 return p;
1057 static char *strtrim_left(register char *p, register char c)
1059 register int len;
1061 len = strlen(p);
1062 while (*p && len--) {
1063 if (c == *p)
1064 p++;
1065 else
1066 break;
1069 return p;
1072 char *skips(char *p)
1074 return strtrim_left(p, ' ');
1077 int get_default_sched_policy(void)
1079 return SCHED_FIFO;
1082 int get_default_sched_prio(void)
1084 return sched_get_priority_max(get_default_sched_policy());
1087 int get_number_cpus(void)
1089 return sysconf(_SC_NPROCESSORS_CONF);
1092 int get_number_cpus_online(void)
1094 return sysconf(_SC_NPROCESSORS_ONLN);
1097 int get_default_proc_prio(void)
1099 return -20;
1102 struct timeval tv_subtract(struct timeval time1, struct timeval time2)
1104 struct timeval result;
1106 if ((time1.tv_sec < time2.tv_sec) || ((time1.tv_sec == time2.tv_sec) &&
1107 (time1.tv_usec <= time2.tv_usec))) {
1108 result.tv_sec = result.tv_usec = 0;
1109 } else {
1110 result.tv_sec = time1.tv_sec - time2.tv_sec;
1111 if (time1.tv_usec < time2.tv_usec) {
1112 result.tv_usec = time1.tv_usec + 1000000L -
1113 time2.tv_usec;
1114 result.tv_sec--;
1115 } else {
1116 result.tv_usec = time1.tv_usec - time2.tv_usec;
1120 return result;
1123 void set_system_socket_memory(int *vals, size_t len)
1125 bug_on(len != 4);
1127 if ((vals[0] = get_system_socket_mem(sock_rmem_max)) < SMEM_SUG_MAX)
1128 set_system_socket_mem(sock_rmem_max, SMEM_SUG_MAX);
1129 if ((vals[1] = get_system_socket_mem(sock_rmem_def)) < SMEM_SUG_DEF)
1130 set_system_socket_mem(sock_rmem_def, SMEM_SUG_DEF);
1131 if ((vals[2] = get_system_socket_mem(sock_wmem_max)) < SMEM_SUG_MAX)
1132 set_system_socket_mem(sock_wmem_max, SMEM_SUG_MAX);
1133 if ((vals[3] = get_system_socket_mem(sock_wmem_def)) < SMEM_SUG_DEF)
1134 set_system_socket_mem(sock_wmem_def, SMEM_SUG_DEF);
1137 void reset_system_socket_memory(int *vals, size_t len)
1139 bug_on(len != 4);
1141 set_system_socket_mem(sock_rmem_max, vals[0]);
1142 set_system_socket_mem(sock_rmem_def, vals[1]);
1143 set_system_socket_mem(sock_wmem_max, vals[2]);
1144 set_system_socket_mem(sock_wmem_def, vals[3]);