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.
16 #include <sys/socket.h>
19 #include <linux/socket.h>
20 #include <linux/types.h>
22 #include <linux/if_ether.h>
23 #include <linux/if_packet.h>
24 #include <linux/sockios.h>
32 if (af
!= AF_INET
&& af
!= AF_INET6
) {
33 whine("Wrong AF socket type! Falling back to AF_INET\n");
37 int sock
= socket(af
, SOCK_DGRAM
, 0);
39 error_and_die(EXIT_FAILURE
, "Creation AF socket failed!\n");
45 int sock
= socket(PF_PACKET
, SOCK_RAW
, 0);
47 error_and_die(EXIT_FAILURE
, "Creation of PF socket failed!\n");
51 int set_nonblocking(int fd
)
53 int ret
= fcntl(fd
, F_SETFL
, fcntl(fd
, F_GETFD
, 0) | O_NONBLOCK
);
55 panic("Cannot fcntl!\n");
59 int set_reuseaddr(int fd
)
62 int ret
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &one
, sizeof (one
));
64 panic("Cannot reuse addr!\n");
68 int wireless_bitrate(const char *ifname
)
70 int sock
, ret
, rate_in_mbit
;
73 sock
= af_socket(AF_INET
);
75 memset(&iwr
, 0, sizeof(iwr
));
76 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
78 ret
= ioctl(sock
, SIOCGIWRATE
, &iwr
);
80 rate_in_mbit
= iwr
.u
.bitrate
.value
/ 1000000;
88 int wireless_essid(const char *ifname
, char *essid
)
90 int ret
, sock
, essid_len
;
93 sock
= af_socket(AF_INET
);
95 memset(&iwr
, 0, sizeof(iwr
));
96 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
98 iwr
.u
.essid
.pointer
= essid
;
99 iwr
.u
.essid
.length
= IW_ESSID_MAX_SIZE
;
101 ret
= ioctl(sock
, SIOCGIWESSID
, &iwr
);
103 essid_len
= iwr
.u
.essid
.length
;
111 int adjust_dbm_level(int dbm_val
)
118 int dbm_to_mwatt(const int in
)
120 /* From Jean Tourrilhes <jt@hpl.hp.com> (iwlib.c) */
127 for (k
= 0; k
< ip
; k
++)
129 for (k
= 0; k
< fp
; k
++)
130 res
*= 1.25892541179; /* LOG10_MAGIC */
135 int wireless_tx_power(const char *ifname
)
137 int ret
, sock
, tx_power
;
140 sock
= af_socket(AF_INET
);
142 memset(&iwr
, 0, sizeof(iwr
));
143 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
145 ret
= ioctl(sock
, SIOCGIWTXPOW
, &iwr
);
147 tx_power
= iwr
.u
.txpower
.value
;
155 int wireless_sigqual(const char *ifname
, struct iw_statistics
*stats
)
160 sock
= af_socket(AF_INET
);
162 memset(&iwr
, 0, sizeof(iwr
));
163 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
165 iwr
.u
.data
.pointer
= (caddr_t
) stats
;
166 iwr
.u
.data
.length
= sizeof(*stats
);
167 iwr
.u
.data
.flags
= 1;
169 ret
= ioctl(sock
, SIOCGIWSTATS
, &iwr
);
175 int wireless_rangemax_sigqual(const char *ifname
)
177 int ret
, sock
, sigqual
;
179 struct iw_range iwrange
;
181 sock
= af_socket(AF_INET
);
183 memset(&iwrange
, 0, sizeof(iwrange
));
184 memset(&iwr
, 0, sizeof(iwr
));
185 strlcpy(iwr
.ifr_name
, ifname
, IFNAMSIZ
);
187 iwr
.u
.data
.pointer
= (caddr_t
) &iwrange
;
188 iwr
.u
.data
.length
= sizeof(iwrange
);
189 iwr
.u
.data
.flags
= 0;
191 ret
= ioctl(sock
, SIOCGIWRANGE
, &iwr
);
193 sigqual
= iwrange
.max_qual
.qual
;
201 int ethtool_bitrate(const char *ifname
)
203 int ret
, sock
, bitrate
;
205 struct ethtool_cmd ecmd
;
207 sock
= af_socket(AF_INET
);
209 memset(&ecmd
, 0, sizeof(ecmd
));
210 memset(&ifr
, 0, sizeof(ifr
));
211 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
213 ecmd
.cmd
= ETHTOOL_GSET
;
214 ifr
.ifr_data
= (char *) &ecmd
;
216 ret
= ioctl(sock
, SIOCETHTOOL
, &ifr
);
222 switch (ecmd
.speed
) {
227 bitrate
= ecmd
.speed
;
239 int ethtool_drvinf(const char *ifname
, struct ethtool_drvinfo
*drvinf
)
244 sock
= af_socket(AF_INET
);
246 memset(drvinf
, 0, sizeof(*drvinf
));
247 memset(&ifr
, 0, sizeof(ifr
));
248 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
250 drvinf
->cmd
= ETHTOOL_GDRVINFO
;
251 ifr
.ifr_data
= (char *) drvinf
;
253 ret
= ioctl(sock
, SIOCETHTOOL
, &ifr
);
259 int device_bitrate(const char *ifname
)
261 int speed_c
, speed_w
;
263 /* Probe for speed rates */
264 speed_c
= ethtool_bitrate(ifname
);
265 speed_w
= wireless_bitrate(ifname
);
267 return (speed_c
== 0 ? speed_w
: speed_c
);
270 int device_ifindex(const char *ifname
)
272 int ret
, sock
, index
;
275 if (!strncmp("any", ifname
, strlen("any")))
278 sock
= af_socket(AF_INET
);
280 memset(&ifr
, 0, sizeof(ifr
));
281 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
283 ret
= ioctl(sock
, SIOCGIFINDEX
, &ifr
);
285 index
= ifr
.ifr_ifindex
;
293 int device_mtu(const char *ifname
)
298 sock
= af_socket(AF_INET
);
300 memset(&ifr
, 0, sizeof(ifr
));
301 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
303 ret
= ioctl(sock
, SIOCGIFMTU
, &ifr
);
313 short device_get_flags(const char *ifname
)
315 /* Really, it's short! Look at struct ifreq */
320 sock
= af_socket(AF_INET
);
322 memset(&ifr
, 0, sizeof(ifr
));
323 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
325 ret
= ioctl(sock
, SIOCGIFFLAGS
, &ifr
);
327 flags
= ifr
.ifr_flags
;
335 void device_set_flags(const char *ifname
, const short flags
)
340 sock
= af_socket(AF_INET
);
342 memset(&ifr
, 0, sizeof(ifr
));
343 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
345 ifr
.ifr_flags
= flags
;
347 ret
= ioctl(sock
, SIOCSIFFLAGS
, &ifr
);
349 error_and_die(EXIT_FAILURE
, "Cannot set NIC flags!\n");
354 int device_irq_number(const char *ifname
)
357 * Since fetching IRQ numbers from SIOCGIFMAP is deprecated and not
358 * supported anymore, we need to grab them from procfs
367 if (!strncmp("lo", ifname
, strlen("lo")))
370 /* Try /proc/interrupts */
371 FILE *fp
= fopen("/proc/interrupts", "r");
373 whine("Cannot open /proc/interrupts!\n");
377 memset(buff
, 0, sizeof(buff
));
379 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
380 buff
[sizeof(buff
) - 1] = 0;
382 if (strstr(buff
, ifname
) == NULL
)
386 while (*buffp
!= ':')
392 memset(buff
, 0, sizeof(buff
));
400 * Try sysfs as fallback. Probably wireless devices will be found
401 * here. We return silently if it fails ...
403 snprintf(sysname
, sizeof(sysname
), "/sys/class/net/%s/device/irq",
406 fp
= fopen(sysname
, "r");
410 memset(buff
, 0, sizeof(buff
));
411 if(fgets(buff
, sizeof(buff
), fp
) != NULL
) {
412 buff
[sizeof(buff
) - 1] = 0;
420 int device_bind_irq_to_cpu(int irq
, int cpu
)
426 /* Note: first CPU begins with CPU 0 */
427 if (irq
< 0 || cpu
< 0)
430 memset(file
, 0, sizeof(file
));
431 memset(buff
, 0, sizeof(buff
));
433 /* smp_affinity starts counting with CPU 1, 2, ... */
436 sprintf(file
, "/proc/irq/%d/smp_affinity", irq
);
438 FILE *fp
= fopen(file
, "w");
440 whine("Cannot open file %s!\n", file
);
444 sprintf(buff
, "%d", cpu
);
445 ret
= fwrite(buff
, sizeof(buff
), 1, fp
);
448 return (ret
> 0 ? 0 : ret
);
451 void sock_print_net_stats(int sock
)
454 struct tpacket_stats kstats
;
455 socklen_t slen
= sizeof(kstats
);
457 memset(&kstats
, 0, sizeof(kstats
));
459 ret
= getsockopt(sock
, SOL_PACKET
, PACKET_STATISTICS
, &kstats
, &slen
);
461 printf("\r%3d frames incoming\n",
463 printf("\r%3d frames passed filter\n",
464 kstats
.tp_packets
- kstats
.tp_drops
);
465 printf("\r%3d frames failed filter (out of space)\n",