pcap_sg: simplify code by using raw
[netsniff-ng.git] / xutils.c
blob4e97b06e6b70604f76051a436d0217fdec6f6f3d
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 whine("Wrong AF socket type! Falling back to AF_INET\n");
96 af = AF_INET;
99 sock = socket(af, SOCK_DGRAM, 0);
100 if (unlikely(sock < 0))
101 panic("Creation AF socket failed!\n");
103 return sock;
106 int pf_socket(void)
108 int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
109 if (unlikely(sock < 0))
110 panic("Creation of PF socket failed!\n");
112 return sock;
115 void set_sock_prio(int fd, int prio)
117 int val = prio;
118 setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
121 void set_udp_cork(int fd)
123 int state = 1;
124 setsockopt(fd, IPPROTO_UDP, UDP_CORK, &state, sizeof(state));
127 void set_udp_uncork(int fd)
129 int state = 0;
130 setsockopt(fd, IPPROTO_UDP, UDP_CORK, &state, sizeof(state));
133 void set_tcp_cork(int fd)
135 int state = 1;
136 setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
139 void set_tcp_uncork(int fd)
141 int state = 0;
142 setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
145 void set_sock_cork(int fd, int udp)
147 if (!!udp)
148 set_udp_cork(fd);
149 else
150 set_tcp_cork(fd);
153 void set_sock_uncork(int fd, int udp)
155 if (!!udp)
156 set_udp_uncork(fd);
157 else
158 set_tcp_uncork(fd);
161 int set_nonblocking(int fd)
163 int ret = fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
164 if (unlikely(ret < 0))
165 panic("Cannot fcntl!\n");
167 return 0;
170 int set_nonblocking_sloppy(int fd)
172 return fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
175 void set_socket_keepalive(int fd)
177 int one = 1;
178 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one));
181 void set_tcp_nodelay(int fd)
183 int one = 1;
184 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
187 int set_ipv6_only(int fd)
189 int one = 1;
190 return setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
193 int set_reuseaddr(int fd)
195 int ret, one = 1;
197 ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (one));
198 if (unlikely(ret < 0))
199 panic("Cannot reuse addr!\n");
201 return 0;
204 void set_mtu_disc_dont(int fd)
206 int mtu = IP_PMTUDISC_DONT;
207 setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu));
210 void set_epoll_descriptor(int fd_epoll, int action, int fd_toadd, int events)
212 int ret;
213 struct epoll_event ev;
215 memset(&ev, 0, sizeof(ev));
216 ev.events = events;
217 ev.data.fd = fd_toadd;
219 ret = epoll_ctl(fd_epoll, action, fd_toadd, &ev);
220 if (ret < 0)
221 panic("Cannot add socket for epoll!\n");
224 int set_epoll_descriptor2(int fd_epoll, int action, int fd_toadd, int events)
226 struct epoll_event ev;
228 memset(&ev, 0, sizeof(ev));
229 ev.events = events;
230 ev.data.fd = fd_toadd;
232 return epoll_ctl(fd_epoll, action, fd_toadd, &ev);
235 u32 wireless_bitrate(const char *ifname)
237 int sock, ret, rate_in_mbit;
238 struct iwreq iwr;
240 sock = af_socket(AF_INET);
242 memset(&iwr, 0, sizeof(iwr));
243 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
245 ret = ioctl(sock, SIOCGIWRATE, &iwr);
246 if (!ret)
247 rate_in_mbit = iwr.u.bitrate.value / 1000000;
248 else
249 rate_in_mbit = 0;
251 close(sock);
253 return rate_in_mbit;
256 int adjust_dbm_level(int in_dbm, int dbm_val)
258 if (!in_dbm)
259 return dbm_val;
261 return dbm_val - 0x100;
264 void drop_privileges(bool enforce, uid_t uid, gid_t gid)
266 if (enforce) {
267 if (uid == getuid())
268 panic("Uid cannot be the same as the current user!\n");
269 if (gid == getgid())
270 panic("Gid cannot be the same as the current user!\n");
272 if (setgid(gid) != 0)
273 panic("Unable to drop group privileges: %s!\n", strerror(errno));
274 if (setuid(uid) != 0)
275 panic("Unable to drop user privileges: %s!\n", strerror(errno));
278 int get_system_socket_mem(int which)
280 int fd, val = -1;
281 ssize_t ret;
282 const char *file = sock_mem[which];
283 char buff[64];
285 fd = open(file, O_RDONLY);
286 if (fd < 0)
287 return val;
289 ret = read(fd, buff, sizeof(buff));
290 if (ret > 0)
291 val = atoi(buff);
293 close(fd);
294 return val;
297 void set_system_socket_mem(int which, int val)
299 int fd;
300 const char *file = sock_mem[which];
301 ssize_t ret;
302 char buff[64];
304 fd = open(file, O_WRONLY);
305 if (fd < 0)
306 return;
308 memset(buff, 0, sizeof(buff));
309 slprintf(buff, sizeof(buff), "%d", val);
311 ret = write(fd, buff, strlen(buff));
312 ret = ret;
314 close(fd);
317 int wireless_sigqual(const char *ifname, struct iw_statistics *stats)
319 int ret, sock;
320 struct iwreq iwr;
322 sock = af_socket(AF_INET);
324 memset(&iwr, 0, sizeof(iwr));
325 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
327 iwr.u.data.pointer = (caddr_t) stats;
328 iwr.u.data.length = sizeof(*stats);
329 iwr.u.data.flags = 1;
331 ret = ioctl(sock, SIOCGIWSTATS, &iwr);
333 close(sock);
335 return ret;
338 int wireless_rangemax_sigqual(const char *ifname)
340 int ret, sock, sigqual;
341 struct iwreq iwr;
342 struct iw_range iwrange;
344 sock = af_socket(AF_INET);
346 memset(&iwrange, 0, sizeof(iwrange));
348 memset(&iwr, 0, sizeof(iwr));
349 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
351 iwr.u.data.pointer = (caddr_t) &iwrange;
352 iwr.u.data.length = sizeof(iwrange);
353 iwr.u.data.flags = 0;
355 ret = ioctl(sock, SIOCGIWRANGE, &iwr);
356 if (!ret)
357 sigqual = iwrange.max_qual.qual;
358 else
359 sigqual = 0;
361 close(sock);
363 return sigqual;
366 u32 ethtool_bitrate(const char *ifname)
368 int ret, sock, bitrate;
369 struct ifreq ifr;
370 struct ethtool_cmd ecmd;
372 sock = af_socket(AF_INET);
374 memset(&ecmd, 0, sizeof(ecmd));
376 memset(&ifr, 0, sizeof(ifr));
377 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
379 ecmd.cmd = ETHTOOL_GSET;
380 ifr.ifr_data = (char *) &ecmd;
382 ret = ioctl(sock, SIOCETHTOOL, &ifr);
383 if (ret) {
384 bitrate = 0;
385 goto out;
388 switch (ecmd.speed) {
389 case SPEED_10:
390 case SPEED_100:
391 case SPEED_1000:
392 case SPEED_2500:
393 case SPEED_10000:
394 bitrate = ecmd.speed;
395 break;
396 default:
397 bitrate = 0;
398 break;
400 out:
401 close(sock);
403 return bitrate;
406 int ethtool_link(const char *ifname)
408 int ret, sock;
409 struct ifreq ifr;
410 struct ethtool_value ecmd;
412 sock = af_socket(AF_INET);
414 memset(&ecmd, 0, sizeof(ecmd));
416 memset(&ifr, 0, sizeof(ifr));
417 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
419 ecmd.cmd = ETHTOOL_GLINK;
420 ifr.ifr_data = (char *) &ecmd;
422 ret = ioctl(sock, SIOCETHTOOL, &ifr);
423 if (ret)
424 ret = -EINVAL;
425 else
426 ret = !!ecmd.data;
428 close(sock);
429 return ret;
432 int ethtool_drvinf(const char *ifname, struct ethtool_drvinfo *drvinf)
434 int ret, sock;
435 struct ifreq ifr;
437 sock = af_socket(AF_INET);
439 memset(drvinf, 0, sizeof(*drvinf));
441 memset(&ifr, 0, sizeof(ifr));
442 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
444 drvinf->cmd = ETHTOOL_GDRVINFO;
445 ifr.ifr_data = (char *) drvinf;
447 ret = ioctl(sock, SIOCETHTOOL, &ifr);
449 close(sock);
451 return ret;
454 u32 device_bitrate(const char *ifname)
456 u32 speed_c, speed_w;
458 speed_c = ethtool_bitrate(ifname);
459 speed_w = wireless_bitrate(ifname);
461 return (speed_c == 0 ? speed_w : speed_c);
464 int device_ifindex(const char *ifname)
466 int ret, sock, index;
467 struct ifreq ifr;
469 if (!strncmp("any", ifname, strlen("any")))
470 return 0;
472 sock = af_socket(AF_INET);
474 memset(&ifr, 0, sizeof(ifr));
475 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
477 ret = ioctl(sock, SIOCGIFINDEX, &ifr);
478 if (!ret)
479 index = ifr.ifr_ifindex;
480 else
481 index = -1;
483 close(sock);
485 return index;
488 static int __device_address6(const char *ifname, struct sockaddr_storage *ss)
490 int ret, family, found = -EINVAL;
491 struct ifaddrs *ifaddr, *ifa;
493 ret = getifaddrs(&ifaddr);
494 if (ret < 0)
495 panic("Cannot get device addresses for IPv6!\n");
497 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
498 family = ifa->ifa_addr->sa_family;
499 if (family != AF_INET6)
500 continue;
501 if (strcmp(ifa->ifa_name, ifname))
502 continue;
504 memcpy(ss, ifa->ifa_addr, sizeof(*ss));
505 found = 0;
506 break;
509 freeifaddrs(ifaddr);
510 return found;
513 int device_address(const char *ifname, int af, struct sockaddr_storage *ss)
515 int ret, sock;
516 struct ifreq ifr;
518 if (!ss)
519 return -EINVAL;
520 if (!strncmp("any", ifname, strlen("any")))
521 return -EINVAL;
522 if (af == AF_INET6)
523 return __device_address6(ifname, ss);
525 sock = af_socket(af);
527 memset(&ifr, 0, sizeof(ifr));
528 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
530 ifr.ifr_addr.sa_family = af;
532 ret = ioctl(sock, SIOCGIFADDR, &ifr);
533 if (!ret)
534 memcpy(ss, &ifr.ifr_addr, sizeof(ifr.ifr_addr));
536 close(sock);
538 return ret;
541 int device_mtu(const char *ifname)
543 int ret, sock, mtu;
544 struct ifreq ifr;
546 sock = af_socket(AF_INET);
548 memset(&ifr, 0, sizeof(ifr));
549 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
551 ret = ioctl(sock, SIOCGIFMTU, &ifr);
552 if (!ret)
553 mtu = ifr.ifr_mtu;
554 else
555 mtu = 0;
557 close(sock);
559 return mtu;
562 short device_get_flags(const char *ifname)
564 /* Really, it's short! Look at struct ifreq */
565 short flags;
566 int ret, sock;
567 struct ifreq ifr;
569 sock = af_socket(AF_INET);
571 memset(&ifr, 0, sizeof(ifr));
572 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
574 ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
575 if (!ret)
576 flags = ifr.ifr_flags;
577 else
578 flags = 0;
580 close(sock);
582 return flags;
585 void device_set_flags(const char *ifname, const short flags)
587 int ret, sock;
588 struct ifreq ifr;
590 sock = af_socket(AF_INET);
592 memset(&ifr, 0, sizeof(ifr));
593 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
595 ifr.ifr_flags = flags;
597 ret = ioctl(sock, SIOCSIFFLAGS, &ifr);
598 if (ret < 0)
599 panic("Cannot set NIC flags!\n");
601 close(sock);
604 /* XXX: also probe ethtool driver name if it fails */
605 int device_irq_number(const char *ifname)
608 * Since fetching IRQ numbers from SIOCGIFMAP is deprecated and not
609 * supported anymore, we need to grab them from procfs
611 int irq = 0;
612 char *buffp;
613 char buff[512];
614 char sysname[512];
615 FILE *fp;
617 if (!strncmp("lo", ifname, strlen("lo")))
618 return 0;
620 fp = fopen("/proc/interrupts", "r");
621 if (!fp) {
622 whine("Cannot open /proc/interrupts!\n");
623 return -ENOENT;
626 memset(buff, 0, sizeof(buff));
627 while (fgets(buff, sizeof(buff), fp) != NULL) {
628 buff[sizeof(buff) - 1] = 0;
630 if (strstr(buff, ifname) == NULL)
631 continue;
633 buffp = buff;
634 while (*buffp != ':')
635 buffp++;
636 *buffp = 0;
637 irq = atoi(buff);
639 memset(buff, 0, sizeof(buff));
642 fclose(fp);
644 if (irq != 0)
645 return irq;
647 * Try sysfs as fallback. Probably wireless devices will be found
648 * here. We return silently if it fails ...
650 slprintf(sysname, sizeof(sysname), "/sys/class/net/%s/device/irq",
651 ifname);
653 fp = fopen(sysname, "r");
654 if (!fp)
655 return -ENOENT;
657 memset(buff, 0, sizeof(buff));
658 if(fgets(buff, sizeof(buff), fp) != NULL) {
659 buff[sizeof(buff) - 1] = 0;
660 irq = atoi(buff);
663 fclose(fp);
665 return irq;
668 int device_set_irq_affinity_list(int irq, unsigned long from, unsigned long to)
670 int ret, fd;
671 char file[256], list[64];
673 slprintf(file, sizeof(file), "/proc/irq/%d/smp_affinity_list", irq);
674 slprintf(list, sizeof(list), "%lu-%lu\n", from, to);
676 fd = open(file, O_WRONLY);
677 if (fd < 0) {
678 whine("Cannot open file %s!\n", file);
679 return -ENOENT;
682 ret = write(fd, list, strlen(list));
684 close(fd);
685 return ret;
688 int device_bind_irq_to_cpu(int irq, int cpu)
690 int ret;
691 char buff[256];
692 char file[256];
693 FILE *fp;
695 /* Note: first CPU begins with CPU 0 */
696 if (irq < 0 || cpu < 0)
697 return -EINVAL;
699 memset(file, 0, sizeof(file));
700 memset(buff, 0, sizeof(buff));
702 /* smp_affinity starts counting with CPU 1, 2, ... */
703 cpu = cpu + 1;
704 sprintf(file, "/proc/irq/%d/smp_affinity", irq);
706 fp = fopen(file, "w");
707 if (!fp) {
708 whine("Cannot open file %s!\n", file);
709 return -ENOENT;
712 sprintf(buff, "%d", cpu);
713 ret = fwrite(buff, sizeof(buff), 1, fp);
715 fclose(fp);
716 return (ret > 0 ? 0 : ret);
719 void sock_print_net_stats(int sock, unsigned long skipped)
721 int ret;
722 struct tpacket_stats kstats;
724 socklen_t slen = sizeof(kstats);
726 memset(&kstats, 0, sizeof(kstats));
727 ret = getsockopt(sock, SOL_PACKET, PACKET_STATISTICS, &kstats, &slen);
728 if (ret > -1) {
729 uint64_t packets = kstats.tp_packets;
730 uint64_t drops = kstats.tp_drops;
732 printf("\r%12ld packets incoming\n", packets);
733 printf("\r%12ld packets passed filter\n", packets - drops - skipped);
734 printf("\r%12ld packets failed filter (out of space)\n", drops + skipped);
735 if (kstats.tp_packets > 0)
736 printf("\r%12.4lf%\% packet droprate\n", (1.0 * drops / packets) * 100.0);
740 void register_signal(int signal, void (*handler)(int))
742 sigset_t block_mask;
743 struct sigaction saction;
745 sigfillset(&block_mask);
747 saction.sa_handler = handler;
748 saction.sa_mask = block_mask;
749 saction.sa_flags = SA_RESTART;
751 sigaction(signal, &saction, NULL);
754 void register_signal_f(int signal, void (*handler)(int), int flags)
756 sigset_t block_mask;
757 struct sigaction saction;
759 sigfillset(&block_mask);
761 saction.sa_handler = handler;
762 saction.sa_mask = block_mask;
763 saction.sa_flags = flags;
765 sigaction(signal, &saction, NULL);
768 int get_tty_size(void)
770 #ifdef TIOCGSIZE
771 struct ttysize ts = {0};
773 return (ioctl(0, TIOCGSIZE, &ts) == 0 ? ts.ts_cols : DEFAULT_TTY_SIZE);
774 #elif defined(TIOCGWINSZ)
775 struct winsize ts;
777 return (ioctl(0, TIOCGWINSZ, &ts) == 0 ? ts.ws_col : DEFAULT_TTY_SIZE);
778 #else
779 return DEFAULT_TTY_SIZE;
780 #endif
783 short enter_promiscuous_mode(char *ifname)
785 short ifflags;
787 if (!strncmp("any", ifname, strlen("any")))
788 return 0;
790 ifflags = device_get_flags(ifname);
791 device_set_flags(ifname, ifflags | IFF_PROMISC);
793 return ifflags;
796 void leave_promiscuous_mode(char *ifname, short oldflags)
798 if (!strncmp("any", ifname, strlen("any")))
799 return;
801 device_set_flags(ifname, oldflags);
804 int device_up(char *ifname)
806 if (!ifname)
807 return -EINVAL;
808 if (!strncmp("any", ifname, strlen("any")))
809 return 1;
811 return (device_get_flags(ifname) & IFF_UP) == IFF_UP;
814 int device_running(char *ifname)
816 if (!ifname)
817 return -EINVAL;
818 if (!strncmp("any", ifname, strlen("any")))
819 return 1;
821 return (device_get_flags(ifname) & IFF_RUNNING) == IFF_RUNNING;
824 int device_up_and_running(char *ifname)
826 if (!ifname)
827 return -EINVAL;
828 if (!strncmp("any", ifname, strlen("any")))
829 return 1;
831 return (device_get_flags(ifname) & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING);
834 int poll_error_maybe_die(int sock, struct pollfd *pfd)
836 if ((pfd->revents & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL)) == 0)
837 return POLL_NEXT_PKT;
838 if (pfd->revents & (POLLHUP | POLLRDHUP))
839 panic("Hangup on socket occured!\n");
840 if (pfd->revents & POLLERR) {
841 int tmp;
843 errno = 0;
844 if (recv(sock, &tmp, sizeof(tmp), MSG_PEEK) >= 0)
845 return POLL_NEXT_PKT;
846 if (errno == ENETDOWN)
847 panic("Interface went down!\n");
849 return POLL_MOVE_OUT;
851 if (pfd->revents & POLLNVAL) {
852 printf("Invalid polling request on socket!\n");
854 return POLL_MOVE_OUT;
857 return POLL_NEXT_PKT;
860 void cpu_affinity(int cpu)
862 int ret;
863 cpu_set_t cpu_bitmask;
865 CPU_ZERO(&cpu_bitmask);
866 CPU_SET(cpu, &cpu_bitmask);
868 ret = sched_setaffinity(getpid(), sizeof(cpu_bitmask),
869 &cpu_bitmask);
870 if (ret)
871 panic("Can't set this cpu affinity!\n");
874 int set_proc_prio(int priority)
876 int ret = setpriority(PRIO_PROCESS, getpid(), priority);
877 if (ret)
878 panic("Can't set nice val to %i!\n", priority);
880 return 0;
883 int set_sched_status(int policy, int priority)
885 int ret, min_prio, max_prio;
886 struct sched_param sp;
888 max_prio = sched_get_priority_max(policy);
889 min_prio = sched_get_priority_min(policy);
891 if (max_prio == -1 || min_prio == -1)
892 whine("Cannot determine scheduler prio limits!\n");
893 else if (priority < min_prio)
894 priority = min_prio;
895 else if (priority > max_prio)
896 priority = max_prio;
898 memset(&sp, 0, sizeof(sp));
899 sp.sched_priority = priority;
901 ret = sched_setscheduler(getpid(), policy, &sp);
902 if (ret) {
903 whine("Cannot set scheduler policy!\n");
904 return -EINVAL;
907 ret = sched_setparam(getpid(), &sp);
908 if (ret) {
909 whine("Cannot set scheduler prio!\n");
910 return -EINVAL;
913 return 0;
916 static inline int ioprio_set(int which, int who, int ioprio)
918 return syscall(SYS_ioprio_set, which, who, ioprio);
921 static inline int ioprio_get(int which, int who)
923 return syscall(SYS_ioprio_get, which, who);
926 static void ioprio_setpid(pid_t pid, int ioprio, int ioclass)
928 int ret = ioprio_set(ioprio_who_process, pid,
929 ioprio | ioclass << IOPRIO_CLASS_SHIFT);
930 if (ret < 0)
931 panic("Failed to set io prio for pid!\n");
934 void ioprio_print(void)
936 int ioprio = ioprio_get(ioprio_who_process, getpid());
937 if (ioprio < 0)
938 panic("Failed to fetch io prio for pid!\n");
939 else {
940 int ioclass = ioprio >> IOPRIO_CLASS_SHIFT;
941 if (ioclass != ioprio_class_idle) {
942 ioprio &= 0xff;
943 printf("%s: prio %d\n", to_prio[ioclass], ioprio);
944 } else
945 printf("%s\n", to_prio[ioclass]);
949 void set_ioprio_rt(void)
951 ioprio_setpid(getpid(), 4, ioprio_class_rt);
954 void set_ioprio_be(void)
956 ioprio_setpid(getpid(), 4, ioprio_class_be);
959 void xlockme(void)
961 if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0)
962 panic("Cannot lock pages!\n");
965 void xunlockme(void)
967 munlockall();
970 int set_timeout(struct timeval *timeval, unsigned int msec)
972 if (msec == 0)
973 return -EINVAL;
975 timeval->tv_sec = 0;
976 timeval->tv_usec = 0;
978 if (msec < 1000) {
979 timeval->tv_usec = msec * 1000;
980 return 0;
983 timeval->tv_sec = (long) (msec / 1000);
984 timeval->tv_usec = (long) ((msec - (timeval->tv_sec * 1000)) * 1000);
986 return 0;
989 size_t strlcpy(char *dest, const char *src, size_t size)
991 size_t ret = strlen(src);
993 if (size) {
994 size_t len = (ret >= size) ? size - 1 : ret;
996 memcpy(dest, src, len);
997 dest[len] = '\0';
1000 return ret;
1003 static inline int vslprintf(char *dst, size_t size, const char *fmt, va_list ap)
1005 int ret;
1007 ret = vsnprintf(dst, size, fmt, ap);
1008 dst[size - 1] = '\0';
1010 return ret;
1013 int slprintf(char *dst, size_t size, const char *fmt, ...)
1015 int ret;
1016 va_list ap;
1018 va_start(ap, fmt);
1019 ret = vslprintf(dst, size, fmt, ap);
1020 va_end(ap);
1022 return ret;
1025 int slprintf_nocheck(char *dst, size_t size, const char *fmt, ...)
1027 int ret;
1028 va_list ap;
1030 va_start(ap, fmt);
1031 ret = vslprintf(dst, size, fmt, ap);
1032 va_end(ap);
1034 return ret;
1037 noinline void *xmemset(void *s, int c, size_t n)
1039 size_t i;
1040 uint8_t *ptr = s;
1042 for (i = 0; i < n; ++i)
1043 ptr[i] = (uint8_t) c;
1045 return ptr;
1048 char *strtrim_right(register char *p, register char c)
1050 register char *end;
1051 register int len;
1053 len = strlen(p);
1054 while (*p && len) {
1055 end = p + len - 1;
1056 if (c == *end)
1057 *end = 0;
1058 else
1059 break;
1060 len = strlen(p);
1063 return p;
1066 static char *strtrim_left(register char *p, register char c)
1068 register int len;
1070 len = strlen(p);
1071 while (*p && len--) {
1072 if (c == *p)
1073 p++;
1074 else
1075 break;
1078 return p;
1081 char *skips(char *p)
1083 return strtrim_left(p, ' ');
1086 int get_default_sched_policy(void)
1088 return SCHED_FIFO;
1091 int get_default_sched_prio(void)
1093 return sched_get_priority_max(get_default_sched_policy());
1096 int get_number_cpus(void)
1098 return sysconf(_SC_NPROCESSORS_CONF);
1101 int get_number_cpus_online(void)
1103 return sysconf(_SC_NPROCESSORS_ONLN);
1106 int get_default_proc_prio(void)
1108 return -20;
1111 struct timeval tv_subtract(struct timeval time1, struct timeval time2)
1113 struct timeval result;
1115 if ((time1.tv_sec < time2.tv_sec) || ((time1.tv_sec == time2.tv_sec) &&
1116 (time1.tv_usec <= time2.tv_usec))) {
1117 result.tv_sec = result.tv_usec = 0;
1118 } else {
1119 result.tv_sec = time1.tv_sec - time2.tv_sec;
1120 if (time1.tv_usec < time2.tv_usec) {
1121 result.tv_usec = time1.tv_usec + 1000000L -
1122 time2.tv_usec;
1123 result.tv_sec--;
1124 } else {
1125 result.tv_usec = time1.tv_usec - time2.tv_usec;
1129 return result;
1132 void set_system_socket_memory(int *vals, size_t len)
1134 bug_on(len != 4);
1136 if ((vals[0] = get_system_socket_mem(sock_rmem_max)) < SMEM_SUG_MAX)
1137 set_system_socket_mem(sock_rmem_max, SMEM_SUG_MAX);
1138 if ((vals[1] = get_system_socket_mem(sock_rmem_def)) < SMEM_SUG_DEF)
1139 set_system_socket_mem(sock_rmem_def, SMEM_SUG_DEF);
1140 if ((vals[2] = get_system_socket_mem(sock_wmem_max)) < SMEM_SUG_MAX)
1141 set_system_socket_mem(sock_wmem_max, SMEM_SUG_MAX);
1142 if ((vals[3] = get_system_socket_mem(sock_wmem_def)) < SMEM_SUG_DEF)
1143 set_system_socket_mem(sock_wmem_def, SMEM_SUG_DEF);
1146 void reset_system_socket_memory(int *vals, size_t len)
1148 bug_on(len != 4);
1150 set_system_socket_mem(sock_rmem_max, vals[0]);
1151 set_system_socket_mem(sock_rmem_def, vals[1]);
1152 set_system_socket_mem(sock_wmem_max, vals[2]);
1153 set_system_socket_mem(sock_wmem_def, vals[3]);