flowtop: Refactor walking for each flow node by presenter
[netsniff-ng.git] / sock.c
blobcfca05eeb730086dc81885870134e052ebff1afd
1 #include <sys/types.h>
2 #include <sys/socket.h>
3 #include <fcntl.h>
4 #include <arpa/inet.h>
5 #include <linux/if_ether.h>
6 #include <linux/tcp.h>
8 #include "sock.h"
9 #include "die.h"
10 #include "str.h"
11 #include "linktype.h"
12 #include "built_in.h"
14 int af_socket(int af)
16 int sock;
18 if (unlikely(af != AF_INET && af != AF_INET6))
19 panic("Wrong AF socket type!\n");
21 sock = socket(af, SOCK_DGRAM, 0);
22 if (unlikely(sock < 0))
23 panic("Creation AF socket failed: %s\n", strerror(errno));
25 return sock;
28 int pf_socket(void)
30 int sock = socket(PF_PACKET, SOCK_RAW, 0);
31 if (unlikely(sock < 0))
32 panic("Creation of PF socket failed: %s\n", strerror(errno));
34 return sock;
37 static int pf_socket_dgram(void)
39 int sock = socket(PF_PACKET, SOCK_DGRAM, 0);
40 if (unlikely(sock < 0))
41 panic("Creation of PF dgram socket failed: %s\n",
42 strerror(errno));
44 return sock;
47 int pf_socket_type(uint32_t type)
49 switch (type) {
50 case LINKTYPE_LINUX_SLL:
51 return pf_socket_dgram();
52 default:
53 return pf_socket();
57 /* Avail in kernel >= 3.14
58 * in commit d346a3fae3 (packet: introduce PACKET_QDISC_BYPASS socket option)
60 void set_sock_qdisc_bypass(int fd, int verbose)
62 int ret, val = 1;
64 ret = setsockopt(fd, SOL_PACKET, PACKET_QDISC_BYPASS, &val, sizeof(val));
65 if (ret < 0) {
66 if (errno == ENOPROTOOPT) {
67 if (verbose)
68 printf("No kernel support for PACKET_QDISC_BYPASS"
69 " (kernel < 3.14?)\n");
70 } else
71 perror("Cannot set PACKET_QDISC_BYPASS");
72 } else
73 if (verbose) printf("Enabled kernel qdisc bypass\n");
76 void set_sock_prio(int fd, int prio)
78 int ret, val = prio;
80 ret = setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
81 if (unlikely(ret))
82 panic("Cannot set socket priority: %s\n", strerror(errno));
85 void set_nonblocking(int fd)
87 int ret = fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
88 if (unlikely(ret < 0))
89 panic("Cannot fcntl: %s\n", strerror(errno));
92 int set_nonblocking_sloppy(int fd)
94 return fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
97 void set_socket_keepalive(int fd)
99 int ret, one = 1;
101 ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one));
102 if (unlikely(ret))
103 panic("Cannot set TCP keepalive: %s\n", strerror(errno));
106 void set_tcp_nodelay(int fd)
108 int ret, one = 1;
110 ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
111 if (unlikely(ret))
112 panic("Cannot set TCP nodelay: %s\n", strerror(errno));
115 int set_ipv6_only(int fd)
117 int one = 1;
118 return setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
121 int set_reuseaddr(int fd)
123 int ret, one = 1;
125 ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
126 if (unlikely(ret < 0))
127 panic("Cannot reuse addr: %s\n", strerror(errno));
129 return 0;
132 void set_mtu_disc_dont(int fd)
134 int mtu = IP_PMTUDISC_DONT, ret;
136 ret = setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu));
137 if (unlikely(ret))
138 panic("Cannot set MTU discovery options: %s\n", strerror(errno));
141 enum {
142 sock_rmem_max = 0,
143 sock_rmem_def,
144 sock_wmem_max,
145 sock_wmem_def,
148 #define SMEM_SUG_MAX 104857600
149 #define SMEM_SUG_DEF 4194304
151 static const char *const sock_mem[] = {
152 [sock_rmem_max] = "/proc/sys/net/core/rmem_max",
153 [sock_rmem_def] = "/proc/sys/net/core/rmem_default",
154 [sock_wmem_max] = "/proc/sys/net/core/wmem_max",
155 [sock_wmem_def] = "/proc/sys/net/core/wmem_default",
158 static int get_system_socket_mem(int which)
160 int fd, val = -1;
161 ssize_t ret;
162 const char *file = sock_mem[which];
163 char buff[64];
165 fd = open(file, O_RDONLY);
166 if (fd < 0)
167 return val;
169 ret = read(fd, buff, sizeof(buff));
170 if (ret > 0)
171 val = atoi(buff);
173 close(fd);
174 return val;
177 static void set_system_socket_mem(int which, int val)
179 int fd;
180 const char *file = sock_mem[which];
181 ssize_t ret;
182 char buff[64];
184 fd = open(file, O_WRONLY);
185 if (fd < 0)
186 return;
188 memset(buff, 0, sizeof(buff));
189 slprintf(buff, sizeof(buff), "%d", val);
191 ret = write(fd, buff, strlen(buff));
192 if (ret < 0)
193 panic("Cannot set system socket memory!\n");
195 close(fd);
198 void set_system_socket_memory(int *vals, size_t len)
200 bug_on(len != 4);
202 if ((vals[0] = get_system_socket_mem(sock_rmem_max)) < SMEM_SUG_MAX)
203 set_system_socket_mem(sock_rmem_max, SMEM_SUG_MAX);
204 if ((vals[1] = get_system_socket_mem(sock_rmem_def)) < SMEM_SUG_DEF)
205 set_system_socket_mem(sock_rmem_def, SMEM_SUG_DEF);
206 if ((vals[2] = get_system_socket_mem(sock_wmem_max)) < SMEM_SUG_MAX)
207 set_system_socket_mem(sock_wmem_max, SMEM_SUG_MAX);
208 if ((vals[3] = get_system_socket_mem(sock_wmem_def)) < SMEM_SUG_DEF)
209 set_system_socket_mem(sock_wmem_def, SMEM_SUG_DEF);
212 void reset_system_socket_memory(int *vals, size_t len)
214 bug_on(len != 4);
216 set_system_socket_mem(sock_rmem_max, vals[0]);
217 set_system_socket_mem(sock_rmem_def, vals[1]);
218 set_system_socket_mem(sock_wmem_max, vals[2]);
219 set_system_socket_mem(sock_wmem_def, vals[3]);