5 #include <sys/socket.h>
6 #include <net/if_arp.h>
17 int __device_ifindex(const char *ifname
)
22 if (!strncmp("any", ifname
, strlen("any")))
25 sock
= af_socket(AF_INET
);
27 memset(&ifr
, 0, sizeof(ifr
));
28 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
30 ret
= ioctl(sock
, SIOCGIFINDEX
, &ifr
);
34 index
= ifr
.ifr_ifindex
;
41 int device_ifindex(const char *ifname
)
43 int index
= __device_ifindex(ifname
);
45 if (unlikely(index
< 0))
46 panic("Cannot get ifindex from device!\n");
51 int device_type(const char *ifname
)
56 if (!strncmp("any", ifname
, strlen("any")))
59 sock
= af_socket(AF_INET
);
61 memset(&ifr
, 0, sizeof(ifr
));
62 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
64 ret
= ioctl(sock
, SIOCGIFHWADDR
, &ifr
);
66 panic("Cannot get iftype from device!\n");
69 type
= ifr
.ifr_hwaddr
.sa_family
;
75 static int __device_address6(const char *ifname
, struct sockaddr_storage
*ss
)
77 int ret
, family
, found
= -EINVAL
;
78 struct ifaddrs
*ifaddr
, *ifa
;
80 ret
= getifaddrs(&ifaddr
);
81 if (unlikely(ret
< 0))
82 panic("Cannot get device addresses for IPv6!\n");
84 for (ifa
= ifaddr
; ifa
!= NULL
; ifa
= ifa
->ifa_next
) {
85 family
= ifa
->ifa_addr
->sa_family
;
86 if (family
!= AF_INET6
)
88 if (strcmp(ifa
->ifa_name
, ifname
))
91 memcpy(ss
, ifa
->ifa_addr
, sizeof(*ss
));
100 int device_address(const char *ifname
, int af
, struct sockaddr_storage
*ss
)
107 if (!strncmp("any", ifname
, strlen("any")))
110 return __device_address6(ifname
, ss
);
112 sock
= af_socket(af
);
114 memset(&ifr
, 0, sizeof(ifr
));
115 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
117 ifr
.ifr_addr
.sa_family
= af
;
119 ret
= ioctl(sock
, SIOCGIFADDR
, &ifr
);
121 memcpy(ss
, &ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
127 int device_hw_address(const char *ifname
, uint8_t *addr
, size_t len
)
134 if (len
< IFHWADDRLEN
)
136 if (!strncmp("any", ifname
, strlen("any")))
139 sock
= af_socket(AF_INET
);
141 memset(&ifr
, 0, sizeof(ifr
));
142 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
144 ret
= ioctl(sock
, SIOCGIFHWADDR
, &ifr
);
146 memcpy(addr
, &ifr
.ifr_hwaddr
.sa_data
[0], IFHWADDRLEN
);
152 size_t device_mtu(const char *ifname
)
158 sock
= af_socket(AF_INET
);
160 memset(&ifr
, 0, sizeof(ifr
));
161 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
163 ret
= ioctl(sock
, SIOCGIFMTU
, &ifr
);
171 short device_get_flags(const char *ifname
)
177 sock
= af_socket(AF_INET
);
179 memset(&ifr
, 0, sizeof(ifr
));
180 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
182 ret
= ioctl(sock
, SIOCGIFFLAGS
, &ifr
);
184 flags
= ifr
.ifr_flags
;
190 void device_set_flags(const char *ifname
, const short flags
)
195 sock
= af_socket(AF_INET
);
197 memset(&ifr
, 0, sizeof(ifr
));
198 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
199 ifr
.ifr_flags
= flags
;
201 ret
= ioctl(sock
, SIOCSIFFLAGS
, &ifr
);
202 if (unlikely(ret
< 0))
203 panic("Cannot set NIC flags (%s)!\n", strerror(errno
));
208 int device_up_and_running(const char *ifname
)
212 if (!strncmp("any", ifname
, strlen("any")))
215 return (device_get_flags(ifname
) &
216 (IFF_UP
| IFF_RUNNING
)) ==
217 (IFF_UP
| IFF_RUNNING
);
220 uint32_t device_bitrate(const char *ifname
)
224 scopper
= ethtool_bitrate(ifname
);
226 return scopper
? : wireless_bitrate(ifname
);
229 short device_enter_promiscuous_mode(const char *ifname
)
233 if (!strncmp("any", ifname
, strlen("any")))
236 ifflags
= device_get_flags(ifname
);
237 device_set_flags(ifname
, ifflags
| IFF_PROMISC
);
242 void device_leave_promiscuous_mode(const char *ifname
, short oldflags
)
244 if (!strncmp("any", ifname
, strlen("any")))
247 device_set_flags(ifname
, oldflags
);
250 const char *device_type2str(uint16_t type
)
267 case ARPHRD_APPLETLK
:
273 case ARPHRD_METRICOM
:
275 case ARPHRD_IEEE1394
:
277 case ARPHRD_INFINIBAND
:
317 case ARPHRD_LOOPBACK
:
319 case ARPHRD_LOCALTLK
:
347 case ARPHRD_FCFABRIC
:
349 case ARPHRD_FCFABRIC
+ 1:
351 case ARPHRD_FCFABRIC
+ 2:
353 case ARPHRD_FCFABRIC
+ 3:
355 case ARPHRD_FCFABRIC
+ 4:
357 case ARPHRD_FCFABRIC
+ 5:
359 case ARPHRD_FCFABRIC
+ 6:
361 case ARPHRD_FCFABRIC
+ 7:
363 case ARPHRD_FCFABRIC
+ 8:
365 case ARPHRD_FCFABRIC
+ 9:
367 case ARPHRD_FCFABRIC
+ 10:
369 case ARPHRD_FCFABRIC
+ 11:
371 case ARPHRD_FCFABRIC
+ 12:
373 case ARPHRD_IEEE802_TR
:
375 case ARPHRD_IEEE80211
:
377 case ARPHRD_IEEE80211_PRISM
:
378 return "ieee80211_prism";
379 case ARPHRD_IEEE80211_RADIOTAP
:
380 return "ieee80211_radiotap";
381 case ARPHRD_IEEE802154
:
385 case ARPHRD_PHONET_PIPE
:
386 return "phonet_pipe";
402 /* Taken from iproute2 ll_addr_n2a func */
403 const char *device_addr2str(const unsigned char *addr
, int alen
, int type
,
409 (type
== ARPHRD_TUNNEL
|| type
== ARPHRD_SIT
||
410 type
== ARPHRD_IPGRE
))
411 return inet_ntop(AF_INET
, addr
, buf
, blen
);
413 if (alen
== 16 && type
== ARPHRD_TUNNEL6
)
414 return inet_ntop(AF_INET6
, addr
, buf
, blen
);
416 snprintf(buf
, blen
, "%02x", addr
[0]);
417 for (i
= 1, l
= 2; i
< alen
&& l
< blen
; i
++, l
+= 3)
418 snprintf(buf
+ l
, blen
- l
, ":%02x", addr
[i
]);