* Get interface identifier for the specified interface. * XXX assumes single sockaddr_dl (AF_LINK address) per an interface * * in6 - upper 64bits are preserved */
| 238 | * in6 - upper 64bits are preserved |
| 239 | */ |
| 240 | int |
| 241 | in6_get_hw_ifid(struct ifnet *ifp, struct in6_addr *in6) |
| 242 | { |
| 243 | struct ifaddr *ifa; |
| 244 | struct sockaddr_dl *sdl; |
| 245 | u_int8_t *addr; |
| 246 | size_t addrlen; |
| 247 | static u_int8_t allzero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 248 | static u_int8_t allone[8] = |
| 249 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
| 250 | |
| 251 | NET_EPOCH_ASSERT(); |
| 252 | |
| 253 | CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { |
| 254 | if (ifa->ifa_addr->sa_family != AF_LINK) |
| 255 | continue; |
| 256 | sdl = (struct sockaddr_dl *)ifa->ifa_addr; |
| 257 | if (sdl == NULL) |
| 258 | continue; |
| 259 | if (sdl->sdl_alen == 0) |
| 260 | continue; |
| 261 | |
| 262 | goto found; |
| 263 | } |
| 264 | |
| 265 | return -1; |
| 266 | |
| 267 | found: |
| 268 | addr = LLADDR(sdl); |
| 269 | addrlen = sdl->sdl_alen; |
| 270 | |
| 271 | /* get EUI64 */ |
| 272 | switch (ifp->if_type) { |
| 273 | case IFT_BRIDGE: |
| 274 | case IFT_ETHER: |
| 275 | case IFT_L2VLAN: |
| 276 | case IFT_ATM: |
| 277 | case IFT_IEEE1394: |
| 278 | /* IEEE802/EUI64 cases - what others? */ |
| 279 | /* IEEE1394 uses 16byte length address starting with EUI64 */ |
| 280 | if (addrlen > 8) |
| 281 | addrlen = 8; |
| 282 | |
| 283 | /* look at IEEE802/EUI64 only */ |
| 284 | if (addrlen != 8 && addrlen != 6) |
| 285 | return -1; |
| 286 | |
| 287 | /* |
| 288 | * check for invalid MAC address - on bsdi, we see it a lot |
| 289 | * since wildboar configures all-zero MAC on pccard before |
| 290 | * card insertion. |
| 291 | */ |
| 292 | if (bcmp(addr, allzero, addrlen) == 0) |
| 293 | return -1; |
| 294 | if (bcmp(addr, allone, addrlen) == 0) |
| 295 | return -1; |
| 296 | |
| 297 | /* make EUI64 address */ |
no outgoing calls
no test coverage detected