* Allocate an address from the FreeBSD Foundation OUI. This uses a * cryptographic hash function on the containing jail's name, UUID and the * interface name to attempt to provide a unique but stable address. * Pseudo-interfaces which require a MAC address should use this function to * allocate non-locally-administered addresses. */
| 1439 | * allocate non-locally-administered addresses. |
| 1440 | */ |
| 1441 | void |
| 1442 | ether_gen_addr(struct ifnet *ifp, struct ether_addr *hwaddr) |
| 1443 | { |
| 1444 | SHA1_CTX ctx; |
| 1445 | char *buf; |
| 1446 | char uuid[HOSTUUIDLEN + 1]; |
| 1447 | uint64_t addr; |
| 1448 | int i, sz; |
| 1449 | char digest[SHA1_RESULTLEN]; |
| 1450 | char jailname[MAXHOSTNAMELEN]; |
| 1451 | |
| 1452 | getcredhostuuid(curthread->td_ucred, uuid, sizeof(uuid)); |
| 1453 | /* If each (vnet) jail would also have a unique hostuuid this would not |
| 1454 | * be necessary. */ |
| 1455 | getjailname(curthread->td_ucred, jailname, sizeof(jailname)); |
| 1456 | sz = asprintf(&buf, M_TEMP, "%s-%s-%s", uuid, if_name(ifp), |
| 1457 | jailname); |
| 1458 | if (sz < 0) { |
| 1459 | /* Fall back to a random mac address. */ |
| 1460 | arc4rand(hwaddr, sizeof(*hwaddr), 0); |
| 1461 | hwaddr->octet[0] = 0x02; |
| 1462 | return; |
| 1463 | } |
| 1464 | |
| 1465 | SHA1Init(&ctx); |
| 1466 | SHA1Update(&ctx, buf, sz); |
| 1467 | SHA1Final(digest, &ctx); |
| 1468 | free(buf, M_TEMP); |
| 1469 | |
| 1470 | addr = ((digest[0] << 16) | (digest[1] << 8) | digest[2]) & |
| 1471 | OUI_FREEBSD_GENERATED_MASK; |
| 1472 | addr = OUI_FREEBSD(addr); |
| 1473 | for (i = 0; i < ETHER_ADDR_LEN; ++i) { |
| 1474 | hwaddr->octet[i] = addr >> ((ETHER_ADDR_LEN - i - 1) * 8) & |
| 1475 | 0xFF; |
| 1476 | } |
| 1477 | } |
| 1478 | |
| 1479 | DECLARE_MODULE(ether, ether_mod, SI_SUB_INIT_IF, SI_ORDER_ANY); |
| 1480 | MODULE_VERSION(ether, 1); |
no test coverage detected