netsniff-ng: Rotate pcap files prematurely on SIGHUP
[netsniff-ng.git] / dev.c
blob2b3a7a5c22fc2b40f08ac762b65e16d6590c96c8
1 #include <string.h>
2 #include <errno.h>
3 #include <sys/ioctl.h>
4 #include <sys/types.h>
5 #include <sys/socket.h>
6 #include <linux/if_arp.h>
7 #include <ifaddrs.h>
9 #include "dev.h"
10 #include "str.h"
11 #include "sock.h"
12 #include "die.h"
13 #include "link.h"
14 #include "built_in.h"
16 int device_ifindex_get(const char *ifname)
18 int ret, sock, index;
19 struct ifreq ifr;
21 if (!strncmp("any", ifname, strlen("any")))
22 return 0;
24 sock = af_socket(AF_INET);
26 memset(&ifr, 0, sizeof(ifr));
27 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
29 ret = ioctl(sock, SIOCGIFINDEX, &ifr);
30 if (ret)
31 index = -1;
32 else
33 index = ifr.ifr_ifindex;
35 close(sock);
37 return index;
40 int device_ifindex(const char *ifname)
42 int index = device_ifindex_get(ifname);
44 if (unlikely(index < 0))
45 panic("Cannot get ifindex from device!\n");
47 return index;
50 int device_type(const char *ifname)
52 int ret, sock, type;
53 struct ifreq ifr;
55 if (!strncmp("any", ifname, strlen("any")))
56 return ARPHRD_ETHER;
58 sock = af_socket(AF_INET);
60 memset(&ifr, 0, sizeof(ifr));
61 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
63 ret = ioctl(sock, SIOCGIFHWADDR, &ifr);
64 if (unlikely(ret))
65 panic("Cannot get iftype from device!\n");
67 /* dev->type */
68 type = ifr.ifr_hwaddr.sa_family;
69 close(sock);
71 return type;
74 static int __device_address6(const char *ifname, struct sockaddr_storage *ss)
76 int ret, family, found = -EINVAL;
77 struct ifaddrs *ifaddr, *ifa;
79 ret = getifaddrs(&ifaddr);
80 if (unlikely(ret < 0))
81 panic("Cannot get device addresses for IPv6!\n");
83 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
84 family = ifa->ifa_addr->sa_family;
85 if (family != AF_INET6)
86 continue;
87 if (strcmp(ifa->ifa_name, ifname))
88 continue;
90 memcpy(ss, ifa->ifa_addr, sizeof(*ss));
91 found = 0;
92 break;
95 freeifaddrs(ifaddr);
96 return found;
99 int device_address(const char *ifname, int af, struct sockaddr_storage *ss)
101 int ret, sock;
102 struct ifreq ifr;
104 if (unlikely(!ss))
105 return -EINVAL;
106 if (!strncmp("any", ifname, strlen("any")))
107 return -EINVAL;
108 if (af == AF_INET6)
109 return __device_address6(ifname, ss);
111 sock = af_socket(af);
113 memset(&ifr, 0, sizeof(ifr));
114 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
116 ifr.ifr_addr.sa_family = af;
118 ret = ioctl(sock, SIOCGIFADDR, &ifr);
119 if (likely(!ret))
120 memcpy(ss, &ifr.ifr_addr, sizeof(ifr.ifr_addr));
122 close(sock);
123 return ret;
126 size_t device_mtu(const char *ifname)
128 size_t mtu = 0;
129 int ret, sock;
130 struct ifreq ifr;
132 sock = af_socket(AF_INET);
134 memset(&ifr, 0, sizeof(ifr));
135 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
137 ret = ioctl(sock, SIOCGIFMTU, &ifr);
138 if (likely(!ret))
139 mtu = ifr.ifr_mtu;
141 close(sock);
142 return mtu;
145 short device_get_flags(const char *ifname)
147 short flags = 0;
148 int ret, sock;
149 struct ifreq ifr;
151 sock = af_socket(AF_INET);
153 memset(&ifr, 0, sizeof(ifr));
154 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
156 ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
157 if (likely(!ret))
158 flags = ifr.ifr_flags;
160 close(sock);
161 return flags;
164 void device_set_flags(const char *ifname, const short flags)
166 int ret, sock;
167 struct ifreq ifr;
169 sock = af_socket(AF_INET);
171 memset(&ifr, 0, sizeof(ifr));
172 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
173 ifr.ifr_flags = flags;
175 ret = ioctl(sock, SIOCSIFFLAGS, &ifr);
176 if (unlikely(ret < 0))
177 panic("Cannot set NIC flags!\n");
179 close(sock);
182 int device_up_and_running(const char *ifname)
184 if (!ifname)
185 return -EINVAL;
186 if (!strncmp("any", ifname, strlen("any")))
187 return 1;
189 return (device_get_flags(ifname) &
190 (IFF_UP | IFF_RUNNING)) ==
191 (IFF_UP | IFF_RUNNING);
194 u32 device_bitrate(const char *ifname)
196 u32 scopper, swireless;
198 scopper = ethtool_bitrate(ifname);
199 swireless = wireless_bitrate(ifname);
201 return scopper ? : swireless;
204 short device_enter_promiscuous_mode(const char *ifname)
206 short ifflags;
208 if (!strncmp("any", ifname, strlen("any")))
209 return 0;
211 ifflags = device_get_flags(ifname);
212 device_set_flags(ifname, ifflags | IFF_PROMISC);
214 return ifflags;
217 void device_leave_promiscuous_mode(const char *ifname, short oldflags)
219 if (!strncmp("any", ifname, strlen("any")))
220 return;
222 device_set_flags(ifname, oldflags);