M ip/devip.c => ip/devip.c +11 -0
@@ 849,6 849,15 @@ bindctlmsg(Proto *x, Conv *c, Cmdbuf *cb)
}
static void
+tosctlmsg(Conv *c, Cmdbuf *cb)
+{
+ if(cb->nf < 2)
+ c->tos = 0;
+ else
+ c->tos = atoi(cb->f[1]);
+}
+
+static void
ttlctlmsg(Conv *c, Cmdbuf *cb)
{
if(cb->nf < 2)
@@ 917,6 926,8 @@ ipwrite(Chan* ch, void *v, long n, vlong)
bindctlmsg(x, c, cb);
else if(strcmp(cb->f[0], "ttl") == 0)
ttlctlmsg(c, cb);
+ else if(strcmp(cb->f[0], "tos") == 0)
+ tosctlmsg(c, cb);
else if(strcmp(cb->f[0], "addmulti") == 0){
if(cb->nf < 2)
error("addmulti needs interface address");
M ip/gre.c => ip/gre.c +1 -1
@@ 160,7 160,7 @@ grekick(Conv *c, int l)
ghp->frag[0] = 0;
ghp->frag[1] = 0;
- ipoput(c->p->f, bp, 0, c->ttl);
+ ipoput(c->p->f, bp, 0, c->ttl, c->tos);
}
static void
M ip/icmp.c => ip/icmp.c +4 -4
@@ 171,7 171,7 @@ icmpkick(Conv *c, int l)
memset(p->cksum, 0, sizeof(p->cksum));
hnputs(p->cksum, ptclcsum(bp, ICMP_IPSIZE, blocklen(bp) - ICMP_IPSIZE));
ipriv->istats.icmpOutMsgs++;
- ipoput(c->p->f, bp, 0, c->ttl);
+ ipoput(c->p->f, bp, 0, c->ttl, c->tos);
}
extern void
@@ 197,7 197,7 @@ icmpttlexceeded(Fs *f, uchar *ia, Block *bp)
memset(np->cksum, 0, sizeof(np->cksum));
hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE));
/* stats.out[TimeExceed]++; */
- ipoput(f, nbp, 0, MAXTTL);
+ ipoput(f, nbp, 0, MAXTTL, DFLTTOS);
}
@@ 236,7 236,7 @@ icmpnoconv(Fs *f, Block *bp)
memset(np->cksum, 0, sizeof(np->cksum));
hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE));
/* stats.out[Unreachable]++; */
- ipoput(f, nbp, 0, MAXTTL);
+ ipoput(f, nbp, 0, MAXTTL, DFLTTOS);
}
static void
@@ 333,7 333,7 @@ icmpiput(Proto *icmp, uchar*, Block *bp)
case EchoRequest:
r = mkechoreply(bp);
ipriv->out[EchoReply]++;
- ipoput(icmp->f, r, 0, MAXTTL);
+ ipoput(icmp->f, r, 0, MAXTTL, DFLTTOS);
break;
case Unreachable:
if(p->code > 5 || p->code < 0)
M ip/igmp.c => ip/igmp.c +1 -1
@@ 96,7 96,7 @@ igmpsendreport(Media *m, byte *addr)
hnputs(p->igmpcksum, ptclcsum(bp, IGMP_IPHDRSIZE, IGMP_HDRSIZE));
netlog(Logigmp, "igmpreport %I\n", p->group);
stats.outreports++;
- ipoput(bp, 0, 1); /* TTL of 1 */
+ ipoput(bp, 0, 1, DFLTTOS); /* TTL of 1 */
}
static int
M ip/il.c => ip/il.c +6 -4
@@ 353,7 353,7 @@ ilkick(Conv *c, int l)
if(later(msec, ic->timeout, nil))
ilsettimeout(ic);
- ipoput(f, bp, 0, c->ttl);
+ ipoput(f, bp, 0, c->ttl, c->tos);
}
static void
@@ 784,7 784,7 @@ ilrexmit(Ilcb *ic)
ilbackoff(ic);
- ipoput(c->p->f, nb, 0, ic->conv->ttl);
+ ipoput(c->p->f, nb, 0, ic->conv->ttl, ic->conv->tos);
/* statistics */
ic->rxtot++;
@@ 938,7 938,7 @@ ilsendctl(Conv *ipc, Ilhdr *inih, int type, ulong id, ulong ack, int ilspec)
Ilhdr *ih;
Ilcb *ic;
Block *bp;
- int ttl;
+ int ttl, tos;
bp = allocb(IL_IPSIZE+IL_HDRSIZE);
bp->wp += IL_IPSIZE+IL_HDRSIZE;
@@ 958,6 958,7 @@ ilsendctl(Conv *ipc, Ilhdr *inih, int type, ulong id, ulong ack, int ilspec)
hnputl(ih->ilid, nhgetl(inih->ilack));
hnputl(ih->ilack, nhgetl(inih->ilid));
ttl = MAXTTL;
+ tos = DFLTTOS;
}
else {
v6tov4(ih->dst, ipc->raddr);
@@ 970,6 971,7 @@ ilsendctl(Conv *ipc, Ilhdr *inih, int type, ulong id, ulong ack, int ilspec)
ic->acksent = ack;
ic->acktime = msec;
ttl = ipc->ttl;
+ tos = ipc->tos;
}
ih->iltype = type;
ih->ilspec = ilspec;
@@ 983,7 985,7 @@ ilsendctl(Conv *ipc, Ilhdr *inih, int type, ulong id, ulong ack, int ilspec)
iltype[ih->iltype], nhgetl(ih->ilid), nhgetl(ih->ilack),
nhgets(ih->ilsrc), nhgets(ih->ildst));
- ipoput(ipc->p->f, bp, 0, ttl);
+ ipoput(ipc->p->f, bp, 0, ttl, tos);
}
void
M ip/ip.c => ip/ip.c +3 -2
@@ 123,7 123,7 @@ iprouting(Fs *f, int on)
}
void
-ipoput(Fs *f, Block *bp, int gating, int ttl)
+ipoput(Fs *f, Block *bp, int gating, int ttl, int tos)
{
Ipifc *ifc;
uchar *gate;
@@ 185,6 185,7 @@ ipoput(Fs *f, Block *bp, int gating, int ttl)
eh->tos = 0;
}
eh->ttl = ttl;
+ eh->tos = tos;
if(!canrlock(ifc))
goto free;
@@ 400,7 401,7 @@ ipiput(Fs *f, uchar *ia, Block *bp)
}
ip->istats.ipForwDatagrams++;
- ipoput(f, bp, 1, h->ttl - 1);
+ ipoput(f, bp, 1, h->ttl - 1, h->tos);
return;
}
M ip/ip.h => ip/ip.h +3 -1
@@ 31,6 31,7 @@ enum
MAClen= 16, /* longest mac address */
MAXTTL= 255,
+ DFLTTOS= 0,
IPaddrlen= 16,
IPv4addrlen= 4,
@@ 69,6 70,7 @@ struct Conv
ushort lport; /* local port number */
ushort rport; /* remote port number */
uint ttl; /* max time to live */
+ uint tos; /* type of service */
char owner[NAMELEN]; /* protections */
int perm;
@@ 490,7 492,7 @@ extern void initfrag(IP*, int);
extern ushort ipcsum(uchar*);
extern void (*ipextprotoiput)(Block*);
extern void ipiput(Fs*, uchar*, Block*);
-extern void ipoput(Fs*, Block*, int, int);
+extern void ipoput(Fs*, Block*, int, int, int);
extern int ipstats(Fs*, char*, int);
extern ushort ptclbsum(uchar*, int);
extern ushort ptclcsum(Block*, int, int);
M ip/ipmux.c => ip/ipmux.c +1 -1
@@ 639,7 639,7 @@ ipmuxkick(Conv *c, int)
ih = (Iphdr*)(bp->rp);
- ipoput(c->p->f, bp, 0, ih->ttl);
+ ipoput(c->p->f, bp, 0, ih->ttl, ih->tos);
}
static void
M ip/rudp.c => ip/rudp.c +5 -5
@@ 296,7 296,7 @@ rudpclose(Conv *c)
* randomly don't send packets
*/
static void
-doipoput(Conv *c, Fs *f, Block *bp, int x, int ttl)
+doipoput(Conv *c, Fs *f, Block *bp, int x, int ttl, int tos)
{
Rudpcb *ucb;
@@ 304,7 304,7 @@ doipoput(Conv *c, Fs *f, Block *bp, int x, int ttl)
if(ucb->randdrop && nrand(100) < ucb->randdrop)
freeblist(bp);
else
- ipoput(f, bp, x, ttl);
+ ipoput(f, bp, x, ttl, tos);
}
int
@@ 436,7 436,7 @@ rudpkick(Conv *c, int)
DPRINT("sent: %lud/%lud, %lud/%lud\n",
r->sndseq, r->sndgen, r->rcvseq, r->rcvgen);
- doipoput(c, f, bp, 0, c->ttl);
+ doipoput(c, f, bp, 0, c->ttl, c->tos);
/* flow control of sorts */
qlock(&r->lock);
@@ 952,7 952,7 @@ relsendack(Conv *c, Reliable *r)
hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, UDP_RHDRSIZE));
DPRINT("sendack: %lud/%lud, %lud/%lud\n", 0L, r->sndgen, r->rcvseq, r->rcvgen);
- doipoput(c, f, bp, 0, c->ttl);
+ doipoput(c, f, bp, 0, c->ttl, c->tos);
}
/*
@@ 1009,5 1009,5 @@ relrexmit(Conv *c, Reliable *r)
upriv->rxmits++;
np = copyblock(r->unacked, blocklen(r->unacked));
DPRINT("rxmit r->ackrvcd+1 = %lud\n", r->ackrcvd+1);
- doipoput(c, f, np, 0, c->ttl);
+ doipoput(c, f, np, 0, c->ttl, c->tos);
}
M ip/tcp.c => ip/tcp.c +4 -4
@@ 885,7 885,7 @@ sndrst(Proto *tcp, uchar *source, uchar *dest, ushort length, Tcp *seg)
if(hbp == nil)
return;
- ipoput(tcp->f, hbp, 0, MAXTTL);
+ ipoput(tcp->f, hbp, 0, MAXTTL, DFLTTOS);
}
/*
@@ 915,7 915,7 @@ tcphangup(Conv *s)
tcb->last_ack = tcb->rcv.nxt;
hnputs(ph.tcplen, TCP_HDRSIZE);
hbp = htontcp(&seg, nil, &tcb->protohdr);
- ipoput(s->p->f, hbp, 0, s->ttl);
+ ipoput(s->p->f, hbp, 0, s->ttl, s->tos);
}
localclose(s, nil);
poperror();
@@ 1773,7 1773,7 @@ tcpoutput(Conv *s)
tpriv->tstats.tcpOutSegs++;
if(tcb->kacounter > 0)
tcpgo(tpriv, &tcb->katimer);
- ipoput(f, hbp, 0, s->ttl);
+ ipoput(f, hbp, 0, s->ttl, s->tos);
}
}
@@ 1814,7 1814,7 @@ tcpsendka(Conv *s)
return;
}
- ipoput(s->p->f, hbp, 0, s->ttl);
+ ipoput(s->p->f, hbp, 0, s->ttl, s->tos);
}
/*
M ip/udp.c => ip/udp.c +1 -1
@@ 226,7 226,7 @@ udpkick(Conv *c, int)
hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, dlen+UDP_HDRSIZE));
upriv->ustats.udpOutDatagrams++;
- ipoput(f, bp, 0, c->ttl);
+ ipoput(f, bp, 0, c->ttl, c->tos);
}
void