* Lookups link header based on an IP address. * On input: * ifp is the interface we use * is_gw != 0 if @dst represents gateway to some destination * m is the mbuf. May be NULL if we don't have a packet. * dst is the next hop, * desten is the storage to put LL header. * flags returns subset of lle flags: LLE_VALID | LLE_IFADDR * * On success, full/partial link header and
| 622 | * Note that m_freem() handles NULL. |
| 623 | */ |
| 624 | int |
| 625 | arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m, |
| 626 | const struct sockaddr *dst, u_char *desten, uint32_t *pflags, |
| 627 | struct llentry **plle) |
| 628 | { |
| 629 | struct llentry *la = NULL; |
| 630 | |
| 631 | NET_EPOCH_ASSERT(); |
| 632 | |
| 633 | if (pflags != NULL) |
| 634 | *pflags = 0; |
| 635 | if (plle != NULL) |
| 636 | *plle = NULL; |
| 637 | |
| 638 | if (m != NULL) { |
| 639 | if (m->m_flags & M_BCAST) { |
| 640 | /* broadcast */ |
| 641 | (void)memcpy(desten, |
| 642 | ifp->if_broadcastaddr, ifp->if_addrlen); |
| 643 | return (0); |
| 644 | } |
| 645 | if (m->m_flags & M_MCAST) { |
| 646 | /* multicast */ |
| 647 | ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten); |
| 648 | return (0); |
| 649 | } |
| 650 | } |
| 651 | |
| 652 | la = lla_lookup(LLTABLE(ifp), plle ? LLE_EXCLUSIVE : LLE_UNLOCKED, dst); |
| 653 | if (la != NULL && (la->r_flags & RLLE_VALID) != 0) { |
| 654 | /* Entry found, let's copy lle info */ |
| 655 | bcopy(la->r_linkdata, desten, la->r_hdrlen); |
| 656 | if (pflags != NULL) |
| 657 | *pflags = LLE_VALID | (la->r_flags & RLLE_IFADDR); |
| 658 | /* Notify the LLE handling code that the entry was used. */ |
| 659 | llentry_mark_used(la); |
| 660 | if (plle) { |
| 661 | LLE_ADDREF(la); |
| 662 | *plle = la; |
| 663 | LLE_WUNLOCK(la); |
| 664 | } |
| 665 | return (0); |
| 666 | } |
| 667 | if (plle && la) |
| 668 | LLE_WUNLOCK(la); |
| 669 | |
| 670 | return (arpresolve_full(ifp, is_gw, la == NULL ? LLE_CREATE : 0, m, dst, |
| 671 | desten, pflags, plle)); |
| 672 | } |
| 673 | |
| 674 | /* |
| 675 | * Common length and type checks are done here, |
no test coverage detected