build: Make module build also depend on header file
[netsniff-ng.git] / sock.c
blobfbf50d88e86d1ed398541e96184482ee20cc74ee
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 "built_in.h"
13 int af_socket(int af)
15 int sock;
17 if (unlikely(af != AF_INET && af != AF_INET6))
18 panic("Wrong AF socket type!\n");
20 sock = socket(af, SOCK_DGRAM, 0);
21 if (unlikely(sock < 0))
22 panic("Creation AF socket failed: %s\n", strerror(errno));
24 return sock;
27 int pf_socket(void)
29 int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
30 if (unlikely(sock < 0))
31 panic("Creation of PF socket failed: %s\n", strerror(errno));
33 return sock;
36 int pf_tx_socket(void)
38 int sock = socket(PF_PACKET, SOCK_RAW, 0);
39 if (unlikely(sock < 0))
40 panic("Creation of PF TX socket failed: %s\n", strerror(errno));
42 return sock;
45 /* Avail in kernel >= 3.14
46 * in commit d346a3fae3 (packet: introduce PACKET_QDISC_BYPASS socket option)
48 void set_sock_qdisc_bypass(int fd, int verbose)
50 int ret, val = 1;
52 ret = setsockopt(fd, SOL_PACKET, PACKET_QDISC_BYPASS, &val, sizeof(val));
53 if (ret < 0) {
54 if (errno == ENOPROTOOPT) {
55 if (verbose)
56 printf("No kernel support for PACKET_QDISC_BYPASS"
57 " (kernel < 3.14?)\n");
58 } else
59 perror("Cannot set PACKET_QDISC_BYPASS");
60 } else
61 if (verbose) printf("Enabled kernel qdisc bypass\n");
64 void set_sock_prio(int fd, int prio)
66 int ret, val = prio;
68 ret = setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
69 if (unlikely(ret))
70 panic("Cannot set socket priority: %s\n", strerror(errno));
73 void set_nonblocking(int fd)
75 int ret = fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
76 if (unlikely(ret < 0))
77 panic("Cannot fcntl: %s\n", strerror(errno));
80 int set_nonblocking_sloppy(int fd)
82 return fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK);
85 void set_socket_keepalive(int fd)
87 int ret, one = 1;
89 ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one));
90 if (unlikely(ret))
91 panic("Cannot set TCP keepalive: %s\n", strerror(errno));
94 void set_tcp_nodelay(int fd)
96 int ret, one = 1;
98 ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
99 if (unlikely(ret))
100 panic("Cannot set TCP nodelay: %s\n", strerror(errno));
103 int set_ipv6_only(int fd)
105 int one = 1;
106 return setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
109 int set_reuseaddr(int fd)
111 int ret, one = 1;
113 ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
114 if (unlikely(ret < 0))
115 panic("Cannot reuse addr: %s\n", strerror(errno));
117 return 0;
120 void set_mtu_disc_dont(int fd)
122 int mtu = IP_PMTUDISC_DONT, ret;
124 ret = setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu));
125 if (unlikely(ret))
126 panic("Cannot set MTU discovery options: %s\n", strerror(errno));
129 enum {
130 sock_rmem_max = 0,
131 sock_rmem_def,
132 sock_wmem_max,
133 sock_wmem_def,
136 #define SMEM_SUG_MAX 104857600
137 #define SMEM_SUG_DEF 4194304
139 static const char *const sock_mem[] = {
140 [sock_rmem_max] = "/proc/sys/net/core/rmem_max",
141 [sock_rmem_def] = "/proc/sys/net/core/rmem_default",
142 [sock_wmem_max] = "/proc/sys/net/core/wmem_max",
143 [sock_wmem_def] = "/proc/sys/net/core/wmem_default",
146 static int get_system_socket_mem(int which)
148 int fd, val = -1;
149 ssize_t ret;
150 const char *file = sock_mem[which];
151 char buff[64];
153 fd = open(file, O_RDONLY);
154 if (fd < 0)
155 return val;
157 ret = read(fd, buff, sizeof(buff));
158 if (ret > 0)
159 val = atoi(buff);
161 close(fd);
162 return val;
165 static void set_system_socket_mem(int which, int val)
167 int fd;
168 const char *file = sock_mem[which];
169 ssize_t ret;
170 char buff[64];
172 fd = open(file, O_WRONLY);
173 if (fd < 0)
174 return;
176 memset(buff, 0, sizeof(buff));
177 slprintf(buff, sizeof(buff), "%d", val);
179 ret = write(fd, buff, strlen(buff));
180 if (ret < 0)
181 panic("Cannot set system socket memory!\n");
183 close(fd);
186 void set_system_socket_memory(int *vals, size_t len)
188 bug_on(len != 4);
190 if ((vals[0] = get_system_socket_mem(sock_rmem_max)) < SMEM_SUG_MAX)
191 set_system_socket_mem(sock_rmem_max, SMEM_SUG_MAX);
192 if ((vals[1] = get_system_socket_mem(sock_rmem_def)) < SMEM_SUG_DEF)
193 set_system_socket_mem(sock_rmem_def, SMEM_SUG_DEF);
194 if ((vals[2] = get_system_socket_mem(sock_wmem_max)) < SMEM_SUG_MAX)
195 set_system_socket_mem(sock_wmem_max, SMEM_SUG_MAX);
196 if ((vals[3] = get_system_socket_mem(sock_wmem_def)) < SMEM_SUG_DEF)
197 set_system_socket_mem(sock_wmem_def, SMEM_SUG_DEF);
200 void reset_system_socket_memory(int *vals, size_t len)
202 bug_on(len != 4);
204 set_system_socket_mem(sock_rmem_max, vals[0]);
205 set_system_socket_mem(sock_rmem_def, vals[1]);
206 set_system_socket_mem(sock_wmem_max, vals[2]);
207 set_system_socket_mem(sock_wmem_def, vals[3]);