diff options
Diffstat (limited to 'xutils.c')
-rw-r--r-- | xutils.c | 1024 |
1 files changed, 1024 insertions, 0 deletions
diff --git a/xutils.c b/xutils.c new file mode 100644 index 0000000..7a12d1e --- /dev/null +++ b/xutils.c @@ -0,0 +1,1024 @@ +/* + * netsniff-ng - the packet sniffing beast + * Copyright 2009, 2010 Daniel Borkmann. + * Copyright 2009, 2010 Emmanuel Roullit. + * Copyright 2010 Marek Polacek. + * Subject to the GPL, version 2. + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <stdarg.h> +#include <ctype.h> +#include <signal.h> +#include <arpa/inet.h> +#include <time.h> +#include <sched.h> +#include <limits.h> +#include <stdbool.h> +#include <netdb.h> +#include <ifaddrs.h> +#include <sys/time.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/resource.h> +#include <sys/epoll.h> +#include <sys/syscall.h> +#include <asm/unistd.h> +#include <linux/if.h> +#include <linux/socket.h> +#include <linux/types.h> +#include <linux/if_ether.h> +#include <linux/if_packet.h> +#include <linux/sockios.h> +#include <netinet/tcp.h> +#include <netinet/udp.h> + +#include "die.h" +#include "xutils.h" +#include "ring.h" +#include "built_in.h" + +#define IOPRIO_CLASS_SHIFT 13 + +enum { + ioprio_class_none, + ioprio_class_rt, + ioprio_class_be, + ioprio_class_idle, +}; + +enum { + ioprio_who_process = 1, + ioprio_who_pgrp, + ioprio_who_user, +}; + +enum { + sock_rmem_max = 0, + sock_rmem_def, + sock_wmem_max, + sock_wmem_def, +}; + +#define SMEM_SUG_MAX 104857600 +#define SMEM_SUG_DEF 4194304 + +static const char *const to_prio[] = { + "none", + "realtime", + "best-effort", + "idle", +}; + +static const char *const sock_mem[] = { + "/proc/sys/net/core/rmem_max", + "/proc/sys/net/core/rmem_default", + "/proc/sys/net/core/wmem_max", + "/proc/sys/net/core/wmem_default", +}; + +int af_socket(int af) +{ + int sock; + + if (unlikely(af != AF_INET && af != AF_INET6)) + panic("Wrong AF socket type!\n"); + + sock = socket(af, SOCK_DGRAM, 0); + if (unlikely(sock < 0)) + panic("Creation AF socket failed!\n"); + + return sock; +} + +int pf_socket(void) +{ + int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + if (unlikely(sock < 0)) + panic("Creation of PF socket failed!\n"); + + return sock; +} + +void set_sock_prio(int fd, int prio) +{ + int val = prio; + setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val)); +} + +void set_udp_cork(int fd) +{ + int state = 1; + setsockopt(fd, IPPROTO_UDP, UDP_CORK, &state, sizeof(state)); +} + +void set_udp_uncork(int fd) +{ + int state = 0; + setsockopt(fd, IPPROTO_UDP, UDP_CORK, &state, sizeof(state)); +} + +void set_tcp_cork(int fd) +{ + int state = 1; + setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state)); +} + +void set_tcp_uncork(int fd) +{ + int state = 0; + setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state)); +} + +void set_sock_cork(int fd, int udp) +{ + if (!!udp) + set_udp_cork(fd); + else + set_tcp_cork(fd); +} + +void set_sock_uncork(int fd, int udp) +{ + if (!!udp) + set_udp_uncork(fd); + else + set_tcp_uncork(fd); +} + +int set_nonblocking(int fd) +{ + int ret = fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK); + if (unlikely(ret < 0)) + panic("Cannot fcntl!\n"); + + return 0; +} + +int set_nonblocking_sloppy(int fd) +{ + return fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK); +} + +void set_socket_keepalive(int fd) +{ + int one = 1; + setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one)); +} + +void set_tcp_nodelay(int fd) +{ + int one = 1; + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)); +} + +int set_ipv6_only(int fd) +{ + int one = 1; + return setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one)); +} + +int set_reuseaddr(int fd) +{ + int ret, one = 1; + + ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + if (unlikely(ret < 0)) + panic("Cannot reuse addr!\n"); + + return 0; +} + +void set_mtu_disc_dont(int fd) +{ + int mtu = IP_PMTUDISC_DONT; + setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu)); +} + +void set_epoll_descriptor(int fd_epoll, int action, int fd_toadd, int events) +{ + int ret; + struct epoll_event ev; + + memset(&ev, 0, sizeof(ev)); + ev.events = events; + ev.data.fd = fd_toadd; + + ret = epoll_ctl(fd_epoll, action, fd_toadd, &ev); + if (ret < 0) + panic("Cannot add socket for epoll!\n"); +} + +int set_epoll_descriptor2(int fd_epoll, int action, int fd_toadd, int events) +{ + struct epoll_event ev; + + memset(&ev, 0, sizeof(ev)); + ev.events = events; + ev.data.fd = fd_toadd; + + return epoll_ctl(fd_epoll, action, fd_toadd, &ev); +} + +u32 wireless_bitrate(const char *ifname) +{ + int sock, ret, rate_in_mbit; + struct iwreq iwr; + + sock = af_socket(AF_INET); + + memset(&iwr, 0, sizeof(iwr)); + strlcpy(iwr.ifr_name, ifname, IFNAMSIZ); + + ret = ioctl(sock, SIOCGIWRATE, &iwr); + if (!ret) + rate_in_mbit = iwr.u.bitrate.value / 1000000; + else + rate_in_mbit = 0; + + close(sock); + + return rate_in_mbit; +} + +void drop_privileges(bool enforce, uid_t uid, gid_t gid) +{ + if (enforce) { + if (uid == getuid()) + panic("Uid cannot be the same as the current user!\n"); + if (gid == getgid()) + panic("Gid cannot be the same as the current user!\n"); + } + if (setgid(gid) != 0) + panic("Unable to drop group privileges: %s!\n", strerror(errno)); + if (setuid(uid) != 0) + panic("Unable to drop user privileges: %s!\n", strerror(errno)); +} + +int get_system_socket_mem(int which) +{ + int fd, val = -1; + ssize_t ret; + const char *file = sock_mem[which]; + char buff[64]; + + fd = open(file, O_RDONLY); + if (fd < 0) + return val; + + ret = read(fd, buff, sizeof(buff)); + if (ret > 0) + val = atoi(buff); + + close(fd); + return val; +} + +void set_system_socket_mem(int which, int val) +{ + int fd; + const char *file = sock_mem[which]; + ssize_t ret; + char buff[64]; + + fd = open(file, O_WRONLY); + if (fd < 0) + return; + + memset(buff, 0, sizeof(buff)); + slprintf(buff, sizeof(buff), "%d", val); + + ret = write(fd, buff, strlen(buff)); + ret = ret; + + close(fd); +} + +int wireless_sigqual(const char *ifname, struct iw_statistics *stats) +{ + int ret, sock; + struct iwreq iwr; + + sock = af_socket(AF_INET); + + memset(&iwr, 0, sizeof(iwr)); + strlcpy(iwr.ifr_name, ifname, IFNAMSIZ); + + iwr.u.data.pointer = (caddr_t) stats; + iwr.u.data.length = sizeof(*stats); + iwr.u.data.flags = 1; + + ret = ioctl(sock, SIOCGIWSTATS, &iwr); + + close(sock); + + return ret; +} + +int wireless_rangemax_sigqual(const char *ifname) +{ + int ret, sock, sigqual; + struct iwreq iwr; + struct iw_range iwrange; + + sock = af_socket(AF_INET); + + memset(&iwrange, 0, sizeof(iwrange)); + + memset(&iwr, 0, sizeof(iwr)); + strlcpy(iwr.ifr_name, ifname, IFNAMSIZ); + + iwr.u.data.pointer = (caddr_t) &iwrange; + iwr.u.data.length = sizeof(iwrange); + iwr.u.data.flags = 0; + + ret = ioctl(sock, SIOCGIWRANGE, &iwr); + if (!ret) + sigqual = iwrange.max_qual.qual; + else + sigqual = 0; + + close(sock); + + return sigqual; +} + +u32 ethtool_bitrate(const char *ifname) +{ + int ret, sock, bitrate; + struct ifreq ifr; + struct ethtool_cmd ecmd; + + sock = af_socket(AF_INET); + + memset(&ecmd, 0, sizeof(ecmd)); + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + + ecmd.cmd = ETHTOOL_GSET; + ifr.ifr_data = (char *) &ecmd; + + ret = ioctl(sock, SIOCETHTOOL, &ifr); + if (ret) { + bitrate = 0; + goto out; + } + + switch (ecmd.speed) { + case SPEED_10: + case SPEED_100: + case SPEED_1000: + case SPEED_2500: + case SPEED_10000: + bitrate = ecmd.speed; + break; + default: + bitrate = 0; + break; + }; +out: + close(sock); + + return bitrate; +} + +int ethtool_link(const char *ifname) +{ + int ret, sock; + struct ifreq ifr; + struct ethtool_value ecmd; + + sock = af_socket(AF_INET); + + memset(&ecmd, 0, sizeof(ecmd)); + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + + ecmd.cmd = ETHTOOL_GLINK; + ifr.ifr_data = (char *) &ecmd; + + ret = ioctl(sock, SIOCETHTOOL, &ifr); + if (ret) + ret = -EINVAL; + else + ret = !!ecmd.data; + + close(sock); + return ret; +} + +int ethtool_drvinf(const char *ifname, struct ethtool_drvinfo *drvinf) +{ + int ret, sock; + struct ifreq ifr; + + sock = af_socket(AF_INET); + + memset(drvinf, 0, sizeof(*drvinf)); + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + + drvinf->cmd = ETHTOOL_GDRVINFO; + ifr.ifr_data = (char *) drvinf; + + ret = ioctl(sock, SIOCETHTOOL, &ifr); + + close(sock); + + return ret; +} + +u32 device_bitrate(const char *ifname) +{ + u32 speed_c, speed_w; + + speed_c = ethtool_bitrate(ifname); + speed_w = wireless_bitrate(ifname); + + return (speed_c == 0 ? speed_w : speed_c); +} + +int device_ifindex(const char *ifname) +{ + int ret, sock, index; + struct ifreq ifr; + + if (!strncmp("any", ifname, strlen("any"))) + return 0; + + sock = af_socket(AF_INET); + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + + ret = ioctl(sock, SIOCGIFINDEX, &ifr); + if (!ret) + index = ifr.ifr_ifindex; + else + index = -1; + + close(sock); + + return index; +} + +static int __device_address6(const char *ifname, struct sockaddr_storage *ss) +{ + int ret, family, found = -EINVAL; + struct ifaddrs *ifaddr, *ifa; + + ret = getifaddrs(&ifaddr); + if (ret < 0) + panic("Cannot get device addresses for IPv6!\n"); + + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + family = ifa->ifa_addr->sa_family; + if (family != AF_INET6) + continue; + if (strcmp(ifa->ifa_name, ifname)) + continue; + + memcpy(ss, ifa->ifa_addr, sizeof(*ss)); + found = 0; + break; + } + + freeifaddrs(ifaddr); + return found; +} + +int device_address(const char *ifname, int af, struct sockaddr_storage *ss) +{ + int ret, sock; + struct ifreq ifr; + + if (!ss) + return -EINVAL; + if (!strncmp("any", ifname, strlen("any"))) + return -EINVAL; + if (af == AF_INET6) + return __device_address6(ifname, ss); + + sock = af_socket(af); + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + + ifr.ifr_addr.sa_family = af; + + ret = ioctl(sock, SIOCGIFADDR, &ifr); + if (!ret) + memcpy(ss, &ifr.ifr_addr, sizeof(ifr.ifr_addr)); + + close(sock); + + return ret; +} + +int device_mtu(const char *ifname) +{ + int ret, sock, mtu; + struct ifreq ifr; + + sock = af_socket(AF_INET); + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + + ret = ioctl(sock, SIOCGIFMTU, &ifr); + if (!ret) + mtu = ifr.ifr_mtu; + else + mtu = 0; + + close(sock); + + return mtu; +} + +short device_get_flags(const char *ifname) +{ + /* Really, it's short! Look at struct ifreq */ + short flags; + int ret, sock; + struct ifreq ifr; + + sock = af_socket(AF_INET); + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + + ret = ioctl(sock, SIOCGIFFLAGS, &ifr); + if (!ret) + flags = ifr.ifr_flags; + else + flags = 0; + + close(sock); + + return flags; +} + +void device_set_flags(const char *ifname, const short flags) +{ + int ret, sock; + struct ifreq ifr; + + sock = af_socket(AF_INET); + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + + ifr.ifr_flags = flags; + + ret = ioctl(sock, SIOCSIFFLAGS, &ifr); + if (ret < 0) + panic("Cannot set NIC flags!\n"); + + close(sock); +} + +int device_irq_number(const char *ifname) +{ + /* + * Since fetching IRQ numbers from SIOCGIFMAP is deprecated and not + * supported anymore, we need to grab them from procfs + */ + int irq = 0; + char *buffp; + char buff[512]; + char sysname[512]; + FILE *fp; + + if (!strncmp("lo", ifname, strlen("lo"))) + return 0; + + fp = fopen("/proc/interrupts", "r"); + if (!fp) + panic("Cannot open /proc/interrupts!\n"); + + memset(buff, 0, sizeof(buff)); + while (fgets(buff, sizeof(buff), fp) != NULL) { + buff[sizeof(buff) - 1] = 0; + + if (strstr(buff, ifname) == NULL) + continue; + + buffp = buff; + while (*buffp != ':') + buffp++; + *buffp = 0; + irq = atoi(buff); + + memset(buff, 0, sizeof(buff)); + } + + fclose(fp); + + if (irq != 0) + return irq; + /* + * Try sysfs as fallback. Probably wireless devices will be found + * here. We return silently if it fails ... + */ + slprintf(sysname, sizeof(sysname), "/sys/class/net/%s/device/irq", + ifname); + + fp = fopen(sysname, "r"); + if (!fp) + return -ENOENT; + + memset(buff, 0, sizeof(buff)); + if(fgets(buff, sizeof(buff), fp) != NULL) { + buff[sizeof(buff) - 1] = 0; + irq = atoi(buff); + } + + fclose(fp); + + return irq; +} + +int device_set_irq_affinity_list(int irq, unsigned long from, unsigned long to) +{ + int ret, fd; + char file[256], list[64]; + + slprintf(file, sizeof(file), "/proc/irq/%d/smp_affinity_list", irq); + slprintf(list, sizeof(list), "%lu-%lu\n", from, to); + + fd = open(file, O_WRONLY); + if (fd < 0) + return -ENOENT; + + ret = write(fd, list, strlen(list)); + + close(fd); + return ret; +} + +int device_bind_irq_to_cpu(int irq, int cpu) +{ + int ret; + char buff[256]; + char file[256]; + FILE *fp; + + /* Note: first CPU begins with CPU 0 */ + if (irq < 0 || cpu < 0) + return -EINVAL; + + memset(file, 0, sizeof(file)); + memset(buff, 0, sizeof(buff)); + + /* smp_affinity starts counting with CPU 1, 2, ... */ + cpu = cpu + 1; + sprintf(file, "/proc/irq/%d/smp_affinity", irq); + + fp = fopen(file, "w"); + if (!fp) + return -ENOENT; + + sprintf(buff, "%d", cpu); + ret = fwrite(buff, sizeof(buff), 1, fp); + + fclose(fp); + return (ret > 0 ? 0 : ret); +} + +void sock_print_net_stats(int sock, unsigned long skipped) +{ + int ret; + struct tpacket_stats kstats; + + socklen_t slen = sizeof(kstats); + + memset(&kstats, 0, sizeof(kstats)); + ret = getsockopt(sock, SOL_PACKET, PACKET_STATISTICS, &kstats, &slen); + if (ret > -1) { + uint64_t packets = kstats.tp_packets; + uint64_t drops = kstats.tp_drops; + + printf("\r%12ld packets incoming\n", packets); + printf("\r%12ld packets passed filter\n", packets - drops - skipped); + printf("\r%12ld packets failed filter (out of space)\n", drops + skipped); + if (kstats.tp_packets > 0) + printf("\r%12.4lf%\% packet droprate\n", (1.0 * drops / packets) * 100.0); + } +} + +void register_signal(int signal, void (*handler)(int)) +{ + sigset_t block_mask; + struct sigaction saction; + + sigfillset(&block_mask); + + saction.sa_handler = handler; + saction.sa_mask = block_mask; + saction.sa_flags = SA_RESTART; + + sigaction(signal, &saction, NULL); +} + +void register_signal_f(int signal, void (*handler)(int), int flags) +{ + sigset_t block_mask; + struct sigaction saction; + + sigfillset(&block_mask); + + saction.sa_handler = handler; + saction.sa_mask = block_mask; + saction.sa_flags = flags; + + sigaction(signal, &saction, NULL); +} + +short enter_promiscuous_mode(char *ifname) +{ + short ifflags; + + if (!strncmp("any", ifname, strlen("any"))) + return 0; + + ifflags = device_get_flags(ifname); + device_set_flags(ifname, ifflags | IFF_PROMISC); + + return ifflags; +} + +void leave_promiscuous_mode(char *ifname, short oldflags) +{ + if (!strncmp("any", ifname, strlen("any"))) + return; + + device_set_flags(ifname, oldflags); +} + +int device_up_and_running(char *ifname) +{ + if (!ifname) + return -EINVAL; + if (!strncmp("any", ifname, strlen("any"))) + return 1; + + return (device_get_flags(ifname) & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING); +} + +void cpu_affinity(int cpu) +{ + int ret; + cpu_set_t cpu_bitmask; + + CPU_ZERO(&cpu_bitmask); + CPU_SET(cpu, &cpu_bitmask); + + ret = sched_setaffinity(getpid(), sizeof(cpu_bitmask), + &cpu_bitmask); + if (ret) + panic("Can't set this cpu affinity!\n"); +} + +int set_proc_prio(int priority) +{ + int ret = setpriority(PRIO_PROCESS, getpid(), priority); + if (ret) + panic("Can't set nice val to %i!\n", priority); + + return 0; +} + +int set_sched_status(int policy, int priority) +{ + int ret, min_prio, max_prio; + struct sched_param sp; + + max_prio = sched_get_priority_max(policy); + min_prio = sched_get_priority_min(policy); + + if (max_prio == -1 || min_prio == -1) + printf("Cannot determine scheduler prio limits!\n"); + else if (priority < min_prio) + priority = min_prio; + else if (priority > max_prio) + priority = max_prio; + + memset(&sp, 0, sizeof(sp)); + sp.sched_priority = priority; + + ret = sched_setscheduler(getpid(), policy, &sp); + if (ret) { + printf("Cannot set scheduler policy!\n"); + return -EINVAL; + } + + ret = sched_setparam(getpid(), &sp); + if (ret) { + printf("Cannot set scheduler prio!\n"); + return -EINVAL; + } + + return 0; +} + +static inline int ioprio_set(int which, int who, int ioprio) +{ + return syscall(SYS_ioprio_set, which, who, ioprio); +} + +static inline int ioprio_get(int which, int who) +{ + return syscall(SYS_ioprio_get, which, who); +} + +static void ioprio_setpid(pid_t pid, int ioprio, int ioclass) +{ + int ret = ioprio_set(ioprio_who_process, pid, + ioprio | ioclass << IOPRIO_CLASS_SHIFT); + if (ret < 0) + panic("Failed to set io prio for pid!\n"); +} + +void ioprio_print(void) +{ + int ioprio = ioprio_get(ioprio_who_process, getpid()); + if (ioprio < 0) + panic("Failed to fetch io prio for pid!\n"); + else { + int ioclass = ioprio >> IOPRIO_CLASS_SHIFT; + if (ioclass != ioprio_class_idle) { + ioprio &= 0xff; + printf("%s: prio %d\n", to_prio[ioclass], ioprio); + } else + printf("%s\n", to_prio[ioclass]); + } +} + +void set_ioprio_rt(void) +{ + ioprio_setpid(getpid(), 4, ioprio_class_rt); +} + +void set_ioprio_be(void) +{ + ioprio_setpid(getpid(), 4, ioprio_class_be); +} + +void xlockme(void) +{ + if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) + panic("Cannot lock pages!\n"); +} + +void xunlockme(void) +{ + munlockall(); +} + +size_t strlcpy(char *dest, const char *src, size_t size) +{ + size_t ret = strlen(src); + + if (size) { + size_t len = (ret >= size) ? size - 1 : ret; + + memcpy(dest, src, len); + dest[len] = '\0'; + } + + return ret; +} + +static inline int vslprintf(char *dst, size_t size, const char *fmt, va_list ap) +{ + int ret; + + ret = vsnprintf(dst, size, fmt, ap); + dst[size - 1] = '\0'; + + return ret; +} + +int slprintf(char *dst, size_t size, const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vslprintf(dst, size, fmt, ap); + va_end(ap); + + return ret; +} + +int slprintf_nocheck(char *dst, size_t size, const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vslprintf(dst, size, fmt, ap); + va_end(ap); + + return ret; +} + +noinline void *xmemset(void *s, int c, size_t n) +{ + size_t i; + uint8_t *ptr = s; + + for (i = 0; i < n; ++i) + ptr[i] = (uint8_t) c; + + return ptr; +} + +char *strtrim_right(char *p, char c) +{ + char *end; + size_t len; + + len = strlen(p); + while (*p && len) { + end = p + len - 1; + if (c == *end) + *end = 0; + else + break; + len = strlen(p); + } + + return p; +} + +int get_default_sched_policy(void) +{ + return SCHED_FIFO; +} + +int get_default_sched_prio(void) +{ + return sched_get_priority_max(get_default_sched_policy()); +} + +int get_number_cpus(void) +{ + return sysconf(_SC_NPROCESSORS_CONF); +} + +int get_number_cpus_online(void) +{ + return sysconf(_SC_NPROCESSORS_ONLN); +} + +int get_default_proc_prio(void) +{ + return -20; +} + +void set_system_socket_memory(int *vals, size_t len) +{ + bug_on(len != 4); + + if ((vals[0] = get_system_socket_mem(sock_rmem_max)) < SMEM_SUG_MAX) + set_system_socket_mem(sock_rmem_max, SMEM_SUG_MAX); + if ((vals[1] = get_system_socket_mem(sock_rmem_def)) < SMEM_SUG_DEF) + set_system_socket_mem(sock_rmem_def, SMEM_SUG_DEF); + if ((vals[2] = get_system_socket_mem(sock_wmem_max)) < SMEM_SUG_MAX) + set_system_socket_mem(sock_wmem_max, SMEM_SUG_MAX); + if ((vals[3] = get_system_socket_mem(sock_wmem_def)) < SMEM_SUG_DEF) + set_system_socket_mem(sock_wmem_def, SMEM_SUG_DEF); +} + +void reset_system_socket_memory(int *vals, size_t len) +{ + bug_on(len != 4); + + set_system_socket_mem(sock_rmem_max, vals[0]); + set_system_socket_mem(sock_rmem_def, vals[1]); + set_system_socket_mem(sock_wmem_max, vals[2]); + set_system_socket_mem(sock_wmem_def, vals[3]); +} + +void set_itimer_interval_value(struct itimerval *itimer, unsigned long sec, + unsigned long usec) +{ + itimer->it_interval.tv_sec = sec; + itimer->it_interval.tv_usec = usec; + + itimer->it_value.tv_sec = sec; + itimer->it_value.tv_usec = usec; +} |