Reorganize and extract arplookup1() for code-sharing. Share
null_sdl. Introduce arp_setgate() for initializing a link-layer nexthop, and use it to fulfill RTM_SETGATE requests.
This commit is contained in:
parent
ae7a571b06
commit
7caec74f02
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: if_arp.c,v 1.125 2007/07/19 20:48:53 dyoung Exp $ */
|
/* $NetBSD: if_arp.c,v 1.126 2007/08/27 01:13:09 dyoung Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
|
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.125 2007/07/19 20:48:53 dyoung Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.126 2007/08/27 01:13:09 dyoung Exp $");
|
||||||
|
|
||||||
#include "opt_ddb.h"
|
#include "opt_ddb.h"
|
||||||
#include "opt_inet.h"
|
#include "opt_inet.h"
|
||||||
|
@ -130,7 +130,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.125 2007/07/19 20:48:53 dyoung Exp $");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SIN(s) ((struct sockaddr_in *)s)
|
#define SIN(s) ((struct sockaddr_in *)s)
|
||||||
#define SDL(s) ((struct sockaddr_dl *)s)
|
|
||||||
#define SRP(s) ((struct sockaddr_inarp *)s)
|
#define SRP(s) ((struct sockaddr_inarp *)s)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -147,8 +146,12 @@ int arpt_refresh = (5*60); /* time left before refreshing */
|
||||||
#define rt_expire rt_rmx.rmx_expire
|
#define rt_expire rt_rmx.rmx_expire
|
||||||
#define rt_pksent rt_rmx.rmx_pksent
|
#define rt_pksent rt_rmx.rmx_pksent
|
||||||
|
|
||||||
|
static struct sockaddr *arp_setgate(struct rtentry *, struct sockaddr *,
|
||||||
|
const struct sockaddr *);
|
||||||
static void arptfree(struct llinfo_arp *);
|
static void arptfree(struct llinfo_arp *);
|
||||||
static void arptimer(void *);
|
static void arptimer(void *);
|
||||||
|
static struct llinfo_arp *arplookup1(struct mbuf *, const struct in_addr *,
|
||||||
|
int, int, struct rtentry *);
|
||||||
static struct llinfo_arp *arplookup(struct mbuf *, const struct in_addr *,
|
static struct llinfo_arp *arplookup(struct mbuf *, const struct in_addr *,
|
||||||
int, int);
|
int, int);
|
||||||
static void in_arpinput(struct mbuf *);
|
static void in_arpinput(struct mbuf *);
|
||||||
|
@ -169,6 +172,9 @@ int arpinit_done = 0;
|
||||||
struct arpstat arpstat;
|
struct arpstat arpstat;
|
||||||
struct callout arptimer_ch;
|
struct callout arptimer_ch;
|
||||||
|
|
||||||
|
/* Prototype for RTF_CLONING routes. */
|
||||||
|
static const struct sockaddr_dl null_sdl = { .sdl_len = sizeof(null_sdl),
|
||||||
|
.sdl_family = AF_LINK};
|
||||||
|
|
||||||
/* revarp state */
|
/* revarp state */
|
||||||
struct in_addr myip, srv_ip;
|
struct in_addr myip, srv_ip;
|
||||||
|
@ -381,6 +387,35 @@ arptimer(void *arg)
|
||||||
splx(s);
|
splx(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We set the gateway for RTF_CLONING routes to a "prototype"
|
||||||
|
* link-layer sockaddr whose interface type (if_type) and interface
|
||||||
|
* index (if_index) fields are prepared.
|
||||||
|
*/
|
||||||
|
static struct sockaddr *
|
||||||
|
arp_setgate(struct rtentry *rt, struct sockaddr *gate,
|
||||||
|
const struct sockaddr *netmask)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* XXX: If this is a manually added route to interface
|
||||||
|
* such as older version of routed or gated might provide,
|
||||||
|
* restore cloning bit.
|
||||||
|
*/
|
||||||
|
if ((rt->rt_flags & RTF_HOST) == 0 && netmask != NULL &&
|
||||||
|
satocsin(netmask)->sin_addr.s_addr != 0xffffffff)
|
||||||
|
rt->rt_flags |= RTF_CLONING;
|
||||||
|
if (rt->rt_flags & RTF_CLONING) {
|
||||||
|
/*
|
||||||
|
* Case 1: This route should come from a route to iface.
|
||||||
|
*/
|
||||||
|
rt_setgate(rt, (const struct sockaddr *)&null_sdl);
|
||||||
|
gate = rt->rt_gateway;
|
||||||
|
satosdl(gate)->sdl_type = rt->rt_ifp->if_type;
|
||||||
|
satosdl(gate)->sdl_index = rt->rt_ifp->if_index;
|
||||||
|
}
|
||||||
|
return gate;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parallel to llc_rtrequest.
|
* Parallel to llc_rtrequest.
|
||||||
*/
|
*/
|
||||||
|
@ -389,10 +424,6 @@ arp_rtrequest(int req, struct rtentry *rt, struct rt_addrinfo *info)
|
||||||
{
|
{
|
||||||
struct sockaddr *gate = rt->rt_gateway;
|
struct sockaddr *gate = rt->rt_gateway;
|
||||||
struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
|
struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
|
||||||
static const struct sockaddr_dl null_sdl = {
|
|
||||||
.sdl_len = sizeof(null_sdl),
|
|
||||||
.sdl_family = AF_LINK,
|
|
||||||
};
|
|
||||||
size_t allocsize;
|
size_t allocsize;
|
||||||
struct mbuf *mold;
|
struct mbuf *mold;
|
||||||
int s;
|
int s;
|
||||||
|
@ -455,23 +486,12 @@ arp_rtrequest(int req, struct rtentry *rt, struct rt_addrinfo *info)
|
||||||
|
|
||||||
switch (req) {
|
switch (req) {
|
||||||
|
|
||||||
|
case RTM_SETGATE:
|
||||||
|
gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]);
|
||||||
|
break;
|
||||||
case RTM_ADD:
|
case RTM_ADD:
|
||||||
/*
|
gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]);
|
||||||
* XXX: If this is a manually added route to interface
|
|
||||||
* such as older version of routed or gated might provide,
|
|
||||||
* restore cloning bit.
|
|
||||||
*/
|
|
||||||
if ((rt->rt_flags & RTF_HOST) == 0 &&
|
|
||||||
satocsin(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
|
|
||||||
rt->rt_flags |= RTF_CLONING;
|
|
||||||
if (rt->rt_flags & RTF_CLONING) {
|
if (rt->rt_flags & RTF_CLONING) {
|
||||||
/*
|
|
||||||
* Case 1: This route should come from a route to iface.
|
|
||||||
*/
|
|
||||||
rt_setgate(rt, (const struct sockaddr *)&null_sdl);
|
|
||||||
gate = rt->rt_gateway;
|
|
||||||
SDL(gate)->sdl_type = rt->rt_ifp->if_type;
|
|
||||||
SDL(gate)->sdl_index = rt->rt_ifp->if_index;
|
|
||||||
/*
|
/*
|
||||||
* Give this route an expiration time, even though
|
* Give this route an expiration time, even though
|
||||||
* it's a "permanent" route, so that routes cloned
|
* it's a "permanent" route, so that routes cloned
|
||||||
|
@ -516,7 +536,7 @@ arp_rtrequest(int req, struct rtentry *rt, struct rt_addrinfo *info)
|
||||||
arprequest(rt->rt_ifp,
|
arprequest(rt->rt_ifp,
|
||||||
&satocsin(rt_getkey(rt))->sin_addr,
|
&satocsin(rt_getkey(rt))->sin_addr,
|
||||||
&satocsin(rt_getkey(rt))->sin_addr,
|
&satocsin(rt_getkey(rt))->sin_addr,
|
||||||
(u_char *)LLADDR(SDL(gate)));
|
CLLADDR(satocsdl(gate)));
|
||||||
/*FALLTHROUGH*/
|
/*FALLTHROUGH*/
|
||||||
case RTM_RESOLVE:
|
case RTM_RESOLVE:
|
||||||
if (gate->sa_family != AF_LINK ||
|
if (gate->sa_family != AF_LINK ||
|
||||||
|
@ -524,15 +544,15 @@ arp_rtrequest(int req, struct rtentry *rt, struct rt_addrinfo *info)
|
||||||
log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n");
|
log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
SDL(gate)->sdl_type = rt->rt_ifp->if_type;
|
satosdl(gate)->sdl_type = rt->rt_ifp->if_type;
|
||||||
SDL(gate)->sdl_index = rt->rt_ifp->if_index;
|
satosdl(gate)->sdl_index = rt->rt_ifp->if_index;
|
||||||
if (la != 0)
|
if (la != 0)
|
||||||
break; /* This happens on a route change */
|
break; /* This happens on a route change */
|
||||||
/*
|
/*
|
||||||
* Case 2: This route may come from cloning, or a manual route
|
* Case 2: This route may come from cloning, or a manual route
|
||||||
* add with a LL address.
|
* add with a LL address.
|
||||||
*/
|
*/
|
||||||
switch (SDL(gate)->sdl_type) {
|
switch (satocsdl(gate)->sdl_type) {
|
||||||
#if NTOKEN > 0
|
#if NTOKEN > 0
|
||||||
case IFT_ISO88025:
|
case IFT_ISO88025:
|
||||||
allocsize = sizeof(*la) + sizeof(struct token_rif);
|
allocsize = sizeof(*la) + sizeof(struct token_rif);
|
||||||
|
@ -575,9 +595,9 @@ arp_rtrequest(int req, struct rtentry *rt, struct rt_addrinfo *info)
|
||||||
* interface.
|
* interface.
|
||||||
*/
|
*/
|
||||||
rt->rt_expire = 0;
|
rt->rt_expire = 0;
|
||||||
Bcopy(LLADDR(rt->rt_ifp->if_sadl),
|
(void)sockaddr_dl_setaddr(satosdl(gate),
|
||||||
LLADDR(SDL(gate)),
|
CLLADDR(rt->rt_ifp->if_sadl),
|
||||||
SDL(gate)->sdl_alen = rt->rt_ifp->if_addrlen);
|
rt->rt_ifp->if_addrlen);
|
||||||
if (useloopback)
|
if (useloopback)
|
||||||
rt->rt_ifp = lo0ifp;
|
rt->rt_ifp = lo0ifp;
|
||||||
/*
|
/*
|
||||||
|
@ -683,16 +703,13 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
|
||||||
const struct sockaddr *dst, u_char *desten)
|
const struct sockaddr *dst, u_char *desten)
|
||||||
{
|
{
|
||||||
struct llinfo_arp *la;
|
struct llinfo_arp *la;
|
||||||
struct sockaddr_dl *sdl;
|
const struct sockaddr_dl *sdl;
|
||||||
struct mbuf *mold;
|
struct mbuf *mold;
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
if (rt)
|
if ((la = arplookup1(m, &satocsin(dst)->sin_addr, 1, 0, rt)) != NULL)
|
||||||
la = (struct llinfo_arp *)rt->rt_llinfo;
|
rt = la->la_rt;
|
||||||
else {
|
|
||||||
if ((la = arplookup(m, &satocsin(dst)->sin_addr, 1, 0)) != NULL)
|
|
||||||
rt = la->la_rt;
|
|
||||||
}
|
|
||||||
if (la == 0 || rt == 0) {
|
if (la == 0 || rt == 0) {
|
||||||
arpstat.as_allocfail++;
|
arpstat.as_allocfail++;
|
||||||
log(LOG_DEBUG,
|
log(LOG_DEBUG,
|
||||||
|
@ -701,14 +718,14 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
sdl = SDL(rt->rt_gateway);
|
sdl = satocsdl(rt->rt_gateway);
|
||||||
/*
|
/*
|
||||||
* Check the address family and length is valid, the address
|
* Check the address family and length is valid, the address
|
||||||
* is resolved; otherwise, try to resolve.
|
* is resolved; otherwise, try to resolve.
|
||||||
*/
|
*/
|
||||||
if ((rt->rt_expire == 0 || rt->rt_expire > time_second) &&
|
if ((rt->rt_expire == 0 || rt->rt_expire > time_second) &&
|
||||||
sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
|
sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
|
||||||
bcopy(LLADDR(sdl), desten,
|
bcopy(CLLADDR(sdl), desten,
|
||||||
min(sdl->sdl_alen, ifp->if_addrlen));
|
min(sdl->sdl_alen, ifp->if_addrlen));
|
||||||
rt->rt_pksent = time_second; /* Time for last pkt sent */
|
rt->rt_pksent = time_second; /* Time for last pkt sent */
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -970,8 +987,7 @@ in_arpinput(struct mbuf *m)
|
||||||
myaddr = ia->ia_addr.sin_addr;
|
myaddr = ia->ia_addr.sin_addr;
|
||||||
|
|
||||||
/* XXX checks for bridge case? */
|
/* XXX checks for bridge case? */
|
||||||
if (!memcmp(ar_sha(ah), LLADDR(ifp->if_sadl),
|
if (!memcmp(ar_sha(ah), CLLADDR(ifp->if_sadl), ifp->if_addrlen)) {
|
||||||
ifp->if_addrlen)) {
|
|
||||||
arpstat.as_rcvlocalsha++;
|
arpstat.as_rcvlocalsha++;
|
||||||
goto out; /* it's from me, ignore it. */
|
goto out; /* it's from me, ignore it. */
|
||||||
}
|
}
|
||||||
|
@ -994,9 +1010,9 @@ in_arpinput(struct mbuf *m)
|
||||||
goto reply;
|
goto reply;
|
||||||
}
|
}
|
||||||
la = arplookup(m, &isaddr, in_hosteq(itaddr, myaddr), 0);
|
la = arplookup(m, &isaddr, in_hosteq(itaddr, myaddr), 0);
|
||||||
if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) {
|
if (la && (rt = la->la_rt) && (sdl = satosdl(rt->rt_gateway))) {
|
||||||
if (sdl->sdl_alen &&
|
if (sdl->sdl_alen &&
|
||||||
memcmp(ar_sha(ah), LLADDR(sdl), sdl->sdl_alen)) {
|
memcmp(ar_sha(ah), CLLADDR(sdl), sdl->sdl_alen)) {
|
||||||
if (rt->rt_flags & RTF_STATIC) {
|
if (rt->rt_flags & RTF_STATIC) {
|
||||||
arpstat.as_rcvoverperm++;
|
arpstat.as_rcvoverperm++;
|
||||||
log(LOG_INFO,
|
log(LOG_INFO,
|
||||||
|
@ -1069,7 +1085,7 @@ in_arpinput(struct mbuf *m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* NTOKEN > 0 */
|
#endif /* NTOKEN > 0 */
|
||||||
memcpy(LLADDR(sdl), ar_sha(ah), sdl->sdl_alen = ah->ar_hln);
|
(void)sockaddr_dl_setaddr(sdl, ar_sha(ah), ah->ar_hln);
|
||||||
if (rt->rt_expire)
|
if (rt->rt_expire)
|
||||||
rt->rt_expire = time_second + arpt_keep;
|
rt->rt_expire = time_second + arpt_keep;
|
||||||
rt->rt_flags &= ~RTF_REJECT;
|
rt->rt_flags &= ~RTF_REJECT;
|
||||||
|
@ -1099,7 +1115,7 @@ reply:
|
||||||
tha = ar_tha(ah);
|
tha = ar_tha(ah);
|
||||||
if (tha)
|
if (tha)
|
||||||
memcpy(tha, ar_sha(ah), ah->ar_hln);
|
memcpy(tha, ar_sha(ah), ah->ar_hln);
|
||||||
memcpy(ar_sha(ah), LLADDR(ifp->if_sadl), ah->ar_hln);
|
memcpy(ar_sha(ah), CLLADDR(ifp->if_sadl), ah->ar_hln);
|
||||||
} else {
|
} else {
|
||||||
la = arplookup(m, &itaddr, 0, SIN_PROXY);
|
la = arplookup(m, &itaddr, 0, SIN_PROXY);
|
||||||
if (la == 0)
|
if (la == 0)
|
||||||
|
@ -1111,8 +1127,8 @@ reply:
|
||||||
tha = ar_tha(ah);
|
tha = ar_tha(ah);
|
||||||
if (tha)
|
if (tha)
|
||||||
memcpy(tha, ar_sha(ah), ah->ar_hln);
|
memcpy(tha, ar_sha(ah), ah->ar_hln);
|
||||||
sdl = SDL(rt->rt_gateway);
|
sdl = satosdl(rt->rt_gateway);
|
||||||
memcpy(ar_sha(ah), LLADDR(sdl), ah->ar_hln);
|
memcpy(ar_sha(ah), CLLADDR(sdl), ah->ar_hln);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(ar_tpa(ah), ar_spa(ah), ah->ar_pln);
|
memcpy(ar_tpa(ah), ar_spa(ah), ah->ar_pln);
|
||||||
|
@ -1155,7 +1171,7 @@ static void arptfree(struct llinfo_arp *la)
|
||||||
|
|
||||||
if (rt == 0)
|
if (rt == 0)
|
||||||
panic("arptfree");
|
panic("arptfree");
|
||||||
if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) &&
|
if (rt->rt_refcnt > 0 && (sdl = satosdl(rt->rt_gateway)) &&
|
||||||
sdl->sdl_family == AF_LINK) {
|
sdl->sdl_family == AF_LINK) {
|
||||||
sdl->sdl_alen = 0;
|
sdl->sdl_alen = 0;
|
||||||
la->la_asked = 0;
|
la->la_asked = 0;
|
||||||
|
@ -1165,11 +1181,18 @@ static void arptfree(struct llinfo_arp *la)
|
||||||
rtrequest(RTM_DELETE, rt_getkey(rt), NULL, rt_mask(rt), 0, NULL);
|
rtrequest(RTM_DELETE, rt_getkey(rt), NULL, rt_mask(rt), 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct llinfo_arp *
|
||||||
|
arplookup(struct mbuf *m, const struct in_addr *addr, int create, int proxy)
|
||||||
|
{
|
||||||
|
return arplookup1(m, addr, create, proxy, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup or enter a new address in arptab.
|
* Lookup or enter a new address in arptab.
|
||||||
*/
|
*/
|
||||||
static struct llinfo_arp *
|
static struct llinfo_arp *
|
||||||
arplookup(struct mbuf *m, const struct in_addr *addr, int create, int proxy)
|
arplookup1(struct mbuf *m, const struct in_addr *addr, int create, int proxy,
|
||||||
|
struct rtentry *rt0)
|
||||||
{
|
{
|
||||||
struct arphdr *ah;
|
struct arphdr *ah;
|
||||||
struct ifnet *ifp = m->m_pkthdr.rcvif;
|
struct ifnet *ifp = m->m_pkthdr.rcvif;
|
||||||
|
@ -1178,21 +1201,26 @@ arplookup(struct mbuf *m, const struct in_addr *addr, int create, int proxy)
|
||||||
const char *why = 0;
|
const char *why = 0;
|
||||||
|
|
||||||
ah = mtod(m, struct arphdr *);
|
ah = mtod(m, struct arphdr *);
|
||||||
sin.sin_len = sizeof(sin);
|
if (rt0 == NULL) {
|
||||||
sin.sin_family = AF_INET;
|
sin.sin_len = sizeof(sin);
|
||||||
sin.sin_addr = *addr;
|
sin.sin_family = AF_INET;
|
||||||
sin.sin_other = proxy ? SIN_PROXY : 0;
|
sin.sin_addr = *addr;
|
||||||
rt = rtalloc1(sintosa(&sin), create);
|
sin.sin_other = proxy ? SIN_PROXY : 0;
|
||||||
if (rt == 0)
|
rt = rtalloc1(sintosa(&sin), create);
|
||||||
return (0);
|
if (rt == NULL)
|
||||||
rt->rt_refcnt--;
|
return (NULL);
|
||||||
|
rt->rt_refcnt--;
|
||||||
|
} else
|
||||||
|
rt = rt0;
|
||||||
|
|
||||||
if ((rt->rt_flags & (RTF_GATEWAY | RTF_LLINFO)) == RTF_LLINFO &&
|
#define IS_LLINFO(__rt) \
|
||||||
rt->rt_gateway->sa_family == AF_LINK)
|
(((__rt)->rt_flags & (RTF_GATEWAY | RTF_LLINFO)) == RTF_LLINFO && \
|
||||||
|
(__rt)->rt_gateway->sa_family == AF_LINK)
|
||||||
|
|
||||||
|
|
||||||
|
if (IS_LLINFO(rt))
|
||||||
return ((struct llinfo_arp *)rt->rt_llinfo);
|
return ((struct llinfo_arp *)rt->rt_llinfo);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (create) {
|
if (create) {
|
||||||
if (rt->rt_flags & RTF_GATEWAY)
|
if (rt->rt_flags & RTF_GATEWAY)
|
||||||
why = "host is not on local network";
|
why = "host is not on local network";
|
||||||
|
@ -1320,7 +1348,7 @@ in_revarpinput(struct mbuf *m)
|
||||||
goto wake;
|
goto wake;
|
||||||
tha = ar_tha(ah);
|
tha = ar_tha(ah);
|
||||||
KASSERT(tha);
|
KASSERT(tha);
|
||||||
if (bcmp(tha, LLADDR(ifp->if_sadl), ifp->if_sadl->sdl_alen))
|
if (bcmp(tha, CLLADDR(ifp->if_sadl), ifp->if_sadl->sdl_alen))
|
||||||
goto out;
|
goto out;
|
||||||
memcpy(&srv_ip, ar_spa(ah), sizeof(srv_ip));
|
memcpy(&srv_ip, ar_spa(ah), sizeof(srv_ip));
|
||||||
memcpy(&myip, ar_tpa(ah), sizeof(myip));
|
memcpy(&myip, ar_tpa(ah), sizeof(myip));
|
||||||
|
@ -1358,10 +1386,10 @@ revarprequest(struct ifnet *ifp)
|
||||||
ah->ar_pln = sizeof(struct in_addr); /* protocol address length */
|
ah->ar_pln = sizeof(struct in_addr); /* protocol address length */
|
||||||
ah->ar_op = htons(ARPOP_REVREQUEST);
|
ah->ar_op = htons(ARPOP_REVREQUEST);
|
||||||
|
|
||||||
memcpy(ar_sha(ah), LLADDR(ifp->if_sadl), ah->ar_hln);
|
memcpy(ar_sha(ah), CLLADDR(ifp->if_sadl), ah->ar_hln);
|
||||||
tha = ar_tha(ah);
|
tha = ar_tha(ah);
|
||||||
KASSERT(tha);
|
KASSERT(tha);
|
||||||
bcopy(LLADDR(ifp->if_sadl), tha, ah->ar_hln);
|
bcopy(CLLADDR(ifp->if_sadl), tha, ah->ar_hln);
|
||||||
|
|
||||||
sa.sa_family = AF_ARP;
|
sa.sa_family = AF_ARP;
|
||||||
sa.sa_len = 2;
|
sa.sa_len = 2;
|
||||||
|
|
Loading…
Reference in New Issue