M ip/arp.c => ip/arp.c +24 -65
@@ 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);
M ip/devip.c => ip/devip.c +14 -2
@@ 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);
M ip/ethermedium.c => ip/ethermedium.c +32 -11
@@ 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)
M ip/icmp.c => ip/icmp.c +3 -1
@@ 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
M ip/icmp6.c => ip/icmp6.c +2 -15
@@ 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;
M ip/il.c => ip/il.c +1 -1
@@ 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);
M ip/ip.h => ip/ip.h +2 -1
@@ 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);
M ip/ipifc.c => ip/ipifc.c +16 -7
@@ 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);
M ip/tcp.c => ip/tcp.c +109 -74
@@ 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();
}
M ip/udp.c => ip/udp.c +59 -38
@@ 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 */