2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Copyright 2009, 2010 Emmanuel Roullit.
5 * Subject to the GPL, version 2.
19 #include <arpa/inet.h>
27 #include <sys/socket.h>
28 #include <sys/ioctl.h>
30 #include <sys/resource.h>
31 #include <sys/epoll.h>
32 #include <sys/syscall.h>
33 #include <asm/unistd.h>
35 #include <linux/socket.h>
36 #include <linux/types.h>
37 #include <linux/if_ether.h>
38 #include <linux/if_packet.h>
39 #include <linux/sockios.h>
40 #include <netinet/tcp.h>
41 #include <netinet/udp.h>
56 #define SMEM_SUG_MAX 104857600
57 #define SMEM_SUG_DEF 4194304
59 static const char *const to_prio
[] = {
66 static const char *const sock_mem
[] = {
67 "/proc/sys/net/core/rmem_max",
68 "/proc/sys/net/core/rmem_default",
69 "/proc/sys/net/core/wmem_max",
70 "/proc/sys/net/core/wmem_default",
77 if (unlikely(af
!= AF_INET
&& af
!= AF_INET6
))
78 panic("Wrong AF socket type!\n");
80 sock
= socket(af
, SOCK_DGRAM
, 0);
81 if (unlikely(sock
< 0))
82 panic("Creation AF socket failed!\n");
89 int sock
= socket(PF_PACKET
, SOCK_RAW
, htons(ETH_P_ALL
));
90 if (unlikely(sock
< 0))
91 panic("Creation of PF socket failed!\n");
96 void set_sock_prio(int fd
, int prio
)
100 ret
= setsockopt(fd
, SOL_SOCKET
, SO_PRIORITY
, &val
, sizeof(val
));
102 panic("Cannot set socket priority!\n");
105 void set_nonblocking(int fd
)
107 int ret
= fcntl(fd
, F_SETFL
, fcntl(fd
, F_GETFD
, 0) | O_NONBLOCK
);
108 if (unlikely(ret
< 0))
109 panic("Cannot fcntl!\n");
112 int set_nonblocking_sloppy(int fd
)
114 return fcntl(fd
, F_SETFL
, fcntl(fd
, F_GETFD
, 0) | O_NONBLOCK
);
117 void set_socket_keepalive(int fd
)
121 ret
= setsockopt(fd
, SOL_SOCKET
, SO_KEEPALIVE
, &one
, sizeof(one
));
123 panic("Cannot set TCP keepalive!\n");
126 void set_tcp_nodelay(int fd
)
129 setsockopt(fd
, IPPROTO_TCP
, TCP_NODELAY
, &one
, sizeof(one
));
132 int set_ipv6_only(int fd
)
135 return setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &one
, sizeof(one
));
138 int set_reuseaddr(int fd
)
142 ret
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &one
, sizeof(one
));
143 if (unlikely(ret
< 0))
144 panic("Cannot reuse addr!\n");
149 void set_mtu_disc_dont(int fd
)
151 int mtu
= IP_PMTUDISC_DONT
, ret
;
153 ret
= setsockopt(fd
, SOL_IP
, IP_MTU_DISCOVER
, &mtu
, sizeof(mtu
));
155 panic("Cannot set MTU discovery options!\n");
158 void set_epoll_descriptor(int fd_epoll
, int action
, int fd_toadd
, int events
)
161 struct epoll_event ev
;
163 memset(&ev
, 0, sizeof(ev
));
165 ev
.data
.fd
= fd_toadd
;
167 ret
= epoll_ctl(fd_epoll
, action
, fd_toadd
, &ev
);
169 panic("Cannot add socket for epoll!\n");
172 int set_epoll_descriptor2(int fd_epoll
, int action
, int fd_toadd
, int events
)
174 struct epoll_event ev
;
176 memset(&ev
, 0, sizeof(ev
));
178 ev
.data
.fd
= fd_toadd
;
180 return epoll_ctl(fd_epoll
, action
, fd_toadd
, &ev
);
183 u32
wireless_bitrate(const char *ifname
)
185 int sock
, ret
, rate_in_mbit
;
188 sock
= af_socket(AF_INET
);
190 memset(&iwr
, 0, sizeof(iwr
));
191 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
193 ret
= ioctl(sock
, SIOCGIWRATE
, &iwr
);
195 rate_in_mbit
= iwr
.u
.bitrate
.value
/ 1000000;
204 int get_system_socket_mem(int which
)
208 const char *file
= sock_mem
[which
];
211 fd
= open(file
, O_RDONLY
);
215 ret
= read(fd
, buff
, sizeof(buff
));
223 void set_system_socket_mem(int which
, int val
)
226 const char *file
= sock_mem
[which
];
230 fd
= open(file
, O_WRONLY
);
234 memset(buff
, 0, sizeof(buff
));
235 slprintf(buff
, sizeof(buff
), "%d", val
);
237 ret
= write(fd
, buff
, strlen(buff
));
243 int wireless_sigqual(const char *ifname
, struct iw_statistics
*stats
)
248 sock
= af_socket(AF_INET
);
250 memset(&iwr
, 0, sizeof(iwr
));
251 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
253 iwr
.u
.data
.pointer
= (caddr_t
) stats
;
254 iwr
.u
.data
.length
= sizeof(*stats
);
255 iwr
.u
.data
.flags
= 1;
257 ret
= ioctl(sock
, SIOCGIWSTATS
, &iwr
);
264 int wireless_rangemax_sigqual(const char *ifname
)
266 int ret
, sock
, sigqual
;
268 struct iw_range iwrange
;
270 sock
= af_socket(AF_INET
);
272 memset(&iwrange
, 0, sizeof(iwrange
));
274 memset(&iwr
, 0, sizeof(iwr
));
275 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
277 iwr
.u
.data
.pointer
= (caddr_t
) &iwrange
;
278 iwr
.u
.data
.length
= sizeof(iwrange
);
279 iwr
.u
.data
.flags
= 0;
281 ret
= ioctl(sock
, SIOCGIWRANGE
, &iwr
);
283 sigqual
= iwrange
.max_qual
.qual
;
292 u32
ethtool_bitrate(const char *ifname
)
294 int ret
, sock
, bitrate
;
296 struct ethtool_cmd ecmd
;
298 sock
= af_socket(AF_INET
);
300 memset(&ecmd
, 0, sizeof(ecmd
));
302 memset(&ifr
, 0, sizeof(ifr
));
303 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
305 ecmd
.cmd
= ETHTOOL_GSET
;
306 ifr
.ifr_data
= (char *) &ecmd
;
308 ret
= ioctl(sock
, SIOCETHTOOL
, &ifr
);
314 switch (ecmd
.speed
) {
320 bitrate
= ecmd
.speed
;
332 int ethtool_link(const char *ifname
)
336 struct ethtool_value ecmd
;
338 sock
= af_socket(AF_INET
);
340 memset(&ecmd
, 0, sizeof(ecmd
));
342 memset(&ifr
, 0, sizeof(ifr
));
343 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
345 ecmd
.cmd
= ETHTOOL_GLINK
;
346 ifr
.ifr_data
= (char *) &ecmd
;
348 ret
= ioctl(sock
, SIOCETHTOOL
, &ifr
);
358 int ethtool_drvinf(const char *ifname
, struct ethtool_drvinfo
*drvinf
)
363 sock
= af_socket(AF_INET
);
365 memset(drvinf
, 0, sizeof(*drvinf
));
367 memset(&ifr
, 0, sizeof(ifr
));
368 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
370 drvinf
->cmd
= ETHTOOL_GDRVINFO
;
371 ifr
.ifr_data
= (char *) drvinf
;
373 ret
= ioctl(sock
, SIOCETHTOOL
, &ifr
);
380 void register_signal(int signal
, void (*handler
)(int))
383 struct sigaction saction
;
385 sigfillset(&block_mask
);
387 saction
.sa_handler
= handler
;
388 saction
.sa_mask
= block_mask
;
389 saction
.sa_flags
= SA_RESTART
;
391 sigaction(signal
, &saction
, NULL
);
394 void register_signal_f(int signal
, void (*handler
)(int), int flags
)
397 struct sigaction saction
;
399 sigfillset(&block_mask
);
401 saction
.sa_handler
= handler
;
402 saction
.sa_mask
= block_mask
;
403 saction
.sa_flags
= flags
;
405 sigaction(signal
, &saction
, NULL
);
408 void cpu_affinity(int cpu
)
411 cpu_set_t cpu_bitmask
;
413 CPU_ZERO(&cpu_bitmask
);
414 CPU_SET(cpu
, &cpu_bitmask
);
416 ret
= sched_setaffinity(getpid(), sizeof(cpu_bitmask
),
419 panic("Can't set this cpu affinity!\n");
422 int set_proc_prio(int priority
)
424 int ret
= setpriority(PRIO_PROCESS
, getpid(), priority
);
426 panic("Can't set nice val to %i!\n", priority
);
431 int set_sched_status(int policy
, int priority
)
433 int ret
, min_prio
, max_prio
;
434 struct sched_param sp
;
436 max_prio
= sched_get_priority_max(policy
);
437 min_prio
= sched_get_priority_min(policy
);
439 if (max_prio
== -1 || min_prio
== -1)
440 printf("Cannot determine scheduler prio limits!\n");
441 else if (priority
< min_prio
)
443 else if (priority
> max_prio
)
446 memset(&sp
, 0, sizeof(sp
));
447 sp
.sched_priority
= priority
;
449 ret
= sched_setscheduler(getpid(), policy
, &sp
);
451 printf("Cannot set scheduler policy!\n");
455 ret
= sched_setparam(getpid(), &sp
);
457 printf("Cannot set scheduler prio!\n");
464 int get_default_sched_policy(void)
469 int get_default_sched_prio(void)
471 return sched_get_priority_max(get_default_sched_policy());
474 int get_default_proc_prio(void)
479 void set_system_socket_memory(int *vals
, size_t len
)
483 if ((vals
[0] = get_system_socket_mem(sock_rmem_max
)) < SMEM_SUG_MAX
)
484 set_system_socket_mem(sock_rmem_max
, SMEM_SUG_MAX
);
485 if ((vals
[1] = get_system_socket_mem(sock_rmem_def
)) < SMEM_SUG_DEF
)
486 set_system_socket_mem(sock_rmem_def
, SMEM_SUG_DEF
);
487 if ((vals
[2] = get_system_socket_mem(sock_wmem_max
)) < SMEM_SUG_MAX
)
488 set_system_socket_mem(sock_wmem_max
, SMEM_SUG_MAX
);
489 if ((vals
[3] = get_system_socket_mem(sock_wmem_def
)) < SMEM_SUG_DEF
)
490 set_system_socket_mem(sock_wmem_def
, SMEM_SUG_DEF
);
493 void reset_system_socket_memory(int *vals
, size_t len
)
497 set_system_socket_mem(sock_rmem_max
, vals
[0]);
498 set_system_socket_mem(sock_rmem_def
, vals
[1]);
499 set_system_socket_mem(sock_wmem_max
, vals
[2]);
500 set_system_socket_mem(sock_wmem_def
, vals
[3]);
503 void set_itimer_interval_value(struct itimerval
*itimer
, unsigned long sec
,
506 itimer
->it_interval
.tv_sec
= sec
;
507 itimer
->it_interval
.tv_usec
= usec
;
509 itimer
->it_value
.tv_sec
= sec
;
510 itimer
->it_value
.tv_usec
= usec
;