ring: add necessary structures and helper functions for v3
[netsniff-ng.git] / xutils.c
blob60b598c041f128aab2b838ada17cc9b3771b8ef9
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 void 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");
179 int set_nonblocking_sloppy(int fd)
181 return fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
184 void set_socket_keepalive(int fd)
186 int ret, one = 1;
188 ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one));
189 if (unlikely(ret))
190 panic("Cannot set TCP keepalive!\n");
193 void set_tcp_nodelay(int fd)
195 int one = 1;
196 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
199 int set_ipv6_only(int fd)
201 int one = 1;
202 return setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
205 int set_reuseaddr(int fd)
207 int ret, one = 1;
209 ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
210 if (unlikely(ret < 0))
211 panic("Cannot reuse addr!\n");
213 return 0;
216 void set_mtu_disc_dont(int fd)
218 int mtu = IP_PMTUDISC_DONT, ret;
220 ret = setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu));
221 if (unlikely(ret))
222 panic("Cannot set MTU discovery options!\n");
225 void set_epoll_descriptor(int fd_epoll, int action, int fd_toadd, int events)
227 int ret;
228 struct epoll_event ev;
230 memset(&ev, 0, sizeof(ev));
231 ev.events = events;
232 ev.data.fd = fd_toadd;
234 ret = epoll_ctl(fd_epoll, action, fd_toadd, &ev);
235 if (ret < 0)
236 panic("Cannot add socket for epoll!\n");
239 int set_epoll_descriptor2(int fd_epoll, int action, int fd_toadd, int events)
241 struct epoll_event ev;
243 memset(&ev, 0, sizeof(ev));
244 ev.events = events;
245 ev.data.fd = fd_toadd;
247 return epoll_ctl(fd_epoll, action, fd_toadd, &ev);
250 u32 wireless_bitrate(const char *ifname)
252 int sock, ret, rate_in_mbit;
253 struct iwreq iwr;
255 sock = af_socket(AF_INET);
257 memset(&iwr, 0, sizeof(iwr));
258 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
260 ret = ioctl(sock, SIOCGIWRATE, &iwr);
261 if (!ret)
262 rate_in_mbit = iwr.u.bitrate.value / 1000000;
263 else
264 rate_in_mbit = 0;
266 close(sock);
268 return rate_in_mbit;
271 void drop_privileges(bool enforce, uid_t uid, gid_t gid)
273 if (enforce) {
274 if (uid == getuid())
275 panic("Uid cannot be the same as the current user!\n");
276 if (gid == getgid())
277 panic("Gid cannot be the same as the current user!\n");
279 if (setgid(gid) != 0)
280 panic("Unable to drop group privileges: %s!\n", strerror(errno));
281 if (setuid(uid) != 0)
282 panic("Unable to drop user privileges: %s!\n", strerror(errno));
285 int get_system_socket_mem(int which)
287 int fd, val = -1;
288 ssize_t ret;
289 const char *file = sock_mem[which];
290 char buff[64];
292 fd = open(file, O_RDONLY);
293 if (fd < 0)
294 return val;
296 ret = read(fd, buff, sizeof(buff));
297 if (ret > 0)
298 val = atoi(buff);
300 close(fd);
301 return val;
304 void set_system_socket_mem(int which, int val)
306 int fd;
307 const char *file = sock_mem[which];
308 ssize_t ret;
309 char buff[64];
311 fd = open(file, O_WRONLY);
312 if (fd < 0)
313 return;
315 memset(buff, 0, sizeof(buff));
316 slprintf(buff, sizeof(buff), "%d", val);
318 ret = write(fd, buff, strlen(buff));
319 ret = ret;
321 close(fd);
324 int wireless_sigqual(const char *ifname, struct iw_statistics *stats)
326 int ret, sock;
327 struct iwreq iwr;
329 sock = af_socket(AF_INET);
331 memset(&iwr, 0, sizeof(iwr));
332 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
334 iwr.u.data.pointer = (caddr_t) stats;
335 iwr.u.data.length = sizeof(*stats);
336 iwr.u.data.flags = 1;
338 ret = ioctl(sock, SIOCGIWSTATS, &iwr);
340 close(sock);
342 return ret;
345 int wireless_rangemax_sigqual(const char *ifname)
347 int ret, sock, sigqual;
348 struct iwreq iwr;
349 struct iw_range iwrange;
351 sock = af_socket(AF_INET);
353 memset(&iwrange, 0, sizeof(iwrange));
355 memset(&iwr, 0, sizeof(iwr));
356 strlcpy(iwr.ifr_name, ifname, IFNAMSIZ);
358 iwr.u.data.pointer = (caddr_t) &iwrange;
359 iwr.u.data.length = sizeof(iwrange);
360 iwr.u.data.flags = 0;
362 ret = ioctl(sock, SIOCGIWRANGE, &iwr);
363 if (!ret)
364 sigqual = iwrange.max_qual.qual;
365 else
366 sigqual = 0;
368 close(sock);
370 return sigqual;
373 u32 ethtool_bitrate(const char *ifname)
375 int ret, sock, bitrate;
376 struct ifreq ifr;
377 struct ethtool_cmd ecmd;
379 sock = af_socket(AF_INET);
381 memset(&ecmd, 0, sizeof(ecmd));
383 memset(&ifr, 0, sizeof(ifr));
384 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
386 ecmd.cmd = ETHTOOL_GSET;
387 ifr.ifr_data = (char *) &ecmd;
389 ret = ioctl(sock, SIOCETHTOOL, &ifr);
390 if (ret) {
391 bitrate = 0;
392 goto out;
395 switch (ecmd.speed) {
396 case SPEED_10:
397 case SPEED_100:
398 case SPEED_1000:
399 case SPEED_2500:
400 case SPEED_10000:
401 bitrate = ecmd.speed;
402 break;
403 default:
404 bitrate = 0;
405 break;
407 out:
408 close(sock);
410 return bitrate;
413 int ethtool_link(const char *ifname)
415 int ret, sock;
416 struct ifreq ifr;
417 struct ethtool_value ecmd;
419 sock = af_socket(AF_INET);
421 memset(&ecmd, 0, sizeof(ecmd));
423 memset(&ifr, 0, sizeof(ifr));
424 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
426 ecmd.cmd = ETHTOOL_GLINK;
427 ifr.ifr_data = (char *) &ecmd;
429 ret = ioctl(sock, SIOCETHTOOL, &ifr);
430 if (ret)
431 ret = -EINVAL;
432 else
433 ret = !!ecmd.data;
435 close(sock);
436 return ret;
439 int ethtool_drvinf(const char *ifname, struct ethtool_drvinfo *drvinf)
441 int ret, sock;
442 struct ifreq ifr;
444 sock = af_socket(AF_INET);
446 memset(drvinf, 0, sizeof(*drvinf));
448 memset(&ifr, 0, sizeof(ifr));
449 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
451 drvinf->cmd = ETHTOOL_GDRVINFO;
452 ifr.ifr_data = (char *) drvinf;
454 ret = ioctl(sock, SIOCETHTOOL, &ifr);
456 close(sock);
458 return ret;
461 u32 device_bitrate(const char *ifname)
463 u32 speed_c, speed_w;
465 speed_c = ethtool_bitrate(ifname);
466 speed_w = wireless_bitrate(ifname);
468 return (speed_c == 0 ? speed_w : speed_c);
471 int device_ifindex(const char *ifname)
473 int ret, sock, index;
474 struct ifreq ifr;
476 if (!strncmp("any", ifname, strlen("any")))
477 return 0;
479 sock = af_socket(AF_INET);
481 memset(&ifr, 0, sizeof(ifr));
482 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
484 ret = ioctl(sock, SIOCGIFINDEX, &ifr);
485 if (!ret)
486 index = ifr.ifr_ifindex;
487 else
488 index = -1;
490 close(sock);
492 return index;
495 static int __device_address6(const char *ifname, struct sockaddr_storage *ss)
497 int ret, family, found = -EINVAL;
498 struct ifaddrs *ifaddr, *ifa;
500 ret = getifaddrs(&ifaddr);
501 if (ret < 0)
502 panic("Cannot get device addresses for IPv6!\n");
504 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
505 family = ifa->ifa_addr->sa_family;
506 if (family != AF_INET6)
507 continue;
508 if (strcmp(ifa->ifa_name, ifname))
509 continue;
511 memcpy(ss, ifa->ifa_addr, sizeof(*ss));
512 found = 0;
513 break;
516 freeifaddrs(ifaddr);
517 return found;
520 int device_address(const char *ifname, int af, struct sockaddr_storage *ss)
522 int ret, sock;
523 struct ifreq ifr;
525 if (!ss)
526 return -EINVAL;
527 if (!strncmp("any", ifname, strlen("any")))
528 return -EINVAL;
529 if (af == AF_INET6)
530 return __device_address6(ifname, ss);
532 sock = af_socket(af);
534 memset(&ifr, 0, sizeof(ifr));
535 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
537 ifr.ifr_addr.sa_family = af;
539 ret = ioctl(sock, SIOCGIFADDR, &ifr);
540 if (!ret)
541 memcpy(ss, &ifr.ifr_addr, sizeof(ifr.ifr_addr));
543 close(sock);
545 return ret;
548 int device_mtu(const char *ifname)
550 int ret, sock, mtu;
551 struct ifreq ifr;
553 sock = af_socket(AF_INET);
555 memset(&ifr, 0, sizeof(ifr));
556 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
558 ret = ioctl(sock, SIOCGIFMTU, &ifr);
559 if (!ret)
560 mtu = ifr.ifr_mtu;
561 else
562 mtu = 0;
564 close(sock);
566 return mtu;
569 short device_get_flags(const char *ifname)
571 /* Really, it's short! Look at struct ifreq */
572 short flags;
573 int ret, sock;
574 struct ifreq ifr;
576 sock = af_socket(AF_INET);
578 memset(&ifr, 0, sizeof(ifr));
579 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
581 ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
582 if (!ret)
583 flags = ifr.ifr_flags;
584 else
585 flags = 0;
587 close(sock);
589 return flags;
592 void device_set_flags(const char *ifname, const short flags)
594 int ret, sock;
595 struct ifreq ifr;
597 sock = af_socket(AF_INET);
599 memset(&ifr, 0, sizeof(ifr));
600 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
602 ifr.ifr_flags = flags;
604 ret = ioctl(sock, SIOCSIFFLAGS, &ifr);
605 if (ret < 0)
606 panic("Cannot set NIC flags!\n");
608 close(sock);
611 int device_irq_number(const char *ifname)
614 * Since fetching IRQ numbers from SIOCGIFMAP is deprecated and not
615 * supported anymore, we need to grab them from procfs
617 int irq = 0;
618 char *buffp;
619 char buff[512];
620 char sysname[512];
621 FILE *fp;
623 if (!strncmp("lo", ifname, strlen("lo")))
624 return 0;
626 fp = fopen("/proc/interrupts", "r");
627 if (!fp)
628 panic("Cannot open /proc/interrupts!\n");
630 memset(buff, 0, sizeof(buff));
631 while (fgets(buff, sizeof(buff), fp) != NULL) {
632 buff[sizeof(buff) - 1] = 0;
634 if (strstr(buff, ifname) == NULL)
635 continue;
637 buffp = buff;
638 while (*buffp != ':')
639 buffp++;
640 *buffp = 0;
641 irq = atoi(buff);
643 memset(buff, 0, sizeof(buff));
646 fclose(fp);
648 if (irq != 0)
649 return irq;
651 * Try sysfs as fallback. Probably wireless devices will be found
652 * here. We return silently if it fails ...
654 slprintf(sysname, sizeof(sysname), "/sys/class/net/%s/device/irq",
655 ifname);
657 fp = fopen(sysname, "r");
658 if (!fp)
659 return -ENOENT;
661 memset(buff, 0, sizeof(buff));
662 if(fgets(buff, sizeof(buff), fp) != NULL) {
663 buff[sizeof(buff) - 1] = 0;
664 irq = atoi(buff);
667 fclose(fp);
669 return irq;
672 int device_set_irq_affinity_list(int irq, unsigned long from, unsigned long to)
674 int ret, fd;
675 char file[256], list[64];
677 slprintf(file, sizeof(file), "/proc/irq/%d/smp_affinity_list", irq);
678 slprintf(list, sizeof(list), "%lu-%lu\n", from, to);
680 fd = open(file, O_WRONLY);
681 if (fd < 0)
682 return -ENOENT;
684 ret = write(fd, list, strlen(list));
686 close(fd);
687 return ret;
690 int device_bind_irq_to_cpu(int irq, int cpu)
692 int ret;
693 char buff[256];
694 char file[256];
695 FILE *fp;
697 /* Note: first CPU begins with CPU 0 */
698 if (irq < 0 || cpu < 0)
699 return -EINVAL;
701 memset(file, 0, sizeof(file));
702 memset(buff, 0, sizeof(buff));
704 /* smp_affinity starts counting with CPU 1, 2, ... */
705 cpu = cpu + 1;
706 sprintf(file, "/proc/irq/%d/smp_affinity", irq);
708 fp = fopen(file, "w");
709 if (!fp)
710 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 short enter_promiscuous_mode(char *ifname)
770 short ifflags;
772 if (!strncmp("any", ifname, strlen("any")))
773 return 0;
775 ifflags = device_get_flags(ifname);
776 device_set_flags(ifname, ifflags | IFF_PROMISC);
778 return ifflags;
781 void leave_promiscuous_mode(char *ifname, short oldflags)
783 if (!strncmp("any", ifname, strlen("any")))
784 return;
786 device_set_flags(ifname, oldflags);
789 int device_up_and_running(char *ifname)
791 if (!ifname)
792 return -EINVAL;
793 if (!strncmp("any", ifname, strlen("any")))
794 return 1;
796 return (device_get_flags(ifname) & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING);
799 void cpu_affinity(int cpu)
801 int ret;
802 cpu_set_t cpu_bitmask;
804 CPU_ZERO(&cpu_bitmask);
805 CPU_SET(cpu, &cpu_bitmask);
807 ret = sched_setaffinity(getpid(), sizeof(cpu_bitmask),
808 &cpu_bitmask);
809 if (ret)
810 panic("Can't set this cpu affinity!\n");
813 int set_proc_prio(int priority)
815 int ret = setpriority(PRIO_PROCESS, getpid(), priority);
816 if (ret)
817 panic("Can't set nice val to %i!\n", priority);
819 return 0;
822 int set_sched_status(int policy, int priority)
824 int ret, min_prio, max_prio;
825 struct sched_param sp;
827 max_prio = sched_get_priority_max(policy);
828 min_prio = sched_get_priority_min(policy);
830 if (max_prio == -1 || min_prio == -1)
831 printf("Cannot determine scheduler prio limits!\n");
832 else if (priority < min_prio)
833 priority = min_prio;
834 else if (priority > max_prio)
835 priority = max_prio;
837 memset(&sp, 0, sizeof(sp));
838 sp.sched_priority = priority;
840 ret = sched_setscheduler(getpid(), policy, &sp);
841 if (ret) {
842 printf("Cannot set scheduler policy!\n");
843 return -EINVAL;
846 ret = sched_setparam(getpid(), &sp);
847 if (ret) {
848 printf("Cannot set scheduler prio!\n");
849 return -EINVAL;
852 return 0;
855 static inline int ioprio_set(int which, int who, int ioprio)
857 return syscall(SYS_ioprio_set, which, who, ioprio);
860 static inline int ioprio_get(int which, int who)
862 return syscall(SYS_ioprio_get, which, who);
865 static void ioprio_setpid(pid_t pid, int ioprio, int ioclass)
867 int ret = ioprio_set(ioprio_who_process, pid,
868 ioprio | ioclass << IOPRIO_CLASS_SHIFT);
869 if (ret < 0)
870 panic("Failed to set io prio for pid!\n");
873 void ioprio_print(void)
875 int ioprio = ioprio_get(ioprio_who_process, getpid());
876 if (ioprio < 0)
877 panic("Failed to fetch io prio for pid!\n");
878 else {
879 int ioclass = ioprio >> IOPRIO_CLASS_SHIFT;
880 if (ioclass != ioprio_class_idle) {
881 ioprio &= 0xff;
882 printf("%s: prio %d\n", to_prio[ioclass], ioprio);
883 } else
884 printf("%s\n", to_prio[ioclass]);
888 void set_ioprio_rt(void)
890 ioprio_setpid(getpid(), 4, ioprio_class_rt);
893 void set_ioprio_be(void)
895 ioprio_setpid(getpid(), 4, ioprio_class_be);
898 void xlockme(void)
900 if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0)
901 panic("Cannot lock pages!\n");
904 void xunlockme(void)
906 munlockall();
909 size_t strlcpy(char *dest, const char *src, size_t size)
911 size_t ret = strlen(src);
913 if (size) {
914 size_t len = (ret >= size) ? size - 1 : ret;
916 memcpy(dest, src, len);
917 dest[len] = '\0';
920 return ret;
923 static inline int vslprintf(char *dst, size_t size, const char *fmt, va_list ap)
925 int ret;
927 ret = vsnprintf(dst, size, fmt, ap);
928 dst[size - 1] = '\0';
930 return ret;
933 int slprintf(char *dst, size_t size, const char *fmt, ...)
935 int ret;
936 va_list ap;
938 va_start(ap, fmt);
939 ret = vslprintf(dst, size, fmt, ap);
940 va_end(ap);
942 return ret;
945 int slprintf_nocheck(char *dst, size_t size, const char *fmt, ...)
947 int ret;
948 va_list ap;
950 va_start(ap, fmt);
951 ret = vslprintf(dst, size, fmt, ap);
952 va_end(ap);
954 return ret;
957 noinline void *xmemset(void *s, int c, size_t n)
959 size_t i;
960 uint8_t *ptr = s;
962 for (i = 0; i < n; ++i)
963 ptr[i] = (uint8_t) c;
965 return ptr;
968 char *strtrim_right(char *p, char c)
970 char *end;
971 size_t len;
973 len = strlen(p);
974 while (*p && len) {
975 end = p + len - 1;
976 if (c == *end)
977 *end = 0;
978 else
979 break;
980 len = strlen(p);
983 return p;
986 int get_default_sched_policy(void)
988 return SCHED_FIFO;
991 int get_default_sched_prio(void)
993 return sched_get_priority_max(get_default_sched_policy());
996 int get_number_cpus(void)
998 return sysconf(_SC_NPROCESSORS_CONF);
1001 int get_number_cpus_online(void)
1003 return sysconf(_SC_NPROCESSORS_ONLN);
1006 int get_default_proc_prio(void)
1008 return -20;
1011 void set_system_socket_memory(int *vals, size_t len)
1013 bug_on(len != 4);
1015 if ((vals[0] = get_system_socket_mem(sock_rmem_max)) < SMEM_SUG_MAX)
1016 set_system_socket_mem(sock_rmem_max, SMEM_SUG_MAX);
1017 if ((vals[1] = get_system_socket_mem(sock_rmem_def)) < SMEM_SUG_DEF)
1018 set_system_socket_mem(sock_rmem_def, SMEM_SUG_DEF);
1019 if ((vals[2] = get_system_socket_mem(sock_wmem_max)) < SMEM_SUG_MAX)
1020 set_system_socket_mem(sock_wmem_max, SMEM_SUG_MAX);
1021 if ((vals[3] = get_system_socket_mem(sock_wmem_def)) < SMEM_SUG_DEF)
1022 set_system_socket_mem(sock_wmem_def, SMEM_SUG_DEF);
1025 void reset_system_socket_memory(int *vals, size_t len)
1027 bug_on(len != 4);
1029 set_system_socket_mem(sock_rmem_max, vals[0]);
1030 set_system_socket_mem(sock_rmem_def, vals[1]);
1031 set_system_socket_mem(sock_wmem_max, vals[2]);
1032 set_system_socket_mem(sock_wmem_def, vals[3]);
1035 void set_itimer_interval_value(struct itimerval *itimer, unsigned long sec,
1036 unsigned long usec)
1038 itimer->it_interval.tv_sec = sec;
1039 itimer->it_interval.tv_usec = usec;
1041 itimer->it_value.tv_sec = sec;
1042 itimer->it_value.tv_usec = usec;