5 #include <sys/socket.h>
6 #include <linux/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 u32
device_bitrate(const char *ifname
)
222 u32 scopper
, swireless
;
224 scopper
= ethtool_bitrate(ifname
);
225 swireless
= wireless_bitrate(ifname
);
227 return scopper
? : swireless
;
230 short device_enter_promiscuous_mode(const char *ifname
)
234 if (!strncmp("any", ifname
, strlen("any")))
237 ifflags
= device_get_flags(ifname
);
238 device_set_flags(ifname
, ifflags
| IFF_PROMISC
);
243 void device_leave_promiscuous_mode(const char *ifname
, short oldflags
)
245 if (!strncmp("any", ifname
, strlen("any")))
248 device_set_flags(ifname
, oldflags
);
251 const char *device_type2str(uint16_t type
)
268 case ARPHRD_APPLETLK
:
274 case ARPHRD_METRICOM
:
276 case ARPHRD_IEEE1394
:
278 case ARPHRD_INFINIBAND
:
318 case ARPHRD_LOOPBACK
:
320 case ARPHRD_LOCALTLK
:
348 case ARPHRD_FCFABRIC
:
350 case ARPHRD_FCFABRIC
+ 1:
352 case ARPHRD_FCFABRIC
+ 2:
354 case ARPHRD_FCFABRIC
+ 3:
356 case ARPHRD_FCFABRIC
+ 4:
358 case ARPHRD_FCFABRIC
+ 5:
360 case ARPHRD_FCFABRIC
+ 6:
362 case ARPHRD_FCFABRIC
+ 7:
364 case ARPHRD_FCFABRIC
+ 8:
366 case ARPHRD_FCFABRIC
+ 9:
368 case ARPHRD_FCFABRIC
+ 10:
370 case ARPHRD_FCFABRIC
+ 11:
372 case ARPHRD_FCFABRIC
+ 12:
374 case ARPHRD_IEEE802_TR
:
376 case ARPHRD_IEEE80211
:
378 case ARPHRD_IEEE80211_PRISM
:
379 return "ieee80211_prism";
380 case ARPHRD_IEEE80211_RADIOTAP
:
381 return "ieee80211_radiotap";
382 case ARPHRD_IEEE802154
:
386 case ARPHRD_PHONET_PIPE
:
387 return "phonet_pipe";
388 #if defined(ARPHRD_CAIF)
405 /* Taken from iproute2 ll_addr_n2a func */
406 const char *device_addr2str(const unsigned char *addr
, int alen
, int type
,
412 (type
== ARPHRD_TUNNEL
|| type
== ARPHRD_SIT
||
413 type
== ARPHRD_IPGRE
))
414 return inet_ntop(AF_INET
, addr
, buf
, blen
);
416 if (alen
== 16 && type
== ARPHRD_TUNNEL6
)
417 return inet_ntop(AF_INET6
, addr
, buf
, blen
);
419 for (l
= 0, i
= 0; i
< alen
; i
++) {
421 snprintf(buf
+ l
, blen
, "%02x", addr
[i
]);
425 snprintf(buf
+ l
, blen
, ":%02x", addr
[i
]);