merge
This commit is contained in:
commit
20cbb88e32
14 changed files with 208 additions and 299 deletions
|
@ -539,7 +539,6 @@ arpread(Arp *arp, char *p, ulong offset, int len)
|
|||
extern int
|
||||
rxmitsols(Arp *arp)
|
||||
{
|
||||
uint sflag;
|
||||
Block *next, *xp;
|
||||
Arpent *a, *b, **l;
|
||||
Fs *f;
|
||||
|
@ -582,8 +581,8 @@ rxmitsols(Arp *arp)
|
|||
|
||||
|
||||
qunlock(arp); /* for icmpns */
|
||||
if((sflag = ipv6anylocal(ifc, ipsrc)) != SRC_UNSPEC)
|
||||
icmpns(f, ipsrc, sflag, a->ip, TARG_MULTI, ifc->mac);
|
||||
if(ipv6local(ifc, ipsrc, a->ip))
|
||||
icmpns(f, ipsrc, SRC_UNI, a->ip, TARG_MULTI, ifc->mac);
|
||||
|
||||
runlock(ifc);
|
||||
qlock(arp);
|
||||
|
|
|
@ -919,12 +919,7 @@ Fsstdconnect(Conv *c, char *argv[], int argc)
|
|||
return p;
|
||||
}
|
||||
|
||||
if( (memcmp(c->raddr, v4prefix, IPv4off) == 0 &&
|
||||
memcmp(c->laddr, v4prefix, IPv4off) == 0)
|
||||
|| ipcmp(c->raddr, IPnoaddr) == 0)
|
||||
c->ipversion = V4;
|
||||
else
|
||||
c->ipversion = V6;
|
||||
c->ipversion = convipvers(c);
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
@ -1150,12 +1145,6 @@ ipwrite(Chan* ch, void *v, long n, vlong off)
|
|||
if (parseip(ia, cb->f[1]) == -1)
|
||||
error(Ebadip);
|
||||
ipifcremmulti(c, c->raddr, ia);
|
||||
} else if(strcmp(cb->f[0], "maxfragsize") == 0){
|
||||
if(cb->nf < 2)
|
||||
error("maxfragsize needs size");
|
||||
|
||||
c->maxfragsize = (int)strtol(cb->f[1], nil, 0);
|
||||
|
||||
} else if(x->ctl != nil) {
|
||||
p = x->ctl(c, cb->f, cb->nf);
|
||||
if(p != nil)
|
||||
|
@ -1329,7 +1318,6 @@ retry:
|
|||
c->lport = 0;
|
||||
c->rport = 0;
|
||||
c->restricted = 0;
|
||||
c->maxfragsize = 0;
|
||||
c->ttl = MAXTTL;
|
||||
qreopen(c->rq);
|
||||
qreopen(c->wq);
|
||||
|
|
|
@ -266,17 +266,6 @@ espclose(Conv *c)
|
|||
memset(ecb, 0, sizeof(Espcb));
|
||||
}
|
||||
|
||||
static int
|
||||
convipvers(Conv *c)
|
||||
{
|
||||
if((memcmp(c->raddr, v4prefix, IPv4off) == 0 &&
|
||||
memcmp(c->laddr, v4prefix, IPv4off) == 0) ||
|
||||
ipcmp(c->raddr, IPnoaddr) == 0)
|
||||
return V4;
|
||||
else
|
||||
return V6;
|
||||
}
|
||||
|
||||
static int
|
||||
pktipvers(Fs *f, Block **bpp)
|
||||
{
|
||||
|
|
|
@ -477,7 +477,7 @@ sendarp(Ipifc *ifc, Arpent *a)
|
|||
memset(bp->rp, 0, n);
|
||||
e = (Etherarp*)bp->rp;
|
||||
memmove(e->tpa, a->ip+IPv4off, sizeof(e->tpa));
|
||||
ipv4local(ifc, e->spa);
|
||||
ipv4local(ifc, e->spa, e->tpa);
|
||||
memmove(e->sha, ifc->mac, sizeof(e->sha));
|
||||
memset(e->d, 0xff, sizeof(e->d)); /* ethernet broadcast */
|
||||
memmove(e->s, ifc->mac, sizeof(e->s));
|
||||
|
@ -496,7 +496,6 @@ sendarp(Ipifc *ifc, Arpent *a)
|
|||
static void
|
||||
resolveaddr6(Ipifc *ifc, Arpent *a)
|
||||
{
|
||||
int sflag;
|
||||
Block *bp;
|
||||
Etherrock *er = ifc->arg;
|
||||
uchar ipsrc[IPaddrlen];
|
||||
|
@ -526,8 +525,8 @@ resolveaddr6(Ipifc *ifc, Arpent *a)
|
|||
a->rxtsrem--;
|
||||
arprelease(er->f->arp, a);
|
||||
|
||||
if(sflag = ipv6anylocal(ifc, ipsrc))
|
||||
icmpns(er->f, ipsrc, sflag, a->ip, TARG_MULTI, ifc->mac);
|
||||
if(ipv6local(ifc, ipsrc, a->ip))
|
||||
icmpns(er->f, ipsrc, SRC_UNI, a->ip, TARG_MULTI, ifc->mac);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -331,7 +331,7 @@ mkechoreply6(Block *bp, Ipifc *ifc)
|
|||
ipmove(addr, p->src);
|
||||
if(!isv6mcast(p->dst))
|
||||
ipmove(p->src, p->dst);
|
||||
else if (!ipv6anylocal(ifc, p->src))
|
||||
else if (!ipv6local(ifc, p->src, addr))
|
||||
return nil;
|
||||
ipmove(p->dst, addr);
|
||||
p->type = EchoReplyV6;
|
||||
|
@ -440,7 +440,7 @@ icmphostunr(Fs *f, Ipifc *ifc, Block *bp, int code, int free)
|
|||
np = (IPICMP *)nbp->rp;
|
||||
|
||||
rlock(ifc);
|
||||
if(ipv6anylocal(ifc, np->src))
|
||||
if(ipv6local(ifc, np->src, p->src))
|
||||
netlog(f, Logicmp, "send icmphostunr -> src %I dst %I\n", p->src, p->dst);
|
||||
else {
|
||||
netlog(f, Logicmp, "icmphostunr fail -> src %I dst %I\n", p->src, p->dst);
|
||||
|
@ -487,7 +487,7 @@ icmpttlexceeded6(Fs *f, Ipifc *ifc, Block *bp)
|
|||
nbp = newIPICMP(sz);
|
||||
np = (IPICMP *) nbp->rp;
|
||||
|
||||
if(ipv6anylocal(ifc, np->src))
|
||||
if(ipv6local(ifc, np->src, p->src))
|
||||
netlog(f, Logicmp, "send icmpttlexceeded6 -> src %I dst %I\n",
|
||||
p->src, p->dst);
|
||||
else {
|
||||
|
@ -526,7 +526,7 @@ icmppkttoobig6(Fs *f, Ipifc *ifc, Block *bp)
|
|||
nbp = newIPICMP(sz);
|
||||
np = (IPICMP *)nbp->rp;
|
||||
|
||||
if(ipv6anylocal(ifc, np->src))
|
||||
if(ipv6local(ifc, np->src, p->src))
|
||||
netlog(f, Logicmp, "send icmppkttoobig6 -> src %I dst %I\n",
|
||||
p->src, p->dst);
|
||||
else {
|
||||
|
@ -778,18 +778,11 @@ icmpiput6(Proto *icmp, Ipifc *ipifc, Block *bp)
|
|||
}
|
||||
bp->rp -= IPICMPSZ;
|
||||
}
|
||||
|
||||
goticmpkt6(icmp, bp, 0);
|
||||
break;
|
||||
|
||||
case RouterAdvert:
|
||||
case RouterSolicit:
|
||||
/* using lsrc as a temp, munge hdr for goticmp6 */
|
||||
if (0) {
|
||||
memmove(lsrc, p->src, IPaddrlen);
|
||||
memmove(p->src, p->dst, IPaddrlen);
|
||||
memmove(p->dst, lsrc, IPaddrlen);
|
||||
}
|
||||
goticmpkt6(icmp, bp, p->type);
|
||||
break;
|
||||
|
||||
|
@ -809,21 +802,21 @@ icmpiput6(Proto *icmp, Ipifc *ipifc, Block *bp)
|
|||
8*np->olen-2, 0);
|
||||
pktflags |= Sflag;
|
||||
}
|
||||
if(ipv6local(ipifc, lsrc))
|
||||
icmpna(icmp->f, lsrc,
|
||||
(ipcmp(np->src, v6Unspecified) == 0?
|
||||
v6allnodesL: np->src),
|
||||
np->target, ipifc->mac, pktflags);
|
||||
else
|
||||
freeblist(bp);
|
||||
if(!ipv6local(ipifc, lsrc, np->src))
|
||||
break;
|
||||
icmpna(icmp->f, lsrc,
|
||||
(ipcmp(np->src, v6Unspecified) == 0?
|
||||
v6allnodesL: np->src),
|
||||
np->target, ipifc->mac, pktflags);
|
||||
break;
|
||||
|
||||
case Tunitent:
|
||||
/* not clear what needs to be done. send up
|
||||
* an icmp mesg saying don't use this address? */
|
||||
default:
|
||||
freeblist(bp);
|
||||
/*
|
||||
* not clear what needs to be done. send up
|
||||
* an icmp mesg saying don't use this address?
|
||||
*/
|
||||
break;
|
||||
}
|
||||
freeblist(bp);
|
||||
break;
|
||||
|
||||
case NbrAdvert:
|
||||
|
@ -839,8 +832,7 @@ icmpiput6(Proto *icmp, Ipifc *ipifc, Block *bp)
|
|||
lifc = iplocalonifc(ipifc, np->target);
|
||||
if(lifc && lifc->tentative)
|
||||
refresh = 0;
|
||||
arpenter(icmp->f, V6, np->target, np->lnaddr, 8*np->olen-2,
|
||||
refresh);
|
||||
arpenter(icmp->f, V6, np->target, np->lnaddr, 8*np->olen-2, refresh);
|
||||
freeblist(bp);
|
||||
break;
|
||||
|
||||
|
|
|
@ -63,8 +63,6 @@ ip_init_6(Fs *f)
|
|||
|
||||
v6p->hp.rxmithost = 1000; /* v6 RETRANS_TIMER */
|
||||
|
||||
v6p->cdrouter = -1;
|
||||
|
||||
f->v6p = v6p;
|
||||
}
|
||||
|
||||
|
@ -118,7 +116,7 @@ iprouting(Fs *f, int on)
|
|||
}
|
||||
|
||||
int
|
||||
ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Conv *c)
|
||||
ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
|
||||
{
|
||||
Ipifc *ifc;
|
||||
uchar *gate;
|
||||
|
@ -156,7 +154,7 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Conv *c)
|
|||
goto free;
|
||||
}
|
||||
|
||||
r = v4lookup(f, eh->dst, c);
|
||||
r = v4lookup(f, eh->dst, rh);
|
||||
if(r == nil){
|
||||
ip->stats[OutNoRoutes]++;
|
||||
netlog(f, Logip, "no interface %V\n", eh->dst);
|
||||
|
@ -193,10 +191,7 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Conv *c)
|
|||
goto raise;
|
||||
|
||||
/* If we dont need to fragment just send it */
|
||||
if(c && c->maxfragsize && c->maxfragsize < ifc->maxtu)
|
||||
medialen = c->maxfragsize - ifc->m->hsize;
|
||||
else
|
||||
medialen = ifc->maxtu - ifc->m->hsize;
|
||||
medialen = ifc->maxtu - ifc->m->hsize;
|
||||
if(len <= medialen) {
|
||||
if(!gating)
|
||||
hnputs(eh->id, incref(&ip->id4));
|
||||
|
@ -315,8 +310,6 @@ ipiput4(Fs *f, Ipifc *ifc, Block *bp)
|
|||
int notforme;
|
||||
uchar *dp, v6dst[IPaddrlen];
|
||||
IP *ip;
|
||||
Route *r;
|
||||
Conv conv;
|
||||
|
||||
if(BLKIPVER(bp) != IP_VER4) {
|
||||
ipiput6(f, ifc, bp);
|
||||
|
@ -377,15 +370,17 @@ ipiput4(Fs *f, Ipifc *ifc, Block *bp)
|
|||
|
||||
/* route */
|
||||
if(notforme) {
|
||||
Route *r;
|
||||
Routehint rh;
|
||||
|
||||
if(!ip->iprouting){
|
||||
freeblist(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* don't forward to source's network */
|
||||
memmove(&conv, ifc->conv, sizeof conv);
|
||||
conv.r = nil;
|
||||
r = v4lookup(f, h->dst, &conv);
|
||||
rh.r = nil;
|
||||
r = v4lookup(f, h->dst, &rh);
|
||||
if(r == nil || r->ifc == ifc){
|
||||
ip->stats[OutDiscards]++;
|
||||
freeblist(bp);
|
||||
|
@ -419,7 +414,7 @@ if(r->ifc == nil) panic("nil route ifc");
|
|||
ip->stats[ForwDatagrams]++;
|
||||
tos = h->tos;
|
||||
hop = h->ttl;
|
||||
ipoput4(f, bp, 1, hop - 1, tos, &conv);
|
||||
ipoput4(f, bp, 1, hop - 1, tos, &rh);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,10 @@ typedef struct Proto Proto;
|
|||
typedef struct Arpent Arpent;
|
||||
typedef struct Arp Arp;
|
||||
typedef struct Route Route;
|
||||
typedef struct Routehint Routehint;
|
||||
|
||||
typedef struct Routerparams Routerparams;
|
||||
typedef struct Hostparams Hostparams;
|
||||
typedef struct v6router v6router;
|
||||
typedef struct v6params v6params;
|
||||
|
||||
#pragma incomplete Arp
|
||||
|
@ -164,6 +164,12 @@ struct Ip4hdr
|
|||
uchar dst[4]; /* IP destination */
|
||||
};
|
||||
|
||||
struct Routehint
|
||||
{
|
||||
Route *r; /* last route used */
|
||||
ulong rgen; /* routetable generation for *r */
|
||||
};
|
||||
|
||||
/*
|
||||
* one per conversation directory
|
||||
*/
|
||||
|
@ -191,8 +197,6 @@ struct Conv
|
|||
int length;
|
||||
int state;
|
||||
|
||||
int maxfragsize; /* If set, used for fragmentation */
|
||||
|
||||
/* udp specific */
|
||||
int headers; /* data src/dst headers in udp */
|
||||
int reliable; /* true if reliable udp */
|
||||
|
@ -217,8 +221,7 @@ struct Conv
|
|||
|
||||
void* ptcl; /* protocol specific stuff */
|
||||
|
||||
Route *r; /* last route used */
|
||||
ulong rgen; /* routetable generation for *r */
|
||||
Routehint;
|
||||
};
|
||||
|
||||
struct Medium
|
||||
|
@ -443,23 +446,10 @@ struct Fs
|
|||
long ndbmtime;
|
||||
};
|
||||
|
||||
/* one per default router known to host */
|
||||
struct v6router {
|
||||
uchar inuse;
|
||||
Ipifc *ifc;
|
||||
int ifcid;
|
||||
uchar routeraddr[IPaddrlen];
|
||||
long ltorigin;
|
||||
Routerparams rp;
|
||||
};
|
||||
|
||||
struct v6params
|
||||
{
|
||||
Routerparams rp; /* v6 params, one copy per node now */
|
||||
Hostparams hp;
|
||||
v6router v6rlist[3]; /* max 3 default routers, currently */
|
||||
int cdrouter; /* uses only v6rlist[cdrouter] if */
|
||||
/* cdrouter >= 0. */
|
||||
};
|
||||
|
||||
|
||||
|
@ -586,8 +576,8 @@ extern void v4addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int
|
|||
extern void v6addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type);
|
||||
extern void v4delroute(Fs *f, uchar *a, uchar *mask, int dolock);
|
||||
extern void v6delroute(Fs *f, uchar *a, uchar *mask, int dolock);
|
||||
extern Route* v4lookup(Fs *f, uchar *a, Conv *c);
|
||||
extern Route* v6lookup(Fs *f, uchar *a, Conv *c);
|
||||
extern Route* v4lookup(Fs *f, uchar *a, Routehint *h);
|
||||
extern Route* v6lookup(Fs *f, uchar *a, Routehint *h);
|
||||
extern long routeread(Fs *f, char*, ulong, int);
|
||||
extern long routewrite(Fs *f, Chan*, char*, int);
|
||||
extern void routetype(int, char*);
|
||||
|
@ -654,6 +644,7 @@ extern int isv4(uchar*);
|
|||
extern void v4tov6(uchar *v6, uchar *v4);
|
||||
extern int v6tov4(uchar *v4, uchar *v6);
|
||||
extern int eipfmt(Fmt*);
|
||||
extern int convipvers(Conv *c);
|
||||
|
||||
#define ipmove(x, y) memmove(x, y, IPaddrlen)
|
||||
#define ipcmp(x, y) ( (x)[IPaddrlen-1] != (y)[IPaddrlen-1] || memcmp(x, y, IPaddrlen) )
|
||||
|
@ -686,9 +677,8 @@ extern int ipisbm(uchar *);
|
|||
extern int ipismulticast(uchar *);
|
||||
extern Ipifc* findipifc(Fs*, uchar *remote, int type);
|
||||
extern void findlocalip(Fs*, uchar *local, uchar *remote);
|
||||
extern int ipv4local(Ipifc *ifc, uchar *addr);
|
||||
extern int ipv6local(Ipifc *ifc, uchar *addr);
|
||||
extern int ipv6anylocal(Ipifc *ifc, uchar *addr);
|
||||
extern int ipv4local(Ipifc *ifc, uchar *local, uchar *remote);
|
||||
extern int ipv6local(Ipifc *ifc, uchar *local, uchar *remote);
|
||||
extern Iplifc* iplocalonifc(Ipifc *ifc, uchar *ip);
|
||||
extern int ipproxyifc(Fs *f, Ipifc *ifc, uchar *ip);
|
||||
extern int ipismulticast(uchar *ip);
|
||||
|
@ -714,8 +704,8 @@ extern void icmpttlexceeded(Fs*, uchar*, Block*);
|
|||
extern ushort ipcsum(uchar*);
|
||||
extern void ipiput4(Fs*, Ipifc*, Block*);
|
||||
extern void ipiput6(Fs*, Ipifc*, Block*);
|
||||
extern int ipoput4(Fs*, Block*, int, int, int, Conv*);
|
||||
extern int ipoput6(Fs*, Block*, int, int, int, Conv*);
|
||||
extern int ipoput4(Fs*, Block*, int, int, int, Routehint*);
|
||||
extern int ipoput6(Fs*, Block*, int, int, int, Routehint*);
|
||||
extern int ipstats(Fs*, char*, int);
|
||||
extern ushort ptclbsum(uchar*, int);
|
||||
extern ushort ptclcsum(Block*, int, int);
|
||||
|
|
|
@ -366,3 +366,12 @@ iphtlook(Ipht *ht, uchar *sa, ushort sp, uchar *da, ushort dp)
|
|||
unlock(ht);
|
||||
return nil;
|
||||
}
|
||||
|
||||
int
|
||||
convipvers(Conv *c)
|
||||
{
|
||||
if(isv4(c->raddr) && isv4(c->laddr) || ipcmp(c->raddr, IPnoaddr) == 0)
|
||||
return V4;
|
||||
else
|
||||
return V6;
|
||||
}
|
||||
|
|
|
@ -1095,7 +1095,7 @@ iptentative(Fs *f, uchar *addr)
|
|||
* 0 - no match
|
||||
* Runi
|
||||
* Rbcast
|
||||
* Rmcast
|
||||
* Rmulti
|
||||
*/
|
||||
int
|
||||
ipforme(Fs *f, uchar *addr)
|
||||
|
@ -1163,7 +1163,6 @@ findipifc(Fs *f, uchar *remote, int type)
|
|||
|
||||
enum {
|
||||
unknownv6, /* UGH */
|
||||
// multicastv6,
|
||||
unspecifiedv6,
|
||||
linklocalv6,
|
||||
globalv6,
|
||||
|
@ -1237,142 +1236,137 @@ findprimaryipv4(Fs *f, uchar *local)
|
|||
return;
|
||||
}
|
||||
}
|
||||
ipmove(local, IPnoaddr);
|
||||
}
|
||||
|
||||
static int
|
||||
comprefixlen(uchar *a, uchar *b, int n)
|
||||
{
|
||||
int i, c;
|
||||
|
||||
for(i = 0; i < n; i++){
|
||||
if((c = a[i] ^ b[i]) == 0)
|
||||
continue;
|
||||
for(i <<= 3; (c & 0x80) == 0; i++)
|
||||
c <<= 1;
|
||||
return i;
|
||||
}
|
||||
return i << 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* find the local address 'closest' to the remote system, copy it to
|
||||
* local and return the ifc for that address
|
||||
* return v4 address associated with an interface close to remote
|
||||
*/
|
||||
int
|
||||
ipv4local(Ipifc *ifc, uchar *local, uchar *remote)
|
||||
{
|
||||
Iplifc *lifc;
|
||||
int a, b;
|
||||
|
||||
b = -1;
|
||||
for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){
|
||||
if(!isv4(lifc->local))
|
||||
continue;
|
||||
a = comprefixlen(lifc->local+IPv4off, remote, IPv4addrlen);
|
||||
if(a > b){
|
||||
b = a;
|
||||
memmove(local, lifc->local+IPv4off, IPv4addrlen);
|
||||
}
|
||||
}
|
||||
return b >= 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* return v6 address associated with an interface close to remote
|
||||
*/
|
||||
int
|
||||
ipv6local(Ipifc *ifc, uchar *local, uchar *remote)
|
||||
{
|
||||
struct {
|
||||
int atype;
|
||||
int deprecated;
|
||||
int comprefixlen;
|
||||
} a, b;
|
||||
int atype;
|
||||
Iplifc *lifc;
|
||||
|
||||
if(isv4(remote)){
|
||||
ipmove(local, v4prefix);
|
||||
return ipv4local(ifc, local+IPv4off, remote+IPv4off);
|
||||
}
|
||||
|
||||
atype = v6addrtype(remote);
|
||||
ipmove(local, v6Unspecified);
|
||||
b.atype = unknownv6;
|
||||
b.deprecated = 1;
|
||||
b.comprefixlen = 0;
|
||||
|
||||
for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){
|
||||
if(lifc->tentative)
|
||||
continue;
|
||||
|
||||
a.atype = v6addrtype(lifc->local);
|
||||
a.deprecated = !v6addrcurr(lifc);
|
||||
a.comprefixlen = comprefixlen(lifc->local, remote, IPaddrlen);
|
||||
|
||||
/* prefer appropriate scope */
|
||||
if(a.atype != b.atype){
|
||||
if(a.atype > b.atype && b.atype < atype ||
|
||||
a.atype < b.atype && b.atype > atype)
|
||||
goto Good;
|
||||
continue;
|
||||
}
|
||||
/* prefer non-deprecated addresses */
|
||||
if(a.deprecated != b.deprecated){
|
||||
if(b.deprecated)
|
||||
goto Good;
|
||||
continue;
|
||||
}
|
||||
/* prefer longer common prefix */
|
||||
if(a.comprefixlen != b.comprefixlen){
|
||||
if(a.comprefixlen > b.comprefixlen)
|
||||
goto Good;
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
Good:
|
||||
b = a;
|
||||
ipmove(local, lifc->local);
|
||||
}
|
||||
|
||||
return b.atype >= atype;
|
||||
}
|
||||
|
||||
/*
|
||||
* find the local address 'closest' to the remote system, copy it to local
|
||||
*/
|
||||
void
|
||||
findlocalip(Fs *f, uchar *local, uchar *remote)
|
||||
{
|
||||
int version, atype = unspecifiedv6, atypel = unknownv6;
|
||||
int atyper, deprecated;
|
||||
uchar gate[IPaddrlen], gnet[IPaddrlen];
|
||||
Ipifc *ifc;
|
||||
Iplifc *lifc;
|
||||
Route *r;
|
||||
|
||||
USED(atype);
|
||||
USED(atypel);
|
||||
qlock(f->ipifc);
|
||||
r = v6lookup(f, remote, nil);
|
||||
version = (memcmp(remote, v4prefix, IPv4off) == 0)? V4: V6;
|
||||
|
||||
if(r != nil){
|
||||
ifc = r->ifc;
|
||||
if(r->type & Rv4)
|
||||
v4tov6(gate, r->v4.gate);
|
||||
else {
|
||||
ipmove(gate, r->v6.gate);
|
||||
ipmove(local, v6Unspecified);
|
||||
if((r = v6lookup(f, remote, nil)) != nil){
|
||||
if(r->type & Runi){
|
||||
ipmove(local, remote);
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch(version) {
|
||||
case V4:
|
||||
/* find ifc address closest to the gateway to use */
|
||||
for(lifc = ifc->lifc; lifc; lifc = lifc->next){
|
||||
maskip(gate, lifc->mask, gnet);
|
||||
if(ipcmp(gnet, lifc->net) == 0){
|
||||
ipmove(local, lifc->local);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case V6:
|
||||
/* find ifc address with scope matching the destination */
|
||||
atyper = v6addrtype(remote);
|
||||
deprecated = 0;
|
||||
for(lifc = ifc->lifc; lifc; lifc = lifc->next){
|
||||
atypel = v6addrtype(lifc->local);
|
||||
/* prefer appropriate scope */
|
||||
if(atypel > atype && atype < atyper ||
|
||||
atypel < atype && atype > atyper){
|
||||
ipmove(local, lifc->local);
|
||||
deprecated = !v6addrcurr(lifc);
|
||||
atype = atypel;
|
||||
} else if(atypel == atype){
|
||||
/* avoid deprecated addresses */
|
||||
if(deprecated && v6addrcurr(lifc)){
|
||||
ipmove(local, lifc->local);
|
||||
atype = atypel;
|
||||
deprecated = 0;
|
||||
}
|
||||
}
|
||||
if(atype == atyper && !deprecated)
|
||||
goto out;
|
||||
}
|
||||
if(atype >= atyper)
|
||||
if((r->type & (Rifc|Rbcast|Rmulti|Rv4)) == Rv4){
|
||||
ipmove(local, v4prefix);
|
||||
if(ipv4local(r->ifc, local+IPv4off, r->v4.gate))
|
||||
goto out;
|
||||
break;
|
||||
default:
|
||||
panic("findlocalip: version %d", version);
|
||||
}
|
||||
if(ipv6local(r->ifc, local, remote))
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch(version){
|
||||
case V4:
|
||||
if(isv4(remote))
|
||||
findprimaryipv4(f, local);
|
||||
break;
|
||||
case V6:
|
||||
else
|
||||
findprimaryipv6(f, local);
|
||||
break;
|
||||
default:
|
||||
panic("findlocalip2: version %d", version);
|
||||
}
|
||||
|
||||
out:
|
||||
qunlock(f->ipifc);
|
||||
}
|
||||
|
||||
/*
|
||||
* return first v4 address associated with an interface
|
||||
*/
|
||||
int
|
||||
ipv4local(Ipifc *ifc, uchar *addr)
|
||||
{
|
||||
Iplifc *lifc;
|
||||
|
||||
for(lifc = ifc->lifc; lifc; lifc = lifc->next){
|
||||
if(isv4(lifc->local)){
|
||||
memmove(addr, lifc->local+IPv4off, IPv4addrlen);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* return first v6 address associated with an interface
|
||||
*/
|
||||
int
|
||||
ipv6local(Ipifc *ifc, uchar *addr)
|
||||
{
|
||||
Iplifc *lifc;
|
||||
|
||||
for(lifc = ifc->lifc; lifc; lifc = lifc->next){
|
||||
if(!isv4(lifc->local) && !(lifc->tentative)){
|
||||
ipmove(addr, lifc->local);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipv6anylocal(Ipifc *ifc, uchar *addr)
|
||||
{
|
||||
Iplifc *lifc;
|
||||
|
||||
for(lifc = ifc->lifc; lifc; lifc = lifc->next){
|
||||
if(!isv4(lifc->local)){
|
||||
ipmove(addr, lifc->local);
|
||||
return SRC_UNI;
|
||||
}
|
||||
}
|
||||
return SRC_UNSPEC;
|
||||
}
|
||||
|
||||
/*
|
||||
* see if this address is bound to the interface
|
||||
*/
|
||||
|
@ -1605,29 +1599,6 @@ ipifcregisterproxy(Fs *f, Ipifc *ifc, uchar *ip)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* added for new v6 mesg types */
|
||||
static void
|
||||
adddefroute6(Fs *f, uchar *gate, int force)
|
||||
{
|
||||
Route *r;
|
||||
|
||||
r = v6lookup(f, v6Unspecified, nil);
|
||||
/*
|
||||
* route entries generated by all other means take precedence
|
||||
* over router announcements.
|
||||
*/
|
||||
if (r && !force && strcmp(r->tag, "ra") != 0)
|
||||
return;
|
||||
|
||||
v6delroute(f, v6Unspecified, v6Unspecified, 1);
|
||||
v6addroute(f, "ra", v6Unspecified, v6Unspecified, gate, 0);
|
||||
}
|
||||
|
||||
enum {
|
||||
Ngates = 3,
|
||||
};
|
||||
|
||||
char*
|
||||
ipifcadd6(Ipifc *ifc, char**argv, int argc)
|
||||
{
|
||||
|
|
|
@ -323,7 +323,6 @@ v4addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type)
|
|||
}
|
||||
|
||||
#define V6H(a) (((a)[IPllen-1] & 0x07ffffff)>>(32-Lroot-5))
|
||||
#define ISDFLT(a, mask, tag) ((ipcmp((a),v6Unspecified)==0) && (ipcmp((mask),v6Unspecified)==0) && (strcmp((tag), "ra")!=0))
|
||||
|
||||
void
|
||||
v6addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type)
|
||||
|
@ -333,12 +332,6 @@ v6addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type)
|
|||
ulong x, y;
|
||||
int h, eh;
|
||||
|
||||
/*
|
||||
if(ISDFLT(a, mask, tag))
|
||||
f->v6p->cdrouter = -1;
|
||||
*/
|
||||
|
||||
|
||||
for(h = 0; h < IPllen; h++){
|
||||
x = nhgetl(a+4*h);
|
||||
y = nhgetl(mask+4*h);
|
||||
|
@ -482,15 +475,15 @@ v6delroute(Fs *f, uchar *a, uchar *mask, int dolock)
|
|||
}
|
||||
|
||||
Route*
|
||||
v4lookup(Fs *f, uchar *a, Conv *c)
|
||||
v4lookup(Fs *f, uchar *a, Routehint *rh)
|
||||
{
|
||||
Route *p, *q;
|
||||
ulong la;
|
||||
uchar gate[IPaddrlen];
|
||||
Ipifc *ifc;
|
||||
|
||||
if(c != nil && c->r != nil && c->r->ifc != nil && c->rgen == v4routegeneration)
|
||||
return c->r;
|
||||
if(rh != nil && rh->r != nil && rh->r->ifc != nil && rh->rgen == v4routegeneration)
|
||||
return rh->r;
|
||||
|
||||
la = nhgetl(a);
|
||||
q = nil;
|
||||
|
@ -517,16 +510,16 @@ v4lookup(Fs *f, uchar *a, Conv *c)
|
|||
q->ifcid = ifc->ifcid;
|
||||
}
|
||||
|
||||
if(c != nil){
|
||||
c->r = q;
|
||||
c->rgen = v4routegeneration;
|
||||
if(rh != nil){
|
||||
rh->r = q;
|
||||
rh->rgen = v4routegeneration;
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
Route*
|
||||
v6lookup(Fs *f, uchar *a, Conv *c)
|
||||
v6lookup(Fs *f, uchar *a, Routehint *rh)
|
||||
{
|
||||
Route *p, *q;
|
||||
ulong la[IPllen];
|
||||
|
@ -536,18 +529,18 @@ v6lookup(Fs *f, uchar *a, Conv *c)
|
|||
Ipifc *ifc;
|
||||
|
||||
if(memcmp(a, v4prefix, IPv4off) == 0){
|
||||
q = v4lookup(f, a+IPv4off, c);
|
||||
q = v4lookup(f, a+IPv4off, rh);
|
||||
if(q != nil)
|
||||
return q;
|
||||
}
|
||||
|
||||
if(c != nil && c->r != nil && c->r->ifc != nil && c->rgen == v6routegeneration)
|
||||
return c->r;
|
||||
if(rh != nil && rh->r != nil && rh->r->ifc != nil && rh->rgen == v6routegeneration)
|
||||
return rh->r;
|
||||
|
||||
for(h = 0; h < IPllen; h++)
|
||||
la[h] = nhgetl(a+4*h);
|
||||
|
||||
q = 0;
|
||||
q = nil;
|
||||
for(p=f->v6root[V6H(la)]; p;){
|
||||
for(h = 0; h < IPllen; h++){
|
||||
x = la[h];
|
||||
|
@ -588,9 +581,10 @@ next: ;
|
|||
q->ifc = ifc;
|
||||
q->ifcid = ifc->ifcid;
|
||||
}
|
||||
if(c != nil){
|
||||
c->r = q;
|
||||
c->rgen = v6routegeneration;
|
||||
|
||||
if(rh != nil){
|
||||
rh->r = q;
|
||||
rh->rgen = v6routegeneration;
|
||||
}
|
||||
|
||||
return q;
|
||||
|
|
|
@ -28,7 +28,7 @@ static Block* procxtns(IP *ip, Block *bp, int doreasm);
|
|||
int unfraglen(Block *bp, uchar *nexthdr, int setfh);
|
||||
|
||||
int
|
||||
ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Conv *c)
|
||||
ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Routehint *rh)
|
||||
{
|
||||
int medialen, len, chunk, uflen, flen, seglen, lid, offset, fragoff;
|
||||
int morefrags, blklen, rv = 0, tentative;
|
||||
|
@ -74,9 +74,8 @@ ipoput6(Fs *f, Block *bp, int gating, int ttl, int tos, Conv *c)
|
|||
goto free;
|
||||
}
|
||||
|
||||
r = v6lookup(f, eh->dst, c);
|
||||
r = v6lookup(f, eh->dst, rh);
|
||||
if(r == nil){
|
||||
// print("no route for %I, src %I free\n", eh->dst, eh->src);
|
||||
ip->stats[OutNoRoutes]++;
|
||||
netlog(f, Logip, "no interface %I\n", eh->dst);
|
||||
rv = -1;
|
||||
|
@ -231,7 +230,6 @@ ipiput6(Fs *f, Ipifc *ifc, Block *bp)
|
|||
IP *ip;
|
||||
Ip6hdr *h;
|
||||
Proto *p;
|
||||
Route *r, *sr;
|
||||
|
||||
ip = f->ip;
|
||||
ip->stats[InReceives]++;
|
||||
|
@ -274,6 +272,9 @@ ipiput6(Fs *f, Ipifc *ifc, Block *bp)
|
|||
|
||||
/* route */
|
||||
if(notforme) {
|
||||
Route *r;
|
||||
Routehint rh;
|
||||
|
||||
if(!ip->iprouting){
|
||||
freeblist(bp);
|
||||
return;
|
||||
|
@ -288,10 +289,9 @@ ipiput6(Fs *f, Ipifc *ifc, Block *bp)
|
|||
}
|
||||
|
||||
/* don't forward to source's network */
|
||||
sr = v6lookup(f, h->src, nil);
|
||||
r = v6lookup(f, h->dst, nil);
|
||||
|
||||
if(r == nil || sr == r){
|
||||
rh.r = nil;
|
||||
r = v6lookup(f, h->dst, &rh);
|
||||
if(r == nil || r->ifc == ifc){
|
||||
ip->stats[OutDiscards]++;
|
||||
freeblist(bp);
|
||||
return;
|
||||
|
@ -315,7 +315,7 @@ ipiput6(Fs *f, Ipifc *ifc, Block *bp)
|
|||
h = (Ip6hdr *)bp->rp;
|
||||
tos = IPV6CLASS(h);
|
||||
hop = h->ttl;
|
||||
ipoput6(f, bp, 1, hop-1, tos, nil);
|
||||
ipoput6(f, bp, 1, hop-1, tos, &rh);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -567,7 +567,7 @@ rudpiput(Proto *rudp, Ipifc *ifc, Block *bp)
|
|||
if(ipforme(f, laddr) == Runi)
|
||||
ipmove(c->laddr, laddr);
|
||||
else
|
||||
v4tov6(c->laddr, ifc->lifc->local);
|
||||
ipv6local(ifc, c->laddr, c->raddr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -189,7 +189,7 @@ udpkick(void *x, Block *bp)
|
|||
Udppriv *upriv;
|
||||
Fs *f;
|
||||
int version;
|
||||
Conv *rc;
|
||||
Routehint *rh;
|
||||
|
||||
upriv = c->p->priv;
|
||||
f = c->p->f;
|
||||
|
@ -222,18 +222,12 @@ udpkick(void *x, Block *bp)
|
|||
}
|
||||
|
||||
if(ucb->headers) {
|
||||
if(memcmp(laddr, v4prefix, IPv4off) == 0
|
||||
|| ipcmp(laddr, IPnoaddr) == 0)
|
||||
version = 4;
|
||||
if(isv4(laddr) || ipcmp(laddr, IPnoaddr) == 0)
|
||||
version = V4;
|
||||
else
|
||||
version = 6;
|
||||
version = V6;
|
||||
} else {
|
||||
if( (memcmp(c->raddr, v4prefix, IPv4off) == 0 &&
|
||||
memcmp(c->laddr, v4prefix, IPv4off) == 0)
|
||||
|| ipcmp(c->raddr, IPnoaddr) == 0)
|
||||
version = 4;
|
||||
else
|
||||
version = 6;
|
||||
version = convipvers(c);
|
||||
}
|
||||
|
||||
dlen = blocklen(bp);
|
||||
|
@ -253,14 +247,14 @@ udpkick(void *x, Block *bp)
|
|||
v6tov4(uh4->udpdst, raddr);
|
||||
hnputs(uh4->udpdport, rport);
|
||||
v6tov4(uh4->udpsrc, laddr);
|
||||
rc = nil;
|
||||
rh = nil;
|
||||
} else {
|
||||
v6tov4(uh4->udpdst, c->raddr);
|
||||
hnputs(uh4->udpdport, c->rport);
|
||||
if(ipcmp(c->laddr, IPnoaddr) == 0)
|
||||
findlocalip(f, c->laddr, c->raddr);
|
||||
v6tov4(uh4->udpsrc, c->laddr);
|
||||
rc = c;
|
||||
rh = c;
|
||||
}
|
||||
hnputs(uh4->udpsport, c->lport);
|
||||
hnputs(uh4->udplen, ptcllen);
|
||||
|
@ -269,7 +263,7 @@ udpkick(void *x, Block *bp)
|
|||
hnputs(uh4->udpcksum,
|
||||
ptclcsum(bp, UDP4_PHDR_OFF, dlen+UDP_UDPHDR_SZ+UDP4_PHDR_SZ));
|
||||
uh4->vihl = IP_VER4;
|
||||
ipoput4(f, bp, 0, c->ttl, c->tos, rc);
|
||||
ipoput4(f, bp, 0, c->ttl, c->tos, rh);
|
||||
break;
|
||||
|
||||
case V6:
|
||||
|
@ -287,14 +281,14 @@ udpkick(void *x, Block *bp)
|
|||
ipmove(uh6->udpdst, raddr);
|
||||
hnputs(uh6->udpdport, rport);
|
||||
ipmove(uh6->udpsrc, laddr);
|
||||
rc = nil;
|
||||
rh = nil;
|
||||
} else {
|
||||
ipmove(uh6->udpdst, c->raddr);
|
||||
hnputs(uh6->udpdport, c->rport);
|
||||
if(ipcmp(c->laddr, IPnoaddr) == 0)
|
||||
findlocalip(f, c->laddr, c->raddr);
|
||||
ipmove(uh6->udpsrc, c->laddr);
|
||||
rc = c;
|
||||
rh = c;
|
||||
}
|
||||
hnputs(uh6->udpsport, c->lport);
|
||||
hnputs(uh6->udplen, ptcllen);
|
||||
|
@ -306,7 +300,7 @@ udpkick(void *x, Block *bp)
|
|||
uh6->viclfl[0] = IP_VER6;
|
||||
hnputs(uh6->len, ptcllen);
|
||||
uh6->nextheader = IP_UDPPROTO;
|
||||
ipoput6(f, bp, 0, c->ttl, c->tos, rc);
|
||||
ipoput6(f, bp, 0, c->ttl, c->tos, rh);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -336,7 +330,7 @@ udpiput(Proto *udp, Ipifc *ifc, Block *bp)
|
|||
upriv->ustats.udpInDatagrams++;
|
||||
|
||||
uh4 = (Udp4hdr*)(bp->rp);
|
||||
version = ((uh4->vihl&0xF0)==IP_VER6) ? 6 : 4;
|
||||
version = ((uh4->vihl&0xF0)==IP_VER6) ? V6 : V4;
|
||||
|
||||
/* Put back pseudo header for checksum
|
||||
* (remember old values for icmpnoconv()) */
|
||||
|
@ -424,18 +418,8 @@ udpiput(Proto *udp, Ipifc *ifc, Block *bp)
|
|||
if(c->state == Announced){
|
||||
if(ucb->headers == 0){
|
||||
/* create a new conversation */
|
||||
if(ipforme(f, laddr) != Runi) {
|
||||
switch(version){
|
||||
case V4:
|
||||
v4tov6(laddr, ifc->lifc->local);
|
||||
break;
|
||||
case V6:
|
||||
ipmove(laddr, ifc->lifc->local);
|
||||
break;
|
||||
default:
|
||||
panic("udpiput3: version %d", version);
|
||||
}
|
||||
}
|
||||
if(ipforme(f, laddr) != Runi)
|
||||
ipv6local(ifc, laddr, raddr);
|
||||
c = Fsnewcall(c, raddr, rport, laddr, lport, version);
|
||||
if(c == nil){
|
||||
qunlock(udp);
|
||||
|
@ -533,7 +517,7 @@ udpadvise(Proto *udp, Block *bp, char *msg)
|
|||
int version;
|
||||
|
||||
h4 = (Udp4hdr*)(bp->rp);
|
||||
version = ((h4->vihl&0xF0)==IP_VER6) ? 6 : 4;
|
||||
version = ((h4->vihl&0xF0)==IP_VER6) ? V6 : V4;
|
||||
|
||||
switch(version) {
|
||||
case V4:
|
||||
|
|
|
@ -468,7 +468,6 @@ static void
|
|||
recvrarouter(uchar buf[], int pktlen)
|
||||
{
|
||||
USED(buf, pktlen);
|
||||
ralog("i am a router and got a router advert");
|
||||
}
|
||||
|
||||
/* host receiving a router advertisement calls this */
|
||||
|
|
Loading…
Reference in a new issue