From 0fb1379c9e77672723371e235624c17c3216afcf Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 1 Jun 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-06-01 --- ip/arp.c | 89 +++++++---------------- ip/devip.c | 16 ++++- ip/ethermedium.c | 43 ++++++++--- ip/icmp.c | 4 +- ip/icmp6.c | 17 +---- ip/il.c | 2 +- ip/ip.h | 3 +- ip/ipifc.c | 23 ++++-- ip/tcp.c | 183 ++++++++++++++++++++++++++++------------------- ip/udp.c | 97 +++++++++++++++---------- 10 files changed, 262 insertions(+), 215 deletions(-) diff --git a/ip/arp.c b/ip/arp.c index 433529f36775d5f4dfd7a204440d9f2488e5f6b4..e9b4fa83729f37f67e6d696412f43e3fe706441e 100644 --- a/ip/arp.c +++ b/ip/arp.c @@ -60,56 +60,9 @@ arpinit(Fs *f) kproc("rxmitproc", rxmitproc, f->arp); } -static Arpent* -newarp(Arp *arp, uchar *ip, Medium *m) -{ - uint t; - Block *next, *xp; - Arpent *a, *e, *f, **l; - - /* find oldest entry */ - e = &arp->cache[NCACHE]; - a = arp->cache; - t = a->used; - for(f = a; f < e; f++){ - if(f->used < t){ - t = f->used; - a = f; - } - } - - /* dump waiting packets */ - xp = a->hold; - a->hold = nil; - - while(xp){ - next = xp->list; - freeblist(xp); - xp = next; - } - - /* take out of current chain */ - l = &arp->hash[haship(a->ip)]; - for(f = *l; f; f = f->hash){ - if(f == a){ - *l = a->hash; - break; - } - l = &f->hash; - } - - /* insert into new chain */ - l = &arp->hash[haship(ip)]; - a->hash = *l; - *l = a; - memmove(a->ip, ip, sizeof(a->ip)); - a->used = msec; - a->time = 0; - a->type = m; - - return a; -} - +/* + * create a new arp entry for an ip address. + */ static Arpent* newarp6(Arp *arp, uchar *ip, Ipifc *ifc, int addrxt) { @@ -243,6 +196,12 @@ cleanarpent(Arp *arp, Arpent *a) a->ifc = nil; } +/* + * fill in the media address if we have it. Otherwise return an + * Arpent that represents the state of the address resolution FSM + * for ip. Add the packet to be sent onto the list of packets + * waiting for ip->mac to be resolved. + */ Arpent* arpget(Arp *arp, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *mac) { @@ -265,11 +224,7 @@ arpget(Arp *arp, Block *bp, int version, Ipifc *ifc, uchar *ip, uchar *mac) } if(a == nil){ - //a = newarp6(arp, ip, ifc, (version != V4)); - if(version == V4) - a = newarp(arp, ip, type); - else - a = newarp6(arp, ip, ifc, 1); + a = newarp6(arp, ip, ifc, (version != V4)); a->state = AWAIT; } a->used = msec; @@ -300,6 +255,9 @@ arprelease(Arp *arp, Arpent*) } /* + * Copy out the mac address from the Arpent. Return the + * block waiting to get sent to this mac address. + * * called with arp locked */ Block* @@ -348,13 +306,19 @@ arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, int refresh) return; } - if(version == V4){ + switch(version){ + case V4: r = v4lookup(fs, ip); v4tov6(v6ip, ip); ip = v6ip; - } - else + break; + case V6: r = v6lookup(fs, ip); + break; + default: + panic("arpenter: version %d", version); + return; /* to supress warnings */ + } if(r == nil){ // print("arp: no route for entry\n"); @@ -417,12 +381,7 @@ arpenter(Fs *fs, int version, uchar *ip, uchar *mac, int n, int refresh) } if(refresh == 0){ - //a = newarp6(arp, ip, ifc, 0); - if(version == 4) - a = newarp(arp, ip, type); - else - a = newarp6(arp, ip, ifc, 0); - + a = newarp6(arp, ip, ifc, 0); a->state = AOK; a->type = type; memmove(a->mac, mac, type->maclen); @@ -672,7 +631,7 @@ rxmitproc(void *v) long wakeupat; arp->rxmitp = up; - print("arp rxmitproc started\n"); + //print("arp rxmitproc started\n"); if(waserror()){ arp->rxmitp = 0; pexit("hangup", 1); diff --git a/ip/devip.c b/ip/devip.c index 675a81ab5f70869cb7735931751b61e40d2831bd..921ca6f8aa6db6e5e7ee356f3f938d5a29acc251 100644 --- a/ip/devip.c +++ b/ip/devip.c @@ -878,8 +878,18 @@ Fsstdconnect(Conv *c, char *argv[], int argc) p = setraddrport(c, argv[1]); if(p != nil) return p; - return setladdrport(c, argv[2], 0); + p = setladdrport(c, argv[2], 0); + if(p != nil) + 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; + return nil; } /* @@ -1308,7 +1318,7 @@ Fsrcvpcolx(Fs *f, uchar proto) * called with protocol locked */ Conv* -Fsnewcall(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport) +Fsnewcall(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport, uchar version) { Conv *nc; Conv **l; @@ -1336,6 +1346,8 @@ Fsnewcall(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport) nc->next = nil; *l = nc; nc->state = Connected; + nc->ipversion = version; + qunlock(c); wakeup(&c->listenr); diff --git a/ip/ethermedium.c b/ip/ethermedium.c index 7eb62ea2ebf95991cd02735580beb9435140eb4c..2d736d610b70b3a3bc5c4d622c9f26b171afe318 100644 --- a/ip/ethermedium.c +++ b/ip/ethermedium.c @@ -252,10 +252,16 @@ etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip) /* check for broadcast or multicast */ bp = multicastarp(er->f, a, ifc->m, mac); if(bp==nil){ - if(version == V4) + switch(version){ + case V4: sendarp(ifc, a); - else + break; + case V6: resolveaddr6(ifc, a); + break; + default: + panic("etherbwrite: version %d", version); + } return; } } @@ -283,6 +289,8 @@ etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip) eh->t[1] = 0xDD; devtab[er->mchan6->type]->bwrite(er->mchan6, bp, 0); break; + default: + panic("etherbwrite2: version %d", version); } ifc->out++; } @@ -371,14 +379,20 @@ etheraddmulti(Ipifc *ifc, uchar *a, uchar *) uchar mac[6]; char buf[64]; Etherrock *er = ifc->arg; - int type; + int version; - type = multicastea(mac, a); + version = multicastea(mac, a); sprint(buf, "addmulti %E", mac); - if(type == V4) + switch(version){ + case V4: devtab[er->cchan4->type]->write(er->cchan4, buf, strlen(buf), 0); - else if(type == V6) + break; + case V6: devtab[er->cchan6->type]->write(er->cchan6, buf, strlen(buf), 0); + break; + default: + panic("etheraddmulti: version %d", version); + } } static void @@ -387,14 +401,20 @@ etherremmulti(Ipifc *ifc, uchar *a, uchar *) uchar mac[6]; char buf[64]; Etherrock *er = ifc->arg; - int type; + int version; - type = multicastea(mac, a); + version = multicastea(mac, a); sprint(buf, "remmulti %E", mac); - if(type == V4) + switch(version){ + case V4: devtab[er->cchan4->type]->write(er->cchan4, buf, strlen(buf), 0); - else if(type == V6) + break; + case V6: devtab[er->cchan6->type]->write(er->cchan6, buf, strlen(buf), 0); + break; + default: + panic("etherremmulti: version %d", version); + } } /* @@ -659,7 +679,8 @@ multicastea(uchar *ea, uchar *ip) /* * fill in an arp entry for broadcast or multicast - * addresses + * addresses. Return the first queued packet for the + * IP address. */ static Block* multicastarp(Fs *f, Arpent *a, Medium *medium, uchar *mac) diff --git a/ip/icmp.c b/ip/icmp.c index 7d5256ef0e7005c1eb85dffe74c92418da90be91..2dcc05347bd4bbd849da0eae8a4d80c5d353cdad 100644 --- a/ip/icmp.c +++ b/ip/icmp.c @@ -110,9 +110,11 @@ icmpconnect(Conv *c, char **argv, int argc) char *e; e = Fsstdconnect(c, argv, argc); + if(e != nil) + return e; Fsconnected(c, e); - return e; + return nil; } extern int diff --git a/ip/icmp6.c b/ip/icmp6.c index b578779f7d7482f07abb7fde813f42da7b67f15f..ca1f36ff892dc75ae96f9c0db9b16f9be2abb459 100644 --- a/ip/icmp6.c +++ b/ip/icmp6.c @@ -196,18 +196,6 @@ newIPICMP(int packetlen) return nbp; } - -char* -icmpconnect6(Conv *c, char **argv, int argc) -{ - char *e; - - e = Fsstdconnect(c, argv, argc); - Fsconnected(c, e); - - return e; -} - void icmpadvise6(Proto *icmp, Block *bp, char *msg) { @@ -245,7 +233,6 @@ icmpkick6(Conv *c) if(icb->headers==6) { /* get user specified addresses */ -//print("icmpkick6: headers\n"); bp = pullupblock(bp, ICMP_USEAD6); if(bp == nil) return; @@ -275,7 +262,6 @@ icmpkick6(Conv *c) p->vcf[0] = 0x06 << 4; if(p->type <= Maxtype6) ipriv->out[p->type]++; -//print("icmpkick6: src %I dst %I\n", p->src, p->dst); ipoput6(c->p->f, bp, 0, c->ttl, c->tos); } @@ -893,6 +879,7 @@ icmpstats6(Proto *icmp6, char *buf, int len) // need to import from icmp.c extern int icmpstate(Conv *c, char *state, int n); extern char* icmpannounce(Conv *c, char **argv, int argc); +extern char* icmpconnect(Conv *c, char **argv, int argc); extern void icmpcreate(Conv *c); extern void icmpclose(Conv *c); @@ -904,7 +891,7 @@ icmp6init(Fs *fs) icmp6->priv = smalloc(sizeof(Icmppriv6)); icmp6->name = "icmpv6"; icmp6->kick = icmpkick6; - icmp6->connect = icmpconnect6; + icmp6->connect = icmpconnect; icmp6->announce = icmpannounce; icmp6->state = icmpstate; icmp6->create = icmpcreate; diff --git a/ip/il.c b/ip/il.c index ba051512cd5da7eed9a3017b1e9478d54a10873d..8476d1445fb8a6302179017c09d72f78d3f0f094 100644 --- a/ip/il.c +++ b/ip/il.c @@ -597,7 +597,7 @@ iliput(Proto *il, Ipifc*, Block *bp) goto raise; } - new = Fsnewcall(s, raddr, dp, laddr, sp); + new = Fsnewcall(s, raddr, dp, laddr, sp, V4); if(new == nil){ qunlock(il); netlog(il->f, Logil, "il: bad newcall %I/%ud->%ud\n", raddr, sp, dp); diff --git a/ip/ip.h b/ip/ip.h index e4ece284eb906f24aeca093c05248d8d6f83395f..06b5da74dbcae4f600833464c03d106b581efe03 100644 --- a/ip/ip.h +++ b/ip/ip.h @@ -84,6 +84,7 @@ struct Conv ushort rport; /* remote port number */ uint ttl; /* max time to live */ uint tos; /* type of service */ + uchar ipversion; /* IPv4 or IPv6 */ char *owner; /* protections */ int perm; @@ -360,7 +361,7 @@ struct v6params int Fsconnected(Conv*, char*); -Conv* Fsnewcall(Conv*, uchar*, ushort, uchar*, ushort); +Conv* Fsnewcall(Conv*, uchar*, ushort, uchar*, ushort, uchar); int Fspcolstats(char*, int); int Fsproto(Fs*, Proto*); int Fsbuiltinproto(Fs*, uchar); diff --git a/ip/ipifc.c b/ip/ipifc.c index 55d408e28ad91729f486bd79e5808cd5b6691d10..567d57dd09ae9619fc61cf30829ea05b974f123c 100644 --- a/ip/ipifc.c +++ b/ip/ipifc.c @@ -1278,7 +1278,7 @@ findlocalip(Fs *f, uchar *local, uchar *remote) USED(atypel); qlock(f->ipifc); r = v6lookup(f, remote); - version = (memcmp(remote, v4prefix, IPv4off) == 0) ? 4 : 6; + version = (memcmp(remote, v4prefix, IPv4off) == 0) ? V4 : V6; if(r != nil){ ifc = r->ifc; @@ -1290,7 +1290,8 @@ findlocalip(Fs *f, uchar *local, uchar *remote) } /* find ifc address closest to the gateway to use */ - if(version == 4) { + switch(version) { + case V4: for(lifc = ifc->lifc; lifc; lifc = lifc->next){ maskip(gate, lifc->mask, gnet); if(ipcmp(gnet, lifc->net) == 0){ @@ -1298,8 +1299,8 @@ findlocalip(Fs *f, uchar *local, uchar *remote) goto out; } } - } - else { + break; + case V6: for(lifc = ifc->lifc; lifc; lifc = lifc->next){ atypel = v6addrtype(lifc->local); maskip(gate, lifc->mask, gnet); @@ -1314,14 +1315,22 @@ findlocalip(Fs *f, uchar *local, uchar *remote) } if(atype > unspecifiedv6) goto out; + break; + default: + panic("findlocalip: version %d", version); } } - if(version == 4) + switch(version){ + case V4: findprimaryip(f, local); - else + break; + case V6: findprimaryip6(f, local); - + break; + default: + panic("findlocalip2: version %d", version); + } out: qunlock(f->ipifc); diff --git a/ip/tcp.c b/ip/tcp.c index 5dab83c0dae7500426c908328fe392ccf217f8f4..9f8433700e2b10bc7739bc3dcfea839543d8ad53 100644 --- a/ip/tcp.c +++ b/ip/tcp.c @@ -676,15 +676,22 @@ tcpmtu(Conv *s) { Ipifc *ifc; int mtu; - int version = (isv4(s->raddr) && isv4(s->laddr)) ? 4 : 6; + uchar version; + version = s->ipversion; mtu = 0; ifc = findipifc(s->p->f, s->raddr, 0); if(ifc != nil) { - if(version == 4) + switch(version){ + case V4: mtu = ifc->maxmtu - ifc->m->hsize - (TCP4_PKT + TCP4_HDRSIZE); - else + break; + case V6: mtu = ifc->maxmtu - ifc->m->hsize - (TCP6_PKT + TCP6_HDRSIZE); + break; + default: + panic("tcpmtu: version %d", version); + } } if(mtu < 32) { @@ -698,6 +705,9 @@ void inittcpctl(Conv *s, int mode) { Tcpctl *tcb; + Tcp4hdr* h4; + Tcp6hdr* h6; + tcb = (Tcpctl*)s->ptcl; memset(tcb, 0, sizeof(Tcpctl)); @@ -719,28 +729,32 @@ inittcpctl(Conv *s, int mode) tcb->katimer.arg = s; /* create a prototype(pseudo) header */ - if(mode != TCP_LISTEN) - if(ipcmp(s->laddr, IPnoaddr) == 0) - findlocalip(s->p->f, s->laddr, s->raddr); - -// if(isv4(s->raddr)) { - if(memcmp(s->raddr, v4prefix, IPv4off) == 0 && - memcmp(s->laddr, v4prefix, IPv4off) == 0) { - Tcp4hdr* h4 = &tcb->protohdr.tcp4hdr; - memset(h4, 0, sizeof(*h4)); - h4->proto = IP_TCPPROTO; - hnputs(h4->tcpsport, s->lport); - hnputs(h4->tcpdport, s->rport); - v6tov4(h4->tcpsrc, s->laddr); - v6tov4(h4->tcpdst, s->raddr); - } else { - Tcp6hdr* h6 = &tcb->protohdr.tcp6hdr; - memset(h6, 0, sizeof(*h6)); - h6->proto = IP_TCPPROTO; - hnputs(h6->tcpsport, s->lport); - hnputs(h6->tcpdport, s->rport); - ipmove(h6->tcpsrc, s->laddr); - ipmove(h6->tcpdst, s->raddr); + if(mode != TCP_LISTEN){ + if(ipcmp(s->laddr, IPnoaddr) == 0) + findlocalip(s->p->f, s->laddr, s->raddr); + + switch(s->ipversion){ + case V4: + h4 = &tcb->protohdr.tcp4hdr; + memset(h4, 0, sizeof(*h4)); + h4->proto = IP_TCPPROTO; + hnputs(h4->tcpsport, s->lport); + hnputs(h4->tcpdport, s->rport); + v6tov4(h4->tcpsrc, s->laddr); + v6tov4(h4->tcpdst, s->raddr); + break; + case V6: + h6 = &tcb->protohdr.tcp6hdr; + memset(h6, 0, sizeof(*h6)); + h6->proto = IP_TCPPROTO; + hnputs(h6->tcpsport, s->lport); + hnputs(h6->tcpdport, s->rport); + ipmove(h6->tcpsrc, s->laddr); + ipmove(h6->tcpdst, s->raddr); + break; + default: + panic("inittcpctl: version %d", s->ipversion); + } } tcb->mss = tcb->cwind = tcpmtu(s); @@ -1062,7 +1076,7 @@ tcpsndsyn(Tcpctl *tcb) } void -sndrst(Proto *tcp, uchar *source, uchar *dest, ushort length, Tcp *seg, int version) +sndrst(Proto *tcp, uchar *source, uchar *dest, ushort length, Tcp *seg, uchar version) { Block *hbp; uchar rflags; @@ -1076,7 +1090,8 @@ sndrst(Proto *tcp, uchar *source, uchar *dest, ushort length, Tcp *seg, int vers return; /* make pseudo header */ - if(version == 4) { + switch(version) { + case V4: memset(&ph4, 0, sizeof(ph4)); ph4.vihl = IP_VER4; v6tov4(ph4.tcpsrc, dest); @@ -1085,8 +1100,8 @@ sndrst(Proto *tcp, uchar *source, uchar *dest, ushort length, Tcp *seg, int vers hnputs(ph4.tcplen, TCP4_HDRSIZE); hnputs(ph4.tcpsport, seg->dest); hnputs(ph4.tcpdport, seg->source); - } - else { + break; + case V6: memset(&ph6, 0, sizeof(ph6)); ph6.vcf[0] = IP_VER6; ipmove(ph6.tcpsrc, dest); @@ -1095,6 +1110,9 @@ sndrst(Proto *tcp, uchar *source, uchar *dest, ushort length, Tcp *seg, int vers hnputs(ph6.ploadlen, TCP6_HDRSIZE); hnputs(ph6.tcpsport, seg->dest); hnputs(ph6.tcpdport, seg->source); + break; + default: + panic("sndrst: version %d", version); } tpriv->stats[OutRsts]++; @@ -1119,17 +1137,21 @@ sndrst(Proto *tcp, uchar *source, uchar *dest, ushort length, Tcp *seg, int vers seg->wnd = 0; seg->urg = 0; seg->mss = 0; - if(version == 4) { + switch(version) { + case V4: hbp = htontcp4(seg, nil, &ph4, nil); if(hbp == nil) return; ipoput4(tcp->f, hbp, 0, MAXTTL, DFLTTOS); - } - else { + break; + case V6: hbp = htontcp6(seg, nil, &ph6, nil); if(hbp == nil) return; ipoput6(tcp->f, hbp, 0, MAXTTL, DFLTTOS); + break; + default: + panic("sndrst2: version %d", version); } } @@ -1148,7 +1170,6 @@ tcphangup(Conv *s) if(waserror()) return commonerror(); if(s->raddr != 0) { - int version = isv4(s->raddr) ? 4 : 6; seg.flags = RST | ACK; seg.ack = tcb->rcv.nxt; seg.seq = tcb->snd.ptr; @@ -1156,15 +1177,19 @@ tcphangup(Conv *s) seg.urg = 0; seg.mss = 0; tcb->last_ack = tcb->rcv.nxt; - if(version == 4) { + switch(s->ipversion) { + case V4: tcb->protohdr.tcp4hdr.vihl = IP_VER4; hbp = htontcp4(&seg, nil, &tcb->protohdr.tcp4hdr, tcb); ipoput4(s->p->f, hbp, 0, s->ttl, s->tos); - } - else { + break; + case V6: tcb->protohdr.tcp6hdr.vcf[0] = IP_VER6; hbp = htontcp6(&seg, nil, &tcb->protohdr.tcp6hdr, tcb); ipoput6(s->p->f, hbp, 0, s->ttl, s->tos); + break; + default: + panic("tcphangup: version %d", s->ipversion); } } localclose(s, nil); @@ -1172,14 +1197,16 @@ tcphangup(Conv *s) return nil; } -Conv* -tcpincoming(Conv *s, Tcp *segp, uchar *src, uchar *dst) +static Conv* +tcpincoming(Conv *s, Tcp *segp, uchar *src, uchar *dst, uchar version) { Conv *new; Tcpctl *tcb; Tcppriv *tpriv; + Tcp4hdr *h4; + Tcp6hdr *h6; - new = Fsnewcall(s, src, segp->source, dst, segp->dest); + new = Fsnewcall(s, src, segp->source, dst, segp->dest, version); if(new == nil) return nil; @@ -1195,23 +1222,27 @@ tcpincoming(Conv *s, Tcp *segp, uchar *src, uchar *dst) tcb->rtt_timer.arg = new; tcb->rtt_timer.state = TcptimerOFF; - if(isv4(src)) { - Tcp4hdr *h = &tcb->protohdr.tcp4hdr; - memset(h, 0, sizeof(*h)); - h->proto = IP_TCPPROTO; - hnputs(h->tcpsport, new->lport); - hnputs(h->tcpdport, new->rport); - v6tov4(h->tcpsrc, dst); - v6tov4(h->tcpdst, src); - } - else { - Tcp6hdr *h = &tcb->protohdr.tcp6hdr; - memset(h, 0, sizeof(*h)); - h->proto = IP_TCPPROTO; - hnputs(h->tcpsport, new->lport); - hnputs(h->tcpdport, new->rport); - ipmove(h->tcpsrc, dst); - ipmove(h->tcpdst, src); + switch(version){ + case V4: + h4 = &tcb->protohdr.tcp4hdr; + memset(h4, 0, sizeof(*h4)); + h4->proto = IP_TCPPROTO; + hnputs(h4->tcpsport, new->lport); + hnputs(h4->tcpdport, new->rport); + v6tov4(h4->tcpsrc, dst); + v6tov4(h4->tcpdst, src); + break; + case V6: + h6 = &tcb->protohdr.tcp6hdr; + memset(h6, 0, sizeof(*h6)); + h6->proto = IP_TCPPROTO; + hnputs(h6->tcpsport, new->lport); + hnputs(h6->tcpdport, new->rport); + ipmove(h6->tcpsrc, dst); + ipmove(h6->tcpdst, src); + break; + default: + panic("tcpincoming: version %d", new->ipversion); } tpriv = new->p->priv; @@ -1442,7 +1473,7 @@ tcpiput(Proto *tcp, Ipifc*, Block *bp) Conv *s; Fs *f; Tcppriv *tpriv; - int version; + uchar version; f = tcp->f; tpriv = tcp->priv; @@ -1453,7 +1484,7 @@ tcpiput(Proto *tcp, Ipifc*, Block *bp) h6 = (Tcp6hdr*)(bp->rp); if((h4->vihl&0xF0)==IP_VER4) { - version = 4; + version = V4; length = nhgets(h4->length); v4tov6(dest, h4->tcpdst); v4tov6(source, h4->tcpsrc); @@ -1491,7 +1522,7 @@ tcpiput(Proto *tcp, Ipifc*, Block *bp) int ttl = h6->ttl; int proto = h6->proto; - version = 6; + version = V6; length = nhgets(h6->ploadlen); ipmove(dest, h6->tcpdst); ipmove(source, h6->tcpsrc); @@ -1554,7 +1585,7 @@ reset: if((seg.flags & SYN) == 0 || (seg.flags & ACK) != 0) goto reset; - s = tcpincoming(s, &seg, source, dest); + s = tcpincoming(s, &seg, source, dest, version); if(s == nil) goto reset; } @@ -1893,18 +1924,11 @@ tcpoutput(Conv *s) ulong ssize, dsize, usable, sent; Fs *f; Tcppriv *tpriv; - //int version = isv4(s->raddr) ? 4 : 6; - int version; - - if( (memcmp(s->raddr, v4prefix, IPv4off) == 0 && - memcmp(s->laddr, v4prefix, IPv4off) == 0) - || ipcmp(s->raddr, IPnoaddr) == 0) - version = 4; - else - version = 6; + uchar version; f = s->p->f; tpriv = s->p->priv; + version = s->ipversion; for(msgs = 0; msgs < 100; msgs++) { tcb = (Tcpctl*)s->ptcl; @@ -2033,21 +2057,26 @@ tcpoutput(Conv *s) tcb->snd.nxt = tcb->snd.ptr; /* Build header, link data and compute cksum */ - if(version == 4) { + switch(version){ + case V4: tcb->protohdr.tcp4hdr.vihl = IP_VER4; hbp = htontcp4(&seg, bp, &tcb->protohdr.tcp4hdr, tcb); if(hbp == nil) { freeblist(bp); return; } - } - else { + break; + case V6: tcb->protohdr.tcp6hdr.vcf[0] = IP_VER6; hbp = htontcp6(&seg, bp, &tcb->protohdr.tcp6hdr, tcb); if(hbp == nil) { freeblist(bp); return; } + break; + default: + hbp = nil; /* to suppress a warning */ + panic("tcpoutput: version %d", version); } /* Start the transmission timers if there is new data and we @@ -2076,10 +2105,16 @@ tcpoutput(Conv *s) qlock(s); nexterror(); } - if(version == 4) + switch(version){ + case V4: ipoput4(f, hbp, 0, s->ttl, s->tos); - else + break; + case V6: ipoput6(f, hbp, 0, s->ttl, s->tos); + break; + default: + panic("tcpoutput2: version %d", version); + } qlock(s); poperror(); } diff --git a/ip/udp.c b/ip/udp.c index 7ff5dc8e3efc2f8993cc8fa9d11e9a71721aab33..80882c7874a4d00641f30a6f85512ac01119eed4 100644 --- a/ip/udp.c +++ b/ip/udp.c @@ -250,18 +250,14 @@ udpkick(Conv *c) } dlen = blocklen(bp); - /* Make space to fit udp & ip header */ - if(version == 4) - bp = padblock(bp, UDP4_IPHDR_SZ+UDP_UDPHDR_SZ); - else - bp = padblock(bp, UDP6_IPHDR_SZ+UDP_UDPHDR_SZ); - - if(bp == nil) - return; /* fill in pseudo header and compute checksum */ - if(version == 4) - { + switch(version){ + case V4: + bp = padblock(bp, UDP4_IPHDR_SZ+UDP_UDPHDR_SZ); + if(bp == nil) + return; + uh4 = (Udp4hdr *)(bp->rp); ptcllen = dlen + UDP_UDPHDR_SZ; uh4->Unused = 0; @@ -288,8 +284,13 @@ udpkick(Conv *c) ptclcsum(bp, UDP4_PHDR_OFF, dlen+UDP_UDPHDR_SZ+UDP4_PHDR_SZ)); uh4->vihl = IP_VER4; ipoput4(f, bp, 0, c->ttl, c->tos); - } - else { + break; + + case V6: + bp = padblock(bp, UDP6_IPHDR_SZ+UDP_UDPHDR_SZ); + if(bp == nil) + return; + // using the v6 ip header to create pseudo header // first then reset it to the normal ip header uh6 = (Udp6hdr *)(bp->rp); @@ -318,22 +319,15 @@ udpkick(Conv *c) uh6->viclfl[0] = IP_VER6; hnputs(uh6->len, ptcllen); uh6->nextheader = IP_UDPPROTO; - ipoput6(f, bp, 0, c->ttl, c->tos); + break; + + default: + panic("udpkick: version %d", version); } upriv->ustats.udpOutDatagrams++; } -Conv* -udpincoming(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport) -{ - Conv *new; - - new = Fsnewcall(c, raddr, rport, laddr, lport); - if(new == nil) - return nil; -} - void udpiput(Proto *udp, Ipifc *ifc, Block *bp) { @@ -347,6 +341,7 @@ udpiput(Proto *udp, Ipifc *ifc, Block *bp) Udppriv *upriv; Fs *f; int version; + int ottl, oviclfl, olen; upriv = udp->priv; f = udp->f; @@ -357,8 +352,8 @@ udpiput(Proto *udp, Ipifc *ifc, Block *bp) /* Put back pseudo header for checksum * (remember old values for icmpnoconv()) */ - if(version == 4) { - int ottl, olen; + switch(version) { + case V4: ottl = uh4->Unused; uh4->Unused = 0; len = nhgets(uh4->udplen); @@ -381,9 +376,8 @@ udpiput(Proto *udp, Ipifc *ifc, Block *bp) } uh4->Unused = ottl; hnputs(uh4->udpplen, olen); - } - else { - int ottl, oviclfl, olen; + break; + case V6: uh6 = (Udp6hdr*)(bp->rp); len = nhgets(uh6->udplen); oviclfl = nhgetl(uh6->viclfl); @@ -407,6 +401,10 @@ udpiput(Proto *udp, Ipifc *ifc, Block *bp) hnputs(uh6->len, olen); uh6->nextheader = IP_UDPPROTO; uh6->hoplimit = ottl; + break; + default: + panic("udpiput: version %d", version); + return; /* to avoid a warning */ } qlock(udp); @@ -419,11 +417,15 @@ udpiput(Proto *udp, Ipifc *ifc, Block *bp) netlog(f, Logudp, "udp: no conv %I!%d -> %I!%d\n", raddr, rport, laddr, lport); - if(version == 4) + switch(version){ + case V4: icmpnoconv(f, bp); - else { -print("udpiput: no conv %I!%d -> %I!%d\n", raddr, rport, laddr, lport); + break; + case V6: icmphostunr(f, ifc, bp, icmp6_port_unreach, 0); + break; + default: + panic("udpiput2: version %d", version); } freeblist(bp); @@ -435,12 +437,18 @@ print("udpiput: no conv %I!%d -> %I!%d\n", raddr, rport, laddr, lport); if(ucb->headers == 0){ /* create a new conversation */ if(ipforme(f, laddr) != Runi) { - if(version == 4) + switch(version){ + case V4: v4tov6(laddr, ifc->lifc->local); - else + break; + case V6: ipmove(laddr, ifc->lifc->local); + break; + default: + panic("udpiput3: version %d", version); + } } - c = Fsnewcall(c, raddr, rport, laddr, lport); + c = Fsnewcall(c, raddr, rport, laddr, lport, version); if(c == nil){ qunlock(udp); freeblist(bp); @@ -458,10 +466,17 @@ print("udpiput: no conv %I!%d -> %I!%d\n", raddr, rport, laddr, lport); * Trim the packet down to data size */ len -= UDP_UDPHDR_SZ; - if(version == 4) + switch(version){ + case V4: bp = trimblock(bp, UDP4_IPHDR_SZ+UDP_UDPHDR_SZ, len); - else + break; + case V6: bp = trimblock(bp, UDP6_IPHDR_SZ+UDP_UDPHDR_SZ, len); + break; + default: + bp = nil; + panic("udpiput4: version %d", version); + } if(bp == nil){ qunlock(c); netlog(f, Logudp, "udp: len err %I.%d -> %I.%d\n", raddr, rport, @@ -545,17 +560,23 @@ udpadvise(Proto *udp, Block *bp, char *msg) h4 = (Udp4hdr*)(bp->rp); version = ((h4->vihl&0xF0)==IP_VER6) ? 6 : 4; - if(version == 4) { + switch(version) { + case V4: v4tov6(dest, h4->udpdst); v4tov6(source, h4->udpsrc); psource = nhgets(h4->udpsport); pdest = nhgets(h4->udpdport); - } else { + break; + case V6: h6 = (Udp6hdr*)(bp->rp); ipmove(dest, h6->udpdst); ipmove(source, h6->udpsrc); psource = nhgets(h6->udpsport); pdest = nhgets(h6->udpdport); + break; + default: + panic("udpadvise: version %d", version); + return; /* to avoid a warning */ } /* Look for a connection */