Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/if_ether.c
Show First 20 Lines • Show All 335 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Broadcast an ARP request. Caller specifies: | * Broadcast an ARP request. Caller specifies: | ||||
* - arp header source ip address | * - arp header source ip address | ||||
* - arp header target ip address | * - arp header target ip address | ||||
* - arp header source ethernet address | * - arp header source ethernet address | ||||
*/ | */ | ||||
void | static int | ||||
arprequest(struct ifnet *ifp, const struct in_addr *sip, | arprequest_internal(struct ifnet *ifp, const struct in_addr *sip, | ||||
hselasky: arprequest_sub() is maybe a better name than xxx_int() ? | |||||
Done Inline ActionsI should spell it out like in_pcbinshash_internal() if_attach_internal() or if_detach_internal(). bz: I should spell it out like in_pcbinshash_internal() if_attach_internal() or if_detach_internal… | |||||
const struct in_addr *tip, u_char *enaddr) | const struct in_addr *tip, u_char *enaddr) | ||||
{ | { | ||||
struct mbuf *m; | struct mbuf *m; | ||||
struct arphdr *ah; | struct arphdr *ah; | ||||
struct sockaddr sa; | struct sockaddr sa; | ||||
u_char *carpaddr = NULL; | u_char *carpaddr = NULL; | ||||
uint8_t linkhdr[LLE_MAX_LINKHDR]; | uint8_t linkhdr[LLE_MAX_LINKHDR]; | ||||
size_t linkhdrsize; | size_t linkhdrsize; | ||||
Show All 24 Lines | CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { | ||||
if (0 == ((sip->s_addr ^ tip->s_addr) & | if (0 == ((sip->s_addr ^ tip->s_addr) & | ||||
IA_MASKSIN(ifa)->sin_addr.s_addr)) | IA_MASKSIN(ifa)->sin_addr.s_addr)) | ||||
break; /* found it. */ | break; /* found it. */ | ||||
} | } | ||||
NET_EPOCH_EXIT(et); | NET_EPOCH_EXIT(et); | ||||
if (sip == NULL) { | if (sip == NULL) { | ||||
printf("%s: cannot find matching address\n", __func__); | printf("%s: cannot find matching address\n", __func__); | ||||
return; | return (EADDRNOTAVAIL); | ||||
} | } | ||||
} | } | ||||
if (enaddr == NULL) | if (enaddr == NULL) | ||||
enaddr = carpaddr ? carpaddr : (u_char *)IF_LLADDR(ifp); | enaddr = carpaddr ? carpaddr : (u_char *)IF_LLADDR(ifp); | ||||
if ((m = m_gethdr(M_NOWAIT, MT_DATA)) == NULL) | if ((m = m_gethdr(M_NOWAIT, MT_DATA)) == NULL) | ||||
return; | return (ENOMEM); | ||||
m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) + | m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) + | ||||
2 * ifp->if_addrlen; | 2 * ifp->if_addrlen; | ||||
m->m_pkthdr.len = m->m_len; | m->m_pkthdr.len = m->m_len; | ||||
M_ALIGN(m, m->m_len); | M_ALIGN(m, m->m_len); | ||||
ah = mtod(m, struct arphdr *); | ah = mtod(m, struct arphdr *); | ||||
bzero((caddr_t)ah, m->m_len); | bzero((caddr_t)ah, m->m_len); | ||||
#ifdef MAC | #ifdef MAC | ||||
mac_netinet_arp_send(ifp, m); | mac_netinet_arp_send(ifp, m); | ||||
Show All 10 Lines | #endif | ||||
/* Calculate link header for sending frame */ | /* Calculate link header for sending frame */ | ||||
bzero(&ro, sizeof(ro)); | bzero(&ro, sizeof(ro)); | ||||
linkhdrsize = sizeof(linkhdr); | linkhdrsize = sizeof(linkhdr); | ||||
error = arp_fillheader(ifp, ah, 1, linkhdr, &linkhdrsize); | error = arp_fillheader(ifp, ah, 1, linkhdr, &linkhdrsize); | ||||
if (error != 0 && error != EAFNOSUPPORT) { | if (error != 0 && error != EAFNOSUPPORT) { | ||||
ARP_LOG(LOG_ERR, "Failed to calculate ARP header on %s: %d\n", | ARP_LOG(LOG_ERR, "Failed to calculate ARP header on %s: %d\n", | ||||
if_name(ifp), error); | if_name(ifp), error); | ||||
return; | return (error); | ||||
} | } | ||||
ro.ro_prepend = linkhdr; | ro.ro_prepend = linkhdr; | ||||
ro.ro_plen = linkhdrsize; | ro.ro_plen = linkhdrsize; | ||||
ro.ro_flags = 0; | ro.ro_flags = 0; | ||||
m->m_flags |= M_BCAST; | m->m_flags |= M_BCAST; | ||||
m_clrprotoflags(m); /* Avoid confusing lower layers. */ | m_clrprotoflags(m); /* Avoid confusing lower layers. */ | ||||
(*ifp->if_output)(ifp, m, &sa, &ro); | error = (*ifp->if_output)(ifp, m, &sa, &ro); | ||||
ARPSTAT_INC(txrequests); | ARPSTAT_INC(txrequests); | ||||
if (error) | |||||
ARP_LOG(LOG_DEBUG, "Failed to send ARP packet on %s: %d\n", | |||||
karelsUnsubmitted Done Inline ActionsI wonder if this log should be rate-limited? karels: I wonder if this log should be rate-limited? | |||||
bzAuthorUnsubmitted Done Inline ActionsThey all are: 164 #define ARP_LOG(pri, ...) do { \ 165 if (ppsratecheck(&arp_lastlog, &arp_curpps, arp_maxpps)) \ 166 log((pri), "arp: " __VA_ARGS__); \ 167 } while (0) bz: They all are:
164 #define ARP_LOG(pri, ...) do { \… | |||||
karelsUnsubmitted Not Done Inline ActionsNever mind, I see that ARP_LOG *is* rate-limited. karels: Never mind, I see that ARP_LOG *is* rate-limited. | |||||
if_name(ifp), error); | |||||
return (error); | |||||
} | } | ||||
void | |||||
arprequest(struct ifnet *ifp, const struct in_addr *sip, | |||||
const struct in_addr *tip, u_char *enaddr) | |||||
{ | |||||
(void) arprequest_internal(ifp, sip, tip, enaddr); | |||||
} | |||||
/* | /* | ||||
* Resolve an IP address into an ethernet address - heavy version. | * Resolve an IP address into an ethernet address - heavy version. | ||||
* Used internally by arpresolve(). | * Used internally by arpresolve(). | ||||
* We have already checked that we can't use an existing lle without | * We have already checked that we can't use an existing lle without | ||||
* modification so we have to acquire an LLE_EXCLUSIVE lle lock. | * modification so we have to acquire an LLE_EXCLUSIVE lle lock. | ||||
* | * | ||||
* On success, desten and pflags are filled in and the function returns 0; | * On success, desten and pflags are filled in and the function returns 0; | ||||
* If the packet must be held pending resolution, we return EWOULDBLOCK | * If the packet must be held pending resolution, we return EWOULDBLOCK | ||||
▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | arpresolve_full(struct ifnet *ifp, int is_gw, int flags, struct mbuf *m, | ||||
* ARP request, but not faster than one request per second. | * ARP request, but not faster than one request per second. | ||||
*/ | */ | ||||
if (la->la_asked < V_arp_maxtries) | if (la->la_asked < V_arp_maxtries) | ||||
error = EWOULDBLOCK; /* First request. */ | error = EWOULDBLOCK; /* First request. */ | ||||
else | else | ||||
error = is_gw != 0 ? EHOSTUNREACH : EHOSTDOWN; | error = is_gw != 0 ? EHOSTUNREACH : EHOSTDOWN; | ||||
if (renew) { | if (renew) { | ||||
int canceled; | int canceled, e; | ||||
LLE_ADDREF(la); | LLE_ADDREF(la); | ||||
la->la_expire = time_uptime; | la->la_expire = time_uptime; | ||||
canceled = callout_reset(&la->lle_timer, hz * V_arpt_down, | canceled = callout_reset(&la->lle_timer, hz * V_arpt_down, | ||||
arptimer, la); | arptimer, la); | ||||
if (canceled) | if (canceled) | ||||
LLE_REMREF(la); | LLE_REMREF(la); | ||||
la->la_asked++; | la->la_asked++; | ||||
LLE_WUNLOCK(la); | LLE_WUNLOCK(la); | ||||
arprequest(ifp, NULL, &SIN(dst)->sin_addr, NULL); | e = arprequest_internal(ifp, NULL, &SIN(dst)->sin_addr, NULL); | ||||
/* | |||||
* Only overwrite 'error' in case of error; in case of success | |||||
* the proper return value was already set above. | |||||
*/ | |||||
if (e != 0) | |||||
return (e); | |||||
return (error); | return (error); | ||||
} | } | ||||
LLE_WUNLOCK(la); | LLE_WUNLOCK(la); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 913 Lines • Show Last 20 Lines |
arprequest_sub() is maybe a better name than xxx_int() ?