|
1 | | -/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. |
| 1 | +/* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. |
2 | 2 |
|
3 | 3 | This program is free software; you can redistribute it and/or modify |
4 | 4 | it under the terms of the GNU General Public License as published by |
@@ -68,30 +68,61 @@ my_bool my_gethwaddr(uchar *to) |
68 | 68 | #include <sys/ioctl.h> |
69 | 69 | #include <net/ethernet.h> |
70 | 70 |
|
| 71 | +#define MAX_IFS 64 |
| 72 | + |
71 | 73 | my_bool my_gethwaddr(uchar *to) |
72 | 74 | { |
73 | | - int fd, res= 1; |
| 75 | + int fd= -1; |
| 76 | + int res= 1; |
74 | 77 | struct ifreq ifr; |
| 78 | + struct ifreq ifs[MAX_IFS]; |
| 79 | + struct ifreq *ifri= NULL; |
| 80 | + struct ifreq *ifend= NULL; |
| 81 | + |
75 | 82 | char zero_array[ETHER_ADDR_LEN] = {0}; |
| 83 | + struct ifconf ifc; |
76 | 84 |
|
77 | 85 | fd = socket(AF_INET, SOCK_DGRAM, 0); |
78 | 86 | if (fd < 0) |
79 | | - goto err; |
| 87 | + return 1; |
| 88 | + |
| 89 | + /* Retrieve interfaces */ |
| 90 | + ifc.ifc_len= sizeof(ifs); |
| 91 | + ifc.ifc_req= ifs; |
| 92 | + if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) |
| 93 | + { |
| 94 | + close(fd); |
| 95 | + return 1; |
| 96 | + } |
| 97 | + |
| 98 | + /* Initialize out parameter */ |
| 99 | + memcpy(to, zero_array, ETHER_ADDR_LEN); |
80 | 100 |
|
81 | | - memset(&ifr, 0, sizeof(ifr)); |
82 | | - strnmov(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name) - 1); |
| 101 | + /* Calculate first address after array */ |
| 102 | + ifend= ifs + (ifc.ifc_len / sizeof(struct ifreq)); |
83 | 103 |
|
84 | | - do |
| 104 | + /* Loop over all interfaces */ |
| 105 | + for (ifri= ifc.ifc_req; ifri < ifend; ifri++) |
85 | 106 | { |
86 | | - if (ioctl(fd, SIOCGIFHWADDR, &ifr) >= 0) |
| 107 | + if (ifri->ifr_addr.sa_family == AF_INET) |
87 | 108 | { |
88 | | - memcpy(to, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); |
89 | | - res= memcmp(to, zero_array, ETHER_ADDR_LEN) ? 0 : 1; |
90 | | - } |
91 | | - } while (res && (errno == 0 || errno == ENODEV) && ifr.ifr_name[3]++ < '6'); |
| 109 | + /* Reset struct, copy interface name */ |
| 110 | + memset(&ifr, 0, sizeof(ifr)); |
| 111 | + strncpy(ifr.ifr_name, ifri->ifr_name, sizeof(ifr.ifr_name)); |
92 | 112 |
|
| 113 | + /* Get HW address, break if not 0 */ |
| 114 | + if (ioctl(fd, SIOCGIFHWADDR, &ifr) >= 0) |
| 115 | + { |
| 116 | + memcpy(to, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); |
| 117 | + if (memcmp(to, zero_array, ETHER_ADDR_LEN)) |
| 118 | + { |
| 119 | + res= 0; |
| 120 | + break; |
| 121 | + } |
| 122 | + } |
| 123 | + } |
| 124 | + } |
93 | 125 | close(fd); |
94 | | -err: |
95 | 126 | return res; |
96 | 127 | } |
97 | 128 |
|
|
0 commit comments