summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/9/ip/arp.c397
-rw-r--r--sys/src/9/ip/ethermedium.c58
-rw-r--r--sys/src/9/ip/icmp6.c11
-rw-r--r--sys/src/9/ip/ip.h17
-rw-r--r--sys/src/9/ip/ipifc.c2
5 files changed, 190 insertions, 295 deletions
diff --git a/sys/src/9/ip/arp.c b/sys/src/9/ip/arp.c
index 42c1ce262..12cb42fd1 100644
--- a/sys/src/9/ip/arp.c
+++ b/sys/src/9/ip/arp.c
@@ -73,132 +73,105 @@ freeblistchain(Block *bp)
}
}
-/*
- * create a new arp entry for an ip address on ifc.
- */
-static Arpent*
-newarp6(Arp *arp, uchar *ip, Ipifc *ifc, int addrxt)
+/* take out of re-transmit chain */
+static Arpent**
+rxmtunchain(Arp *arp, Arpent *a)
{
- uint t;
- Block *xp;
- Arpent *a, *e, *f, **l;
- int empty;
+ Arpent **l;
- /* find oldest entry */
- e = &arp->cache[NCACHE];
- a = arp->cache;
- t = a->utime;
- for(f = a; f < e; f++){
- if(f->utime < t){
- t = f->utime;
- a = f;
+ for(l = &arp->rxmt; *l != nil; l = &((*l)->nextrxt)){
+ if(*l == a){
+ *l = a->nextrxt;
+ break;
+ }
+ }
+ a->nextrxt = nil;
+ return l;
+}
+
+static void
+cleanarpent(Arp *arp, Arpent *a)
+{
+ Arpent **l;
+ Block *bp;
+
+ /* take out of current chain */
+ for(l = &arp->hash[haship(a->ip)]; *l != nil; l = &((*l)->hash)){
+ if(*l == a){
+ *l = a->hash;
+ break;
}
}
+ a->hash = nil;
/* dump waiting packets */
- xp = a->hold;
+ bp = a->hold;
a->hold = nil;
if(isv4(a->ip))
- freeblistchain(xp);
- else { /* queue icmp unreachable for rxmitproc later on, w/o arp lock */
- if(xp != nil){
- if(arp->dropf == nil)
- arp->dropf = xp;
+ freeblistchain(bp);
+ else {
+ rxmtunchain(arp, a);
+
+ /* queue icmp unreachable for rxmitproc later on, w/o arp lock */
+ if(bp != nil){
+ if(arp->dropf == nil)
+ arp->dropf = bp;
else
- arp->dropl->list = xp;
+ arp->dropl->list = bp;
arp->dropl = a->last;
- wakeup(&arp->rxmtq);
+
+ if(bp == arp->dropf)
+ wakeup(&arp->rxmtq);
}
}
a->last = nil;
- /* take out of current chain */
- l = &arp->hash[haship(a->ip)];
- for(f = *l; f != nil; f = f->hash){
- if(f == a){
- *l = a->hash;
- break;
- }
- l = &f->hash;
- }
+ a->ifc = nil;
+ a->ifcid = 0;
- /* insert into new chain */
- l = &arp->hash[haship(ip)];
- a->hash = *l;
- *l = a;
+ a->state = 0;
+ a->rxtsrem = 0;
- ipmove(a->ip, ip);
- a->utime = NOW;
+ a->utime = 0;
a->ctime = 0;
- a->rtime = NOW + ReTransTimer;
- a->rxtsrem = MAX_MULTICAST_SOLICIT;
- a->ifc = ifc;
- a->ifcid = ifc->ifcid;
+ memset(a->ip, 0, sizeof(a->ip));
+ memset(a->mac, 0, sizeof(a->mac));
+}
- /* put to the end of re-transmit chain; addrxt is 0 when isv4(a->ip) */
- if(!ipismulticast(a->ip) && addrxt){
- l = &arp->rxmt;
- empty = (*l == nil);
+/*
+ * create a new arp entry for an ip address on ifc.
+ */
+static Arpent*
+newarpent(Arp *arp, uchar *ip, Ipifc *ifc)
+{
+ Arpent *a, *e, *f, **l;
+ ulong t;
- for(f = *l; f != nil; f = f->nextrxt){
- if(f == a){
- *l = a->nextrxt;
- break;
- }
- l = &f->nextrxt;
+ /* find oldest entry */
+ e = &arp->cache[NCACHE];
+ a = arp->cache;
+ t = a->utime;
+ for(f = a; f < e; f++){
+ if(f->utime < t){
+ t = f->utime;
+ a = f;
}
- for(f = *l; f != nil; f = f->nextrxt)
- l = &f->nextrxt;
-
- *l = a;
- if(empty)
- wakeup(&arp->rxmtq);
}
+ cleanarpent(arp, a);
- a->nextrxt = nil;
+ ipmove(a->ip, ip);
+ a->ifc = ifc;
+ a->ifcid = ifc->ifcid;
+
+ /* insert into new chain */
+ l = &arp->hash[haship(ip)];
+ a->hash = *l;
+ *l = a;
return a;
}
-/* called with arp qlocked */
-
-static void
-cleanarpent(Arp *arp, Arpent *a)
-{
- Arpent *f, **l;
-
- a->utime = 0;
- a->ctime = 0;
- a->state = 0;
-
- a->ifc = nil;
- a->ifcid = 0;
-
- /* take out of current chain */
- l = &arp->hash[haship(a->ip)];
- for(f = *l; f != nil; f = f->hash){
- if(f == a){
- *l = a->hash;
- break;
- }
- l = &f->hash;
- }
-
- /* take out of re-transmit chain */
- l = &arp->rxmt;
- for(f = *l; f != nil; f = f->nextrxt){
- if(f == a){
- *l = a->nextrxt;
- break;
- }
- l = &f->nextrxt;
- }
- a->nextrxt = nil;
- a->hash = nil;
- freeblistchain(a->hold);
- a->hold = a->last = nil;
-}
/*
* fill in the media address if we have it. Otherwise return an
@@ -225,7 +198,7 @@ arpget(Arp *arp, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *mac)
break;
}
if(a == nil){
- a = newarp6(arp, ip, ifc, (version != V4));
+ a = newarpent(arp, ip, ifc);
a->state = AWAIT;
}
a->utime = NOW;
@@ -270,21 +243,14 @@ Block*
arpresolve(Arp *arp, Arpent *a, Medium *type, uchar *mac)
{
Block *bp;
- Arpent *f, **l;
-
- if(!isv4(a->ip)){
- l = &arp->rxmt;
- for(f = *l; f != nil; f = f->nextrxt){
- if(f == a){
- *l = a->nextrxt;
- break;
- }
- l = &f->nextrxt;
- }
- }
+
memmove(a->mac, mac, type->maclen);
+ if(a->state == AWAIT && !isv4(a->ip)){
+ rxmtunchain(arp, a);
+ a->rxtsrem = 0;
+ }
a->state = AOK;
- a->utime = NOW;
+ a->ctime = a->utime = NOW;
bp = a->hold;
a->hold = a->last = nil;
qunlock(arp);
@@ -293,16 +259,17 @@ arpresolve(Arp *arp, Arpent *a, Medium *type, uchar *mac)
}
int
-arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, uchar *ia, int refresh)
+arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, uchar *ia, Ipifc *ifc, int refresh)
{
- Arp *arp;
- Route *r;
- Arpent *a, *f, **l;
- Ipifc *ifc;
- Block *bp, *next;
uchar v6ip[IPaddrlen];
+ Block *bp, *next;
+ Arpent *a;
+ Route *r;
+ Arp *arp;
+
+ if(ifc->m == nil || ifc->m->maclen != n || ifc->m->maclen == 0)
+ return -1;
- arp = fs->arp;
switch(version){
case V4:
r = v4lookup(fs, ip, ia, nil);
@@ -316,46 +283,20 @@ arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, uchar *ia, int refre
panic("arpenter: version %d", version);
return -1; /* to supress warnings */
}
- if(r == nil || (ifc = r->ifc) == nil)
- return -1;
- rlock(ifc);
- if(ifc->m == nil || ifc->m->maclen != n || ifc->m->maclen == 0){
- runlock(ifc);
+ if(r == nil || r->ifc != ifc || (r->type & (Rbcast|Rmulti)) != 0)
return -1;
- }
+ arp = fs->arp;
qlock(arp);
for(a = arp->hash[haship(ip)]; a != nil; a = a->hash){
- if(a->state != AWAIT && a->state != AOK)
- continue;
if(a->ifc != ifc || a->ifcid != ifc->ifcid)
continue;
if(ipcmp(a->ip, ip) == 0){
- a->state = AOK;
- memmove(a->mac, mac, n);
-
- if(version == V6){
- /* take out of re-transmit chain */
- l = &arp->rxmt;
- for(f = *l; f != nil; f = f->nextrxt){
- if(f == a){
- *l = a->nextrxt;
- break;
- }
- l = &f->nextrxt;
- }
- }
-
- bp = a->hold;
- a->hold = a->last = nil;
if(version == V4)
ip += IPv4off;
- a->utime = NOW;
- a->ctime = a->utime;
- qunlock(arp);
-
- while(bp != nil){
+ bp = arpresolve(arp, a, ifc->m, mac); /* unlocks arp */
+ for(; bp != nil; bp = next){
next = bp->list;
bp->list = nil;
if(waserror()){
@@ -364,21 +305,18 @@ arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, uchar *ia, int refre
}
ifc->m->bwrite(ifc, concatblock(bp), version, ip);
poperror();
- bp = next;
}
- runlock(ifc);
return 1;
}
}
if(refresh == 0){
- a = newarp6(arp, ip, ifc, 0);
+ a = newarpent(arp, ip, ifc);
a->state = AOK;
- a->ctime = NOW;
+ a->ctime = a->utime = NOW;
memmove(a->mac, mac, n);
}
qunlock(arp);
- runlock(ifc);
return refresh == 0;
}
@@ -390,6 +328,7 @@ arpwrite(Fs *fs, char *s, int len)
Arp *arp;
Arpent *a, *x;
Medium *m;
+ Ipifc *ifc;
char *f[5], buf[256];
uchar ip[IPaddrlen], ia[IPaddrlen], mac[MAClen];
@@ -411,18 +350,20 @@ arpwrite(Fs *fs, char *s, int len)
memset(a->ip, 0, sizeof(a->ip));
memset(a->mac, 0, sizeof(a->mac));
a->hash = nil;
- a->state = 0;
- a->utime = 0;
+ a->nextrxt = nil;
a->ifc = nil;
a->ifcid = 0;
+ a->state = 0;
+ a->rxtsrem = 0;
+ a->ctime = 0;
+ a->utime = 0;
freeblistchain(a->hold);
a->hold = a->last = nil;
}
memset(arp->hash, 0, sizeof(arp->hash));
- /* clear all pkts on these lists (rxmt, dropf/l) */
- arp->rxmt = nil;
freeblistchain(arp->dropf);
arp->dropf = arp->dropl = nil;
+ arp->rxmt = nil;
qunlock(arp);
} else if(strcmp(f[0], "add") == 0){
switch(n){
@@ -457,8 +398,14 @@ arpwrite(Fs *fs, char *s, int len)
error(Ebadip);
break;
}
- if(arpenter(fs, V6, ip, mac, n, ia, 0) <= 0)
+ if((ifc = findipifc(fs, ia, ia, Runi)) == nil)
+ error("no interface");
+ rlock(ifc);
+ if(arpenter(fs, V6, ip, mac, n, ia, ifc, 0) < 0){
+ runlock(ifc);
error("destination unreachable");
+ }
+ runlock(ifc);
} else if(strcmp(f[0], "del") == 0){
if (n != 2)
error(Ebadarg);
@@ -467,11 +414,8 @@ arpwrite(Fs *fs, char *s, int len)
qlock(arp);
for(a = arp->hash[haship(ip)]; a != nil; a = x){
x = a->hash;
- if(ipcmp(ip, a->ip) == 0){
+ if(ipcmp(ip, a->ip) == 0)
cleanarpent(arp, a);
- memset(a->ip, 0, sizeof(a->ip));
- memset(a->mac, 0, sizeof(a->mac));
- }
}
qunlock(arp);
} else
@@ -535,9 +479,24 @@ void
ndpsendsol(Fs *f, Ipifc *ifc, Arpent *a)
{
uchar targ[IPaddrlen], src[IPaddrlen];
+ Arpent **l;
- ipmove(targ, a->ip);
+ a->ctime = NOW;
+ if(a->rxtsrem == 0)
+ a->rxtsrem = MAX_MULTICAST_SOLICIT;
+ else
+ a->rxtsrem--;
+ /* put on end of re-transmit chain */
+ for(l = rxmtunchain(f->arp, a); *l != nil; l = &(*l)->nextrxt)
+ ;
+ *l = a;
+
+ if(l == &f->arp->rxmt)
+ wakeup(&f->arp->rxmtq);
+
+ /* try to use source address of original packet */
+ ipmove(targ, a->ip);
if(a->last != nil){
ipmove(src, ((Ip6hdr*)a->last->rp)->src);
arprelease(f->arp, a);
@@ -547,7 +506,6 @@ ndpsendsol(Fs *f, Ipifc *ifc, Arpent *a)
} else {
arprelease(f->arp, a);
}
-
if(!ipv6local(ifc, src, targ))
return;
send:
@@ -557,107 +515,50 @@ send:
}
}
-long
+static void
rxmitsols(Arp *arp)
{
- Block *next, *xp;
- Arpent *a, *b, **l;
+ Block *next, *bp;
+ Arpent *a;
Ipifc *ifc;
- long nrxt;
- Fs *f;
+ Route *r;
qlock(arp);
- f = arp->f;
-
- a = arp->rxmt;
- if(a == nil){
- nrxt = 0;
- goto dodrops; /* return nrxt; */
- }
- nrxt = a->rtime - NOW;
- if(nrxt > 3*ReTransTimer/4)
- goto dodrops; /* return nrxt; */
-
- ifc = nil;
- for(; a != nil; a = a->nextrxt){
- ifc = a->ifc;
- if(a->rxtsrem > 0 && ifc != nil && canrlock(ifc)){
- if(a->ifcid == ifc->ifcid)
- break;
+ while((a = arp->rxmt) != nil && NOW - a->ctime > 3*ReTransTimer/4){
+ if(a->rxtsrem > 0 && (ifc = a->ifc) != nil && canrlock(ifc)){
+ if(a->ifcid == ifc->ifcid){
+ ndpsendsol(arp->f, ifc, a); /* unlocks arp */
+ runlock(ifc);
+ qlock(arp);
+ continue;
+ }
runlock(ifc);
}
- xp = a->hold;
- a->hold = nil;
- if(xp != nil){
- if(arp->dropf == nil)
- arp->dropf = xp;
- else
- arp->dropl->list = xp;
- arp->dropl = a->last;
- }
cleanarpent(arp, a);
}
- if(a == nil)
- goto dodrops;
-
- ndpsendsol(f, ifc, a); /* unlocks arp */
-
- runlock(ifc);
- qlock(arp);
-
- /* put to the end of re-transmit chain */
- l = &arp->rxmt;
- for(b = *l; b != nil; b = b->nextrxt){
- if(b == a){
- *l = a->nextrxt;
- break;
- }
- l = &b->nextrxt;
- }
- for(b = *l; b != nil; b = b->nextrxt)
- l = &b->nextrxt;
-
- *l = a;
- a->rxtsrem--;
- a->nextrxt = nil;
- a->rtime = NOW + ReTransTimer;
-
- a = arp->rxmt;
- if(a == nil)
- nrxt = 0;
- else
- nrxt = a->rtime - NOW;
-
-dodrops:
- xp = arp->dropf;
+ bp = arp->dropf;
arp->dropf = arp->dropl = nil;
qunlock(arp);
- for(; xp != nil; xp = next){
- Ip6hdr *eh;
- Route *r;
-
- next = xp->list;
- eh = (Ip6hdr*)xp->rp;
- r = v6lookup(f, eh->src, eh->dst, nil);
+ for(; bp != nil; bp = next){
+ next = bp->list;
+ bp->list = nil;
+ r = v6lookup(arp->f, ((Ip6hdr*)bp->rp)->src, ((Ip6hdr*)bp->rp)->dst, nil);
if(r != nil && (ifc = r->ifc) != nil && canrlock(ifc)){
if(!waserror()){
- icmphostunr6(f, ifc, xp, Icmp6_adr_unreach, (r->type & Runi) != 0);
+ icmphostunr6(arp->f, ifc, bp, Icmp6_adr_unreach, (r->type & Runi) != 0);
poperror();
}
runlock(ifc);
}
- freeblist(xp);
+ freeblist(bp);
}
-
- return nrxt;
-
}
static int
rxready(void *v)
{
- Arp *arp = (Arp *) v;
+ Arp *arp = (Arp *)v;
return arp->rxmt != nil || arp->dropf != nil;
}
@@ -666,7 +567,6 @@ static void
rxmitproc(void *v)
{
Arp *arp = v;
- long wakeupat;
arp->rxmitp = up;
if(waserror()){
@@ -674,11 +574,8 @@ rxmitproc(void *v)
pexit("hangup", 1);
}
for(;;){
- wakeupat = rxmitsols(arp);
- if(wakeupat == 0)
- sleep(&arp->rxmtq, rxready, v);
- else if(wakeupat > ReTransTimer/4)
- tsleep(&arp->rxmtq, return0, 0, wakeupat);
+ sleep(&arp->rxmtq, rxready, v);
+ rxmitsols(arp);
+ tsleep(&arp->rxmtq, return0, nil, ReTransTimer/4);
}
}
-
diff --git a/sys/src/9/ip/ethermedium.c b/sys/src/9/ip/ethermedium.c
index 245959eb5..3aa74f42f 100644
--- a/sys/src/9/ip/ethermedium.c
+++ b/sys/src/9/ip/ethermedium.c
@@ -36,9 +36,9 @@ static void etherremmulti(Ipifc *ifc, uchar *a, uchar *ia);
static void etherareg(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *ip);
static Block* multicastarp(Fs *f, Arpent *a, Medium*, uchar *mac);
static void sendarp(Ipifc *ifc, Arpent *a);
+static void sendndp(Ipifc *ifc, Arpent *a);
static int multicastea(uchar *ea, uchar *ip);
static void recvarpproc(void*);
-static void resolveaddr6(Ipifc *ifc, Arpent *a);
static void etherpref2addr(uchar *pref, uchar *ea);
Medium ethermedium =
@@ -272,13 +272,13 @@ etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip)
if(a != nil){
/* check for broadcast or multicast */
bp = multicastarp(er->f, a, ifc->m, mac);
- if(bp==nil){
+ if(bp == nil){
switch(version){
case V4:
sendarp(ifc, a);
break;
case V6:
- resolveaddr6(ifc, a);
+ sendndp(ifc, a);
break;
default:
panic("etherbwrite: version %d", version);
@@ -492,7 +492,7 @@ sendarp(Ipifc *ifc, Arpent *a)
}
static void
-resolveaddr6(Ipifc *ifc, Arpent *a)
+sendndp(Ipifc *ifc, Arpent *a)
{
Block *bp;
Etherrock *er = ifc->arg;
@@ -511,15 +511,6 @@ resolveaddr6(Ipifc *ifc, Arpent *a)
freeblist(bp);
}
- /* try to keep it around for a second more */
- a->ctime = NOW;
- a->rtime = NOW + ReTransTimer;
- if(a->rxtsrem <= 0) {
- arprelease(er->f->arp, a);
- return;
- }
-
- a->rxtsrem--;
ndpsendsol(er->f, ifc, a); /* unlocks arp */
}
@@ -560,7 +551,7 @@ sendgarp(Ipifc *ifc, uchar *ip)
static void
recvarp(Ipifc *ifc)
{
- int n;
+ int n, forme;
Block *ebp, *rbp;
Etherarp *e, *r;
uchar ip[IPaddrlen];
@@ -582,6 +573,10 @@ recvarp(Ipifc *ifc)
break;
case ARPREPLY:
+ /* make sure not to enter multi/broadcat address */
+ if(e->sha[0] & 1)
+ break;
+
/* check for machine using my ip address */
v4tov6(ip, e->spa);
if(iplocalonifc(ifc, ip) != nil || ipproxyifc(er->f, ifc, ip)){
@@ -592,17 +587,15 @@ recvarp(Ipifc *ifc)
}
}
- /* make sure we're not entering broadcast addresses */
- if(ipcmp(ip, ipbroadcast) == 0 || memcmp(e->sha, etherbroadcast, sizeof(e->sha)) == 0){
- print("arprep: 0x%E/0x%E cannot register broadcast address %I\n",
- e->s, e->sha, e->spa);
- break;
- }
-
- arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), e->tpa, 0);
+ /* refresh what we know about sender */
+ arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), e->tpa, ifc, 1);
break;
case ARPREQUEST:
+ /* don't reply to multi/broadcat addresses */
+ if(e->sha[0] & 1)
+ break;
+
/* don't answer arps till we know who we are */
if(ifc->lifc == nil)
break;
@@ -613,23 +606,28 @@ recvarp(Ipifc *ifc)
if(memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0){
if(memcmp(eprinted, e->spa, sizeof(e->spa)) != 0){
/* print only once */
- print("arpreq: 0x%E also has ip addr %V\n", e->sha, e->spa);
+ print("arpreq: 0x%E also has ip addr %V\n",
+ e->sha, e->spa);
memmove(eprinted, e->spa, sizeof(e->spa));
}
+ break;
}
} else {
if(memcmp(e->sha, ifc->mac, sizeof(e->sha)) == 0){
- print("arpreq: %V also has ether addr %E\n", e->spa, e->sha);
+ print("arpreq: %V also has ether addr %E\n",
+ e->spa, e->sha);
break;
}
}
- /* refresh what we know about sender */
- arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), e->tpa, 1);
-
- /* answer only requests for our address or systems we're proxying for */
+ /*
+ * when request is for our address or systems we're proxying for,
+ * enter senders address into arp table and reply, otherwise just
+ * refresh the senders address.
+ */
v4tov6(ip, e->tpa);
- if(iplocalonifc(ifc, ip) == nil && !ipproxyifc(er->f, ifc, ip))
+ forme = iplocalonifc(ifc, ip) != nil || ipproxyifc(er->f, ifc, ip);
+ if(arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), e->tpa, ifc, !forme) < 0 || !forme)
break;
n = sizeof(Etherarp);
@@ -761,7 +759,7 @@ etherareg(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *ip)
static char tdad[] = "dad6";
uchar a[IPaddrlen];
- if(ipcmp(ip, IPnoaddr) == 0)
+ if(ipcmp(ip, IPnoaddr) == 0 || ipcmp(ip, v4prefix) == 0)
return;
if(isv4(ip)){
diff --git a/sys/src/9/ip/icmp6.c b/sys/src/9/ip/icmp6.c
index d32a8bd61..cbbf3f182 100644
--- a/sys/src/9/ip/icmp6.c
+++ b/sys/src/9/ip/icmp6.c
@@ -752,7 +752,7 @@ icmpiput6(Proto *icmp, Ipifc *ifc, Block *bp)
break;
case NbrSolicit:
- np = (Ndpkt*) p;
+ np = (Ndpkt*)p;
pktflags = 0;
if(ifc->sendra6)
pktflags |= Rflag;
@@ -763,7 +763,8 @@ icmpiput6(Proto *icmp, Ipifc *ifc, Block *bp)
case Tuniproxy:
if(ipv6local(ifc, ia, np->src)) {
- arpenter(icmp->f, V6, np->src, np->lnaddr, 8*np->olen-2, ia, 0);
+ if(arpenter(icmp->f, V6, np->src, np->lnaddr, 8*np->olen-2, ia, ifc, 0) < 0)
+ break;
pktflags |= Sflag;
} else
ipmove(ia, np->target);
@@ -781,7 +782,7 @@ icmpiput6(Proto *icmp, Ipifc *ifc, Block *bp)
break;
case NbrAdvert:
- np = (Ndpkt*) p;
+ np = (Ndpkt*)p;
/*
* if the target address matches one of the local interface
@@ -792,9 +793,9 @@ icmpiput6(Proto *icmp, Ipifc *ifc, Block *bp)
*/
lifc = iplocalonifc(ifc, np->target);
if(lifc != nil && lifc->tentative)
- arpenter(icmp->f, V6, np->target, np->lnaddr, 8*np->olen-2, np->target, 0);
+ arpenter(icmp->f, V6, np->target, np->lnaddr, 8*np->olen-2, np->target, ifc, 0);
else if(ipv6local(ifc, ia, np->target))
- arpenter(icmp->f, V6, np->target, np->lnaddr, 8*np->olen-2, ia, 1);
+ arpenter(icmp->f, V6, np->target, np->lnaddr, 8*np->olen-2, ia, ifc, 1);
freeblist(bp);
break;
diff --git a/sys/src/9/ip/ip.h b/sys/src/9/ip/ip.h
index 10428afdf..84edd761e 100644
--- a/sys/src/9/ip/ip.h
+++ b/sys/src/9/ip/ip.h
@@ -589,17 +589,16 @@ struct Arpent
{
uchar ip[IPaddrlen];
uchar mac[MAClen];
- Arpent* hash;
- Block* hold;
- Block* last;
- uint ctime; /* time entry was created or refreshed */
- uint utime; /* time entry was last used */
- uchar state;
+ Arpent *hash;
Arpent *nextrxt; /* re-transmit chain */
- uint rtime; /* time for next retransmission */
- uchar rxtsrem;
+ Block *hold;
+ Block *last;
Ipifc *ifc;
uchar ifcid; /* must match ifc->id */
+ uchar state;
+ uchar rxtsrem; /* re-tranmissions remaining */
+ ulong ctime; /* time entry was created or refreshed */
+ ulong utime; /* time entry was last used */
};
extern void arpinit(Fs*);
@@ -608,7 +607,7 @@ extern int arpwrite(Fs*, char*, int);
extern Arpent* arpget(Arp*, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *h);
extern void arprelease(Arp*, Arpent *a);
extern Block* arpresolve(Arp*, Arpent *a, Medium *type, uchar *mac);
-extern int arpenter(Fs*, int version, uchar *ip, uchar *mac, int n, uchar *ia, int norefresh);
+extern int arpenter(Fs*, int version, uchar *ip, uchar *mac, int n, uchar *ia, Ipifc *ifc, int refresh);
extern void ndpsendsol(Fs*, Ipifc*, Arpent*);
/*
diff --git a/sys/src/9/ip/ipifc.c b/sys/src/9/ip/ipifc.c
index af5c1606f..037f2abd9 100644
--- a/sys/src/9/ip/ipifc.c
+++ b/sys/src/9/ip/ipifc.c
@@ -1145,7 +1145,7 @@ findipifcstr(Fs *f, char *s)
return (Ipifc*)c->ptcl;
}
if(parseip(ip, s) != -1)
- return findipifc(f, IPnoaddr, ip, Runi);
+ return findipifc(f, ip, ip, Runi);
return nil;
}