-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathget_hw_addrs.c
94 lines (84 loc) · 2.75 KB
/
get_hw_addrs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <errno.h> /* error numbers */
#include <sys/ioctl.h> /* ioctls */
#include <net/if.h> /* generic interface structures */
#include <string.h>
#include "hw_addrs.h"
struct hwa_info *
get_hw_addrs()
{
struct hwa_info *hwa, *hwahead, **hwapnext;
int sockfd, len, lastlen, alias;
char *ptr, *buf, lastname[IF_NAME], *cptr;
struct ifconf ifc;
struct ifreq *ifr, ifrcopy;
struct sockaddr *sinptr;
sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
lastlen = 0;
len = 100 * sizeof(struct ifreq); /* initial buffer size guess */
for ( ; ; ) {
buf = (char*) Malloc(len);
ifc.ifc_len = len;
ifc.ifc_buf = buf;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
if (errno != EINVAL || lastlen != 0)
err_sys("ioctl error");
} else {
if (ifc.ifc_len == lastlen)
break; /* success, len has not changed */
lastlen = ifc.ifc_len;
}
len += 10 * sizeof(struct ifreq); /* increment */
free(buf);
}
hwahead = NULL;
hwapnext = &hwahead;
lastname[0] = 0;
for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
ifr = (struct ifreq *) ptr;
len = sizeof(struct sockaddr);
ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */
alias = 0;
hwa = (struct hwa_info *) Calloc(1, sizeof(struct hwa_info));
memcpy(hwa->if_name, ifr->ifr_name, IF_NAME); /* interface name */
hwa->if_name[IF_NAME-1] = '\0';
/* start to check if alias address */
if ( (cptr = (char *) strchr(ifr->ifr_name, ':')) != NULL)
*cptr = 0; /* replace colon will null */
if (strncmp(lastname, ifr->ifr_name, IF_NAME) == 0) {
alias = IP_ALIAS;
}
memcpy(lastname, ifr->ifr_name, IF_NAME);
ifrcopy = *ifr;
*hwapnext = hwa; /* prev points to this new one */
hwapnext = &hwa->hwa_next; /* pointer to next one goes here */
hwa->ip_alias = alias; /* alias IP address flag: 0 if no; 1 if yes */
sinptr = &ifr->ifr_addr;
hwa->ip_addr = (struct sockaddr *) Calloc(1, sizeof(struct sockaddr));
memcpy(hwa->ip_addr, sinptr, sizeof(struct sockaddr)); /* IP address */
Ioctl(sockfd, SIOCGIFHWADDR, &ifrcopy); /* get hw address */
memcpy(hwa->if_haddr, ifrcopy.ifr_hwaddr.sa_data, IF_HADDR);
Ioctl(sockfd, SIOCGIFINDEX, &ifrcopy); /* get interface index */
memcpy(&hwa->if_index, &ifrcopy.ifr_ifindex, sizeof(int));
}
free(buf);
return(hwahead); /* pointer to first structure in linked list */
}
void
free_hwa_info(struct hwa_info *hwahead)
{
struct hwa_info *hwa, *hwanext;
for (hwa = hwahead; hwa != NULL; hwa = hwanext) {
free(hwa->ip_addr);
hwanext = hwa->hwa_next; /* can't fetch hwa_next after free() */
free(hwa); /* the hwa_info{} itself */
}
}
/* end free_hwa_info */
struct hwa_info *
Get_hw_addrs()
{
struct hwa_info *hwa;
if ( (hwa = get_hw_addrs()) == NULL)
err_quit("get_hw_addrs error");
return(hwa);
}