File Coverage

ulib/node.c
Criterion Covered Total %
statement 21 30 70.0
branch 13 26 50.0
condition n/a
subroutine n/a
pod n/a
total 34 56 60.7


line stmt bran cond sub pod time code
1             #ifdef __cplusplus
2             extern "C" {
3             #endif
4              
5             #include "ulib/node.h"
6              
7             #ifdef __cplusplus
8             }
9             #endif
10              
11             /*
12             * BSD 4.4 defines the size of an ifreq to be
13             * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
14             * However, under earlier systems, sa_len isn't present, so the size is
15             * just sizeof(struct ifreq)
16             */
17             #ifndef max
18             # define max(a,b) ((a) > (b) ? (a) : (b))
19             #endif
20             #ifdef HAVE_SA_LEN
21             # define ifreq_size(i) \
22             max( \
23             sizeof(struct ifreq), \
24             sizeof((i).ifr_name) + (i).ifr_addr.sa_len \
25             )
26             #else
27             # define ifreq_size(i) sizeof(struct ifreq)
28             #endif /* HAVE_SA_LEN*/
29              
30 156           static int try_unix_node(pUCXT, U8 *node_id){
31             #ifdef HAVE_NET_IF_H
32             struct ifconf ifc;
33             struct ifreq ifr, *ifrp;
34             #ifdef HAVE_NET_IF_DL_H
35             struct sockaddr_dl *sdlp;
36             #endif
37             unsigned char *a;
38             int i, n, sd;
39             char buf[1024];
40              
41 156 50         if ((sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0)
42 0           return -1;
43              
44 156           Zero(buf, sizeof(buf), char);
45 156           ifc.ifc_len = sizeof(buf);
46 156           ifc.ifc_buf = buf;
47              
48 156 50         if (ioctl(sd, SIOCGIFCONF, (char*)&ifc) < 0) {
49 0           close(sd);
50 0           return -1;
51             }
52              
53 156           n = ifc.ifc_len;
54 312 50         for (i = 0 ; i < n ; i += ifreq_size(*ifrp)) {
55 312           ifrp = (struct ifreq*)((char*)ifc.ifc_buf + i);
56 312           Copy(ifrp->ifr_name, ifr.ifr_name, IFNAMSIZ, char);
57              
58             #if defined(SIOCGIFHWADDR) && ( defined(ifr_hwaddr) || defined(ifr_addr) )
59 312 50         if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
60 0           continue;
61             # ifdef ifr_hwaddr
62 312           a = (unsigned char*)&ifr.ifr_hwaddr.sa_data;
63             # else
64             # ifdef ifr_addr
65             a = (unsigned char*)&ifr.ifr_addr.sa_data;
66             # endif /* ifr_addr */
67             # endif /* ifr_hwaddr */
68             #else
69             # ifdef SIOCGENADDR
70             if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
71             continue;
72             a = (unsigned char*)ifr.ifr_enaddr;
73             # else
74             # ifdef HAVE_NET_IF_DL_H
75             sdlp = (struct sockaddr_dl*)&ifrp->ifr_addr;
76             if ((sdlp->sdl_family != AF_LINK) || (sdlp->sdl_alen != 6))
77             continue;
78             a = (unsigned char*)&sdlp->sdl_data[sdlp->sdl_nlen];
79             # else
80             /* XXX any other way of finding hardware address? */
81             close(sd);
82             return 0;
83             # endif /* HAVE_NET_IF_DL_H */
84             # endif /* SIOCGENADDR */
85             #endif /*SIOCGIFHWADDR */
86              
87 312 100         if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
    50          
    50          
    50          
    50          
    50          
88 156           continue;
89 156 50         if (node_id) {
90 156           memcpy(node_id, a, 6);
91 156           close(sd);
92 156           return 1;
93             }
94             }
95 0           close(sd);
96             #endif /* HAVE_NET_IF_H */
97 0           return 0;
98             }
99              
100 0           static int try_windows_node(pUCXT, U8 *node_id) {
101 0           int rv = 0;
102             #ifdef USE_WIN32_NATIVE
103             #ifdef HAVE_IPHLPAPI_H
104             IP_ADAPTER_ADDRESSES *pAddr = NULL;
105             IP_ADAPTER_ADDRESSES *pCurr = NULL;
106             DWORD dwRetVal = 0;
107             ULONG outBufLen = 8 * 1024;
108             unsigned int i;
109              
110             rv = -1;
111             for (i = 0 ; i < 3 ; ++i) {
112             Newc(0, pAddr, outBufLen, char, IP_ADAPTER_ADDRESSES);
113             if (pAddr == NULL) break;
114              
115             dwRetVal = GetAdaptersAddresses(AF_INET, 0, NULL, pAddr, &outBufLen);
116              
117             if (dwRetVal == ERROR_SUCCESS) {
118             rv = 0;
119             break;
120             }
121             if (dwRetVal != ERROR_BUFFER_OVERFLOW) {
122             break;
123             }
124             Safefree(pAddr);
125             pAddr = NULL;
126             }
127              
128             if (rv == 0) {
129             pCurr = pAddr;
130             while (pCurr) {
131             if (
132             pCurr->OperStatus == IfOperStatusUp
133             &&
134             pCurr->IfType != IF_TYPE_SOFTWARE_LOOPBACK
135             &&
136             pCurr->PhysicalAddressLength == 6
137             ) {
138             /*
139             printf("# Physical address:\n");
140             for (i = 0; i < (int) pCurr->PhysicalAddressLength; i++) {
141             if (i == (pCurr->PhysicalAddressLength - 1))
142             printf("# %.2X\n", (int) pCurr->PhysicalAddress[i]);
143             else
144             printf("# %.2X-", (int) pCurr->PhysicalAddress[i]);
145             }
146             */
147             node_id[0] = pCurr->PhysicalAddress[0];
148             node_id[1] = pCurr->PhysicalAddress[1];
149             node_id[2] = pCurr->PhysicalAddress[2];
150             node_id[3] = pCurr->PhysicalAddress[3];
151             node_id[4] = pCurr->PhysicalAddress[4];
152             node_id[5] = pCurr->PhysicalAddress[5];
153             rv = 1;
154             break;
155             }
156             pCurr = pCurr->Next;
157             }
158             }
159              
160             if (pAddr)
161             Safefree(pAddr);
162             #endif /* HAVE_IPHLPAPI_H */
163             #endif /* USE_WIN32_NATIVE */
164 0           return rv;
165             }
166              
167 156           int uu_get_node_id(pUCXT, U8 *node_id) {
168             /* returns:
169             * -1 if cant find due to error.
170             * 0 if cant find.
171             * 1 if found.
172             */
173 156           return try_unix_node(aUCXT, node_id)
174 156 50         || try_windows_node(aUCXT, node_id);
    0          
175             }
176              
177             /* ex:set ts=2 sw=2 itab=spaces: */