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 if (ifa
->ifa_addr
== NULL
)
87 family
= ifa
->ifa_addr
->sa_family
;
88 if (family
!= AF_INET6
)
90 if (strcmp(ifa
->ifa_name
, ifname
))
93 memcpy(ss
, ifa
->ifa_addr
, sizeof(*ss
));
102 int device_address(const char *ifname
, int af
, struct sockaddr_storage
*ss
)
109 if (!strncmp("any", ifname
, strlen("any")))
112 return __device_address6(ifname
, ss
);
114 sock
= af_socket(af
);
116 memset(&ifr
, 0, sizeof(ifr
));
117 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
119 ifr
.ifr_addr
.sa_family
= af
;
121 ret
= ioctl(sock
, SIOCGIFADDR
, &ifr
);
123 memcpy(ss
, &ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
129 int device_hw_address(const char *ifname
, uint8_t *addr
, size_t len
)
136 if (len
< IFHWADDRLEN
)
138 if (!strncmp("any", ifname
, strlen("any")))
141 sock
= af_socket(AF_INET
);
143 memset(&ifr
, 0, sizeof(ifr
));
144 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
146 ret
= ioctl(sock
, SIOCGIFHWADDR
, &ifr
);
148 memcpy(addr
, &ifr
.ifr_hwaddr
.sa_data
[0], IFHWADDRLEN
);
154 size_t device_mtu(const char *ifname
)
160 sock
= af_socket(AF_INET
);
162 memset(&ifr
, 0, sizeof(ifr
));
163 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
165 ret
= ioctl(sock
, SIOCGIFMTU
, &ifr
);
173 short device_get_flags(const char *ifname
)
179 sock
= af_socket(AF_INET
);
181 memset(&ifr
, 0, sizeof(ifr
));
182 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
184 ret
= ioctl(sock
, SIOCGIFFLAGS
, &ifr
);
186 flags
= ifr
.ifr_flags
;
192 void device_set_flags(const char *ifname
, const short flags
)
197 sock
= af_socket(AF_INET
);
199 memset(&ifr
, 0, sizeof(ifr
));
200 strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
201 ifr
.ifr_flags
= flags
;
203 ret
= ioctl(sock
, SIOCSIFFLAGS
, &ifr
);
204 if (unlikely(ret
< 0))
205 panic("Cannot set NIC flags (%s)!\n", strerror(errno
));
210 int device_up_and_running(const char *ifname
)
214 if (!strncmp("any", ifname
, strlen("any")))
217 return (device_get_flags(ifname
) &
218 (IFF_UP
| IFF_RUNNING
)) ==
219 (IFF_UP
| IFF_RUNNING
);
222 uint32_t device_bitrate(const char *ifname
)
226 scopper
= ethtool_bitrate(ifname
);
228 return scopper
? : wireless_bitrate(ifname
);
231 short device_enter_promiscuous_mode(const char *ifname
)
235 if (!strncmp("any", ifname
, strlen("any")))
238 ifflags
= device_get_flags(ifname
);
239 device_set_flags(ifname
, ifflags
| IFF_PROMISC
);
244 void device_leave_promiscuous_mode(const char *ifname
, short oldflags
)
246 if (!strncmp("any", ifname
, strlen("any")))
249 device_set_flags(ifname
, oldflags
);
252 const char *device_type2str(uint16_t type
)
269 case ARPHRD_APPLETLK
:
275 case ARPHRD_METRICOM
:
277 case ARPHRD_IEEE1394
:
279 case ARPHRD_INFINIBAND
:
319 case ARPHRD_LOOPBACK
:
321 case ARPHRD_LOCALTLK
:
349 case ARPHRD_FCFABRIC
:
351 case ARPHRD_FCFABRIC
+ 1:
353 case ARPHRD_FCFABRIC
+ 2:
355 case ARPHRD_FCFABRIC
+ 3:
357 case ARPHRD_FCFABRIC
+ 4:
359 case ARPHRD_FCFABRIC
+ 5:
361 case ARPHRD_FCFABRIC
+ 6:
363 case ARPHRD_FCFABRIC
+ 7:
365 case ARPHRD_FCFABRIC
+ 8:
367 case ARPHRD_FCFABRIC
+ 9:
369 case ARPHRD_FCFABRIC
+ 10:
371 case ARPHRD_FCFABRIC
+ 11:
373 case ARPHRD_FCFABRIC
+ 12:
375 case ARPHRD_IEEE802_TR
:
377 case ARPHRD_IEEE80211
:
379 case ARPHRD_IEEE80211_PRISM
:
380 return "ieee80211_prism";
381 case ARPHRD_IEEE80211_RADIOTAP
:
382 return "ieee80211_radiotap";
383 case ARPHRD_IEEE802154
:
387 case ARPHRD_PHONET_PIPE
:
388 return "phonet_pipe";
404 /* Taken from iproute2 ll_addr_n2a func */
405 const char *device_addr2str(const unsigned char *addr
, int alen
, int type
,
411 (type
== ARPHRD_TUNNEL
|| type
== ARPHRD_SIT
||
412 type
== ARPHRD_IPGRE
))
413 return inet_ntop(AF_INET
, addr
, buf
, blen
);
415 if (alen
== 16 && type
== ARPHRD_TUNNEL6
)
416 return inet_ntop(AF_INET6
, addr
, buf
, blen
);
418 snprintf(buf
, blen
, "%02x", addr
[0]);
419 for (i
= 1, l
= 2; i
< alen
&& l
< blen
; i
++, l
+= 3)
420 snprintf(buf
+ l
, blen
- l
, ":%02x", addr
[i
]);