all: import netsniff-ng 0.5.8-rc0 source
[netsniff-ng.git] / xutils.c
blob7a12d1eb33251cc57cff2e5214251105b3e5cf5b
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Copyright 2009, 2010 Emmanuel Roullit.
5 * Copyright 2010 Marek Polacek.
6 * Subject to the GPL, version 2.
7 */
9 #define _GNU_SOURCE
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <stdint.h>
13 #include <fcntl.h>
14 #include <string.h>
15 #include <unistd.h>
16 #include <errno.h>
17 #include <stdarg.h>
18 #include <ctype.h>
19 #include <signal.h>
20 #include <arpa/inet.h>
21 #include <time.h>
22 #include <sched.h>
23 #include <limits.h>
24 #include <stdbool.h>
25 #include <netdb.h>
26 #include <ifaddrs.h>
27 #include <sys/time.h>
28 #include <sys/socket.h>
29 #include <sys/ioctl.h>
30 #include <sys/mman.h>
31 #include <sys/resource.h>
32 #include <sys/epoll.h>
33 #include <sys/syscall.h>
34 #include <asm/unistd.h>
35 #include <linux/if.h>
36 #include <linux/socket.h>
37 #include <linux/types.h>
38 #include <linux/if_ether.h>
39 #include <linux/if_packet.h>
40 #include <linux/sockios.h>
41 #include <netinet/tcp.h>
42 #include <netinet/udp.h>
44 #include "die.h"
45 #include "xutils.h"
46 #include "ring.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 enum {
65 sock_rmem_max = 0,
66 sock_rmem_def,
67 sock_wmem_max,
68 sock_wmem_def,
71 #define SMEM_SUG_MAX 104857600
72 #define SMEM_SUG_DEF 4194304
74 static const char *const to_prio[] = {
75 "none",
76 "realtime",
77 "best-effort",
78 "idle",
81 static const char *const sock_mem[] = {
82 "/proc/sys/net/core/rmem_max",
83 "/proc/sys/net/core/rmem_default",
84 "/proc/sys/net/core/wmem_max",
85 "/proc/sys/net/core/wmem_default",
88 int af_socket(int af)
90 int sock;
92 if (unlikely(af != AF_INET && af != AF_INET6))
93 panic("Wrong AF socket type!\n");
95 sock = socket(af, SOCK_DGRAM, 0);
96 if (unlikely(sock < 0))
97 panic("Creation AF socket failed!\n");
99 return sock;
102 int pf_socket(void)
104 int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
105 if (unlikely(sock < 0))
106 panic("Creation of PF socket failed!\n");
108 return sock;
111 void set_sock_prio(int fd, int prio)
113 int val = prio;
114 setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
117 void set_udp_cork(int fd)
119 int state = 1;
120 setsockopt(fd, IPPROTO_UDP, UDP_CORK, &state, sizeof(state));
123 void set_udp_uncork(int fd)
125 int state = 0;
126 setsockopt(fd, IPPROTO_UDP, UDP_CORK, &state, sizeof(state));
129 void set_tcp_cork(int fd)
131 int state = 1;
132 setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
135 void set_tcp_uncork(int fd)
137 int state = 0;
138 setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
141 void set_sock_cork(int fd, int udp)
143 if (!!udp)
144 set_udp_cork(fd);
145 else
146 set_tcp_cork(fd);
149 void set_sock_uncork(int fd, int udp)
151 if (!!udp)
152 set_udp_uncork(fd);
153 else
154 set_tcp_uncork(fd);
157 int set_nonblocking(int fd)
159 int ret = fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
160 if (unlikely(ret < 0))
161 panic("Cannot fcntl!\n");
163 return 0;
166 int set_nonblocking_sloppy(int fd)
168 return fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
171 void set_socket_keepalive(int fd)
173 int one = 1;
174 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one));
177 void set_tcp_nodelay(int fd)
179 int one = 1;
180 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
183 int set_ipv6_only(int fd)
185 int one = 1;
186 return setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
189 int set_reuseaddr(int fd)
191 int ret, one = 1;
193 ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
194 if (unlikely(ret < 0))
195 panic("Cannot reuse addr!\n");
197 return 0;
200 void set_mtu_disc_dont(int fd)
202 int mtu = IP_PMTUDISC_DONT;
203 setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu));
206 void set_epoll_descriptor(int fd_epoll, int action, int fd_toadd, int events)
208 int ret;
209 struct epoll_event ev;
211 memset(&ev, 0, sizeof(ev));
212 ev.events = events;
213 ev.data.fd = fd_toadd;
215 ret = epoll_ctl(fd_epoll, action, fd_toadd, &ev);
216 if (ret < 0)
217 panic("Cannot add socket for epoll!\n");
220 int set_epoll_descriptor2(int fd_epoll, int action, int fd_toadd, int events)
222 struct epoll_event ev;
224 memset(&ev, 0, sizeof(ev));
225 ev.events = events;
226 ev.data.fd = fd_toadd;
228 return epoll_ctl(fd_epoll, action, fd_toadd, &ev);
231 u32 wireless_bitrate(const char *ifname)
233 int sock, ret, rate_in_mbit;
234 struct iwreq iwr;
236 sock = af_socket(AF_INET);
238 memset(&iwr, 0, sizeof(iwr));
239 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
241 ret = ioctl(sock, SIOCGIWRATE, &iwr);
242 if (!ret)
243 rate_in_mbit = iwr.u.bitrate.value / 1000000;
244 else
245 rate_in_mbit = 0;
247 close(sock);
249 return rate_in_mbit;
252 void drop_privileges(bool enforce, uid_t uid, gid_t gid)
254 if (enforce) {
255 if (uid == getuid())
256 panic("Uid cannot be the same as the current user!\n");
257 if (gid == getgid())
258 panic("Gid cannot be the same as the current user!\n");
260 if (setgid(gid) != 0)
261 panic("Unable to drop group privileges: %s!\n", strerror(errno));
262 if (setuid(uid) != 0)
263 panic("Unable to drop user privileges: %s!\n", strerror(errno));
266 int get_system_socket_mem(int which)
268 int fd, val = -1;
269 ssize_t ret;
270 const char *file = sock_mem[which];
271 char buff[64];
273 fd = open(file, O_RDONLY);
274 if (fd < 0)
275 return val;
277 ret = read(fd, buff, sizeof(buff));
278 if (ret > 0)
279 val = atoi(buff);
281 close(fd);
282 return val;
285 void set_system_socket_mem(int which, int val)
287 int fd;
288 const char *file = sock_mem[which];
289 ssize_t ret;
290 char buff[64];
292 fd = open(file, O_WRONLY);
293 if (fd < 0)
294 return;
296 memset(buff, 0, sizeof(buff));
297 slprintf(buff, sizeof(buff), "%d", val);
299 ret = write(fd, buff, strlen(buff));
300 ret = ret;
302 close(fd);
305 int wireless_sigqual(const char *ifname, struct iw_statistics *stats)
307 int ret, sock;
308 struct iwreq iwr;
310 sock = af_socket(AF_INET);
312 memset(&iwr, 0, sizeof(iwr));
313 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
315 iwr.u.data.pointer = (caddr_t) stats;
316 iwr.u.data.length = sizeof(*stats);
317 iwr.u.data.flags = 1;
319 ret = ioctl(sock, SIOCGIWSTATS, &iwr);
321 close(sock);
323 return ret;
326 int wireless_rangemax_sigqual(const char *ifname)
328 int ret, sock, sigqual;
329 struct iwreq iwr;
330 struct iw_range iwrange;
332 sock = af_socket(AF_INET);
334 memset(&iwrange, 0, sizeof(iwrange));
336 memset(&iwr, 0, sizeof(iwr));
337 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
339 iwr.u.data.pointer = (caddr_t) &iwrange;
340 iwr.u.data.length = sizeof(iwrange);
341 iwr.u.data.flags = 0;
343 ret = ioctl(sock, SIOCGIWRANGE, &iwr);
344 if (!ret)
345 sigqual = iwrange.max_qual.qual;
346 else
347 sigqual = 0;
349 close(sock);
351 return sigqual;
354 u32 ethtool_bitrate(const char *ifname)
356 int ret, sock, bitrate;
357 struct ifreq ifr;
358 struct ethtool_cmd ecmd;
360 sock = af_socket(AF_INET);
362 memset(&ecmd, 0, sizeof(ecmd));
364 memset(&ifr, 0, sizeof(ifr));
365 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
367 ecmd.cmd = ETHTOOL_GSET;
368 ifr.ifr_data = (char *) &ecmd;
370 ret = ioctl(sock, SIOCETHTOOL, &ifr);
371 if (ret) {
372 bitrate = 0;
373 goto out;
376 switch (ecmd.speed) {
377 case SPEED_10:
378 case SPEED_100:
379 case SPEED_1000:
380 case SPEED_2500:
381 case SPEED_10000:
382 bitrate = ecmd.speed;
383 break;
384 default:
385 bitrate = 0;
386 break;
388 out:
389 close(sock);
391 return bitrate;
394 int ethtool_link(const char *ifname)
396 int ret, sock;
397 struct ifreq ifr;
398 struct ethtool_value ecmd;
400 sock = af_socket(AF_INET);
402 memset(&ecmd, 0, sizeof(ecmd));
404 memset(&ifr, 0, sizeof(ifr));
405 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
407 ecmd.cmd = ETHTOOL_GLINK;
408 ifr.ifr_data = (char *) &ecmd;
410 ret = ioctl(sock, SIOCETHTOOL, &ifr);
411 if (ret)
412 ret = -EINVAL;
413 else
414 ret = !!ecmd.data;
416 close(sock);
417 return ret;
420 int ethtool_drvinf(const char *ifname, struct ethtool_drvinfo *drvinf)
422 int ret, sock;
423 struct ifreq ifr;
425 sock = af_socket(AF_INET);
427 memset(drvinf, 0, sizeof(*drvinf));
429 memset(&ifr, 0, sizeof(ifr));
430 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
432 drvinf->cmd = ETHTOOL_GDRVINFO;
433 ifr.ifr_data = (char *) drvinf;
435 ret = ioctl(sock, SIOCETHTOOL, &ifr);
437 close(sock);
439 return ret;
442 u32 device_bitrate(const char *ifname)
444 u32 speed_c, speed_w;
446 speed_c = ethtool_bitrate(ifname);
447 speed_w = wireless_bitrate(ifname);
449 return (speed_c == 0 ? speed_w : speed_c);
452 int device_ifindex(const char *ifname)
454 int ret, sock, index;
455 struct ifreq ifr;
457 if (!strncmp("any", ifname, strlen("any")))
458 return 0;
460 sock = af_socket(AF_INET);
462 memset(&ifr, 0, sizeof(ifr));
463 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
465 ret = ioctl(sock, SIOCGIFINDEX, &ifr);
466 if (!ret)
467 index = ifr.ifr_ifindex;
468 else
469 index = -1;
471 close(sock);
473 return index;
476 static int __device_address6(const char *ifname, struct sockaddr_storage *ss)
478 int ret, family, found = -EINVAL;
479 struct ifaddrs *ifaddr, *ifa;
481 ret = getifaddrs(&ifaddr);
482 if (ret < 0)
483 panic("Cannot get device addresses for IPv6!\n");
485 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
486 family = ifa->ifa_addr->sa_family;
487 if (family != AF_INET6)
488 continue;
489 if (strcmp(ifa->ifa_name, ifname))
490 continue;
492 memcpy(ss, ifa->ifa_addr, sizeof(*ss));
493 found = 0;
494 break;
497 freeifaddrs(ifaddr);
498 return found;
501 int device_address(const char *ifname, int af, struct sockaddr_storage *ss)
503 int ret, sock;
504 struct ifreq ifr;
506 if (!ss)
507 return -EINVAL;
508 if (!strncmp("any", ifname, strlen("any")))
509 return -EINVAL;
510 if (af == AF_INET6)
511 return __device_address6(ifname, ss);
513 sock = af_socket(af);
515 memset(&ifr, 0, sizeof(ifr));
516 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
518 ifr.ifr_addr.sa_family = af;
520 ret = ioctl(sock, SIOCGIFADDR, &ifr);
521 if (!ret)
522 memcpy(ss, &ifr.ifr_addr, sizeof(ifr.ifr_addr));
524 close(sock);
526 return ret;
529 int device_mtu(const char *ifname)
531 int ret, sock, mtu;
532 struct ifreq ifr;
534 sock = af_socket(AF_INET);
536 memset(&ifr, 0, sizeof(ifr));
537 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
539 ret = ioctl(sock, SIOCGIFMTU, &ifr);
540 if (!ret)
541 mtu = ifr.ifr_mtu;
542 else
543 mtu = 0;
545 close(sock);
547 return mtu;
550 short device_get_flags(const char *ifname)
552 /* Really, it's short! Look at struct ifreq */
553 short flags;
554 int ret, sock;
555 struct ifreq ifr;
557 sock = af_socket(AF_INET);
559 memset(&ifr, 0, sizeof(ifr));
560 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
562 ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
563 if (!ret)
564 flags = ifr.ifr_flags;
565 else
566 flags = 0;
568 close(sock);
570 return flags;
573 void device_set_flags(const char *ifname, const short flags)
575 int ret, sock;
576 struct ifreq ifr;
578 sock = af_socket(AF_INET);
580 memset(&ifr, 0, sizeof(ifr));
581 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
583 ifr.ifr_flags = flags;
585 ret = ioctl(sock, SIOCSIFFLAGS, &ifr);
586 if (ret < 0)
587 panic("Cannot set NIC flags!\n");
589 close(sock);
592 int device_irq_number(const char *ifname)
595 * Since fetching IRQ numbers from SIOCGIFMAP is deprecated and not
596 * supported anymore, we need to grab them from procfs
598 int irq = 0;
599 char *buffp;
600 char buff[512];
601 char sysname[512];
602 FILE *fp;
604 if (!strncmp("lo", ifname, strlen("lo")))
605 return 0;
607 fp = fopen("/proc/interrupts", "r");
608 if (!fp)
609 panic("Cannot open /proc/interrupts!\n");
611 memset(buff, 0, sizeof(buff));
612 while (fgets(buff, sizeof(buff), fp) != NULL) {
613 buff[sizeof(buff) - 1] = 0;
615 if (strstr(buff, ifname) == NULL)
616 continue;
618 buffp = buff;
619 while (*buffp != ':')
620 buffp++;
621 *buffp = 0;
622 irq = atoi(buff);
624 memset(buff, 0, sizeof(buff));
627 fclose(fp);
629 if (irq != 0)
630 return irq;
632 * Try sysfs as fallback. Probably wireless devices will be found
633 * here. We return silently if it fails ...
635 slprintf(sysname, sizeof(sysname), "/sys/class/net/%s/device/irq",
636 ifname);
638 fp = fopen(sysname, "r");
639 if (!fp)
640 return -ENOENT;
642 memset(buff, 0, sizeof(buff));
643 if(fgets(buff, sizeof(buff), fp) != NULL) {
644 buff[sizeof(buff) - 1] = 0;
645 irq = atoi(buff);
648 fclose(fp);
650 return irq;
653 int device_set_irq_affinity_list(int irq, unsigned long from, unsigned long to)
655 int ret, fd;
656 char file[256], list[64];
658 slprintf(file, sizeof(file), "/proc/irq/%d/smp_affinity_list", irq);
659 slprintf(list, sizeof(list), "%lu-%lu\n", from, to);
661 fd = open(file, O_WRONLY);
662 if (fd < 0)
663 return -ENOENT;
665 ret = write(fd, list, strlen(list));
667 close(fd);
668 return ret;
671 int device_bind_irq_to_cpu(int irq, int cpu)
673 int ret;
674 char buff[256];
675 char file[256];
676 FILE *fp;
678 /* Note: first CPU begins with CPU 0 */
679 if (irq < 0 || cpu < 0)
680 return -EINVAL;
682 memset(file, 0, sizeof(file));
683 memset(buff, 0, sizeof(buff));
685 /* smp_affinity starts counting with CPU 1, 2, ... */
686 cpu = cpu + 1;
687 sprintf(file, "/proc/irq/%d/smp_affinity", irq);
689 fp = fopen(file, "w");
690 if (!fp)
691 return -ENOENT;
693 sprintf(buff, "%d", cpu);
694 ret = fwrite(buff, sizeof(buff), 1, fp);
696 fclose(fp);
697 return (ret > 0 ? 0 : ret);
700 void sock_print_net_stats(int sock, unsigned long skipped)
702 int ret;
703 struct tpacket_stats kstats;
705 socklen_t slen = sizeof(kstats);
707 memset(&kstats, 0, sizeof(kstats));
708 ret = getsockopt(sock, SOL_PACKET, PACKET_STATISTICS, &kstats, &slen);
709 if (ret > -1) {
710 uint64_t packets = kstats.tp_packets;
711 uint64_t drops = kstats.tp_drops;
713 printf("\r%12ld packets incoming\n", packets);
714 printf("\r%12ld packets passed filter\n", packets - drops - skipped);
715 printf("\r%12ld packets failed filter (out of space)\n", drops + skipped);
716 if (kstats.tp_packets > 0)
717 printf("\r%12.4lf%\% packet droprate\n", (1.0 * drops / packets) * 100.0);
721 void register_signal(int signal, void (*handler)(int))
723 sigset_t block_mask;
724 struct sigaction saction;
726 sigfillset(&block_mask);
728 saction.sa_handler = handler;
729 saction.sa_mask = block_mask;
730 saction.sa_flags = SA_RESTART;
732 sigaction(signal, &saction, NULL);
735 void register_signal_f(int signal, void (*handler)(int), int flags)
737 sigset_t block_mask;
738 struct sigaction saction;
740 sigfillset(&block_mask);
742 saction.sa_handler = handler;
743 saction.sa_mask = block_mask;
744 saction.sa_flags = flags;
746 sigaction(signal, &saction, NULL);
749 short enter_promiscuous_mode(char *ifname)
751 short ifflags;
753 if (!strncmp("any", ifname, strlen("any")))
754 return 0;
756 ifflags = device_get_flags(ifname);
757 device_set_flags(ifname, ifflags | IFF_PROMISC);
759 return ifflags;
762 void leave_promiscuous_mode(char *ifname, short oldflags)
764 if (!strncmp("any", ifname, strlen("any")))
765 return;
767 device_set_flags(ifname, oldflags);
770 int device_up_and_running(char *ifname)
772 if (!ifname)
773 return -EINVAL;
774 if (!strncmp("any", ifname, strlen("any")))
775 return 1;
777 return (device_get_flags(ifname) & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING);
780 void cpu_affinity(int cpu)
782 int ret;
783 cpu_set_t cpu_bitmask;
785 CPU_ZERO(&cpu_bitmask);
786 CPU_SET(cpu, &cpu_bitmask);
788 ret = sched_setaffinity(getpid(), sizeof(cpu_bitmask),
789 &cpu_bitmask);
790 if (ret)
791 panic("Can't set this cpu affinity!\n");
794 int set_proc_prio(int priority)
796 int ret = setpriority(PRIO_PROCESS, getpid(), priority);
797 if (ret)
798 panic("Can't set nice val to %i!\n", priority);
800 return 0;
803 int set_sched_status(int policy, int priority)
805 int ret, min_prio, max_prio;
806 struct sched_param sp;
808 max_prio = sched_get_priority_max(policy);
809 min_prio = sched_get_priority_min(policy);
811 if (max_prio == -1 || min_prio == -1)
812 printf("Cannot determine scheduler prio limits!\n");
813 else if (priority < min_prio)
814 priority = min_prio;
815 else if (priority > max_prio)
816 priority = max_prio;
818 memset(&sp, 0, sizeof(sp));
819 sp.sched_priority = priority;
821 ret = sched_setscheduler(getpid(), policy, &sp);
822 if (ret) {
823 printf("Cannot set scheduler policy!\n");
824 return -EINVAL;
827 ret = sched_setparam(getpid(), &sp);
828 if (ret) {
829 printf("Cannot set scheduler prio!\n");
830 return -EINVAL;
833 return 0;
836 static inline int ioprio_set(int which, int who, int ioprio)
838 return syscall(SYS_ioprio_set, which, who, ioprio);
841 static inline int ioprio_get(int which, int who)
843 return syscall(SYS_ioprio_get, which, who);
846 static void ioprio_setpid(pid_t pid, int ioprio, int ioclass)
848 int ret = ioprio_set(ioprio_who_process, pid,
849 ioprio | ioclass << IOPRIO_CLASS_SHIFT);
850 if (ret < 0)
851 panic("Failed to set io prio for pid!\n");
854 void ioprio_print(void)
856 int ioprio = ioprio_get(ioprio_who_process, getpid());
857 if (ioprio < 0)
858 panic("Failed to fetch io prio for pid!\n");
859 else {
860 int ioclass = ioprio >> IOPRIO_CLASS_SHIFT;
861 if (ioclass != ioprio_class_idle) {
862 ioprio &= 0xff;
863 printf("%s: prio %d\n", to_prio[ioclass], ioprio);
864 } else
865 printf("%s\n", to_prio[ioclass]);
869 void set_ioprio_rt(void)
871 ioprio_setpid(getpid(), 4, ioprio_class_rt);
874 void set_ioprio_be(void)
876 ioprio_setpid(getpid(), 4, ioprio_class_be);
879 void xlockme(void)
881 if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0)
882 panic("Cannot lock pages!\n");
885 void xunlockme(void)
887 munlockall();
890 size_t strlcpy(char *dest, const char *src, size_t size)
892 size_t ret = strlen(src);
894 if (size) {
895 size_t len = (ret >= size) ? size - 1 : ret;
897 memcpy(dest, src, len);
898 dest[len] = '\0';
901 return ret;
904 static inline int vslprintf(char *dst, size_t size, const char *fmt, va_list ap)
906 int ret;
908 ret = vsnprintf(dst, size, fmt, ap);
909 dst[size - 1] = '\0';
911 return ret;
914 int slprintf(char *dst, size_t size, const char *fmt, ...)
916 int ret;
917 va_list ap;
919 va_start(ap, fmt);
920 ret = vslprintf(dst, size, fmt, ap);
921 va_end(ap);
923 return ret;
926 int slprintf_nocheck(char *dst, size_t size, const char *fmt, ...)
928 int ret;
929 va_list ap;
931 va_start(ap, fmt);
932 ret = vslprintf(dst, size, fmt, ap);
933 va_end(ap);
935 return ret;
938 noinline void *xmemset(void *s, int c, size_t n)
940 size_t i;
941 uint8_t *ptr = s;
943 for (i = 0; i < n; ++i)
944 ptr[i] = (uint8_t) c;
946 return ptr;
949 char *strtrim_right(char *p, char c)
951 char *end;
952 size_t len;
954 len = strlen(p);
955 while (*p && len) {
956 end = p + len - 1;
957 if (c == *end)
958 *end = 0;
959 else
960 break;
961 len = strlen(p);
964 return p;
967 int get_default_sched_policy(void)
969 return SCHED_FIFO;
972 int get_default_sched_prio(void)
974 return sched_get_priority_max(get_default_sched_policy());
977 int get_number_cpus(void)
979 return sysconf(_SC_NPROCESSORS_CONF);
982 int get_number_cpus_online(void)
984 return sysconf(_SC_NPROCESSORS_ONLN);
987 int get_default_proc_prio(void)
989 return -20;
992 void set_system_socket_memory(int *vals, size_t len)
994 bug_on(len != 4);
996 if ((vals[0] = get_system_socket_mem(sock_rmem_max)) < SMEM_SUG_MAX)
997 set_system_socket_mem(sock_rmem_max, SMEM_SUG_MAX);
998 if ((vals[1] = get_system_socket_mem(sock_rmem_def)) < SMEM_SUG_DEF)
999 set_system_socket_mem(sock_rmem_def, SMEM_SUG_DEF);
1000 if ((vals[2] = get_system_socket_mem(sock_wmem_max)) < SMEM_SUG_MAX)
1001 set_system_socket_mem(sock_wmem_max, SMEM_SUG_MAX);
1002 if ((vals[3] = get_system_socket_mem(sock_wmem_def)) < SMEM_SUG_DEF)
1003 set_system_socket_mem(sock_wmem_def, SMEM_SUG_DEF);
1006 void reset_system_socket_memory(int *vals, size_t len)
1008 bug_on(len != 4);
1010 set_system_socket_mem(sock_rmem_max, vals[0]);
1011 set_system_socket_mem(sock_rmem_def, vals[1]);
1012 set_system_socket_mem(sock_wmem_max, vals[2]);
1013 set_system_socket_mem(sock_wmem_def, vals[3]);
1016 void set_itimer_interval_value(struct itimerval *itimer, unsigned long sec,
1017 unsigned long usec)
1019 itimer->it_interval.tv_sec = sec;
1020 itimer->it_interval.tv_usec = usec;
1022 itimer->it_value.tv_sec = sec;
1023 itimer->it_value.tv_usec = usec;