| 335 | TASK_INITIALIZER(0, carp_send_ad_all, NULL); |
| 336 | |
| 337 | static void |
| 338 | carp_hmac_prepare(struct carp_softc *sc) |
| 339 | { |
| 340 | uint8_t version = CARP_VERSION, type = CARP_ADVERTISEMENT; |
| 341 | uint8_t vhid = sc->sc_vhid & 0xff; |
| 342 | struct ifaddr *ifa; |
| 343 | int i, found; |
| 344 | #ifdef INET |
| 345 | struct in_addr last, cur, in; |
| 346 | #endif |
| 347 | #ifdef INET6 |
| 348 | struct in6_addr last6, cur6, in6; |
| 349 | #endif |
| 350 | |
| 351 | CARP_LOCK_ASSERT(sc); |
| 352 | |
| 353 | /* Compute ipad from key. */ |
| 354 | bzero(sc->sc_pad, sizeof(sc->sc_pad)); |
| 355 | bcopy(sc->sc_key, sc->sc_pad, sizeof(sc->sc_key)); |
| 356 | for (i = 0; i < sizeof(sc->sc_pad); i++) |
| 357 | sc->sc_pad[i] ^= 0x36; |
| 358 | |
| 359 | /* Precompute first part of inner hash. */ |
| 360 | SHA1Init(&sc->sc_sha1); |
| 361 | SHA1Update(&sc->sc_sha1, sc->sc_pad, sizeof(sc->sc_pad)); |
| 362 | SHA1Update(&sc->sc_sha1, (void *)&version, sizeof(version)); |
| 363 | SHA1Update(&sc->sc_sha1, (void *)&type, sizeof(type)); |
| 364 | SHA1Update(&sc->sc_sha1, (void *)&vhid, sizeof(vhid)); |
| 365 | #ifdef INET |
| 366 | cur.s_addr = 0; |
| 367 | do { |
| 368 | found = 0; |
| 369 | last = cur; |
| 370 | cur.s_addr = 0xffffffff; |
| 371 | CARP_FOREACH_IFA(sc, ifa) { |
| 372 | in.s_addr = ifatoia(ifa)->ia_addr.sin_addr.s_addr; |
| 373 | if (ifa->ifa_addr->sa_family == AF_INET && |
| 374 | ntohl(in.s_addr) > ntohl(last.s_addr) && |
| 375 | ntohl(in.s_addr) < ntohl(cur.s_addr)) { |
| 376 | cur.s_addr = in.s_addr; |
| 377 | found++; |
| 378 | } |
| 379 | } |
| 380 | if (found) |
| 381 | SHA1Update(&sc->sc_sha1, (void *)&cur, sizeof(cur)); |
| 382 | } while (found); |
| 383 | #endif /* INET */ |
| 384 | #ifdef INET6 |
| 385 | memset(&cur6, 0, sizeof(cur6)); |
| 386 | do { |
| 387 | found = 0; |
| 388 | last6 = cur6; |
| 389 | memset(&cur6, 0xff, sizeof(cur6)); |
| 390 | CARP_FOREACH_IFA(sc, ifa) { |
| 391 | in6 = ifatoia6(ifa)->ia_addr.sin6_addr; |
| 392 | if (IN6_IS_SCOPE_EMBED(&in6)) |
| 393 | in6.s6_addr16[1] = 0; |
| 394 | if (ifa->ifa_addr->sa_family == AF_INET6 && |
no test coverage detected