2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2009, 2010 Daniel Borkmann.
5 * Copyright 2009, 2010 Emmanuel Roullit.
6 * Subject to the GPL, version 2.
17 #include <arpa/inet.h>
18 #include <sys/socket.h>
19 #include <sys/ioctl.h>
22 #include <linux/socket.h>
23 #include <linux/types.h>
25 #include <linux/if_ether.h>
26 #include <linux/if_packet.h>
27 #include <linux/sockios.h>
36 if (af
!= AF_INET
&& af
!= AF_INET6
) {
37 whine("Wrong AF socket type! Falling back to AF_INET\n");
40 sock
= socket(af
, SOCK_DGRAM
, 0);
42 panic("Creation AF socket failed!\n");
46 int af_raw_socket(int af
, int proto
)
49 if (af
!= AF_INET
&& af
!= AF_INET6
) {
50 whine("Wrong AF socket type! Falling back to AF_INET\n");
53 sock
= socket(af
, SOCK_RAW
, proto
);
55 panic("Creation AF socket failed!\n");
61 int sock
= socket(PF_PACKET
, SOCK_RAW
, htons(ETH_P_ALL
));
63 panic("Creation of PF socket failed!\n");
67 int set_nonblocking(int fd
)
69 int ret
= fcntl(fd
, F_SETFL
, fcntl(fd
, F_GETFD
, 0) | O_NONBLOCK
);
71 panic("Cannot fcntl!\n");
75 int set_nonblocking_sloppy(int fd
)
77 return fcntl(fd
, F_SETFL
, fcntl(fd
, F_GETFD
, 0) | O_NONBLOCK
);
80 int set_reuseaddr(int fd
)
83 int ret
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &one
, sizeof (one
));
85 panic("Cannot reuse addr!\n");
89 int wireless_bitrate(const char *ifname
)
91 int sock
, ret
, rate_in_mbit
;
93 sock
= af_socket(AF_INET
);
94 memset(&iwr
, 0, sizeof(iwr
));
95 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
96 ret
= ioctl(sock
, SIOCGIWRATE
, &iwr
);
98 rate_in_mbit
= iwr
.u
.bitrate
.value
/ 1000000;
105 int wireless_essid(const char *ifname
, char *essid
)
107 int ret
, sock
, essid_len
;
109 sock
= af_socket(AF_INET
);
110 memset(&iwr
, 0, sizeof(iwr
));
111 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
112 iwr
.u
.essid
.pointer
= essid
;
113 iwr
.u
.essid
.length
= IW_ESSID_MAX_SIZE
;
114 ret
= ioctl(sock
, SIOCGIWESSID
, &iwr
);
116 essid_len
= iwr
.u
.essid
.length
;
123 int adjust_dbm_level(int dbm_val
)
130 int dbm_to_mwatt(const int in
)
132 /* From Jean Tourrilhes <jt@hpl.hp.com> (iwlib.c) */
137 for (k
= 0; k
< ip
; k
++)
139 for (k
= 0; k
< fp
; k
++)
140 res
*= 1.25892541179; /* LOG10_MAGIC */
144 int wireless_tx_power(const char *ifname
)
146 int ret
, sock
, tx_power
;
149 sock
= af_socket(AF_INET
);
151 memset(&iwr
, 0, sizeof(iwr
));
152 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
154 ret
= ioctl(sock
, SIOCGIWTXPOW
, &iwr
);
156 tx_power
= iwr
.u
.txpower
.value
;
164 int wireless_sigqual(const char *ifname
, struct iw_statistics
*stats
)
168 sock
= af_socket(AF_INET
);
169 memset(&iwr
, 0, sizeof(iwr
));
170 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
171 iwr
.u
.data
.pointer
= (caddr_t
) stats
;
172 iwr
.u
.data
.length
= sizeof(*stats
);
173 iwr
.u
.data
.flags
= 1;
174 ret
= ioctl(sock
, SIOCGIWSTATS
, &iwr
);
179 int wireless_rangemax_sigqual(const char *ifname
)
181 int ret
, sock
, sigqual
;
183 struct iw_range iwrange
;
184 sock
= af_socket(AF_INET
);
185 memset(&iwrange
, 0, sizeof(iwrange
));
186 memset(&iwr
, 0, sizeof(iwr
));
187 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
188 iwr
.u
.data
.pointer
= (caddr_t
) &iwrange
;
189 iwr
.u
.data
.length
= sizeof(iwrange
);
190 iwr
.u
.data
.flags
= 0;
191 ret
= ioctl(sock
, SIOCGIWRANGE
, &iwr
);
193 sigqual
= iwrange
.max_qual
.qual
;
200 int ethtool_bitrate(const char *ifname
)
202 int ret
, sock
, bitrate
;
204 struct ethtool_cmd ecmd
;
205 sock
= af_socket(AF_INET
);
206 memset(&ecmd
, 0, sizeof(ecmd
));
207 memset(&ifr
, 0, sizeof(ifr
));
208 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
209 ecmd
.cmd
= ETHTOOL_GSET
;
210 ifr
.ifr_data
= (char *) &ecmd
;
211 ret
= ioctl(sock
, SIOCETHTOOL
, &ifr
);
216 switch (ecmd
.speed
) {
221 bitrate
= ecmd
.speed
;
232 int ethtool_drvinf(const char *ifname
, struct ethtool_drvinfo
*drvinf
)
236 sock
= af_socket(AF_INET
);
237 memset(drvinf
, 0, sizeof(*drvinf
));
238 memset(&ifr
, 0, sizeof(ifr
));
239 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
240 drvinf
->cmd
= ETHTOOL_GDRVINFO
;
241 ifr
.ifr_data
= (char *) drvinf
;
242 ret
= ioctl(sock
, SIOCETHTOOL
, &ifr
);
247 int device_bitrate(const char *ifname
)
249 int speed_c
, speed_w
;
250 /* Probe for speed rates */
251 speed_c
= ethtool_bitrate(ifname
);
252 speed_w
= wireless_bitrate(ifname
);
253 return (speed_c
== 0 ? speed_w
: speed_c
);
256 int device_ifindex(const char *ifname
)
258 int ret
, sock
, index
;
260 if (!strncmp("any", ifname
, strlen("any")))
262 sock
= af_socket(AF_INET
);
263 memset(&ifr
, 0, sizeof(ifr
));
264 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
265 ret
= ioctl(sock
, SIOCGIFINDEX
, &ifr
);
267 index
= ifr
.ifr_ifindex
;
274 int device_address(const char *ifname
, int af
, struct sockaddr_storage
*ss
)
280 if (!strncmp("any", ifname
, strlen("any")))
282 sock
= af_socket(af
);
283 memset(&ifr
, 0, sizeof(ifr
));
284 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
285 ifr
.ifr_addr
.sa_family
= af
;
286 ret
= ioctl(sock
, SIOCGIFADDR
, &ifr
);
288 memcpy(ss
, &ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
293 int device_mtu(const char *ifname
)
297 sock
= af_socket(AF_INET
);
298 memset(&ifr
, 0, sizeof(ifr
));
299 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
300 ret
= ioctl(sock
, SIOCGIFMTU
, &ifr
);
309 short device_get_flags(const char *ifname
)
311 /* Really, it's short! Look at struct ifreq */
315 sock
= af_socket(AF_INET
);
316 memset(&ifr
, 0, sizeof(ifr
));
317 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
318 ret
= ioctl(sock
, SIOCGIFFLAGS
, &ifr
);
320 flags
= ifr
.ifr_flags
;
327 void device_set_flags(const char *ifname
, const short flags
)
331 sock
= af_socket(AF_INET
);
332 memset(&ifr
, 0, sizeof(ifr
));
333 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
334 ifr
.ifr_flags
= flags
;
335 ret
= ioctl(sock
, SIOCSIFFLAGS
, &ifr
);
337 panic("Cannot set NIC flags!\n");
341 int device_irq_number(const char *ifname
)
344 * Since fetching IRQ numbers from SIOCGIFMAP is deprecated and not
345 * supported anymore, we need to grab them from procfs
351 if (!strncmp("lo", ifname
, strlen("lo")))
353 FILE *fp
= fopen("/proc/interrupts", "r");
355 whine("Cannot open /proc/interrupts!\n");
358 memset(buff
, 0, sizeof(buff
));
359 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
360 buff
[sizeof(buff
) - 1] = 0;
361 if (strstr(buff
, ifname
) == NULL
)
364 while (*buffp
!= ':')
368 memset(buff
, 0, sizeof(buff
));
374 * Try sysfs as fallback. Probably wireless devices will be found
375 * here. We return silently if it fails ...
377 slprintf(sysname
, sizeof(sysname
), "/sys/class/net/%s/device/irq",
379 fp
= fopen(sysname
, "r");
382 memset(buff
, 0, sizeof(buff
));
383 if(fgets(buff
, sizeof(buff
), fp
) != NULL
) {
384 buff
[sizeof(buff
) - 1] = 0;
391 int device_bind_irq_to_cpu(int irq
, int cpu
)
396 /* Note: first CPU begins with CPU 0 */
397 if (irq
< 0 || cpu
< 0)
399 memset(file
, 0, sizeof(file
));
400 memset(buff
, 0, sizeof(buff
));
401 /* smp_affinity starts counting with CPU 1, 2, ... */
403 sprintf(file
, "/proc/irq/%d/smp_affinity", irq
);
404 FILE *fp
= fopen(file
, "w");
406 whine("Cannot open file %s!\n", file
);
409 sprintf(buff
, "%d", cpu
);
410 ret
= fwrite(buff
, sizeof(buff
), 1, fp
);
412 return (ret
> 0 ? 0 : ret
);
415 void sock_print_net_stats(int sock
)
418 struct tpacket_stats kstats
;
419 socklen_t slen
= sizeof(kstats
);
420 memset(&kstats
, 0, sizeof(kstats
));
421 ret
= getsockopt(sock
, SOL_PACKET
, PACKET_STATISTICS
, &kstats
, &slen
);
423 printf("\r%12d frames incoming\n",
425 printf("\r%12d frames passed filter\n",
426 kstats
.tp_packets
- kstats
.tp_drops
);
427 printf("\r%12d frames failed filter (out of space)\n",
429 if (kstats
.tp_packets
> 0)
430 printf("\r%12.4f%% frame droprate\n", 1.f
*
431 kstats
.tp_drops
/ kstats
.tp_packets
* 100.f
);
435 void register_signal(int signal
, void (*handler
)(int))
438 struct sigaction saction
;
439 sigfillset(&block_mask
);
440 saction
.sa_handler
= handler
;
441 saction
.sa_mask
= block_mask
;
442 saction
.sa_flags
= SA_RESTART
;
443 sigaction(signal
, &saction
, NULL
);
446 void register_signal_f(int signal
, void (*handler
)(int), int flags
)
449 struct sigaction saction
;
450 sigfillset(&block_mask
);
451 saction
.sa_handler
= handler
;
452 saction
.sa_mask
= block_mask
;
453 saction
.sa_flags
= flags
;
454 sigaction(signal
, &saction
, NULL
);