210487ce6b55c1d727e968035e2a99bba4f84958
[netsniff-ng.git] / dev.c
blob210487ce6b55c1d727e968035e2a99bba4f84958
1 #include <string.h>
2 #include <errno.h>
3 #include <sys/ioctl.h>
4 #include <sys/types.h>
5 #include <ifaddrs.h>
7 #include "dev.h"
8 #include "str.h"
9 #include "sock.h"
10 #include "die.h"
11 #include "link.h"
13 int device_ifindex(const char *ifname)
15 int ret, sock, index;
16 struct ifreq ifr;
18 if (!strncmp("any", ifname, strlen("any")))
19 return 0;
21 sock = af_socket(AF_INET);
23 memset(&ifr, 0, sizeof(ifr));
24 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
26 ret = ioctl(sock, SIOCGIFINDEX, &ifr);
27 if (!ret)
28 index = ifr.ifr_ifindex;
29 else
30 index = -1;
32 close(sock);
34 return index;
37 static int __device_address6(const char *ifname, struct sockaddr_storage *ss)
39 int ret, family, found = -EINVAL;
40 struct ifaddrs *ifaddr, *ifa;
42 ret = getifaddrs(&ifaddr);
43 if (ret < 0)
44 panic("Cannot get device addresses for IPv6!\n");
46 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
47 family = ifa->ifa_addr->sa_family;
48 if (family != AF_INET6)
49 continue;
50 if (strcmp(ifa->ifa_name, ifname))
51 continue;
53 memcpy(ss, ifa->ifa_addr, sizeof(*ss));
54 found = 0;
55 break;
58 freeifaddrs(ifaddr);
59 return found;
62 int device_address(const char *ifname, int af, struct sockaddr_storage *ss)
64 int ret, sock;
65 struct ifreq ifr;
67 if (!ss)
68 return -EINVAL;
69 if (!strncmp("any", ifname, strlen("any")))
70 return -EINVAL;
71 if (af == AF_INET6)
72 return __device_address6(ifname, ss);
74 sock = af_socket(af);
76 memset(&ifr, 0, sizeof(ifr));
77 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
79 ifr.ifr_addr.sa_family = af;
81 ret = ioctl(sock, SIOCGIFADDR, &ifr);
82 if (!ret)
83 memcpy(ss, &ifr.ifr_addr, sizeof(ifr.ifr_addr));
85 close(sock);
87 return ret;
90 int device_mtu(const char *ifname)
92 int ret, sock, mtu;
93 struct ifreq ifr;
95 sock = af_socket(AF_INET);
97 memset(&ifr, 0, sizeof(ifr));
98 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
100 ret = ioctl(sock, SIOCGIFMTU, &ifr);
101 if (!ret)
102 mtu = ifr.ifr_mtu;
103 else
104 mtu = 0;
106 close(sock);
108 return mtu;
111 short device_get_flags(const char *ifname)
113 short flags;
114 int ret, sock;
115 struct ifreq ifr;
117 sock = af_socket(AF_INET);
119 memset(&ifr, 0, sizeof(ifr));
120 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
122 ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
123 if (!ret)
124 flags = ifr.ifr_flags;
125 else
126 flags = 0;
128 close(sock);
130 return flags;
133 void device_set_flags(const char *ifname, const short flags)
135 int ret, sock;
136 struct ifreq ifr;
138 sock = af_socket(AF_INET);
140 memset(&ifr, 0, sizeof(ifr));
141 strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
143 ifr.ifr_flags = flags;
145 ret = ioctl(sock, SIOCSIFFLAGS, &ifr);
146 if (ret < 0)
147 panic("Cannot set NIC flags!\n");
149 close(sock);
152 int device_up_and_running(char *ifname)
154 if (!ifname)
155 return -EINVAL;
156 if (!strncmp("any", ifname, strlen("any")))
157 return 1;
159 return (device_get_flags(ifname) & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING);
162 u32 device_bitrate(const char *ifname)
164 u32 speed_c, speed_w;
166 speed_c = ethtool_bitrate(ifname);
167 speed_w = wireless_bitrate(ifname);
169 return (speed_c == 0 ? speed_w : speed_c);