flowtop: Print error cause if errno is set when panic
[netsniff-ng.git] / dev.c
blobb3249e6c98d0675c3ec7747b59946c1279834136
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(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 (unlikely(ret))
31 panic("Cannot get ifindex from device!\n");
33 index = ifr.ifr_ifindex;
34 close(sock);
36 return index;
39 int device_type(const char *ifname)
41 int ret, sock, type;
42 struct ifreq ifr;
44 if (!strncmp("any", ifname, strlen("any")))
45 return ARPHRD_ETHER;
47 sock = af_socket(AF_INET);
49 memset(&ifr, 0, sizeof(ifr));
50 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
52 ret = ioctl(sock, SIOCGIFHWADDR, &ifr);
53 if (unlikely(ret))
54 panic("Cannot get iftype from device!\n");
56 /* dev->type */
57 type = ifr.ifr_hwaddr.sa_family;
58 close(sock);
60 return type;
63 static int __device_address6(const char *ifname, struct sockaddr_storage *ss)
65 int ret, family, found = -EINVAL;
66 struct ifaddrs *ifaddr, *ifa;
68 ret = getifaddrs(&ifaddr);
69 if (unlikely(ret < 0))
70 panic("Cannot get device addresses for IPv6!\n");
72 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
73 family = ifa->ifa_addr->sa_family;
74 if (family != AF_INET6)
75 continue;
76 if (strcmp(ifa->ifa_name, ifname))
77 continue;
79 memcpy(ss, ifa->ifa_addr, sizeof(*ss));
80 found = 0;
81 break;
84 freeifaddrs(ifaddr);
85 return found;
88 int device_address(const char *ifname, int af, struct sockaddr_storage *ss)
90 int ret, sock;
91 struct ifreq ifr;
93 if (unlikely(!ss))
94 return -EINVAL;
95 if (!strncmp("any", ifname, strlen("any")))
96 return -EINVAL;
97 if (af == AF_INET6)
98 return __device_address6(ifname, ss);
100 sock = af_socket(af);
102 memset(&ifr, 0, sizeof(ifr));
103 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
105 ifr.ifr_addr.sa_family = af;
107 ret = ioctl(sock, SIOCGIFADDR, &ifr);
108 if (likely(!ret))
109 memcpy(ss, &ifr.ifr_addr, sizeof(ifr.ifr_addr));
111 close(sock);
112 return ret;
115 size_t device_mtu(const char *ifname)
117 size_t mtu = 0;
118 int ret, sock;
119 struct ifreq ifr;
121 sock = af_socket(AF_INET);
123 memset(&ifr, 0, sizeof(ifr));
124 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
126 ret = ioctl(sock, SIOCGIFMTU, &ifr);
127 if (likely(!ret))
128 mtu = ifr.ifr_mtu;
130 close(sock);
131 return mtu;
134 short device_get_flags(const char *ifname)
136 short flags = 0;
137 int ret, sock;
138 struct ifreq ifr;
140 sock = af_socket(AF_INET);
142 memset(&ifr, 0, sizeof(ifr));
143 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
145 ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
146 if (likely(!ret))
147 flags = ifr.ifr_flags;
149 close(sock);
150 return flags;
153 void device_set_flags(const char *ifname, const short flags)
155 int ret, sock;
156 struct ifreq ifr;
158 sock = af_socket(AF_INET);
160 memset(&ifr, 0, sizeof(ifr));
161 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
162 ifr.ifr_flags = flags;
164 ret = ioctl(sock, SIOCSIFFLAGS, &ifr);
165 if (unlikely(ret < 0))
166 panic("Cannot set NIC flags!\n");
168 close(sock);
171 int device_up_and_running(const char *ifname)
173 if (!ifname)
174 return -EINVAL;
175 if (!strncmp("any", ifname, strlen("any")))
176 return 1;
178 return (device_get_flags(ifname) &
179 (IFF_UP | IFF_RUNNING)) ==
180 (IFF_UP | IFF_RUNNING);
183 u32 device_bitrate(const char *ifname)
185 u32 scopper, swireless;
187 scopper = ethtool_bitrate(ifname);
188 swireless = wireless_bitrate(ifname);
190 return scopper ? : swireless;
193 short device_enter_promiscuous_mode(const char *ifname)
195 short ifflags;
197 if (!strncmp("any", ifname, strlen("any")))
198 return 0;
200 ifflags = device_get_flags(ifname);
201 device_set_flags(ifname, ifflags | IFF_PROMISC);
203 return ifflags;
206 void device_leave_promiscuous_mode(const char *ifname, short oldflags)
208 if (!strncmp("any", ifname, strlen("any")))
209 return;
211 device_set_flags(ifname, oldflags);