netsniff-ng: also capture if NIC is currently down
[netsniff-ng.git] / xutils.c
blob019c44518d15113eda01bf81873d8d8c20eccce1
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 ret, val = prio;
115 ret = setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
116 if (unlikely(ret))
117 panic("Cannot set socket priority!\n");
120 void set_udp_cork(int fd)
122 int ret, state = 1;
124 ret = setsockopt(fd, IPPROTO_UDP, UDP_CORK, &state, sizeof(state));
125 if (unlikely(ret))
126 panic("Cannot cork UDP socket!\n");
129 void set_udp_uncork(int fd)
131 int ret, state = 0;
133 ret = setsockopt(fd, IPPROTO_UDP, UDP_CORK, &state, sizeof(state));
134 if (unlikely(ret))
135 panic("Cannot uncork UDP socket!\n");
138 void set_tcp_cork(int fd)
140 int ret, state = 1;
142 ret = setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
143 if (unlikely(ret))
144 panic("Cannot cork TCP socket!\n");
147 void set_tcp_uncork(int fd)
149 int ret, state = 0;
151 ret = setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
152 if (unlikely(ret))
153 panic("Cannot uncork TCP socket!\n");
156 void set_sock_cork(int fd, int udp)
158 if (!!udp)
159 set_udp_cork(fd);
160 else
161 set_tcp_cork(fd);
164 void set_sock_uncork(int fd, int udp)
166 if (!!udp)
167 set_udp_uncork(fd);
168 else
169 set_tcp_uncork(fd);
172 int set_nonblocking(int fd)
174 int ret = fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
175 if (unlikely(ret < 0))
176 panic("Cannot fcntl!\n");
178 return 0;
181 int set_nonblocking_sloppy(int fd)
183 return fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
186 void set_socket_keepalive(int fd)
188 int ret, one = 1;
190 ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one));
191 if (unlikely(ret))
192 panic("Cannot set TCP keepalive!\n");
195 void set_tcp_nodelay(int fd)
197 int one = 1;
198 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
201 int set_ipv6_only(int fd)
203 int one = 1;
204 return setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
207 int set_reuseaddr(int fd)
209 int ret, one = 1;
211 ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
212 if (unlikely(ret < 0))
213 panic("Cannot reuse addr!\n");
215 return 0;
218 void set_mtu_disc_dont(int fd)
220 int mtu = IP_PMTUDISC_DONT, ret;
222 ret = setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu));
223 if (unlikely(ret))
224 panic("Cannot set MTU discovery options!\n");
227 void set_epoll_descriptor(int fd_epoll, int action, int fd_toadd, int events)
229 int ret;
230 struct epoll_event ev;
232 memset(&ev, 0, sizeof(ev));
233 ev.events = events;
234 ev.data.fd = fd_toadd;
236 ret = epoll_ctl(fd_epoll, action, fd_toadd, &ev);
237 if (ret < 0)
238 panic("Cannot add socket for epoll!\n");
241 int set_epoll_descriptor2(int fd_epoll, int action, int fd_toadd, int events)
243 struct epoll_event ev;
245 memset(&ev, 0, sizeof(ev));
246 ev.events = events;
247 ev.data.fd = fd_toadd;
249 return epoll_ctl(fd_epoll, action, fd_toadd, &ev);
252 u32 wireless_bitrate(const char *ifname)
254 int sock, ret, rate_in_mbit;
255 struct iwreq iwr;
257 sock = af_socket(AF_INET);
259 memset(&iwr, 0, sizeof(iwr));
260 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
262 ret = ioctl(sock, SIOCGIWRATE, &iwr);
263 if (!ret)
264 rate_in_mbit = iwr.u.bitrate.value / 1000000;
265 else
266 rate_in_mbit = 0;
268 close(sock);
270 return rate_in_mbit;
273 void drop_privileges(bool enforce, uid_t uid, gid_t gid)
275 if (enforce) {
276 if (uid == getuid())
277 panic("Uid cannot be the same as the current user!\n");
278 if (gid == getgid())
279 panic("Gid cannot be the same as the current user!\n");
281 if (setgid(gid) != 0)
282 panic("Unable to drop group privileges: %s!\n", strerror(errno));
283 if (setuid(uid) != 0)
284 panic("Unable to drop user privileges: %s!\n", strerror(errno));
287 int get_system_socket_mem(int which)
289 int fd, val = -1;
290 ssize_t ret;
291 const char *file = sock_mem[which];
292 char buff[64];
294 fd = open(file, O_RDONLY);
295 if (fd < 0)
296 return val;
298 ret = read(fd, buff, sizeof(buff));
299 if (ret > 0)
300 val = atoi(buff);
302 close(fd);
303 return val;
306 void set_system_socket_mem(int which, int val)
308 int fd;
309 const char *file = sock_mem[which];
310 ssize_t ret;
311 char buff[64];
313 fd = open(file, O_WRONLY);
314 if (fd < 0)
315 return;
317 memset(buff, 0, sizeof(buff));
318 slprintf(buff, sizeof(buff), "%d", val);
320 ret = write(fd, buff, strlen(buff));
321 ret = ret;
323 close(fd);
326 int wireless_sigqual(const char *ifname, struct iw_statistics *stats)
328 int ret, sock;
329 struct iwreq iwr;
331 sock = af_socket(AF_INET);
333 memset(&iwr, 0, sizeof(iwr));
334 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
336 iwr.u.data.pointer = (caddr_t) stats;
337 iwr.u.data.length = sizeof(*stats);
338 iwr.u.data.flags = 1;
340 ret = ioctl(sock, SIOCGIWSTATS, &iwr);
342 close(sock);
344 return ret;
347 int wireless_rangemax_sigqual(const char *ifname)
349 int ret, sock, sigqual;
350 struct iwreq iwr;
351 struct iw_range iwrange;
353 sock = af_socket(AF_INET);
355 memset(&iwrange, 0, sizeof(iwrange));
357 memset(&iwr, 0, sizeof(iwr));
358 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
360 iwr.u.data.pointer = (caddr_t) &iwrange;
361 iwr.u.data.length = sizeof(iwrange);
362 iwr.u.data.flags = 0;
364 ret = ioctl(sock, SIOCGIWRANGE, &iwr);
365 if (!ret)
366 sigqual = iwrange.max_qual.qual;
367 else
368 sigqual = 0;
370 close(sock);
372 return sigqual;
375 u32 ethtool_bitrate(const char *ifname)
377 int ret, sock, bitrate;
378 struct ifreq ifr;
379 struct ethtool_cmd ecmd;
381 sock = af_socket(AF_INET);
383 memset(&ecmd, 0, sizeof(ecmd));
385 memset(&ifr, 0, sizeof(ifr));
386 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
388 ecmd.cmd = ETHTOOL_GSET;
389 ifr.ifr_data = (char *) &ecmd;
391 ret = ioctl(sock, SIOCETHTOOL, &ifr);
392 if (ret) {
393 bitrate = 0;
394 goto out;
397 switch (ecmd.speed) {
398 case SPEED_10:
399 case SPEED_100:
400 case SPEED_1000:
401 case SPEED_2500:
402 case SPEED_10000:
403 bitrate = ecmd.speed;
404 break;
405 default:
406 bitrate = 0;
407 break;
409 out:
410 close(sock);
412 return bitrate;
415 int ethtool_link(const char *ifname)
417 int ret, sock;
418 struct ifreq ifr;
419 struct ethtool_value ecmd;
421 sock = af_socket(AF_INET);
423 memset(&ecmd, 0, sizeof(ecmd));
425 memset(&ifr, 0, sizeof(ifr));
426 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
428 ecmd.cmd = ETHTOOL_GLINK;
429 ifr.ifr_data = (char *) &ecmd;
431 ret = ioctl(sock, SIOCETHTOOL, &ifr);
432 if (ret)
433 ret = -EINVAL;
434 else
435 ret = !!ecmd.data;
437 close(sock);
438 return ret;
441 int ethtool_drvinf(const char *ifname, struct ethtool_drvinfo *drvinf)
443 int ret, sock;
444 struct ifreq ifr;
446 sock = af_socket(AF_INET);
448 memset(drvinf, 0, sizeof(*drvinf));
450 memset(&ifr, 0, sizeof(ifr));
451 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
453 drvinf->cmd = ETHTOOL_GDRVINFO;
454 ifr.ifr_data = (char *) drvinf;
456 ret = ioctl(sock, SIOCETHTOOL, &ifr);
458 close(sock);
460 return ret;
463 u32 device_bitrate(const char *ifname)
465 u32 speed_c, speed_w;
467 speed_c = ethtool_bitrate(ifname);
468 speed_w = wireless_bitrate(ifname);
470 return (speed_c == 0 ? speed_w : speed_c);
473 int device_ifindex(const char *ifname)
475 int ret, sock, index;
476 struct ifreq ifr;
478 if (!strncmp("any", ifname, strlen("any")))
479 return 0;
481 sock = af_socket(AF_INET);
483 memset(&ifr, 0, sizeof(ifr));
484 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
486 ret = ioctl(sock, SIOCGIFINDEX, &ifr);
487 if (!ret)
488 index = ifr.ifr_ifindex;
489 else
490 index = -1;
492 close(sock);
494 return index;
497 static int __device_address6(const char *ifname, struct sockaddr_storage *ss)
499 int ret, family, found = -EINVAL;
500 struct ifaddrs *ifaddr, *ifa;
502 ret = getifaddrs(&ifaddr);
503 if (ret < 0)
504 panic("Cannot get device addresses for IPv6!\n");
506 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
507 family = ifa->ifa_addr->sa_family;
508 if (family != AF_INET6)
509 continue;
510 if (strcmp(ifa->ifa_name, ifname))
511 continue;
513 memcpy(ss, ifa->ifa_addr, sizeof(*ss));
514 found = 0;
515 break;
518 freeifaddrs(ifaddr);
519 return found;
522 int device_address(const char *ifname, int af, struct sockaddr_storage *ss)
524 int ret, sock;
525 struct ifreq ifr;
527 if (!ss)
528 return -EINVAL;
529 if (!strncmp("any", ifname, strlen("any")))
530 return -EINVAL;
531 if (af == AF_INET6)
532 return __device_address6(ifname, ss);
534 sock = af_socket(af);
536 memset(&ifr, 0, sizeof(ifr));
537 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
539 ifr.ifr_addr.sa_family = af;
541 ret = ioctl(sock, SIOCGIFADDR, &ifr);
542 if (!ret)
543 memcpy(ss, &ifr.ifr_addr, sizeof(ifr.ifr_addr));
545 close(sock);
547 return ret;
550 int device_mtu(const char *ifname)
552 int ret, sock, mtu;
553 struct ifreq ifr;
555 sock = af_socket(AF_INET);
557 memset(&ifr, 0, sizeof(ifr));
558 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
560 ret = ioctl(sock, SIOCGIFMTU, &ifr);
561 if (!ret)
562 mtu = ifr.ifr_mtu;
563 else
564 mtu = 0;
566 close(sock);
568 return mtu;
571 short device_get_flags(const char *ifname)
573 /* Really, it's short! Look at struct ifreq */
574 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 ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
584 if (!ret)
585 flags = ifr.ifr_flags;
586 else
587 flags = 0;
589 close(sock);
591 return flags;
594 void device_set_flags(const char *ifname, const short flags)
596 int ret, sock;
597 struct ifreq ifr;
599 sock = af_socket(AF_INET);
601 memset(&ifr, 0, sizeof(ifr));
602 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
604 ifr.ifr_flags = flags;
606 ret = ioctl(sock, SIOCSIFFLAGS, &ifr);
607 if (ret < 0)
608 panic("Cannot set NIC flags!\n");
610 close(sock);
613 int device_irq_number(const char *ifname)
616 * Since fetching IRQ numbers from SIOCGIFMAP is deprecated and not
617 * supported anymore, we need to grab them from procfs
619 int irq = 0;
620 char *buffp;
621 char buff[512];
622 char sysname[512];
623 FILE *fp;
625 if (!strncmp("lo", ifname, strlen("lo")))
626 return 0;
628 fp = fopen("/proc/interrupts", "r");
629 if (!fp)
630 panic("Cannot open /proc/interrupts!\n");
632 memset(buff, 0, sizeof(buff));
633 while (fgets(buff, sizeof(buff), fp) != NULL) {
634 buff[sizeof(buff) - 1] = 0;
636 if (strstr(buff, ifname) == NULL)
637 continue;
639 buffp = buff;
640 while (*buffp != ':')
641 buffp++;
642 *buffp = 0;
643 irq = atoi(buff);
645 memset(buff, 0, sizeof(buff));
648 fclose(fp);
650 if (irq != 0)
651 return irq;
653 * Try sysfs as fallback. Probably wireless devices will be found
654 * here. We return silently if it fails ...
656 slprintf(sysname, sizeof(sysname), "/sys/class/net/%s/device/irq",
657 ifname);
659 fp = fopen(sysname, "r");
660 if (!fp)
661 return -ENOENT;
663 memset(buff, 0, sizeof(buff));
664 if(fgets(buff, sizeof(buff), fp) != NULL) {
665 buff[sizeof(buff) - 1] = 0;
666 irq = atoi(buff);
669 fclose(fp);
671 return irq;
674 int device_set_irq_affinity_list(int irq, unsigned long from, unsigned long to)
676 int ret, fd;
677 char file[256], list[64];
679 slprintf(file, sizeof(file), "/proc/irq/%d/smp_affinity_list", irq);
680 slprintf(list, sizeof(list), "%lu-%lu\n", from, to);
682 fd = open(file, O_WRONLY);
683 if (fd < 0)
684 return -ENOENT;
686 ret = write(fd, list, strlen(list));
688 close(fd);
689 return ret;
692 int device_bind_irq_to_cpu(int irq, int cpu)
694 int ret;
695 char buff[256];
696 char file[256];
697 FILE *fp;
699 /* Note: first CPU begins with CPU 0 */
700 if (irq < 0 || cpu < 0)
701 return -EINVAL;
703 memset(file, 0, sizeof(file));
704 memset(buff, 0, sizeof(buff));
706 /* smp_affinity starts counting with CPU 1, 2, ... */
707 cpu = cpu + 1;
708 sprintf(file, "/proc/irq/%d/smp_affinity", irq);
710 fp = fopen(file, "w");
711 if (!fp)
712 return -ENOENT;
714 sprintf(buff, "%d", cpu);
715 ret = fwrite(buff, sizeof(buff), 1, fp);
717 fclose(fp);
718 return (ret > 0 ? 0 : ret);
721 void sock_print_net_stats(int sock, unsigned long skipped)
723 int ret;
724 struct tpacket_stats kstats;
726 socklen_t slen = sizeof(kstats);
728 memset(&kstats, 0, sizeof(kstats));
729 ret = getsockopt(sock, SOL_PACKET, PACKET_STATISTICS, &kstats, &slen);
730 if (ret > -1) {
731 uint64_t packets = kstats.tp_packets;
732 uint64_t drops = kstats.tp_drops;
734 printf("\r%12ld packets incoming\n", packets);
735 printf("\r%12ld packets passed filter\n", packets - drops - skipped);
736 printf("\r%12ld packets failed filter (out of space)\n", drops + skipped);
737 if (kstats.tp_packets > 0)
738 printf("\r%12.4lf%\% packet droprate\n", (1.0 * drops / packets) * 100.0);
742 void register_signal(int signal, void (*handler)(int))
744 sigset_t block_mask;
745 struct sigaction saction;
747 sigfillset(&block_mask);
749 saction.sa_handler = handler;
750 saction.sa_mask = block_mask;
751 saction.sa_flags = SA_RESTART;
753 sigaction(signal, &saction, NULL);
756 void register_signal_f(int signal, void (*handler)(int), int flags)
758 sigset_t block_mask;
759 struct sigaction saction;
761 sigfillset(&block_mask);
763 saction.sa_handler = handler;
764 saction.sa_mask = block_mask;
765 saction.sa_flags = flags;
767 sigaction(signal, &saction, NULL);
770 short enter_promiscuous_mode(char *ifname)
772 short ifflags;
774 if (!strncmp("any", ifname, strlen("any")))
775 return 0;
777 ifflags = device_get_flags(ifname);
778 device_set_flags(ifname, ifflags | IFF_PROMISC);
780 return ifflags;
783 void leave_promiscuous_mode(char *ifname, short oldflags)
785 if (!strncmp("any", ifname, strlen("any")))
786 return;
788 device_set_flags(ifname, oldflags);
791 int device_up_and_running(char *ifname)
793 if (!ifname)
794 return -EINVAL;
795 if (!strncmp("any", ifname, strlen("any")))
796 return 1;
798 return (device_get_flags(ifname) & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING);
801 void cpu_affinity(int cpu)
803 int ret;
804 cpu_set_t cpu_bitmask;
806 CPU_ZERO(&cpu_bitmask);
807 CPU_SET(cpu, &cpu_bitmask);
809 ret = sched_setaffinity(getpid(), sizeof(cpu_bitmask),
810 &cpu_bitmask);
811 if (ret)
812 panic("Can't set this cpu affinity!\n");
815 int set_proc_prio(int priority)
817 int ret = setpriority(PRIO_PROCESS, getpid(), priority);
818 if (ret)
819 panic("Can't set nice val to %i!\n", priority);
821 return 0;
824 int set_sched_status(int policy, int priority)
826 int ret, min_prio, max_prio;
827 struct sched_param sp;
829 max_prio = sched_get_priority_max(policy);
830 min_prio = sched_get_priority_min(policy);
832 if (max_prio == -1 || min_prio == -1)
833 printf("Cannot determine scheduler prio limits!\n");
834 else if (priority < min_prio)
835 priority = min_prio;
836 else if (priority > max_prio)
837 priority = max_prio;
839 memset(&sp, 0, sizeof(sp));
840 sp.sched_priority = priority;
842 ret = sched_setscheduler(getpid(), policy, &sp);
843 if (ret) {
844 printf("Cannot set scheduler policy!\n");
845 return -EINVAL;
848 ret = sched_setparam(getpid(), &sp);
849 if (ret) {
850 printf("Cannot set scheduler prio!\n");
851 return -EINVAL;
854 return 0;
857 static inline int ioprio_set(int which, int who, int ioprio)
859 return syscall(SYS_ioprio_set, which, who, ioprio);
862 static inline int ioprio_get(int which, int who)
864 return syscall(SYS_ioprio_get, which, who);
867 static void ioprio_setpid(pid_t pid, int ioprio, int ioclass)
869 int ret = ioprio_set(ioprio_who_process, pid,
870 ioprio | ioclass << IOPRIO_CLASS_SHIFT);
871 if (ret < 0)
872 panic("Failed to set io prio for pid!\n");
875 void ioprio_print(void)
877 int ioprio = ioprio_get(ioprio_who_process, getpid());
878 if (ioprio < 0)
879 panic("Failed to fetch io prio for pid!\n");
880 else {
881 int ioclass = ioprio >> IOPRIO_CLASS_SHIFT;
882 if (ioclass != ioprio_class_idle) {
883 ioprio &= 0xff;
884 printf("%s: prio %d\n", to_prio[ioclass], ioprio);
885 } else
886 printf("%s\n", to_prio[ioclass]);
890 void set_ioprio_rt(void)
892 ioprio_setpid(getpid(), 4, ioprio_class_rt);
895 void set_ioprio_be(void)
897 ioprio_setpid(getpid(), 4, ioprio_class_be);
900 void xlockme(void)
902 if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0)
903 panic("Cannot lock pages!\n");
906 void xunlockme(void)
908 munlockall();
911 size_t strlcpy(char *dest, const char *src, size_t size)
913 size_t ret = strlen(src);
915 if (size) {
916 size_t len = (ret >= size) ? size - 1 : ret;
918 memcpy(dest, src, len);
919 dest[len] = '\0';
922 return ret;
925 static inline int vslprintf(char *dst, size_t size, const char *fmt, va_list ap)
927 int ret;
929 ret = vsnprintf(dst, size, fmt, ap);
930 dst[size - 1] = '\0';
932 return ret;
935 int slprintf(char *dst, size_t size, const char *fmt, ...)
937 int ret;
938 va_list ap;
940 va_start(ap, fmt);
941 ret = vslprintf(dst, size, fmt, ap);
942 va_end(ap);
944 return ret;
947 int slprintf_nocheck(char *dst, size_t size, const char *fmt, ...)
949 int ret;
950 va_list ap;
952 va_start(ap, fmt);
953 ret = vslprintf(dst, size, fmt, ap);
954 va_end(ap);
956 return ret;
959 noinline void *xmemset(void *s, int c, size_t n)
961 size_t i;
962 uint8_t *ptr = s;
964 for (i = 0; i < n; ++i)
965 ptr[i] = (uint8_t) c;
967 return ptr;
970 char *strtrim_right(char *p, char c)
972 char *end;
973 size_t len;
975 len = strlen(p);
976 while (*p && len) {
977 end = p + len - 1;
978 if (c == *end)
979 *end = 0;
980 else
981 break;
982 len = strlen(p);
985 return p;
988 int get_default_sched_policy(void)
990 return SCHED_FIFO;
993 int get_default_sched_prio(void)
995 return sched_get_priority_max(get_default_sched_policy());
998 int get_number_cpus(void)
1000 return sysconf(_SC_NPROCESSORS_CONF);
1003 int get_number_cpus_online(void)
1005 return sysconf(_SC_NPROCESSORS_ONLN);
1008 int get_default_proc_prio(void)
1010 return -20;
1013 void set_system_socket_memory(int *vals, size_t len)
1015 bug_on(len != 4);
1017 if ((vals[0] = get_system_socket_mem(sock_rmem_max)) < SMEM_SUG_MAX)
1018 set_system_socket_mem(sock_rmem_max, SMEM_SUG_MAX);
1019 if ((vals[1] = get_system_socket_mem(sock_rmem_def)) < SMEM_SUG_DEF)
1020 set_system_socket_mem(sock_rmem_def, SMEM_SUG_DEF);
1021 if ((vals[2] = get_system_socket_mem(sock_wmem_max)) < SMEM_SUG_MAX)
1022 set_system_socket_mem(sock_wmem_max, SMEM_SUG_MAX);
1023 if ((vals[3] = get_system_socket_mem(sock_wmem_def)) < SMEM_SUG_DEF)
1024 set_system_socket_mem(sock_wmem_def, SMEM_SUG_DEF);
1027 void reset_system_socket_memory(int *vals, size_t len)
1029 bug_on(len != 4);
1031 set_system_socket_mem(sock_rmem_max, vals[0]);
1032 set_system_socket_mem(sock_rmem_def, vals[1]);
1033 set_system_socket_mem(sock_wmem_max, vals[2]);
1034 set_system_socket_mem(sock_wmem_def, vals[3]);
1037 void set_itimer_interval_value(struct itimerval *itimer, unsigned long sec,
1038 unsigned long usec)
1040 itimer->it_interval.tv_sec = sec;
1041 itimer->it_interval.tv_usec = usec;
1043 itimer->it_value.tv_sec = sec;
1044 itimer->it_value.tv_usec = usec;