diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2018-03-19 01:11:08 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2018-03-19 01:11:08 +0100 |
commit | 547f60b4c507778099635f5d2ec4919e1beb6a57 (patch) | |
tree | 054f072e361b27b433515e4688eb33555bfc340f /sys/src | |
parent | 20cbb88e32ece30dd984ab658c365f574790d6ba (diff) |
devip: pick source address for neighbor solicitations as of rfc4861 7.2.2, cleanup
rfc4861 7.2.2:
If the source address of the packet prompting the solicitation is the
same as one of the addresses assigned to the outgoing interface, that
address SHOULD be placed in the IP Source Address of the outgoing
solicitation.
this change adds ndbsendsol() which handles the source address selection
and also handles the arp table locking; avoiding access to the arp entry
after the arp table is unlocked.
cleanups:
- use ipmove() instead of memmove().
- useless extern qualifiers
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/9/ip/arp.c | 35 | ||||
-rw-r--r-- | sys/src/9/ip/ethermedium.c | 8 | ||||
-rw-r--r-- | sys/src/9/ip/icmp.c | 14 | ||||
-rw-r--r-- | sys/src/9/ip/icmp6.c | 30 | ||||
-rw-r--r-- | sys/src/9/ip/ip.h | 1 |
5 files changed, 52 insertions, 36 deletions
diff --git a/sys/src/9/ip/arp.c b/sys/src/9/ip/arp.c index ba158cf29..e8b1b831e 100644 --- a/sys/src/9/ip/arp.c +++ b/sys/src/9/ip/arp.c @@ -47,7 +47,7 @@ char *Ebadarp = "bad arp"; #define haship(s) ((s)[IPaddrlen-1]%NHASH) -extern int ReTransTimer = RETRANS_TIMER; +int ReTransTimer = RETRANS_TIMER; static void rxmitproc(void *v); @@ -223,7 +223,7 @@ arpget(Arp *arp, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *mac) qlock(arp); hash = haship(ip); for(a = arp->hash[hash]; a != nil; a = a->hash){ - if(memcmp(ip, a->ip, sizeof(a->ip)) == 0) + if(ipcmp(ip, a->ip) == 0) if(type == a->type) break; } @@ -536,13 +536,35 @@ arpread(Arp *arp, char *p, ulong offset, int len) return n; } -extern int +void +ndpsendsol(Fs *f, Ipifc *ifc, Arpent *a) +{ + uchar targ[IPaddrlen], src[IPaddrlen]; + + ipmove(targ, a->ip); + + if(a->last != nil){ + ipmove(src, ((Ip6hdr*)a->last->rp)->src); + arprelease(f->arp, a); + + if(iplocalonifc(ifc, src) || ipproxyifc(f, ifc, src)) + goto send; + } else { + arprelease(f->arp, a); + } + + if(!ipv6local(ifc, src, targ)) + return; +send: + icmpns(f, src, SRC_UNI, targ, TARG_MULTI, ifc->mac); +} + +int rxmitsols(Arp *arp) { Block *next, *xp; Arpent *a, *b, **l; Fs *f; - uchar ipsrc[IPaddrlen]; Ipifc *ifc = nil; long nrxt; @@ -579,10 +601,7 @@ rxmitsols(Arp *arp) if(a == nil) goto dodrops; - - qunlock(arp); /* for icmpns */ - if(ipv6local(ifc, ipsrc, a->ip)) - icmpns(f, ipsrc, SRC_UNI, a->ip, TARG_MULTI, ifc->mac); + ndpsendsol(f, ifc, a); /* unlocks arp */ runlock(ifc); qlock(arp); diff --git a/sys/src/9/ip/ethermedium.c b/sys/src/9/ip/ethermedium.c index d8691b0e7..9b1962450 100644 --- a/sys/src/9/ip/ethermedium.c +++ b/sys/src/9/ip/ethermedium.c @@ -498,7 +498,6 @@ resolveaddr6(Ipifc *ifc, Arpent *a) { Block *bp; Etherrock *er = ifc->arg; - uchar ipsrc[IPaddrlen]; /* don't do anything if it's been less than a second since the last */ if(NOW - a->ctime < ReTransTimer){ @@ -523,10 +522,7 @@ resolveaddr6(Ipifc *ifc, Arpent *a) } a->rxtsrem--; - arprelease(er->f->arp, a); - - if(ipv6local(ifc, ipsrc, a->ip)) - icmpns(er->f, ipsrc, SRC_UNI, a->ip, TARG_MULTI, ifc->mac); + ndpsendsol(er->f, ifc, a); /* unlocks arp */ } /* @@ -610,7 +606,7 @@ recvarp(Ipifc *ifc) case ARPREQUEST: /* don't answer arps till we know who we are */ - if(ifc->lifc == 0) + if(ifc->lifc == nil) break; /* check for machine using my ip or ether address */ diff --git a/sys/src/9/ip/icmp.c b/sys/src/9/ip/icmp.c index b063d5da5..21f226c7f 100644 --- a/sys/src/9/ip/icmp.c +++ b/sys/src/9/ip/icmp.c @@ -113,7 +113,7 @@ icmpcreate(Conv *c) c->wq = qbypass(icmpkick, c); } -extern char* +char* icmpconnect(Conv *c, char **argv, int argc) { char *e; @@ -126,7 +126,7 @@ icmpconnect(Conv *c, char **argv, int argc) return nil; } -extern int +int icmpstate(Conv *c, char *state, int n) { USED(c); @@ -137,7 +137,7 @@ icmpstate(Conv *c, char *state, int n) ); } -extern char* +char* icmpannounce(Conv *c, char **argv, int argc) { char *e; @@ -150,7 +150,7 @@ icmpannounce(Conv *c, char **argv, int argc) return nil; } -extern void +void icmpclose(Conv *c) { qclose(c->rq); @@ -214,7 +214,7 @@ ip4me(Fs *f, uchar ip4[4]) return (ipforme(f, addr) & Runi) != 0; } -extern void +void icmpttlexceeded(Fs *f, uchar *ia, Block *bp) { Block *nbp; @@ -270,13 +270,13 @@ icmpunreachable(Fs *f, Block *bp, int code, int seq) ipoput4(f, nbp, 0, MAXTTL, DFLTTOS, nil); } -extern void +void icmpnoconv(Fs *f, Block *bp) { icmpunreachable(f, bp, 3, 0); } -extern void +void icmpcantfrag(Fs *f, Block *bp, int mtu) { icmpunreachable(f, bp, 4, mtu); diff --git a/sys/src/9/ip/icmp6.c b/sys/src/9/ip/icmp6.c index 17d24d623..617370472 100644 --- a/sys/src/9/ip/icmp6.c +++ b/sys/src/9/ip/icmp6.c @@ -345,7 +345,7 @@ mkechoreply6(Block *bp, Ipifc *ifc) * tuni == TARG_MULTI => multicast for address resolution, * and tuni == TARG_UNI => neighbor reachability. */ -extern void +void icmpns(Fs *f, uchar* src, int suni, uchar* targ, int tuni, uchar* mac) { Block *nbp; @@ -357,18 +357,18 @@ icmpns(Fs *f, uchar* src, int suni, uchar* targ, int tuni, uchar* mac) np = (Ndpkt*) nbp->rp; if(suni == SRC_UNSPEC) - memmove(np->src, v6Unspecified, IPaddrlen); + ipmove(np->src, v6Unspecified); else - memmove(np->src, src, IPaddrlen); + ipmove(np->src, src); if(tuni == TARG_UNI) - memmove(np->dst, targ, IPaddrlen); + ipmove(np->dst, targ); else ipv62smcast(np->dst, targ); np->type = NbrSolicit; np->code = 0; - memmove(np->target, targ, IPaddrlen); + ipmove(np->target, targ); if(suni != SRC_UNSPEC) { np->otype = SRC_LLADDR; np->olen = 1; /* 1+1+6 = 8 = 1 8-octet */ @@ -388,7 +388,7 @@ icmpns(Fs *f, uchar* src, int suni, uchar* targ, int tuni, uchar* mac) /* * sends out an ICMPv6 neighbor advertisement. pktflags == RSO flags. */ -extern void +void icmpna(Fs *f, uchar* src, uchar* dst, uchar* targ, uchar* mac, uchar flags) { Block *nbp; @@ -399,13 +399,13 @@ icmpna(Fs *f, uchar* src, uchar* dst, uchar* targ, uchar* mac, uchar flags) nbp = newIPICMP(NDPKTSZ); np = (Ndpkt*)nbp->rp; - memmove(np->src, src, IPaddrlen); - memmove(np->dst, dst, IPaddrlen); + ipmove(np->src, src); + ipmove(np->dst, dst); np->type = NbrAdvert; np->code = 0; np->icmpid[0] = flags; - memmove(np->target, targ, IPaddrlen); + ipmove(np->target, targ); np->otype = TARGET_LLADDR; np->olen = 1; @@ -420,7 +420,7 @@ icmpna(Fs *f, uchar* src, uchar* dst, uchar* targ, uchar* mac, uchar flags) ipoput6(f, nbp, 0, MAXTTL, DFLTTOS, nil); } -extern void +void icmphostunr(Fs *f, Ipifc *ifc, Block *bp, int code, int free) { int osz = BLEN(bp); @@ -449,7 +449,7 @@ icmphostunr(Fs *f, Ipifc *ifc, Block *bp, int code, int free) goto freebl; } - memmove(np->dst, p->src, IPaddrlen); + ipmove(np->dst, p->src); np->type = UnreachableV6; np->code = code; memmove(nbp->rp + IPICMPSZ, bp->rp, sz - IPICMPSZ); @@ -468,7 +468,7 @@ freebl: freeblist(bp); } -extern void +void icmpttlexceeded6(Fs *f, Ipifc *ifc, Block *bp) { int osz = BLEN(bp); @@ -496,7 +496,7 @@ icmpttlexceeded6(Fs *f, Ipifc *ifc, Block *bp) return; } - memmove(np->dst, p->src, IPaddrlen); + ipmove(np->dst, p->src); np->type = TimeExceedV6; np->code = 0; memmove(nbp->rp + IPICMPSZ, bp->rp, sz - IPICMPSZ); @@ -507,7 +507,7 @@ icmpttlexceeded6(Fs *f, Ipifc *ifc, Block *bp) ipoput6(f, nbp, 0, MAXTTL, DFLTTOS, nil); } -extern void +void icmppkttoobig6(Fs *f, Ipifc *ifc, Block *bp) { int osz = BLEN(bp); @@ -535,7 +535,7 @@ icmppkttoobig6(Fs *f, Ipifc *ifc, Block *bp) return; } - memmove(np->dst, p->src, IPaddrlen); + ipmove(np->dst, p->src); np->type = PacketTooBigV6; np->code = 0; hnputl(np->icmpid, ifc->maxtu - ifc->m->hsize); diff --git a/sys/src/9/ip/ip.h b/sys/src/9/ip/ip.h index 84e776e4e..5b3e41967 100644 --- a/sys/src/9/ip/ip.h +++ b/sys/src/9/ip/ip.h @@ -628,6 +628,7 @@ extern Arpent* arpget(Arp*, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar extern void arprelease(Arp*, Arpent *a); extern Block* arpresolve(Arp*, Arpent *a, Medium *type, uchar *mac); extern void arpenter(Fs*, int version, uchar *ip, uchar *mac, int len, int norefresh); +extern void ndpsendsol(Fs*, Ipifc*, Arpent*); /* * ipaux.c |