M ip/arp.c => ip/arp.c +43 -36
@@ 27,30 27,38 @@ char *arpstate[] =
"WAIT",
};
-typedef struct Arpcache Arpcache;
-struct Arpcache
+/*
+ * one per Fs
+ */
+struct Arp
{
QLock;
- Arpent* hash[NHASH];
+ Fs *f;
+ Arpent *hash[NHASH];
Arpent cache[NCACHE];
};
-Arpcache arp;
-
char *Ebadarp = "bad arp";
#define haship(s) ((s)[IPaddrlen-1]%NHASH)
+void
+arpinit(Fs *f)
+{
+ f->arp = smalloc(sizeof(Arp));
+ f->arp->f = f;
+}
+
static Arpent*
-newarp(uchar *ip, Medium *m)
+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;
+ e = &arp->cache[NCACHE];
+ a = arp->cache;
t = a->used;
for(f = a; f < e; f++){
if(f->used < t){
@@ 69,7 77,7 @@ newarp(uchar *ip, Medium *m)
}
/* take out of current chain */
- l = &arp.hash[haship(a->ip)];
+ l = &arp->hash[haship(a->ip)];
for(f = *l; f; f = f->hash){
if(f == a) {
*l = a->hash;
@@ 79,7 87,7 @@ newarp(uchar *ip, Medium *m)
}
/* insert into new chain */
- l = &arp.hash[haship(ip)];
+ l = &arp->hash[haship(ip)];
a->hash = *l;
*l = a;
memmove(a->ip, ip, sizeof(a->ip));
@@ 91,7 99,7 @@ newarp(uchar *ip, Medium *m)
}
Arpent*
-arpget(Block *bp, int version, Medium *type, uchar *ip, uchar *mac)
+arpget(Arp *arp, Block *bp, int version, Medium *type, uchar *ip, uchar *mac)
{
int hash;
Arpent *a;
@@ 102,16 110,16 @@ arpget(Block *bp, int version, Medium *type, uchar *ip, uchar *mac)
ip = v6ip;
}
- qlock(&arp);
+ qlock(arp);
hash = haship(ip);
- for(a = arp.hash[hash]; a; a = a->hash) {
+ for(a = arp->hash[hash]; a; a = a->hash) {
if(memcmp(ip, a->ip, sizeof(a->ip)) == 0)
if(type == a->type)
break;
}
if(a == nil){
- a = newarp(ip, type);
+ a = newarp(arp, ip, type);
a->state = AWAIT;
}
a->used = msec;
@@ 126,7 134,7 @@ arpget(Block *bp, int version, Medium *type, uchar *ip, uchar *mac)
}
memmove(mac, a->mac, a->type->maclen);
- qunlock(&arp);
+ qunlock(arp);
return nil;
}
@@ 134,16 142,16 @@ arpget(Block *bp, int version, Medium *type, uchar *ip, uchar *mac)
* called with arp locked
*/
void
-arprelease(Arpent*)
+arprelease(Arp *arp, Arpent*)
{
- qunlock(&arp);
+ qunlock(arp);
}
/*
* called with arp locked
*/
Block*
-arpresolve(Arpent *a, Medium *type, uchar *mac)
+arpresolve(Arp *arp, Arpent *a, Medium *type, uchar *mac)
{
Block *bp;
@@ 153,13 161,13 @@ arpresolve(Arpent *a, Medium *type, uchar *mac)
a->used = msec;
bp = a->hold;
a->hold = nil;
- qunlock(&arp);
+ qunlock(arp);
return bp;
}
void
-arpenter(Ipifc *ifc, int version, uchar *ip, uchar *mac, Medium *type, int refresh)
+arpenter(Arp *arp, Ipifc *ifc, int version, uchar *ip, uchar *mac, Medium *type, int refresh)
{
Arpent *a;
Block *bp, *next;
@@ 170,8 178,8 @@ arpenter(Ipifc *ifc, int version, uchar *ip, uchar *mac, Medium *type, int refre
ip = v6ip;
}
- qlock(&arp);
- for(a = arp.hash[haship(ip)]; a; a = a->hash) {
+ qlock(arp);
+ for(a = arp->hash[haship(ip)]; a; a = a->hash) {
if(a->type != type || (a->state != AWAIT && a->state != AOK))
continue;
@@ 182,7 190,7 @@ arpenter(Ipifc *ifc, int version, uchar *ip, uchar *mac, Medium *type, int refre
a->hold = nil;
if(version == V4)
ip += IPv4off;
- qunlock(&arp);
+ qunlock(arp);
while(bp) {
next = bp->list;
if(ifc != nil){
@@ 206,19 214,18 @@ arpenter(Ipifc *ifc, int version, uchar *ip, uchar *mac, Medium *type, int refre
}
}
- /* if nil, we're adding a new entry */
if(refresh == 0){
- a = newarp(ip, type);
+ a = newarp(arp, ip, type);
a->state = AOK;
a->type = type;
memmove(a->mac, mac, type->maclen);
}
- qunlock(&arp);
+ qunlock(arp);
}
int
-arpwrite(char *s, int len)
+arpwrite(Arp *arp, char *s, int len)
{
int n;
Block *bp;
@@ 238,8 245,8 @@ arpwrite(char *s, int len)
n = parsefields(buf, f, 4, " ");
if(strcmp(f[0], "flush") == 0){
- qlock(&arp);
- for(a = arp.cache; a < &arp.cache[NCACHE]; a++){
+ qlock(arp);
+ for(a = arp->cache; a < &arp->cache[NCACHE]; a++){
memset(a->ip, 0, sizeof(a->ip));
memset(a->mac, 0, sizeof(a->mac));
a->hash = nil;
@@ 251,8 258,8 @@ arpwrite(char *s, int len)
a->hold = bp;
}
}
- memset(arp.hash, 0, sizeof(arp.hash));
- qunlock(&arp);
+ memset(arp->hash, 0, sizeof(arp->hash));
+ qunlock(arp);
} else if(strcmp(f[0], "add") == 0){
if(n != 4)
error(Ebadarp);
@@ 261,7 268,7 @@ arpwrite(char *s, int len)
error(Ebadarp);
parseip(ip, f[2]);
parsemac(mac, f[3], m->maclen);
- arpenter(nil, V6, ip, mac, m, 0);
+ arpenter(arp, nil, V6, ip, mac, m, 0);
} else
error(Ebadarp);
@@ 283,7 290,7 @@ convmac(char *p, uchar *mac, int n)
}
int
-arpread(char *p, ulong offset, int len)
+arpread(Arp *arp, char *p, ulong offset, int len)
{
Arpent *a;
int n;
@@ 296,7 303,7 @@ arpread(char *p, ulong offset, int len)
len = len/Alinelen;
n = 0;
- for(a = arp.cache; len > 0 && a < &arp.cache[NCACHE]; a++){
+ for(a = arp->cache; len > 0 && a < &arp->cache[NCACHE]; a++){
if(a->state == 0)
continue;
if(offset > 0){
@@ 304,10 311,10 @@ arpread(char *p, ulong offset, int len)
continue;
}
len--;
- qlock(&arp);
+ qlock(arp);
convmac(mac, a->mac, a->type->maclen);
n += sprint(p+n, aformat, a->type->name, arpstate[a->state], a->ip, mac);
- qunlock(&arp);
+ qunlock(arp);
}
return n;
M ip/devip.c => ip/devip.c +128 -63
@@ 6,14 6,12 @@
#include "../port/error.h"
#include "../ip/ip.h"
-Fs fs;
-Queue* qlog;
-
enum
{
Qtopdir= 1, /* top level directory */
Qtopbase,
Qarp= Qtopbase,
+ Qbootp,
Qiproute,
Qiprouter,
Qipselftab,
@@ 33,14 31,29 @@ enum
Qlocal,
Qremote,
Qstatus,
+
+ Logtype= 5,
+ Masktype= (1<<Logtype)-1,
+ Logconv= 12,
+ Maskconv= (1<<Logconv)-1,
+ Shiftconv= Logtype,
+ Logproto= 8,
+ Maskproto= (1<<Logproto)-1,
+ Shiftproto= Logtype + Logconv,
+
+ Nfs= 16,
};
-#define TYPE(x) ((x).path & 0x1f)
-#define CONV(x) (((x).path >> 5)&0xfff)
-#define PROTO(x) (((x).path >> 17)&0xff)
-#define QID(p, c, y) (((p)<<17) | ((c)<<5) | (y))
+#define TYPE(x) ( (x).path & Masktype )
+#define CONV(x) ( ((x).path >> Shiftconv) & Maskconv )
+#define PROTO(x) ( ((x).path >> Shiftproto) & Maskproto )
+#define QID(p, c, y) ( ((p)<<(Shiftproto)) | ((c)<<Shiftconv) | (y) )
static char network[] = "network";
+QLock fslock;
+Fs *ipfs[Nfs]; /* attached fs's */
+Queue *qlog;
+
static int
ip3gen(Chan *c, int i, Dir *dp)
{
@@ 48,7 61,7 @@ ip3gen(Chan *c, int i, Dir *dp)
Conv *cv;
char *p;
- cv = fs.p[PROTO(c->qid)]->conv[CONV(c->qid)];
+ cv = ipfs[c->dev]->p[PROTO(c->qid)]->conv[CONV(c->qid)];
switch(i) {
default:
return -1;
@@ 118,6 131,10 @@ ip1gen(Chan *c, int i, Dir *dp)
p = "arp";
q = (Qid){QID(0, 0, Qarp), 0};
break;
+ case Qbootp:
+ p = "bootp";
+ q = (Qid){QID(0, 0, Qbootp), 0};
+ break;
case Qiproute:
p = "iproute";
q = (Qid){QID(0, 0, Qiproute), 0};
@@ 146,33 163,37 @@ ipgen(Chan *c, Dirtab*, int, int s, Dir *dp)
Qid q;
Conv *cv;
char name[16];
+ Fs *f;
+
+ f = ipfs[c->dev];
switch(TYPE(c->qid)) {
case Qtopdir:
- if(s < fs.np) {
- if(fs.p[s]->connect == nil)
+ if(s < f->np) {
+ if(f->p[s]->connect == nil)
return 0; /* protocol with no user interface */
q = (Qid){QID(s, 0, Qprotodir)|CHDIR, 0};
- devdir(c, q, fs.p[s]->name, 0, network, CHDIR|0555, dp);
+ devdir(c, q, f->p[s]->name, 0, network, CHDIR|0555, dp);
return 1;
}
- s -= fs.np;
+ s -= f->np;
return ip1gen(c, s+Qtopbase, dp);
case Qarp:
+ case Qbootp:
case Qlog:
case Qiproute:
case Qiprouter:
case Qipselftab:
return ip1gen(c, TYPE(c->qid), dp);
case Qprotodir:
- if(s < fs.p[PROTO(c->qid)]->ac) {
- cv = fs.p[PROTO(c->qid)]->conv[s];
+ if(s < f->p[PROTO(c->qid)]->ac) {
+ cv = f->p[PROTO(c->qid)]->conv[s];
sprint(name, "%d", s);
q = (Qid){QID(PROTO(c->qid), s, Qconvdir)|CHDIR, 0};
devdir(c, q, name, 0, cv->owner, CHDIR|0555, dp);
return 1;
}
- s -= fs.p[PROTO(c->qid)]->ac;
+ s -= f->p[PROTO(c->qid)]->ac;
return ip2gen(c, s+Qprotobase, dp);
case Qclone:
case Qstats:
@@ 199,12 220,6 @@ ipreset(void)
static void
ipinit(void)
{
- int i;
- extern void (*ipprotoinit[])(Fs*);
-
- initfrag(100);
- for(i = 0; ipprotoinit[i]; i++)
- ipprotoinit[i](&fs);
fmtinstall('i', eipconv);
fmtinstall('I', eipconv);
fmtinstall('E', eipconv);
@@ 212,13 227,45 @@ ipinit(void)
fmtinstall('M', eipconv);
}
+static Fs*
+ipgetfs(int dev)
+{
+ extern void (*ipprotoinit[])(Fs*);
+ Fs *f;
+ int i;
+
+ if(dev >= Nfs)
+ return nil;
+
+ qlock(&fslock);
+ if(ipfs[dev] == nil){
+ f = smalloc(sizeof(Fs));
+ ip_init(f);
+ arpinit(f);
+ netloginit(f);
+ for(i = 0; ipprotoinit[i]; i++)
+ ipprotoinit[i](f);
+ ipfs[dev] = f;
+ }
+ qunlock(&fslock);
+
+ return ipfs[dev];
+}
+
static Chan*
ipattach(char* spec)
{
Chan *c;
+ int dev;
+
+ dev = atoi(spec);
+ if(dev >= 16)
+ error("bad specification");
+ ipgetfs(dev);
c = devattach('I', spec);
c->qid = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0};
+ c->dev = dev;
return c;
}
@@ 281,18 328,21 @@ ipopen(Chan* c, int omode)
Conv *cv, *nc;
Proto *p;
int perm;
+ Fs *f;
omode &= 3;
perm = m2p[omode];
+ f = ipfs[c->dev];
+
switch(TYPE(c->qid)) {
default:
break;
case Qlog:
- netlogopen();
+ netlogopen(f);
break;
case Qiprouter:
- iprouteropen();
+ iprouteropen(f);
break;
case Qiproute:
memmove(c->tag, "none", sizeof(c->tag));
@@ 304,13 354,14 @@ ipopen(Chan* c, int omode)
case Qremote:
case Qlocal:
case Qstats:
+ case Qbootp:
case Qipselftab:
if(omode != OREAD)
error(Eperm);
break;
case Qclone:
- p = fs.p[PROTO(c->qid)];
- cv = Fsprotoclone(p, up->user);
+ p = f->p[PROTO(c->qid)];
+ cv = Fsprotoclone(p, commonuser());
if(cv == nil) {
error(Enodev);
break;
@@ 320,7 371,7 @@ ipopen(Chan* c, int omode)
case Qdata:
case Qctl:
case Qerr:
- p = fs.p[PROTO(c->qid)];
+ p = f->p[PROTO(c->qid)];
qlock(p);
cv = p->conv[CONV(c->qid)];
lock(cv);
@@ 330,7 381,7 @@ ipopen(Chan* c, int omode)
nexterror();
}
if((perm & (cv->perm>>6)) != perm) {
- if(strcmp(up->user, cv->owner) != 0)
+ if(strcmp(commonuser(), cv->owner) != 0)
error(Eperm);
if((perm & cv->perm) != perm)
error(Eperm);
@@ 338,7 389,7 @@ ipopen(Chan* c, int omode)
}
cv->inuse++;
if(cv->inuse == 1){
- memmove(cv->owner, up->user, NAMELEN);
+ memmove(cv->owner, commonuser(), NAMELEN);
cv->perm = 0660;
}
unlock(cv);
@@ 346,7 397,7 @@ ipopen(Chan* c, int omode)
poperror();
break;
case Qlisten:
- cv = fs.p[PROTO(c->qid)]->conv[CONV(c->qid)];
+ cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)];
if(cv->state != Announced)
error("not announced");
@@ 365,7 416,7 @@ ipopen(Chan* c, int omode)
if(nc != nil){
cv->incall = nc->next;
c->qid = (Qid){QID(PROTO(c->qid), nc->x, Qctl), 0};
- memmove(cv->owner, up->user, NAMELEN);
+ memmove(cv->owner, commonuser(), NAMELEN);
}
unlock(cv);
@@ 430,22 481,25 @@ closeconv(Conv *cv)
static void
ipclose(Chan* c)
{
+ Fs *f;
+
+ f = ipfs[c->dev];
switch(TYPE(c->qid)) {
default:
break;
case Qlog:
if(c->flag & COPEN)
- netlogclose();
+ netlogclose(f);
break;
case Qiprouter:
if(c->flag & COPEN)
- iprouterclose();
+ iprouterclose(f);
break;
case Qdata:
case Qctl:
case Qerr:
if(c->flag & COPEN)
- closeconv(fs.p[PROTO(c->qid)]->conv[CONV(c->qid)]);
+ closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]);
}
}
@@ 461,6 515,9 @@ ipread(Chan *ch, void *a, long n, ulong offset)
Proto *x;
char *buf, *p;
long m, rv;
+ Fs *f;
+
+ f = ipfs[ch->dev];
p = a;
switch(TYPE(ch->qid)) {
@@ 471,13 528,15 @@ ipread(Chan *ch, void *a, long n, ulong offset)
case Qconvdir:
return devdirread(ch, a, n, 0, 0, ipgen);
case Qarp:
- return arpread(a, offset, n);
+ return arpread(f->arp, a, offset, n);
+ case Qbootp:
+ return bootpread(a, offset, n);
case Qiproute:
- return routeread(a, offset, n);
+ return routeread(f, a, offset, n);
case Qipselftab:
- return ipselftabread(a, offset, n);
+ return ipselftabread(f, a, offset, n);
case Qlog:
- return netlogread(a, offset, n);
+ return netlogread(f, a, offset, n);
case Qctl:
buf = smalloc(16);
sprint(buf, "%d", CONV(ch->qid));
@@ 486,14 545,14 @@ ipread(Chan *ch, void *a, long n, ulong offset)
return rv;
case Qremote:
buf = smalloc(Statelen);
- c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
+ c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
sprint(buf, "%I!%d\n", c->raddr, c->rport);
rv = readstr(offset, p, n, buf);
free(buf);
return rv;
case Qlocal:
buf = smalloc(Statelen);
- x = fs.p[PROTO(ch->qid)];
+ x = f->p[PROTO(ch->qid)];
c = x->conv[CONV(ch->qid)];
if(x->local == nil) {
sprint(buf, "%I!%d\n", c->laddr, c->lport);
@@ 505,7 564,7 @@ ipread(Chan *ch, void *a, long n, ulong offset)
return rv;
case Qstatus:
buf = smalloc(Statelen);
- x = fs.p[PROTO(ch->qid)];
+ x = f->p[PROTO(ch->qid)];
c = x->conv[CONV(ch->qid)];
m = sprint(buf, "%s/%d %d ", c->p->name, c->x, c->inuse);
(*x->state)(c, buf, Statelen-m-2);
@@ 513,17 572,17 @@ ipread(Chan *ch, void *a, long n, ulong offset)
free(buf);
return rv;
case Qdata:
- c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
+ c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
return qread(c->rq, a, n);
case Qerr:
- c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
+ c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
return qread(c->eq, a, n);
case Qstats:
- x = fs.p[PROTO(ch->qid)];
+ x = f->p[PROTO(ch->qid)];
if(x->stats == nil)
error("stats not implemented");
buf = smalloc(Statelen);
- (*x->stats)(buf, Statelen);
+ (*x->stats)(x, buf, Statelen);
rv = readstr(offset, p, n, buf);
free(buf);
return rv;
@@ 542,7 601,7 @@ ipbread(Chan* c, long n, ulong offset)
static void
setladdr(Conv* c)
{
- findlocalip(c->laddr, c->raddr);
+ findlocalip(c->p->f, c->laddr, c->raddr);
}
/*
@@ 787,12 846,15 @@ ipwrite(Chan* ch, char* a, long n, ulong)
char *p;
Cmdbuf *cb;
uchar ia[IPaddrlen];
+ Fs *f;
+
+ f = ipfs[ch->dev];
switch(TYPE(ch->qid)){
default:
error(Eperm);
case Qdata:
- x = fs.p[PROTO(ch->qid)];
+ x = f->p[PROTO(ch->qid)];
c = x->conv[CONV(ch->qid)];
if(c->wq == nil)
@@ 802,16 864,16 @@ ipwrite(Chan* ch, char* a, long n, ulong)
x->kick(c, n);
break;
case Qarp:
- return arpwrite(a, n);
+ return arpwrite(f->arp, a, n);
case Qiproute:
- return routewrite(ch, a, n);
+ return routewrite(f, ch, a, n);
case Qlog:
- p = netlogctl(a, n);
+ p = netlogctl(f, a, n);
if(p != nil)
error(p);
return n;
case Qctl:
- x = fs.p[PROTO(ch->qid)];
+ x = f->p[PROTO(ch->qid)];
c = x->conv[CONV(ch->qid)];
cb = parsecmd(a, n);
@@ 887,26 949,29 @@ Dev ipdevtab = {
};
int
-Fsproto(Fs *fs, Proto *p)
+Fsproto(Fs *f, Proto *p)
{
- if(fs->np >= Maxproto)
+ if(f->np >= Maxproto)
return -1;
+ p->f = f;
+
if(p->ipproto > 0){
- if(fs->t2p[p->ipproto] != nil)
+ if(f->t2p[p->ipproto] != nil)
return -1;
- fs->t2p[p->ipproto] = p;
+ f->t2p[p->ipproto] = p;
}
- p->qid.path = CHDIR|QID(fs->np, 0, Qprotodir);
+ p->qid.path = CHDIR|QID(f->np, 0, Qprotodir);
p->conv = malloc(sizeof(Conv*)*(p->nc+1));
if(p->conv == nil)
panic("Fsproto");
- p->x = fs->np;
+ p->x = f->np;
p->nextport = 0;
p->nextrport = 600;
- fs->p[fs->np++] = p;
+ f->p[f->np++] = p;
+
return 0;
}
@@ 915,9 980,9 @@ Fsproto(Fs *fs, Proto *p)
* built in
*/
int
-Fsbuiltinproto(Fs* fs, uchar proto)
+Fsbuiltinproto(Fs* f, uchar proto)
{
- return fs->t2p[proto] != nil;
+ return f->t2p[proto] != nil;
}
Conv*
@@ 990,7 1055,7 @@ Fsprotoclone(Proto *p, char *user)
}
int
-Fsconnected(Fs*, Conv* c, char* msg)
+Fsconnected(Conv* c, char* msg)
{
if(msg != nil && *msg != '\0')
strncpy(c->cerr, msg, ERRLEN-1);
@@ 1011,13 1076,13 @@ Fsconnected(Fs*, Conv* c, char* msg)
}
Proto*
-Fsrcvpcol(Fs* fs, uchar proto)
+Fsrcvpcol(Fs* f, uchar proto)
{
- return fs->t2p[proto];
+ return f->t2p[proto];
}
Conv*
-Fsnewcall(Fs*, Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport)
+Fsnewcall(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport)
{
Conv *nc;
Conv **l;
M ip/ethermedium.c => ip/ethermedium.c +18 -16
@@ 22,7 22,7 @@ static void etherunbind(Ipifc *ifc);
static void etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip);
static void etheraddmulti(Ipifc *ifc, uchar *a, uchar *ia);
static void etherremmulti(Ipifc *ifc, uchar *a, uchar *ia);
-static Block* multicastarp(Arpent *a, uchar *mac);
+static Block* multicastarp(Fs *f, Arpent *a, uchar *mac);
static void sendarp(Ipifc *ifc, Arpent *a);
static int multicastea(uchar *ea, uchar *ip);
static void recvarpproc(Ipifc *ifc);
@@ 51,6 51,7 @@ Medium ethermedium =
typedef struct Etherrock Etherrock;
struct Etherrock
{
+ Fs *f; /* file system we belong to */
Proc *arpp; /* arp process */
Proc *readp; /* reading process */
Chan *mchan; /* Data channel */
@@ 128,8 129,8 @@ etherbind(Ipifc *ifc, int argc, char **argv)
fd = kdial(addr, nil, dir, &cfd);
if(fd < 0)
error("dial 0x800 failed");
- mchan = fdtochan(fd, ORDWR, 0, 1);
- cchan = fdtochan(cfd, ORDWR, 0, 1);
+ mchan = commonfdtochan(fd, ORDWR, 0, 1);
+ cchan = commonfdtochan(cfd, ORDWR, 0, 1);
kclose(fd);
kclose(cfd);
@@ 162,13 163,14 @@ etherbind(Ipifc *ifc, int argc, char **argv)
fd = kdial(addr, nil, nil, nil);
if(fd < 0)
error("dial 0x806 failed");
- achan = fdtochan(fd, ORDWR, 0, 1);
+ achan = commonfdtochan(fd, ORDWR, 0, 1);
kclose(fd);
er = smalloc(sizeof(*er));
er->mchan = mchan;
er->cchan = cchan;
er->achan = achan;
+ er->f = ifc->conv->p->f;
ifc->arg = er;
free(buf);
@@ 217,10 219,10 @@ etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip)
Etherrock *er = ifc->arg;
/* get mac address of destination */
- a = arpget(bp, version, ðermedium, ip, mac);
+ a = arpget(er->f->arp, bp, version, ðermedium, ip, mac);
if(a){
/* check for broadcast or multicast */
- bp = multicastarp(a, mac);
+ bp = multicastarp(er->f, a, mac);
if(bp == nil){
sendarp(ifc, a);
return;
@@ 281,7 283,7 @@ etherread(void *a)
if(ifc->lifc == nil)
freeb(bp);
else
- ipiput(ifc->lifc->local, bp);
+ ipiput(er->f, ifc->lifc->local, bp);
runlock(ifc); locked = 0; USED(locked);
}
@@ 325,7 327,7 @@ sendarp(Ipifc *ifc, Arpent *a)
/* don't do anything if it's been less than a second since the last */
if(msec - a->time < 1000){
- arprelease(a);
+ arprelease(er->f->arp, a);
return;
}
@@ 339,7 341,7 @@ sendarp(Ipifc *ifc, Arpent *a)
/* try to keep it around for a second more */
a->time = msec;
- arprelease(a);
+ arprelease(er->f->arp, a);
n = sizeof(Etherarp);
if(n < a->type->minmtu)
@@ 387,7 389,7 @@ recvarp(Ipifc *ifc)
break;
case ARPREPLY:
- arpenter(ifc, V4, e->spa, e->sha, ðermedium, 0);
+ arpenter(er->f->arp, ifc, V4, e->spa, e->sha, ðermedium, 0);
break;
case ARPREQUEST:
@@ 408,12 410,12 @@ recvarp(Ipifc *ifc)
}
/* refresh what we know about sender */
- arpenter(ifc, V4, e->spa, e->sha, ðermedium, 1);
+ arpenter(er->f->arp, ifc, V4, e->spa, e->sha, ðermedium, 1);
/* answer only requests for our address or systems we're proxying for */
v4tov6(ip, e->tpa);
if(!iplocalonifc(ifc, ip))
- if(ipproxyifc(ifc, ip) == 0)
+ if(ipproxyifc(er->f, ifc, ip) == 0)
break;
/* print("arp: rem %I %E (for %I)\n", e->spa, e->sha, e->tpa); /**/
@@ 490,15 492,15 @@ multicastea(uchar *ea, uchar *ip)
* addresses
*/
static Block*
-multicastarp(Arpent *a, uchar *mac)
+multicastarp(Fs *f, Arpent *a, uchar *mac)
{
/* is it broadcast? */
- switch(ipforme(a->ip)){
+ switch(ipforme(f, a->ip)){
case Runi:
return nil;
case Rbcast:
memset(mac, 0xff, 6);
- return arpresolve(a, ðermedium, mac);
+ return arpresolve(f->arp, a, ðermedium, mac);
default:
break;
}
@@ 507,7 509,7 @@ multicastarp(Arpent *a, uchar *mac)
switch(multicastea(mac, a->ip)){
case V4:
case V6:
- return arpresolve(a, ðermedium, mac);
+ return arpresolve(f->arp, a, ðermedium, mac);
}
/* let arp take care of it */
M ip/gre.c => ip/gre.c +41 -29
@@ 39,9 39,13 @@ typedef struct GREhdr
uchar eproto[2]; /* encapsulation protocol */
} GREhdr;
- Proto gre;
-extern Fs fs;
- int gredebug;
+typedef struct GREpriv GREpriv;
+struct GREpriv
+{
+ /* non-MIB stats */
+ ulong csumerr; /* checksum errors */
+ ulong lenerr; /* short packet */
+};
static char*
greconnect(Conv *c, char **argv, int argc)
@@ 75,7 79,7 @@ greconnect(Conv *c, char **argv, int argc)
if(err != nil)
return err;
- Fsconnected(&fs, c, nil);
+ Fsconnected(c, nil);
return nil;
}
@@ 147,7 151,7 @@ grekick(Conv *c, int l)
v4tov6(laddr, ghp->src);
if(ipcmp(laddr, v4prefix) == 0){
if(ipcmp(c->laddr, IPnoaddr) == 0)
- findlocalip(c->laddr, raddr); /* pick interface closest to dest */
+ findlocalip(c->p->f, c->laddr, raddr); /* pick interface closest to dest */
memmove(ghp->src, c->laddr + IPv4off, IPv4addrlen);
}
@@ 156,18 160,20 @@ grekick(Conv *c, int l)
ghp->frag[0] = 0;
ghp->frag[1] = 0;
- ipoput(bp, 0, c->ttl);
+ ipoput(c->p->f, bp, 0, c->ttl);
}
static void
-greiput(uchar*, Block *bp)
+greiput(Proto *gre, uchar*, Block *bp)
{
int len;
GREhdr *ghp;
Conv *c, **p;
ushort eproto;
uchar raddr[IPaddrlen];
+ GREpriv *gpriv;
+ gpriv = gre->priv;
ghp = (GREhdr*)(bp->rp);
v4tov6(raddr, ghp->src);
@@ 175,7 181,7 @@ greiput(uchar*, Block *bp)
/* Look for a conversation structure for this port and address */
c = nil;
- for(p = gre.conv; *p; p++) {
+ for(p = gre->conv; *p; p++) {
c = *p;
if(c->inuse == 0)
continue;
@@ 198,7 204,7 @@ greiput(uchar*, Block *bp)
}
bp = trimblock(bp, GRE_IPONLY, len);
if(bp == nil){
- gre.lenerr++;
+ gpriv->lenerr++;
return;
}
@@ 216,30 222,36 @@ greiput(uchar*, Block *bp)
}
int
-grestats(char *buf, int len)
+grestats(Proto *gre, char *buf, int len)
{
- return snprint(buf, len,
- "gre: csum %d hlen %d len %d order %d rexmit %d\n",
- gre.csumerr, gre.hlenerr, gre.lenerr, gre.order, gre.rexmit);
+ GREpriv *gpriv;
+
+ gpriv = gre->priv;
+
+ return snprint(buf, len, "gre: len %d\n", gpriv->lenerr);
}
void
greinit(Fs *fs)
{
- gre.name = "gre";
- gre.kick = grekick;
- gre.connect = greconnect;
- gre.announce = greannounce;
- gre.state = grestate;
- gre.create = grecreate;
- gre.close = greclose;
- gre.rcv = greiput;
- gre.ctl = nil;
- gre.advise = nil;
- gre.stats = grestats;
- gre.ipproto = IP_GREPROTO;
- gre.nc = 64;
- gre.ptclsize = 0;
-
- Fsproto(fs, &gre);
+ Proto *gre;
+
+ gre = smalloc(sizeof(Proto));
+ gre->priv = smalloc(sizeof(GREpriv));
+ gre->name = "gre";
+ gre->kick = grekick;
+ gre->connect = greconnect;
+ gre->announce = greannounce;
+ gre->state = grestate;
+ gre->create = grecreate;
+ gre->close = greclose;
+ gre->rcv = greiput;
+ gre->ctl = nil;
+ gre->advise = nil;
+ gre->stats = grestats;
+ gre->ipproto = IP_GREPROTO;
+ gre->nc = 64;
+ gre->ptclsize = 0;
+
+ Fsproto(fs, gre);
}
M ip/icmp.c => ip/icmp.c +73 -59
@@ 46,14 46,16 @@ enum {
ICMP_HDRSIZE = 8,
};
- Proto icmp;
-extern Fs fs;
-
-static struct Icmpstats
+typedef struct Icmppriv Icmppriv;
+struct Icmppriv
{
+ /* non-MIB stats */
+ ulong csumerr; /* checksum errors */
+ ulong lenerr; /* short packet */
+ ulong hlenerr; /* short header */
ulong in[Maxtype+1];
ulong out[Maxtype+1];
-} stats;
+};
static char*
icmpconnect(Conv *c, char **argv, int argc)
@@ 61,7 63,7 @@ icmpconnect(Conv *c, char **argv, int argc)
char *e;
e = Fsstdconnect(c, argv, argc);
- Fsconnected(&fs, c, e);
+ Fsconnected(c, e);
return e;
}
@@ 88,7 90,7 @@ icmpannounce(Conv *c, char **argv, int argc)
e = Fsstdannounce(c, argv, argc);
if(e != nil);
return e;
- Fsconnected(&fs, c, nil);
+ Fsconnected(c, nil);
return nil;
}
@@ 109,6 111,7 @@ icmpkick(Conv *c, int l)
{
Icmp *p;
Block *bp;
+ Icmppriv *ipriv;
USED(l);
bp = qget(c->wq);
@@ 120,25 123,27 @@ icmpkick(Conv *c, int l)
return;
}
p = (Icmp *)(bp->rp);
- if(p->type <= Maxtype)
- stats.out[p->type]++;
+ if(p->type <= Maxtype){
+ ipriv = c->p->priv;
+ ipriv->out[p->type]++;
+ }
v6tov4(p->dst, c->raddr);
v6tov4(p->src, c->laddr);
p->proto = IP_ICMPPROTO;
hnputs(p->icmpid, c->lport);
memset(p->cksum, 0, sizeof(p->cksum));
hnputs(p->cksum, ptclcsum(bp, ICMP_IPSIZE, blocklen(bp) - ICMP_IPSIZE));
- ipoput(bp, 0, c->ttl);
+ ipoput(c->p->f, bp, 0, c->ttl);
}
extern void
-icmpnoconv(Block *bp)
+icmpnoconv(Fs *f, Block *bp)
{
Block *nbp;
Icmp *p, *np;
p = (Icmp *)bp->rp;
- netlog(Logicmp, "sending icmpnoconv -> %V\n", p->src);
+ netlog(f, Logicmp, "sending icmpnoconv -> %V\n", p->src);
nbp = allocb(ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8);
nbp->wp += ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8;
np = (Icmp *)nbp->rp;
@@ 152,12 157,12 @@ icmpnoconv(Block *bp)
hnputs(np->seq, 0);
memset(np->cksum, 0, sizeof(np->cksum));
hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE));
- stats.out[Unreachable]++;
- ipoput(nbp, 0, MAXTTL);
+/* stats.out[Unreachable]++; */
+ ipoput(f, nbp, 0, MAXTTL);
}
static void
-goticmpkt(Block *bp)
+goticmpkt(Proto *icmp, Block *bp)
{
Conv **c, *s;
Icmp *p;
@@ 168,7 173,7 @@ goticmpkt(Block *bp)
v4tov6(dst, p->src);
recid = nhgets(p->icmpid);
- for(c = icmp.conv; *c; c++) {
+ for(c = icmp->conv; *c; c++) {
s = *c;
if(s->lport == recid)
if(ipcmp(s->raddr, dst) == 0){
@@ 207,7 212,7 @@ static char *unreachcode[] =
};
static void
-icmpiput(uchar*, Block *bp)
+icmpiput(Proto *icmp, uchar*, Block *bp)
{
int n, iplen;
Icmp *p;
@@ 215,33 220,36 @@ icmpiput(uchar*, Block *bp)
Proto *pr;
char *msg;
char m2[128];
+ Icmppriv *ipriv;
+
+ ipriv = icmp->priv;
p = (Icmp *)bp->rp;
- netlog(Logicmp, "icmpiput %d %d\n", p->type, p->code);
+ netlog(icmp->f, Logicmp, "icmpiput %d %d\n", p->type, p->code);
n = blocklen(bp);
if(n < ICMP_IPSIZE+ICMP_HDRSIZE){
- icmp.hlenerr++;
- netlog(Logicmp, "icmp hlen %d\n", n);
+ ipriv->hlenerr++;
+ netlog(icmp->f, Logicmp, "icmp hlen %d\n", n);
goto raise;
}
iplen = nhgets(p->length);
if(iplen > n || (iplen % 1)){
- icmp.lenerr++;
- netlog(Logicmp, "icmp length %d\n", iplen);
+ ipriv->lenerr++;
+ netlog(icmp->f, Logicmp, "icmp length %d\n", iplen);
goto raise;
}
if(ptclcsum(bp, ICMP_IPSIZE, iplen - ICMP_IPSIZE)){
- icmp.csumerr++;
- netlog(Logicmp, "icmp checksum error\n");
+ ipriv->csumerr++;
+ netlog(icmp->f, Logicmp, "icmp checksum error\n");
goto raise;
}
if(p->type <= Maxtype)
- stats.in[p->type]++;
+ ipriv->in[p->type]++;
switch(p->type) {
case EchoRequest:
r = mkechoreply(bp);
- stats.out[EchoReply]++;
- ipoput(r, 0, MAXTTL);
+ ipriv->out[EchoReply]++;
+ ipoput(icmp->f, r, 0, MAXTTL);
break;
case Unreachable:
if(p->code > 5 || p->code < 0)
@@ 251,18 259,18 @@ icmpiput(uchar*, Block *bp)
bp->rp += ICMP_IPSIZE+ICMP_HDRSIZE;
if(blocklen(bp) < 8){
- icmp.lenerr++;
+ ipriv->lenerr++;
goto raise;
}
p = (Icmp *)bp->rp;
- pr = Fsrcvpcol(&fs, p->proto);
+ pr = Fsrcvpcol(icmp->f, p->proto);
if(pr != nil && pr->advise != nil) {
- (*pr->advise)(bp, msg);
+ (*pr->advise)(pr, bp, msg);
return;
}
bp->rp -= ICMP_IPSIZE+ICMP_HDRSIZE;
- goticmpkt(bp);
+ goticmpkt(icmp, bp);
break;
case TimeExceed:
if(p->code == 0){
@@ 270,21 278,21 @@ icmpiput(uchar*, Block *bp)
bp->rp += ICMP_IPSIZE+ICMP_HDRSIZE;
if(blocklen(bp) < 8){
- icmp.lenerr++;
+ ipriv->lenerr++;
goto raise;
}
p = (Icmp *)bp->rp;
- pr = Fsrcvpcol(&fs, p->proto);
+ pr = Fsrcvpcol(icmp->f, p->proto);
if(pr != nil && pr->advise != nil) {
- (*pr->advise)(bp, m2);
+ (*pr->advise)(pr, bp, m2);
return;
}
}
- goticmpkt(bp);
+ goticmpkt(icmp, bp);
break;
default:
- goticmpkt(bp);
+ goticmpkt(icmp, bp);
break;
}
return;
@@ 294,7 302,7 @@ raise:
}
void
-icmpadvise(Block *bp, char *msg)
+icmpadvise(Proto *icmp, Block *bp, char *msg)
{
Conv **c, *s;
Icmp *p;
@@ 305,7 313,7 @@ icmpadvise(Block *bp, char *msg)
v4tov6(dst, p->dst);
recid = nhgets(p->icmpid);
- for(c = icmp.conv; *c; c++) {
+ for(c = icmp->conv; *c; c++) {
s = *c;
if(s->lport == recid)
if(ipcmp(s->raddr, dst) == 0){
@@ 318,20 326,22 @@ icmpadvise(Block *bp, char *msg)
}
int
-icmpstats(char *buf, int len)
+icmpstats(Proto *icmp, char *buf, int len)
{
int i, n;
+ Icmppriv *ipriv;
+ ipriv = icmp->priv;
n = snprint(buf, len,
- "icmp: csum %d hlen %d len %d order %d rexmit %d\n",
- icmp.csumerr, icmp.hlenerr, icmp.lenerr, icmp.order, icmp.rexmit);
+ "icmp: csum %d hlen %d len %d\n",
+ ipriv->csumerr, ipriv->hlenerr, ipriv->lenerr);
n += snprint(buf+n, len-n, "\trcvd ");
for(i = 0; i < Maxtype && len > n; i++)
- n += snprint(buf+n, len-n, " %d", stats.in[i]);
+ n += snprint(buf+n, len-n, " %d", ipriv->in[i]);
n += snprint(buf+n, len-n, "\n\tsent ");
for(i = 0; i < Maxtype && len > n; i++)
- n += snprint(buf+n, len-n, " %d", stats.out[i]);
+ n += snprint(buf+n, len-n, " %d", ipriv->out[i]);
if(n < len)
n += snprint(buf+n, len-n, "\n");
return n;
@@ 340,20 350,24 @@ icmpstats(char *buf, int len)
void
icmpinit(Fs *fs)
{
- icmp.name = "icmp";
- icmp.kick = icmpkick;
- icmp.connect = icmpconnect;
- icmp.announce = icmpannounce;
- icmp.state = icmpstate;
- icmp.create = icmpcreate;
- icmp.close = icmpclose;
- icmp.rcv = icmpiput;
- icmp.stats = icmpstats;
- icmp.ctl = nil;
- icmp.advise = icmpadvise;
- icmp.ipproto = IP_ICMPPROTO;
- icmp.nc = 16;
- icmp.ptclsize = 0;
-
- Fsproto(fs, &icmp);
+ Proto *icmp;
+
+ icmp = smalloc(sizeof(Proto));
+ icmp->priv = smalloc(sizeof(Icmppriv));
+ icmp->name = "icmp";
+ icmp->kick = icmpkick;
+ icmp->connect = icmpconnect;
+ icmp->announce = icmpannounce;
+ icmp->state = icmpstate;
+ icmp->create = icmpcreate;
+ icmp->close = icmpclose;
+ icmp->rcv = icmpiput;
+ icmp->stats = icmpstats;
+ icmp->ctl = nil;
+ icmp->advise = icmpadvise;
+ icmp->ipproto = IP_ICMPPROTO;
+ icmp->nc = 16;
+ icmp->ptclsize = 0;
+
+ Fsproto(fs, icmp);
}
M ip/il.c => ip/il.c +102 -75
@@ 121,11 121,22 @@ struct Ilhdr
uchar ilack[4]; /* Acked sequence */
};
-static struct Ilstats
+
+typedef struct Ilpriv Ilpriv;
+struct Ilpriv
{
- ulong dup;
- ulong dupb;
-} ilstats;
+
+ /* non-MIB stats */
+ ulong csumerr; /* checksum errors */
+ ulong hlenerr; /* header length error */
+ ulong lenerr; /* short packet */
+ ulong order; /* out of order */
+ ulong rexmit; /* retransmissions */
+ ulong dup;
+ ulong dupb;
+
+ Rendez ilr;
+};
/* Always Acktime < Fasttime < Slowtime << Ackkeepalive */
enum
@@ 164,18 175,14 @@ void ilrexmit(Ilcb*);
void ilbackoff(Ilcb*);
void iltimers(Ilcb*);
char* ilstart(Conv*, int, int);
-void ilackproc();
+void ilackproc(void*);
void iloutoforder(Conv*, Ilhdr*, Block*);
-void iliput(uchar*, Block*);
-void iladvise(Block*, char*);
+void iliput(Proto*, uchar*, Block*);
+void iladvise(Proto*, Block*, char*);
int ilnextqt(Ilcb*);
-#define DBG(x) if((logmask & Logilmsg) && (iponly == 0 || x == iponly))netlog
-
- Proto il;
int ilcksum = 1;
static int initseq = 25001;
-extern Fs fs;
static char*
ilconnect(Conv *c, char **argv, int argc)
@@ 222,7 229,7 @@ ilannounce(Conv *c, char **argv, int argc)
e = ilstart(c, IL_LISTEN, 20);
if(e != nil)
return e;
- Fsconnected(&fs, c, nil);
+ Fsconnected(c, nil);
return nil;
}
@@ 266,9 273,11 @@ ilkick(Conv *c, int l)
int dlen;
ulong id;
Block *bp;
+ Fs *f;
USED(l);
+ f = c->p->f;
ic = (Ilcb*)c->ptcl;
bp = qget(c->wq);
@@ 327,7 336,7 @@ ilkick(Conv *c, int l)
}
ic->acktime = Ackkeepalive;
- ipoput(bp, 0, c->ttl);
+ ipoput(f, bp, 0, c->ttl);
}
static void
@@ 338,40 347,46 @@ ilcreate(Conv *c)
}
int
-ilxstats(char *buf, int len)
+ilxstats(Proto *il, char *buf, int len)
{
int n;
+ Ilpriv *ipriv;
+
+ ipriv = il->priv;
n = snprint(buf, len,
"il: csum %d hlen %d len %d order %d rexmit %d",
- il.csumerr, il.hlenerr, il.lenerr, il.order, il.rexmit);
+ ipriv->csumerr, ipriv->hlenerr, ipriv->lenerr, ipriv->order, ipriv->rexmit);
n += snprint(buf+n, len-n, " dupp %d dupb %d\n",
- ilstats.dup, ilstats.dupb);
+ ipriv->dup, ipriv->dupb);
return n;
}
void
-ilinit(Fs *fs)
+ilinit(Fs *f)
{
- il.name = "il";
- il.kick = ilkick;
- il.connect = ilconnect;
- il.announce = ilannounce;
- il.state = ilstate;
- il.create = ilcreate;
- il.close = ilclose;
- il.rcv = iliput;
- il.ctl = nil;
- il.advise = iladvise;
- il.stats = ilxstats;
- il.inuse = ilinuse;
- il.ipproto = IP_ILPROTO;
- il.nc = Nchans;
- il.ptclsize = sizeof(Ilcb);
-
- kproc("ilack", ilackproc, 0);
-
- Fsproto(fs, &il);
+ Proto *il;
+
+ il = smalloc(sizeof(Proto));
+ il->priv = smalloc(sizeof(Ilpriv));
+ il->name = "il";
+ il->kick = ilkick;
+ il->connect = ilconnect;
+ il->announce = ilannounce;
+ il->state = ilstate;
+ il->create = ilcreate;
+ il->close = ilclose;
+ il->rcv = iliput;
+ il->ctl = nil;
+ il->advise = iladvise;
+ il->stats = ilxstats;
+ il->inuse = ilinuse;
+ il->ipproto = IP_ILPROTO;
+ il->nc = Nchans;
+ il->ptclsize = sizeof(Ilcb);
+ Fsproto(f, il);
+
+ kproc("ilack", ilackproc, il);
}
void
@@ 467,7 482,7 @@ ilackto(Ilcb *ic, ulong ackto)
}
void
-iliput(uchar*, Block *bp)
+iliput(Proto *il, uchar*, Block *bp)
{
char *st;
Ilcb *ic;
@@ 477,19 492,22 @@ iliput(uchar*, Block *bp)
ushort sp, dp, csum;
int plen, illen;
Conv *s, **p, *new, *spec, *gen;
+ Ilpriv *ipriv;
+
+ ipriv = il->priv;
ih = (Ilhdr *)bp->rp;
plen = blocklen(bp);
if(plen < IL_IPSIZE+IL_HDRSIZE){
- netlog(Logil, "il: hlenerr\n");
- il.hlenerr++;
+ netlog(il->f, Logil, "il: hlenerr\n");
+ ipriv->hlenerr++;
goto raise;
}
illen = nhgets(ih->illen);
if(illen+IL_IPSIZE > plen){
- netlog(Logil, "il: lenerr\n");
- il.lenerr++;
+ netlog(il->f, Logil, "il: lenerr\n");
+ ipriv->lenerr++;
goto raise;
}
@@ 497,18 515,18 @@ iliput(uchar*, Block *bp)
dp = nhgets(ih->ilsrc);
v4tov6(raddr, ih->src);
- if(ilcksum && (csum = ptclcsum(bp, IL_IPSIZE, illen)) != 0) {
+ if((csum = ptclcsum(bp, IL_IPSIZE, illen)) != 0) {
if(ih->iltype < 0 || ih->iltype > Ilclose)
st = "?";
else
st = iltype[ih->iltype];
- il.csumerr++;
- netlog(Logil, "il: cksum %ux %ux, pkt(%s id %lud ack %lud %I/%d->%d)\n",
+ ipriv->csumerr++;
+ netlog(il->f, Logil, "il: cksum %ux %ux, pkt(%s id %lud ack %lud %I/%d->%d)\n",
csum, st, nhgetl(ih->ilid), nhgetl(ih->ilack), raddr, sp, dp);
goto raise;
}
- for(p = il.conv; *p; p++) {
+ for(p = il->conv; *p; p++) {
s = *p;
if(s->lport == sp)
if(s->rport == dp)
@@ 523,14 541,14 @@ iliput(uchar*, Block *bp)
st = "?";
else
st = iltype[ih->iltype];
- netlog(Logil, "il: no channel, pkt(%s id %lud ack %lud %I/%ud->%ud)\n",
+ netlog(il->f, Logil, "il: no channel, pkt(%s id %lud ack %lud %I/%ud->%ud)\n",
st, nhgetl(ih->ilid), nhgetl(ih->ilack), raddr, sp, dp);
goto raise;
}
gen = nil;
spec = nil;
- for(p = il.conv; *p; p++) {
+ for(p = il->conv; *p; p++) {
s = *p;
ic = (Ilcb*)s->ptcl;
if(ic->state != Illistening)
@@ 555,9 573,9 @@ iliput(uchar*, Block *bp)
goto raise;
v4tov6(laddr, ih->dst);
- new = Fsnewcall(&fs, s, raddr, dp, laddr, sp);
+ new = Fsnewcall(s, raddr, dp, laddr, sp);
if(new == nil){
- netlog(Logil, "il: bad newcall %I/%ud->%ud\n", raddr, sp, dp);
+ netlog(il->f, Logil, "il: bad newcall %I/%ud->%ud\n", raddr, sp, dp);
ilsendctl(nil, ih, Ilclose, 0, nhgetl(ih->ilid), 0);
goto raise;
}
@@ 602,7 620,7 @@ _ilprocess(Conv *s, Ilhdr *h, Block *bp)
switch(ic->state) {
default:
- netlog(Logil, "il: unknown state %d\n", ic->state);
+ netlog(s->p->f, Logil, "il: unknown state %d\n", ic->state);
case Ilclosed:
freeblist(bp);
break;
@@ 618,7 636,7 @@ _ilprocess(Conv *s, Ilhdr *h, Block *bp)
ic->rstart = id;
ilsendctl(s, nil, Ilack, ic->next, ic->recvd, 0);
ic->state = Ilestablished;
- Fsconnected(&fs, s, nil);
+ Fsconnected(s, nil);
ilpullup(s);
iltimers(ic);
}
@@ 742,6 760,7 @@ ilrexmit(Ilcb *ic)
Conv *c;
ulong id;
int x;
+ Ilpriv *ipriv;
nb = nil;
qlock(&ic->ackq);
@@ 759,16 778,16 @@ ilrexmit(Ilcb *ic)
h->ilspec = ilnextqt(ic);
h->ilsum[0] = 0;
h->ilsum[1] = 0;
- if(ilcksum)
- hnputs(h->ilsum, ptclcsum(nb, IL_IPSIZE, nhgets(h->illen)));
+ hnputs(h->ilsum, ptclcsum(nb, IL_IPSIZE, nhgets(h->illen)));
c = ic->conv;
+ ipriv = c->p->priv;
id = nhgetl(h->ilid);
- netlog(Logil, "il: rexmit %ud %ud: %d %d: %i %d/%d\n", id, ic->recvd,
+ netlog(c->p->f, Logil, "il: rexmit %ud %ud: %d %d: %i %d/%d\n", id, ic->recvd,
ic->fasttime, ic->timeout,
c->raddr, c->lport, c->rport);
- il.rexmit++;
+ ipriv->rexmit++;
ic->rexmit++;
/*
@@ 782,7 801,7 @@ ilrexmit(Ilcb *ic)
if(x >= (1<<LogAGain))
ic->rate = x;
- ipoput(nb, 0, ic->conv->ttl);
+ ipoput(c->p->f, nb, 0, ic->conv->ttl);
}
/* DEBUG */
@@ 794,14 813,14 @@ ilprocess(Conv *s, Ilhdr *h, Block *bp)
ic = (Ilcb*)s->ptcl;
USED(ic);
- DBG(s->raddr)(Logilmsg, "%11s rcv %d/%d snt %d/%d pkt(%s id %d ack %d %d->%d) ",
+ netlog(s->p->f, Logilmsg, "%11s rcv %d/%d snt %d/%d pkt(%s id %d ack %d %d->%d) ",
ilstates[ic->state], ic->rstart, ic->recvd, ic->start,
ic->next, iltype[h->iltype], nhgetl(h->ilid),
nhgetl(h->ilack), nhgets(h->ilsrc), nhgets(h->ildst));
_ilprocess(s, h, bp);
- DBG(s->raddr)(Logilmsg, "%11s rcv %d snt %d\n", ilstates[ic->state], ic->recvd, ic->next);
+ netlog(s->p->f, Logilmsg, "%11s rcv %d snt %d\n", ilstates[ic->state], ic->recvd, ic->next);
}
void
@@ 810,7 829,7 @@ ilhangup(Conv *s, char *msg)
Ilcb *ic;
int callout;
- netlog(Logil, "il: hangup! %I %d/%d: %s\n", s->raddr, s->lport, s->rport, msg?msg:"no reason");
+ netlog(s->p->f, Logil, "il: hangup! %I %d/%d: %s\n", s->raddr, s->lport, s->rport, msg?msg:"no reason");
ic = (Ilcb*)s->ptcl;
callout = ic->state == Ilsyncer;
@@ 820,7 839,7 @@ ilhangup(Conv *s, char *msg)
qhangup(s->wq, msg);
if(callout)
- Fsconnected(&fs, s, msg);
+ Fsconnected(s, msg);
}
void
@@ 830,6 849,7 @@ ilpullup(Conv *s)
Ilhdr *oh;
Block *bp;
ulong oid, dlen;
+ Ilpriv *ipriv;
ic = (Ilcb*)s->ptcl;
if(ic->state != Ilestablished)
@@ 846,7 866,8 @@ ilpullup(Conv *s)
continue;
}
if(oid != ic->recvd+1){
- il.order++;
+ ipriv = s->p->priv;
+ ipriv->order++;
break;
}
@@ 875,14 896,16 @@ iloutoforder(Conv *s, Ilhdr *h, Block *bp)
uchar *lid;
Block *f, **l;
ulong id, newid;
+ Ilpriv *ipriv;
+ ipriv = s->p->priv;
ic = (Ilcb*)s->ptcl;
bp->list = nil;
id = nhgetl(h->ilid);
/* Window checks */
if(id <= ic->recvd || id > ic->recvd+ic->window) {
- netlog(Logil, "il: message outside window %ud <%ud-%ud>: %i %d/%d\n",
+ netlog(s->p->f, Logil, "il: message outside window %ud <%ud-%ud>: %i %d/%d\n",
id, ic->recvd, ic->recvd+ic->window, s->raddr, s->lport, s->rport);
freeblist(bp);
return;
@@ 899,8 922,8 @@ iloutoforder(Conv *s, Ilhdr *h, Block *bp)
newid = nhgetl(lid);
if(id <= newid) {
if(id == newid) {
- ilstats.dup++;
- ilstats.dupb += blocklen(bp);
+ ipriv->dup++;
+ ipriv->dupb += blocklen(bp);
qunlock(&ic->outo);
freeblist(bp);
return;
@@ 964,24 987,28 @@ ilsendctl(Conv *ipc, Ilhdr *inih, int type, ulong id, ulong ack, int ilspec)
hnputs(ih->ilsum, ptclcsum(bp, IL_IPSIZE, IL_HDRSIZE));
if(ipc){
- DBG(ipc->raddr)(Logilmsg, "ctl(%s id %d ack %d %d->%d)\n",
+ netlog(ipc->p->f, Logilmsg, "ctl(%s id %d ack %d %d->%d)\n",
iltype[ih->iltype], nhgetl(ih->ilid), nhgetl(ih->ilack),
nhgets(ih->ilsrc), nhgets(ih->ildst));
}
- ipoput(bp, 0, ttl);
+ ipoput(ipc->p->f, bp, 0, ttl);
}
void
-ilackproc()
+ilackproc(void *x)
{
Ilcb *ic;
Conv **s, *p;
- static Rendez ilr;
+ Proto *il;
+ Ilpriv *ipriv;
+
+ il = x;
+ ipriv = il->priv;
loop:
- tsleep(&ilr, return0, 0, Iltickms);
- for(s = il.conv; s && *s; s++) {
+ tsleep(&ipriv->ilr, return0, 0, Iltickms);
+ for(s = il->conv; s && *s; s++) {
p = *s;
ic = (Ilcb*)p->ptcl;
@@ 1016,7 1043,7 @@ loop:
if(ic->querytime <= 0){
ic->deathtime -= Querytime;
if(ic->deathtime < 0){
- netlog(Logil, "il: hangup due to deathtime (%d) < 0 \n", ic->deathtime);
+ netlog(il->f, Logil, "il: hangup due to deathtime (%d) < 0 \n", ic->deathtime);
ilhangup(p, etime);
break;
}
@@ 1032,7 1059,7 @@ loop:
ilbackoff(ic);
}
if(ic->timeout >= ic->slowtime) {
- netlog(Logil, "il: hangup due to timeout (%d) >= slowtime (%d)\n", ic->timeout, ic->slowtime);
+ netlog(il->f, Logil, "il: hangup due to timeout (%d) >= slowtime (%d)\n", ic->timeout, ic->slowtime);
ilhangup(p, etime);
break;
}
@@ 1080,7 1107,7 @@ ilstart(Conv *c, int type, int window)
switch(type) {
default:
- netlog(Logil, "il: start: type %d\n", type);
+ netlog(c->p->f, Logil, "il: start: type %d\n", type);
break;
case IL_LISTEN:
ic->state = Illistening;
@@ 1132,7 1159,7 @@ iltimers(Ilcb *ic)
}
void
-iladvise(Block *bp, char *msg)
+iladvise(Proto *il, Block *bp, char *msg)
{
Ilhdr *h;
Ilcb *ic;
@@ 1148,7 1175,7 @@ iladvise(Block *bp, char *msg)
/* Look for a connection, unfortunately the destination port is missing */
- for(p = il.conv; *p; p++) {
+ for(p = il->conv; *p; p++) {
s = *p;
if(s->lport == psource)
if(ipcmp(s->laddr, source) == 0)
A ip/inferno.c => ip/inferno.c +46 -0
@@ 0,0 1,46 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+#include "ip.h"
+
+/*
+ * some hacks for commonality twixt inferno and plan9
+ */
+
+char*
+commonuser(void)
+{
+ return up->user;
+}
+
+Chan*
+commonfdtochan(int fd, int mode, int a, int b)
+{
+ return fdtochan(fd, mode, a, b);
+}
+
+char*
+commonerror(void)
+{
+ return up->error;
+}
+
+char*
+bootp(Ipifc*)
+{
+ return "unimplmented";
+}
+
+int
+bootpread(char*, ulong, int)
+{
+ return 0;
+}
+
+Medium tripmedium =
+{
+ "trip",
+};
M ip/ip.c => ip/ip.c +203 -118
@@ 26,13 26,13 @@ struct Iphdr
uchar vihl; /* Version and header length */
uchar tos; /* Type of service */
uchar length[2]; /* packet length */
- uchar id[2]; /* Identification */
+ uchar id[2]; /* ip->identification */
uchar frag[2]; /* Fragment information */
uchar ttl; /* Time to live */
uchar proto; /* Protocol */
uchar cksum[2]; /* Header checksum */
- uchar src[4]; /* Ip source */
- uchar dst[4]; /* Ip destination */
+ uchar src[4]; /* IP source */
+ uchar dst[4]; /* IP destination */
};
struct Fragment
@@ 51,14 51,44 @@ struct Ipfrag
ushort flen;
};
-QLock fraglock;
-Fragment* flisthead;
-Fragment* fragfree;
-ulong Id;
-int iprouting; /* true if we route like a gateway */
-ulong ipcsumerr;
-ulong ipin, ippin; /* uchars, packets in */
-ulong ipout, ippout; /* uchars, packets out */
+/* MIB II counters */
+typedef struct Ipstats Ipstats;
+struct Ipstats
+{
+ ulong ipForwarding;
+ ulong ipDefaultTTL;
+ ulong ipInReceives;
+ ulong ipInHdrErrors;
+ ulong ipInAddrErrors;
+ ulong ipForwDatagrams;
+ ulong ipInUnknownProtos;
+ ulong ipInDiscards;
+ ulong ipInDelivers;
+ ulong ipOutRequests;
+ ulong ipOutDiscards;
+ ulong ipOutNoRoutes;
+ ulong ipReasmTimeout;
+ ulong ipReasmReqds;
+ ulong ipReasmOKs;
+ ulong ipReasmFails;
+ ulong ipFragOKs;
+ ulong ipFragFails;
+ ulong ipFragCreates;
+};
+
+/* an instance of IP */
+struct IP
+{
+ Ipstats istats;
+
+ QLock fraglock;
+ Fragment* flisthead;
+ Fragment* fragfree;
+
+ ulong id;
+ int iprouting; /* true if we route like a gateway */
+ void (*ipextprotoiput)(Block*);
+};
#define BLKIP(xp) ((Iphdr*)((xp)->rp))
/*
@@ 67,19 97,23 @@ ulong ipout, ippout; /* uchars, packets out */
*/
#define BKFG(xp) ((Ipfrag*)((xp)->base))
-static struct Stats
+ushort ipcsum(uchar*);
+Block* ipreassemble(IP*, int, Block*, Iphdr*);
+void ipfragfree(IP*, Fragment*);
+Fragment* ipfragallo(IP*);
+
+void
+ip_init(Fs *f)
{
- ulong noroute;
- ulong droppedfrag;
-} stats;
+ IP *ip;
-ushort ipcsum(uchar*);
-Block* ipreassemble(int, Block*, Iphdr*);
-void ipfragfree(Fragment*);
-Fragment* ipfragallo(void);
+ ip = smalloc(sizeof(IP));
+ initfrag(ip, 100);
+ f->ip = ip;
+}
void
-ipoput(Block *bp, int gating, int ttl)
+ipoput(Fs *f, Block *bp, int gating, int ttl)
{
Ipifc *ifc;
uchar *gate;
@@ 87,45 121,60 @@ ipoput(Block *bp, int gating, int ttl)
Block *xp, *nb;
Iphdr *eh, *feh;
int lid, len, seglen, chunk, dlen, blklen, offset, medialen;
- Route *r;
+ Route *r, *sr;
+ IP *ip;
+
+ ip = f->ip;
/* Fill out the ip header */
eh = (Iphdr *)(bp->rp);
+ ip->istats.ipOutRequests++;
+
/* Number of uchars in data and ip header to write */
len = blocklen(bp);
- ipout += len;
- ippout++;
+
if(gating){
chunk = nhgets(eh->length);
if(chunk > len){
- netlog(Logip, "short gated packet\n");
+ ip->istats.ipOutDiscards++;
+ netlog(f, Logip, "short gated packet\n");
goto free;
}
if(chunk < len)
len = chunk;
}
if(len >= IP_MAX){
- netlog(Logip, "exceeded ip max size %V\n", eh->dst);
+ ip->istats.ipOutDiscards++;
+ netlog(f, Logip, "exceeded ip max size %V\n", eh->dst);
goto free;
}
- r = v4lookup(eh->dst);
+ r = v4lookup(f, eh->dst);
if(r == nil){
- stats.noroute++;
- netlog(Logip, "no interface %V\n", eh->dst);
+ ip->istats.ipOutNoRoutes++;
+ netlog(f, Logip, "no interface %V\n", eh->dst);
goto free;
}
- if(r->type & (Rifc|Runi|Rbcast|Rmulti))
+
+ ifc = r->ifc;
+ if(r->type & (Rifc|Runi))
gate = eh->dst;
else
+ if(r->type & (Rbcast|Rmulti)) {
+ gate = eh->dst;
+ sr = v4lookup(f, eh->src);
+ if(sr != nil && (sr->type & Runi))
+ ifc = sr->ifc;
+ }
+ else
gate = r->v4.gate;
+
if(!gating){
eh->vihl = IP_VER|IP_HLEN;
eh->tos = 0;
eh->ttl = ttl;
}
- ifc = r->ifc;
if(waserror()){
runlock(ifc);
@@ 139,7 188,7 @@ ipoput(Block *bp, int gating, int ttl)
medialen = ifc->m->maxmtu - ifc->m->hsize;
if(len <= medialen) {
if(!gating)
- hnputs(eh->id, Id++);
+ hnputs(eh->id, ip->id++);
hnputs(eh->length, len);
eh->frag[0] = 0;
eh->frag[1] = 0;
@@ 147,7 196,7 @@ ipoput(Block *bp, int gating, int ttl)
eh->cksum[1] = 0;
hnputs(eh->cksum, ipcsum(&eh->vihl));
-/*print("ipoput %V->%V via %V\n", eh->src, eh->dst, gate);*/
+/* print("ipoput %V->%V via %V\n", eh->src, eh->dst, gate); /**/
ifc->m->bwrite(ifc, bp, V4, gate);
runlock(ifc);
poperror();
@@ 155,13 204,15 @@ ipoput(Block *bp, int gating, int ttl)
}
if(eh->frag[0] & (IP_DF>>8)){
- netlog(Logip, "%V: eh->frag[0] & (IP_DF>>8)\n", eh->dst);
+ ip->istats.ipOutDiscards++;
+ netlog(f, Logip, "%V: eh->frag[0] & (IP_DF>>8)\n", eh->dst);
goto raise;
}
seglen = (medialen - IPHDR) & ~7;
if(seglen < 8){
- netlog(Logip, "%V seglen < 8\n", eh->dst);
+ ip->istats.ipOutDiscards++;
+ netlog(f, Logip, "%V seglen < 8\n", eh->dst);
goto raise;
}
@@ 170,7 221,7 @@ ipoput(Block *bp, int gating, int ttl)
if(gating)
lid = nhgets(eh->id);
else
- lid = Id++;
+ lid = ip->id++;
offset = IPHDR;
while(xp != nil && offset && offset >= BLEN(xp)) {
@@ 200,8 251,9 @@ ipoput(Block *bp, int gating, int ttl)
chunk = seglen;
while(chunk) {
if(!xp) {
+ ip->istats.ipOutDiscards++;
freeblist(nb);
- netlog(Logip, "!xp: chunk %d\n", chunk);
+ netlog(f, Logip, "!xp: chunk %d\n", chunk);
goto raise;
}
blklen = chunk;
@@ 213,14 265,14 @@ ipoput(Block *bp, int gating, int ttl)
chunk -= blklen;
if(xp->rp == xp->wp)
xp = xp->next;
- }
+ }
feh->cksum[0] = 0;
feh->cksum[1] = 0;
hnputs(feh->cksum, ipcsum(&feh->vihl));
ifc->m->bwrite(ifc, nb, V4, gate);
+ ip->istats.ipFragCreates++;
}
-
raise:
runlock(ifc);
poperror();
@@ 229,36 281,40 @@ free:
}
void
-initfrag(int size)
+initfrag(IP *ip, int size)
{
Fragment *fq, *eq;
- fragfree = (Fragment*)malloc(sizeof(Fragment) * size);
- if(fragfree == nil)
+ ip->fragfree = (Fragment*)malloc(sizeof(Fragment) * size);
+ if(ip->fragfree == nil)
panic("initfrag");
- eq = &fragfree[size];
- for(fq = fragfree; fq < eq; fq++)
+ eq = &ip->fragfree[size];
+ for(fq = ip->fragfree; fq < eq; fq++)
fq->next = fq+1;
- fragfree[size-1].next = nil;
+ ip->fragfree[size-1].next = nil;
}
-void (*ipextprotoiput)(Block*);
-
-//#define DBG(x) if((logmask & Logipmsg) && (iponly == 0 || x == iponly))netlog
+#define DBG(x) if((logmask & Logipmsg) && (iponly == 0 || x == iponly))netlog
void
-ipiput(uchar *ia, Block *bp)
+ipiput(Fs *f, uchar *ia, Block *bp)
{
+ int hl;
Iphdr *h;
Proto *p;
ushort frag;
int notforme;
- uchar v6dst[IPaddrlen];
+ uchar *dp, v6dst[IPaddrlen];
+ IP *ip;
+
+ ip = f->ip;
+ ip->istats.ipInReceives++;
// h = (Iphdr *)(bp->rp);
-// DBG(nhgetl(h->src))(Logipmsg, "ipiput %I %I len %d proto %d\n", h->src, h->dst, BLEN(bp), h->proto);
+// DBG(nhgetl(h->src))(Logipmsg, "ipiput %V %V len %d proto %d\n",
+// h->src, h->dst, BLEN(bp), h->proto);
/* Ensure we have enough data to process */
if(BLEN(bp) < IPHDR) {
@@ 270,70 326,95 @@ ipiput(uchar *ia, Block *bp)
/* dump anything that whose header doesn't checksum */
if(ipcsum(&h->vihl)) {
- ipcsumerr++;
- netlog(Logip, "ip: checksum error %I\n", h->src);
+ ip->istats.ipInHdrErrors++;
+ netlog(f, Logip, "ip: checksum error %I\n", h->src);
freeblist(bp);
return;
}
- /* route */
v4tov6(v6dst, h->dst);
- notforme = ipforme(v6dst) == 0;
+ notforme = ipforme(f, v6dst) == 0;
+
+ /* Check header length and version */
+ if(h->vihl != (IP_VER|IP_HLEN)) {
+ hl = (h->vihl&0xF)<<2;
+ if((h->vihl&0xF0) != IP_VER || hl < (IP_HLEN<<2)) {
+ ip->istats.ipInHdrErrors++;
+ netlog(f, Logip, "ip: %V bad hivl %ux\n", h->src, h->vihl);
+ freeblist(bp);
+ return;
+ }
+ /* If this is not routed strip off the options */
+ if(notforme == 0) {
+ dp = bp->rp + (hl - (IP_HLEN<<2));
+ memmove(dp, h, IP_HLEN<<2);
+ bp->rp = dp;
+ h = (Iphdr *)(bp->rp);
+ h->vihl = (IP_VER|IP_HLEN);
+ }
+ }
+
+ /* route */
if(notforme) {
- if(iprouting) {
+ if(ip->iprouting) {
/* gate */
if(h->ttl <= 1)
freeblist(bp);
- else
- ipoput(bp, 1, h->ttl - 1);
+ else {
+ ip->istats.ipForwDatagrams++;
+ ipoput(f, bp, 1, h->ttl - 1);
+ }
} else
- useriprouter(ia, bp);
+ useriprouter(f, ia, bp);
return;
}
- /* Check header length and version */
- if(h->vihl != (IP_VER|IP_HLEN)) {
- netlog(Logip, "ip: %I bad hivl %ux\n", h->src, h->vihl);
- freeblist(bp);
- return;
- }
+
+
frag = nhgets(h->frag);
if(frag) {
h->tos = 0;
if(frag & IP_MF)
h->tos = 1;
- bp = ipreassemble(frag, bp, h);
+ bp = ipreassemble(ip, frag, bp, h);
if(bp == nil)
return;
h = (Iphdr *)(bp->rp);
}
- ipin += blocklen(bp);
- ippin++;
-
- p = Fsrcvpcol(&fs, h->proto);
- if(p != nil && p->rcv != nil)
- (*p->rcv)(ia, bp);
- else if(ipextprotoiput != nil)
- ipextprotoiput(bp);
- else
- freeblist(bp);
+ p = Fsrcvpcol(f, h->proto);
+ if(p != nil && p->rcv != nil) {
+ ip->istats.ipInDelivers++;
+ (*p->rcv)(p, ia, bp);
+ return;
+ }
+ ip->istats.ipInDiscards++;
+ ip->istats.ipInUnknownProtos++;
+ freeblist(bp);
}
int
-ipstats(char *buf, int len)
+ipstats(Fs *f, char *buf, int len)
{
- int n;
-
- n = snprint(buf, len, "ip: csum %lud inb %lud outb %lud inp %lud outp %lud\n",
- ipcsumerr, ipin, ipout, ippin, ippout);
- n += snprint(buf+n, len - n, "\tnoroute %lud droppedfrag %lud\n",
- stats.noroute, stats.droppedfrag);
- return n;
+ IP *ip;
+
+ ip = f->ip;
+ return snprint(buf, len, "%d %d %d %d %d %d %d %d %d %d "
+ "%d %d %d %d %d %d %d %d %d",
+ ip->istats.ipForwarding, ip->istats.ipDefaultTTL,
+ ip->istats.ipInReceives, ip->istats.ipInHdrErrors,
+ ip->istats.ipInAddrErrors, ip->istats.ipForwDatagrams,
+ ip->istats.ipInUnknownProtos, ip->istats.ipInDiscards,
+ ip->istats.ipInDelivers, ip->istats.ipOutRequests,
+ ip->istats.ipOutDiscards, ip->istats.ipOutNoRoutes,
+ ip->istats.ipReasmTimeout, ip->istats.ipReasmReqds,
+ ip->istats.ipReasmOKs, ip->istats.ipReasmFails,
+ ip->istats.ipFragOKs, ip->istats.ipFragFails,
+ ip->istats.ipFragCreates);
}
Block*
-ipreassemble(int offset, Block *bp, Iphdr *ip)
+ipreassemble(IP *ip, int offset, Block *bp, Iphdr *ih)
{
int fend;
ushort id;
@@ 342,30 423,30 @@ ipreassemble(int offset, Block *bp, Iphdr *ip)
Block *bl, **l, *last, *prev;
int ovlap, len, fragsize, pktposn;
- src = nhgetl(ip->src);
- dst = nhgetl(ip->dst);
- id = nhgets(ip->id);
+ src = nhgetl(ih->src);
+ dst = nhgetl(ih->dst);
+ id = nhgets(ih->id);
/*
* block lists are too hard, pullupblock into a single block
*/
if(bp->next){
bp = pullupblock(bp, blocklen(bp));
- ip = (Iphdr *)(bp->rp);
+ ih = (Iphdr *)(bp->rp);
}
- qlock(&fraglock);
+ qlock(&ip->fraglock);
/*
* find a reassembly queue for this fragment
*/
- for(f = flisthead; f; f = fnext){
+ for(f = ip->flisthead; f; f = fnext){
fnext = f->next; /* because ipfragfree changes the list */
if(f->src == src && f->dst == dst && f->id == id)
break;
if(f->age < msec){
- stats.droppedfrag++;
- ipfragfree(f);
+ ip->istats.ipReasmTimeout++;
+ ipfragfree(ip, f);
}
}
@@ 374,10 455,12 @@ ipreassemble(int offset, Block *bp, Iphdr *ip)
* and get rid of any fragments that might go
* with it.
*/
- if(!ip->tos && (offset & ~(IP_MF|IP_DF)) == 0) {
- if(f != nil)
- ipfragfree(f);
- qunlock(&fraglock);
+ if(!ih->tos && (offset & ~(IP_MF|IP_DF)) == 0) {
+ if(f != nil) {
+ ipfragfree(ip, f);
+ ip->istats.ipReasmFails++;
+ }
+ qunlock(&ip->fraglock);
return bp;
}
@@ 387,18 470,19 @@ ipreassemble(int offset, Block *bp, Iphdr *ip)
}
BKFG(bp)->foff = offset<<3;
- BKFG(bp)->flen = nhgets(ip->length)-IPHDR;
+ BKFG(bp)->flen = nhgets(ih->length)-IPHDR;
/* First fragment allocates a reassembly queue */
if(f == nil) {
- f = ipfragallo();
+ f = ipfragallo(ip);
f->id = id;
f->src = src;
f->dst = dst;
f->blist = bp;
- qunlock(&fraglock);
+ qunlock(&ip->fraglock);
+ ip->istats.ipReasmReqds++;
return nil;
}
@@ 420,7 504,7 @@ ipreassemble(int offset, Block *bp, Iphdr *ip)
if(ovlap > 0) {
if(ovlap >= BKFG(bp)->flen) {
freeblist(bp);
- qunlock(&fraglock);
+ qunlock(&ip->fraglock);
return nil;
}
BKFG(prev)->flen -= ovlap;
@@ 443,7 527,7 @@ ipreassemble(int offset, Block *bp, Iphdr *ip)
if(ovlap < BKFG(*l)->flen) {
BKFG(*l)->flen -= ovlap;
BKFG(*l)->foff += ovlap;
- /* move up ip hdrs */
+ /* move up ih hdrs */
memmove((*l)->rp + ovlap, (*l)->rp, IPHDR);
(*l)->rp += ovlap;
break;
@@ 480,15 564,16 @@ ipreassemble(int offset, Block *bp, Iphdr *ip)
bl = f->blist;
f->blist = nil;
- ipfragfree(f);
- ip = BLKIP(bl);
- hnputs(ip->length, len);
- qunlock(&fraglock);
+ ipfragfree(ip, f);
+ ih = BLKIP(bl);
+ hnputs(ih->length, len);
+ qunlock(&ip->fraglock);
+ ip->istats.ipReasmOKs++;
return bl;
}
pktposn += BKFG(bl)->flen;
}
- qunlock(&fraglock);
+ qunlock(&ip->fraglock);
return nil;
}
@@ 496,7 581,7 @@ ipreassemble(int offset, Block *bp, Iphdr *ip)
* ipfragfree - Free a list of fragments - assume hold fraglock
*/
void
-ipfragfree(Fragment *frag)
+ipfragfree(IP *ip, Fragment *frag)
{
Fragment *fl, **l;
@@ 507,7 592,7 @@ ipfragfree(Fragment *frag)
frag->id = 0;
frag->blist = nil;
- l = &flisthead;
+ l = &ip->flisthead;
for(fl = *l; fl; fl = fl->next) {
if(fl == frag) {
*l = frag->next;
@@ 516,8 601,8 @@ ipfragfree(Fragment *frag)
l = &fl->next;
}
- frag->next = fragfree;
- fragfree = frag;
+ frag->next = ip->fragfree;
+ ip->fragfree = frag;
}
@@ 525,20 610,20 @@ ipfragfree(Fragment *frag)
* ipfragallo - allocate a reassembly queue - assume hold fraglock
*/
Fragment *
-ipfragallo(void)
+ipfragallo(IP *ip)
{
Fragment *f;
- while(fragfree == nil) {
+ while(ip->fragfree == nil) {
/* free last entry on fraglist */
- for(f = flisthead; f->next; f = f->next)
+ for(f = ip->flisthead; f->next; f = f->next)
;
- ipfragfree(f);
+ ipfragfree(ip, f);
}
- f = fragfree;
- fragfree = f->next;
- f->next = flisthead;
- flisthead = f;
+ f = ip->fragfree;
+ ip->fragfree = f->next;
+ f->next = ip->flisthead;
+ ip->flisthead = f;
f->age = msec + 30000;
return f;
M ip/ip.h => ip/ip.h +96 -53
@@ 2,17 2,22 @@ typedef struct Conv Conv;
typedef struct Fs Fs;
typedef union Hwaddr Hwaddr;
typedef struct Ifcconv Ifcconv;
+typedef struct IP IP;
typedef struct Ipself Ipself;
+typedef struct Ipselftab Ipselftab;
typedef struct Iplink Iplink;
typedef struct Iplifc Iplifc;
typedef struct Ipmulti Ipmulti;
typedef struct Iproute Iproute;
+typedef struct IProuter IProuter;
typedef struct Ipifc Ipifc;
+typedef struct Log Log;
typedef struct Medium Medium;
typedef struct Proto Proto;
typedef struct Pstate Pstate;
typedef struct Tcpc Tcpc;
typedef struct Arpent Arpent;
+typedef struct Arp Arp;
typedef struct Route Route;
enum
@@ 34,6 39,9 @@ enum
/* ip versions */
V4= 4,
V6= 6,
+
+ /* 2^Lroot trees in the root table */
+ Lroot = 10,
};
enum
@@ 106,7 114,7 @@ struct Medium
void (*remmulti)(Ipifc *ifc, uchar *a, uchar *ia);
/* process packets written to 'data' */
- void (*pktin)(Ipifc *ifc, Block *bp);
+ void (*pktin)(Fs *f, Ipifc *ifc, Block *bp);
/* routes for router boards */
void (*addroute)(Ipifc *ifc, int, uchar*, uchar*, uchar*, int);
@@ 114,7 122,7 @@ struct Medium
void (*flushroutes)(Ipifc *ifc);
/* for routing multicast groups */
- void (*joinmulti)(Ipifc *ifc, uchar *a, uchar *ia, uchar **iap);
+ void (*joinmulti)(Ipifc *ifc, uchar *a, uchar *ia);
void (*leavemulti)(Ipifc *ifc, uchar *a, uchar *ia);
int unbindonclose; /* if non-zero, unbind on last close */
@@ 196,13 204,14 @@ struct Proto
int (*state)(Conv*, char*, int);
void (*create)(Conv*);
void (*close)(Conv*);
- void (*rcv)(uchar*, Block*);
+ void (*rcv)(Proto*, uchar*, Block*);
char* (*ctl)(Conv*, char**, int);
- void (*advise)(Block*, char*);
- int (*stats)(char*, int);
+ void (*advise)(Proto*, Block*, char*);
+ int (*stats)(Proto*, char*, int);
int (*local)(Conv*, char*, int);
int (*inuse)(Conv*);
+ Fs *f; /* file system this proto is part of */
Conv **conv; /* array of conversations */
int ptclsize; /* size of per protocol ctl block */
int nc; /* number of conversations */
@@ 211,13 220,21 @@ struct Proto
ushort nextport;
ushort nextrport;
- ulong csumerr; /* checksum errors */
- ulong hlenerr; /* header length error */
- ulong lenerr; /* short packet */
- ulong order; /* out of order */
- ulong rexmit; /* retransmissions */
+ void *priv;
+};
+
+/*
+ * Stream for sending packets to user level
+ */
+struct IProuter {
+ QLock;
+ int opens;
+ Queue *q;
};
+/*
+ * one per IP protocol stack
+ */
struct Fs
{
Lock;
@@ 225,9 242,22 @@ struct Fs
int np;
Proto* p[Maxproto+1]; /* list of supported protocols */
Proto* t2p[256]; /* vector of all ip protocol handlers */
+ Proto* ipifc; /* kludge for ipifcremroute & ipifcaddroute */
+
+ IP *ip;
+ Ipselftab *self;
+ Arp *arp;
+ IProuter iprouter;
+
+ Route *v4root[1<<Lroot]; /* v4 routing forest */
+ Route *v6root[1<<Lroot]; /* v6 routing forest */
+ Route *queue; /* used as temp when reinjecting routes */
+
+ Log *alog;
};
-int Fsconnected(Fs*, Conv*, char*);
-Conv* Fsnewcall(Fs*, Conv*, uchar*, ushort, uchar*, ushort);
+
+int Fsconnected(Conv*, char*);
+Conv* Fsnewcall(Conv*, uchar*, ushort, uchar*, ushort);
int Fspcolstats(char*, int);
int Fsproto(Fs*, Proto*);
int Fsbuiltinproto(Fs*, uchar);
@@ 258,15 288,12 @@ enum
Logipmsg= 1<<14,
};
-extern int logmask; /* mask of things to debug */
-extern uchar iponly[IPaddrlen]; /* ip address to print debugging for */
-extern int iponlyset;
-
-void netlogopen(void);
-void netlogclose(void);
-char* netlogctl(char*, int);
-long netlogread(void*, ulong, long);
-void netlog(int, char*, ...);
+void netloginit(Fs*);
+void netlogopen(Fs*);
+void netlogclose(Fs*);
+char* netlogctl(Fs*, char*, int);
+long netlogread(Fs*, void*, ulong, long);
+void netlog(Fs*, int, char*, ...);
/*
* iproute.c
@@ 332,15 359,17 @@ struct Route
V4route v4;
};
};
-extern void v4addroute(char *tag, uchar *a, uchar *mask, uchar *gate, int type);
-extern void v6addroute(char *tag, uchar *a, uchar *mask, uchar *gate, int type);
-extern void v4delroute(uchar *a, uchar *mask);
-extern void v6delroute(uchar *a, uchar *mask);
-extern Route* v4lookup(uchar *a);
-extern Route* v6lookup(uchar *a);
-extern long routeread(char*, ulong, int);
-extern long routewrite(Chan*, char*, int);
+extern void v4addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type);
+extern void v6addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type);
+extern void v4delroute(Fs *f, uchar *a, uchar *mask);
+extern void v6delroute(Fs *f, uchar *a, uchar *mask);
+extern Route* v4lookup(Fs *f, uchar *a);
+extern Route* v6lookup(Fs *f, uchar *a);
+extern long routeread(Fs *f, char*, ulong, int);
+extern long routewrite(Fs *f, Chan*, char*, int);
extern void routetype(int, char*);
+extern void ipwalkroutes(Fs*, Routewalk*);
+extern void convroute(Route*, uchar*, uchar*, uchar*, char*, int*);
/*
* arp.c
@@ 358,12 387,13 @@ struct Arpent
uchar state;
};
-extern int arpread(char*, ulong, int);
-extern int arpwrite(char*, int);
-extern Arpent* arpget(Block *bp, int version, Medium *type, uchar *ip, uchar *h);
-extern void arprelease(Arpent *a);
-extern Block* arpresolve(Arpent *a, Medium *type, uchar *mac);
-extern void arpenter(Ipifc *ifc, int version, uchar *ip, uchar *mac, Medium *type, int norefresh);
+extern void arpinit(Fs*);
+extern int arpread(Arp*, char*, ulong, int);
+extern int arpwrite(Arp*, char*, int);
+extern Arpent* arpget(Arp*, Block *bp, int version, Medium *type, uchar *ip, uchar *h);
+extern void arprelease(Arp*, Arpent *a);
+extern Block* arpresolve(Arp*, Arpent *a, Medium *type, uchar *mac);
+extern void arpenter(Arp*, Ipifc *ifc, int version, uchar *ip, uchar *mac, Medium *type, int norefresh);
/*
* ipaux.c
@@ 408,57 438,70 @@ extern uchar IPallbits[IPaddrlen];
extern Medium ethermedium;
extern Medium nullmedium;
extern Medium pktmedium;
+extern Medium tripmedium;
extern Proto ipifc;
/*
* ipifc.c
*/
extern Medium* ipfindmedium(char *name);
-extern int ipforme(uchar *addr);
+extern int ipforme(Fs*, uchar *addr);
extern int ipismulticast(uchar *);
-extern Ipifc* findipifc(uchar *remote, int type);
-extern void findlocalip(uchar *local, uchar *remote);
+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 Iplifc* iplocalonifc(Ipifc *ifc, uchar *ip);
-extern int ipproxyifc(Ipifc *ifc, uchar *ip);
+extern int ipproxyifc(Fs *f, Ipifc *ifc, uchar *ip);
extern int ipismulticast(uchar *ip);
extern int ipisbooting(void);
extern int ipifccheckin(Ipifc *ifc, Medium *med);
extern void ipifccheckout(Ipifc *ifc);
extern int ipifcgrab(Ipifc *ifc);
-extern void ipifcaddroute(int, uchar*, uchar*, uchar*, int);
-extern void ipifcremroute(int, uchar*, uchar*);
+extern void ipifcaddroute(Fs*, int, uchar*, uchar*, uchar*, int);
+extern void ipifcremroute(Fs*, int, uchar*, uchar*);
extern void ipifcremmulti(Conv *c, uchar *ma, uchar *ia);
extern void ipifcaddmulti(Conv *c, uchar *ma, uchar *ia);
extern char* ipifcrem(Ipifc *ifc, char **argv, int argc, int dolock);
extern char* ipifcadd(Ipifc *ifc, char **argv, int argc);
-extern long ipselftabread(char *a, ulong offset, int n);
+extern long ipselftabread(Fs*, char *a, ulong offset, int n);
/*
* ip.c
*/
extern void closeifcconv(Ifcconv*);
-extern void icmpnoconv(Block*);
-extern void initfrag(int);
+extern void icmpnoconv(Fs*, Block*);
+extern void initfrag(IP*, int);
extern ushort ipcsum(uchar*);
extern void (*ipextprotoiput)(Block*);
-extern void ipiput(uchar*, Block*);
-extern void ipoput(Block*, int, int);
-extern int ipstats(char*, int);
+extern void ipiput(Fs*, uchar*, Block*);
+extern void ipoput(Fs*, Block*, int, int);
+extern int ipstats(Fs*, char*, int);
extern uchar* logctl(uchar*);
-extern Ifcconv* newifcconv(void);
-extern void (*pktifcrcv)(Conv*, Block*);
extern ushort ptclbsum(uchar*, int);
extern ushort ptclcsum(Block*, int, int);
+extern void ip_init(Fs*);
+
+/*
+ * bootp.c
+ */
+extern char* bootp(Ipifc*);
+extern int bootpread(char*, ulong, int);
/*
* iprouter.c
*/
-void useriprouter(uchar*, Block*);
-void iprouteropen(void);
-void iprouterclose(void);
-long iprouterread(void*, int);
+void useriprouter(Fs*, uchar*, Block*);
+void iprouteropen(Fs*);
+void iprouterclose(Fs*);
+long iprouterread(Fs*, void*, int);
+
+/*
+ * resolving inferno/plan9 differences
+ */
+Chan* commonfdtochan(int, int, int, int);
+char* commonuser(void);
+char* commonerror(void);
/*
* global to all of the stack
M ip/ipaux.c => ip/ipaux.c +2 -0
@@ 372,6 372,8 @@ parsecmd(char *p, int n)
if(n > sizeof(cb->buf)-1)
n = sizeof(cb->buf)-1;
memmove(cb->buf, p, n);
+ if(n > 0 && cb->buf[n-1] == '\n')
+ n--;
cb->buf[n] = '\0';
cb->nf = parsefields(cb->buf, cb->f, nelem(cb->f), " ");
return cb;
M ip/ipifc.c => ip/ipifc.c +110 -112
@@ 17,14 17,12 @@ enum {
QMAX = 64*1024-1,
};
- Proto ipifc;
-extern Fs fs;
-
Medium *media[] =
{
ðermedium,
&pktmedium,
&nullmedium,
+ &tripmedium,
0
};
@@ 43,7 41,6 @@ struct Ipself
Ipself *next; /* free list */
};
-typedef struct Ipselftab Ipselftab;
struct Ipselftab
{
QLock;
@@ 51,7 48,6 @@ struct Ipselftab
int acceptall; /* true if an interface has the null address */
Ipself *hash[NHASH]; /* hash chains */
};
-Ipselftab selftab;
/*
* Multicast addresses are chained onto a Chan so that
@@ 70,8 66,8 @@ struct Ipmcast
static char tifc[] = "ifc ";
-static void addselfcache(Ipifc *ifc, Iplifc *lifc, uchar *a, int type);
-static void remselfcache(Ipifc *ifc, Iplifc *lifc, uchar *a);
+static void addselfcache(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *a, int type);
+static void remselfcache(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *a);
static char* ipifcjoinmulti(Ipifc *ifc, char **argv, int argc);
static char* ipifcleavemulti(Ipifc *ifc, char **argv, int argc);
@@ 252,7 248,7 @@ ipifckick(Conv *c, int)
if(ifc->m == nil || ifc->m->pktin == nil)
freeb(bp);
else
- (*ifc->m->pktin)(ifc, bp);
+ (*ifc->m->pktin)(c->p->f, ifc, bp);
}
/*
@@ 299,6 295,9 @@ ipifcadd(Ipifc *ifc, char **argv, int argc)
uchar bcast[IPaddrlen], net[IPaddrlen];
Iplifc *lifc, **l;
int i, type, mtu;
+ Fs *f;
+
+ f = ifc->conv->p->f;
memset(ip, 0, IPaddrlen);
memset(mask, 0, IPaddrlen);
@@ 359,24 358,24 @@ ipifcadd(Ipifc *ifc, char **argv, int argc)
if(ipcmp(mask, IPallbits) == 0)
type |= Rptpt;
if(isv4(ip))
- v4addroute(tifc, rem+IPv4off, mask+IPv4off, ip+IPv4off, type);
+ v4addroute(f, tifc, rem+IPv4off, mask+IPv4off, ip+IPv4off, type);
else
- v6addroute(tifc, ip, mask, rem, type);
+ v6addroute(f, tifc, ip, mask, rem, type);
- addselfcache(ifc, lifc, ip, Runi);
+ addselfcache(f, ifc, lifc, ip, Runi);
/* add subnet directed broadcast addresses to the self cache */
for(i = 0; i < IPaddrlen; i++)
bcast[i] = (ip[i] & mask[i]) | ~mask[i];
- addselfcache(ifc, lifc, bcast, Rbcast);
+ addselfcache(f, ifc, lifc, bcast, Rbcast);
/* add network directed broadcast addresses to the self cache */
memmove(mask, defmask(ip), IPaddrlen);
for(i = 0; i < IPaddrlen; i++)
bcast[i] = (ip[i] & mask[i]) | ~mask[i];
- addselfcache(ifc, lifc, bcast, Rbcast);
+ addselfcache(f, ifc, lifc, bcast, Rbcast);
- addselfcache(ifc, lifc, IPv4bcast, Rbcast);
+ addselfcache(f, ifc, lifc, IPv4bcast, Rbcast);
out:
wunlock(ifc);
@@ 394,10 393,13 @@ ipifcrem(Ipifc *ifc, char **argv, int argc, int dolock)
uchar ip[IPaddrlen];
uchar mask[IPaddrlen];
Iplifc *lifc, **l;
+ Fs *f;
if(argc < 3)
return Ebadarg;
+ f = ifc->conv->p->f;
+
parseip(ip, argv[1]);
parseipmask(mask, argv[2]);
@@ 424,13 426,13 @@ ipifcrem(Ipifc *ifc, char **argv, int argc, int dolock)
/* disassociate any addresses */
while(lifc->link)
- remselfcache(ifc, lifc, lifc->link->self->a);
+ remselfcache(f, ifc, lifc, lifc->link->self->a);
/* remove the route for this logical interface */
if(isv4(ip))
- v4delroute(lifc->remote+IPv4off, lifc->mask+IPv4off);
+ v4delroute(f, lifc->remote+IPv4off, lifc->mask+IPv4off);
else
- v6delroute(lifc->remote, lifc->mask);
+ v6delroute(f, lifc->remote, lifc->mask);
free(lifc);
@@ 447,13 449,14 @@ out:
* TRIP linecards
*/
void
-ipifcaddroute(int vers, uchar *addr, uchar *mask, uchar *gate, int type)
+ipifcaddroute(Fs *f, int vers, uchar *addr, uchar *mask, uchar *gate, int type)
{
Medium *m;
- Conv **cp;
+ Conv **cp, **e;
Ipifc *ifc;
- for(cp = ipifc.conv; cp < &ipifc.conv[ipifc.nc]; cp++){
+ e = &f->ipifc->conv[f->ipifc->nc];
+ for(cp = f->ipifc->conv; cp < e; cp++){
if(*cp != nil) {
ifc = (Ipifc*)(*cp)->ptcl;
m = ifc->m;
@@ 466,13 469,14 @@ ipifcaddroute(int vers, uchar *addr, uchar *mask, uchar *gate, int type)
}
void
-ipifcremroute(int vers, uchar *addr, uchar *mask)
+ipifcremroute(Fs *f, int vers, uchar *addr, uchar *mask)
{
Medium *m;
- Conv **cp;
+ Conv **cp, **e;
Ipifc *ifc;
- for(cp = ipifc.conv; cp < &ipifc.conv[ipifc.nc]; cp++){
+ e = &f->ipifc->conv[f->ipifc->nc];
+ for(cp = f->ipifc->conv; cp < e; cp++){
if(*cp != nil) {
ifc = (Ipifc*)(*cp)->ptcl;
m = ifc->m;
@@ 523,7 527,7 @@ ipifcconnect(Conv* c, char **argv, int argc)
if(err)
return err;
- Fsconnected(&fs, c, nil);
+ Fsconnected(c, nil);
return nil;
}
@@ 540,6 544,8 @@ ipifcctl(Conv* c, char**argv, int argc)
ifc = (Ipifc*)c->ptcl;
if(strcmp(argv[0], "add") == 0)
return ipifcadd(ifc, argv, argc);
+ else if(strcmp(argv[0], "bootp") == 0)
+ return bootp(ifc);
else if(strcmp(argv[0], "remove") == 0)
return ipifcrem(ifc, argv, argc, 1);
else if(strcmp(argv[0], "unbind") == 0)
@@ 551,28 557,39 @@ ipifcctl(Conv* c, char**argv, int argc)
return "unsupported ctl";
}
+ipifcstats(Proto *ipifc, char *buf, int len)
+{
+ return ipstats(ipifc->f, buf, len);
+}
+
void
-ipifcinit(Fs *fs)
+ipifcinit(Fs *f)
{
- ipifc.name = "ipifc";
- ipifc.kick = ipifckick;
- ipifc.connect = ipifcconnect;
- ipifc.announce = nil;
- ipifc.bind = ipifcbind;
- ipifc.state = ipifcstate;
- ipifc.create = ipifccreate;
- ipifc.close = ipifcclose;
- ipifc.rcv = nil;
- ipifc.ctl = ipifcctl;
- ipifc.advise = nil;
- ipifc.stats = ipstats;
- ipifc.inuse = ipifcinuse;
- ipifc.local = ipifclocal;
- ipifc.ipproto = -1;
- ipifc.nc = Maxmedia;
- ipifc.ptclsize = sizeof(Ipifc);
-
- Fsproto(fs, &ipifc);
+ Proto *ipifc;
+
+ ipifc = smalloc(sizeof(Ipifc));
+ ipifc->name = "ipifc";
+ ipifc->kick = ipifckick;
+ ipifc->connect = ipifcconnect;
+ ipifc->announce = nil;
+ ipifc->bind = ipifcbind;
+ ipifc->state = ipifcstate;
+ ipifc->create = ipifccreate;
+ ipifc->close = ipifcclose;
+ ipifc->rcv = nil;
+ ipifc->ctl = ipifcctl;
+ ipifc->advise = nil;
+ ipifc->stats = ipifcstats;
+ ipifc->inuse = ipifcinuse;
+ ipifc->local = ipifclocal;
+ ipifc->ipproto = -1;
+ ipifc->nc = Maxmedia;
+ ipifc->ptclsize = sizeof(Ipifc);
+
+ f->ipifc = ipifc; /* hack for ipifcremroute, findipifc, ... */
+ f->self = smalloc(sizeof(Ipselftab)); /* hack for ipforme */
+
+ Fsproto(f, ipifc);
}
/*
@@ 580,17 597,17 @@ ipifcinit(Fs *fs)
* called with c->car locked
*/
static void
-addselfcache(Ipifc *ifc, Iplifc *lifc, uchar *a, int type)
+addselfcache(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *a, int type)
{
Ipself *p;
Iplink *lp;
int h;
- qlock(&selftab);
+ qlock(f->self);
/* see if the address already exists */
h = hashipa(a);
- for(p = selftab.hash[h]; p; p = p->next)
+ for(p = f->self->hash[h]; p; p = p->next)
if(memcmp(a, p->a, IPaddrlen) == 0)
break;
@@ 599,12 616,12 @@ addselfcache(Ipifc *ifc, Iplifc *lifc, uchar *a, int type)
p = smalloc(sizeof(*p));
ipmove(p->a, a);
p->type = type;
- p->next = selftab.hash[h];
- selftab.hash[h] = p;
+ p->next = f->self->hash[h];
+ f->self->hash[h] = p;
/* if the null address, accept all packets */
if(ipcmp(a, v4prefix) == 0 || ipcmp(a, IPnoaddr) == 0)
- selftab.acceptall = 1;
+ f->self->acceptall = 1;
}
/* look for a link for this lifc */
@@ 625,9 642,9 @@ addselfcache(Ipifc *ifc, Iplifc *lifc, uchar *a, int type)
/* add to routing table */
if(isv4(a))
- v4addroute(tifc, a+IPv4off, IPallbits+IPv4off, a+IPv4off, type);
+ v4addroute(f, tifc, a+IPv4off, IPallbits+IPv4off, a+IPv4off, type);
else
- v6addroute(tifc, a, IPallbits, a, type);
+ v6addroute(f, tifc, a, IPallbits, a, type);
if((type & Rmulti) && ifc->m->addmulti != nil)
(*ifc->m->addmulti)(ifc, a, lifc->local);
@@ 635,14 652,14 @@ addselfcache(Ipifc *ifc, Iplifc *lifc, uchar *a, int type)
lp->ref++;
}
- qunlock(&selftab);
+ qunlock(f->self);
}
/*
* These structures are unlinked from their chains while
* other threads may be using them. To avoid excessive locking,
* just put them aside for a while before freeing them.
- * called with &selftab locked
+ * called with f->self locked
*/
static Iplink *freeiplink;
static Ipself *freeipself;
@@ 692,15 709,15 @@ ipselffree(Ipself *p)
* called with c->car locked
*/
static void
-remselfcache(Ipifc *ifc, Iplifc *lifc, uchar *a)
+remselfcache(Fs *f, Ipifc *ifc, Iplifc *lifc, uchar *a)
{
Ipself *p, **l;
Iplink *link, **l_self, **l_lifc;
- qlock(&selftab);
+ qlock(f->self);
/* find the unique selftab entry */
- l = &selftab.hash[hashipa(a)];
+ l = &f->self->hash[hashipa(a)];
for(p = *l; p; p = *l){
if(ipcmp(p->a, a) == 0)
break;
@@ 754,9 771,9 @@ remselfcache(Ipifc *ifc, Iplifc *lifc, uchar *a)
/* remove from routing table */
if(isv4(a))
- v4delroute(a+IPv4off, IPallbits+IPv4off);
+ v4delroute(f, a+IPv4off, IPallbits+IPv4off);
else
- v6delroute(a, IPallbits);
+ v6delroute(f, a, IPallbits);
/* no more links, remove from hash and free */
*l = p->next;
@@ 764,29 781,10 @@ remselfcache(Ipifc *ifc, Iplifc *lifc, uchar *a)
/* if IPnoaddr, forget */
if(ipcmp(a, v4prefix) == 0 || ipcmp(a, IPnoaddr) == 0)
- selftab.acceptall = 0;
+ f->self->acceptall = 0;
out:
- qunlock(&selftab);
-}
-
-static void
-dumpselftab(void)
-{
- int i, count;
- Ipself *p;
-
- qlock(&selftab);
- for(i = 0; i < NHASH; i++){
- p = selftab.hash[i];
- if(p == nil)
- continue;
- count = 0;
- for(; p != nil && count++ < 6; p = p->next)
- print("(%I %d %lux)", p->a, p->type, p);
- print("\n");
- }
- qunlock(&selftab);
+ qunlock(f->self);
}
static char *stformat = "%-32.32I %2.2d %4.4s\n";
@@ 796,7 794,7 @@ enum
};
long
-ipselftabread(char *cp, ulong offset, int n)
+ipselftabread(Fs *f, char *cp, ulong offset, int n)
{
int i, m, nifc;
Ipself *p;
@@ 804,9 802,9 @@ ipselftabread(char *cp, ulong offset, int n)
char state[8];
m = 0;
- qlock(&selftab);
+ qlock(f->self);
for(i = 0; i < NHASH && m < n; i++){
- for(p = selftab.hash[i]; p != nil && m < n; p = p->next){
+ for(p = f->self->hash[i]; p != nil && m < n; p = p->next){
if(offset == 0){
nifc = 0;
for(link = p->link; link; link = link->selflink)
@@ 817,7 815,7 @@ ipselftabread(char *cp, ulong offset, int n)
offset -= Nstformat;
}
}
- qunlock(&selftab);
+ qunlock(f->self);
return m;
}
@@ 830,24 828,18 @@ ipselftabread(char *cp, ulong offset, int n)
* Rmcast
*/
int
-ipforme(uchar *addr)
+ipforme(Fs *f, uchar *addr)
{
Ipself *p;
- int count;
- p = selftab.hash[hashipa(addr)];
- count = 0;
+ p = f->self->hash[hashipa(addr)];
for(; p; p = p->next){
- if(count++ > 1000){ /* check for loops */
- dumpselftab();
- break;
- }
if(ipcmp(addr, p->a) == 0)
return p->type;
}
/* hack to say accept anything */
- if(selftab.acceptall)
+ if(f->self->acceptall)
return Runi;
return 0;
@@ 858,29 850,28 @@ ipforme(uchar *addr)
* return nil.
*/
Ipifc*
-findipifc(uchar *remote, int type)
+findipifc(Fs *f, uchar *remote, int type)
{
Ipifc *ifc;
Iplifc *lifc;
- Conv **cp;
+ Conv **cp, **e;
uchar gnet[IPaddrlen];
- for(cp = ipifc.conv; cp < &ipifc.conv[ipifc.nc]; cp++){
+ e = &f->ipifc->conv[f->ipifc->nc];
+ for(cp = f->ipifc->conv; cp < e; cp++){
if(*cp == 0)
continue;
ifc = (Ipifc*)(*cp)->ptcl;
for(lifc = ifc->lifc; lifc; lifc = lifc->next){
maskip(remote, lifc->mask, gnet);
- if(ipcmp(gnet, lifc->net) == 0){
- qunlock(&ipifc);
+ if(ipcmp(gnet, lifc->net) == 0)
return ifc;
- }
}
}
/* for now for broadcast and mutlicast, just use first interface */
if(type & (Rbcast|Rmulti)){
- for(cp = ipifc.conv; cp < &ipifc.conv[ipifc.nc]; cp++){
+ for(cp = f->ipifc->conv; cp < e; cp++){
if(*cp == 0)
continue;
ifc = (Ipifc*)(*cp)->ptcl;
@@ 897,17 888,17 @@ findipifc(uchar *remote, int type)
* local and return the ifc for that address
*/
void
-findlocalip(uchar *local, uchar *remote)
+findlocalip(Fs *f, uchar *local, uchar *remote)
{
Ipifc *ifc;
Iplifc *lifc;
- Conv **cp;
+ Conv **cp, **e;
Route *r;
uchar gate[IPaddrlen];
uchar gnet[IPaddrlen];
- qlock(&ipifc);
- r = v6lookup(remote);
+ qlock(f->ipifc);
+ r = v6lookup(f, remote);
if(r != nil){
ifc = r->ifc;
@@ 932,7 923,8 @@ findlocalip(uchar *local, uchar *remote)
}
/* no match, choose first ifc local address */
- for(cp = ipifc.conv; cp < &ipifc.conv[ipifc.nc]; cp++){
+ e = &f->ipifc->conv[f->ipifc->nc];
+ for(cp = f->ipifc->conv; cp < e; cp++){
if(*cp == 0)
continue;
ifc = (Ipifc*)(*cp)->ptcl;
@@ 943,7 935,7 @@ findlocalip(uchar *local, uchar *remote)
}
out:
- qunlock(&ipifc);
+ qunlock(f->ipifc);
}
/*
@@ 999,14 991,14 @@ iplocalonifc(Ipifc *ifc, uchar *ip)
* See if we're proxying for this address on this interface
*/
int
-ipproxyifc(Ipifc *ifc, uchar *ip)
+ipproxyifc(Fs *f, Ipifc *ifc, uchar *ip)
{
Route *r;
uchar net[IPaddrlen];
Iplifc *lifc;
/* see if this is a direct connected pt to pt address */
- r = v6lookup(ip);
+ r = v6lookup(f, ip);
if(r == nil)
return 0;
if((r->type & Rifc) == 0)
@@ 1050,6 1042,9 @@ ipifcaddmulti(Conv *c, uchar *ma, uchar *ia)
Iplifc *lifc;
Conv **p;
Ipmulti *multi, **l;
+ Fs *f;
+
+ f = c->p->f;
for(l = &c->multi; *l; l = &(*l)->next)
if(ipcmp(ma, (*l)->ma) == 0)
@@ 1061,7 1056,7 @@ ipifcaddmulti(Conv *c, uchar *ma, uchar *ia)
ipmove(multi->ia, ia);
multi->next = nil;
- for(p = ipifc.conv; *p; p++){
+ for(p = f->ipifc->conv; *p; p++){
if((*p)->inuse == 0)
continue;
ifc = (Ipifc*)(*p)->ptcl;
@@ 1072,7 1067,7 @@ ipifcaddmulti(Conv *c, uchar *ma, uchar *ia)
wlock(ifc);
for(lifc = ifc->lifc; lifc; lifc = lifc->next)
if(ipcmp(ia, lifc->local) == 0)
- addselfcache(ifc, lifc, ma, Rmulti);
+ addselfcache(f, ifc, lifc, ma, Rmulti);
wunlock(ifc);
poperror();
}
@@ 1089,6 1084,9 @@ ipifcremmulti(Conv *c, uchar *ma, uchar *ia)
Iplifc *lifc;
Conv **p;
Ipifc *ifc;
+ Fs *f;
+
+ f = c->p->f;
for(l = &c->multi; *l; l = &(*l)->next)
if(ipcmp(ma, (*l)->ma) == 0)
@@ 1101,7 1099,7 @@ ipifcremmulti(Conv *c, uchar *ma, uchar *ia)
*l = multi->next;
- for(p = ipifc.conv; *p; p++){
+ for(p = f->ipifc->conv; *p; p++){
if((*p)->inuse == 0)
continue;
@@ 1113,7 1111,7 @@ ipifcremmulti(Conv *c, uchar *ma, uchar *ia)
wlock(ifc);
for(lifc = ifc->lifc; lifc; lifc = lifc->next)
if(ipcmp(ia, lifc->local) == 0)
- remselfcache(ifc, lifc, ma);
+ remselfcache(f, ifc, lifc, ma);
wunlock(ifc);
poperror();
}
M ip/iproute.c => ip/iproute.c +73 -79
@@ 7,17 7,11 @@
#include "ip.h"
-enum
-{
- Lroot = 10,
-};
-
-Route *v4root[1<<Lroot], *v6root[1<<Lroot], *queue;
-
-static void walkadd(Route**, Route*);
-static void addnode(Route**, Route*);
+static void walkadd(Fs*, Route**, Route*);
+static void addnode(Fs*, Route**, Route*);
static void calcd(Route*);
+/* these are used for all instances of IP */
Route* v4freelist;
Route* v6freelist;
RWlock routelock;
@@ 160,7 154,7 @@ copygate(Route *old, Route *new)
* walk down a tree adding nodes back in
*/
static void
-walkadd(Route **root, Route *p)
+walkadd(Fs *f, Route **root, Route *p)
{
Route *l, *r;
@@ 168,11 162,11 @@ walkadd(Route **root, Route *p)
r = p->right;
p->left = 0;
p->right = 0;
- addnode(root, p);
+ addnode(f, root, p);
if(l)
- walkadd(root, l);
+ walkadd(f, root, l);
if(r)
- walkadd(root, r);
+ walkadd(f, root, r);
}
/*
@@ 238,7 232,7 @@ balancetree(Route **cur)
* add a new node to the tree
*/
static void
-addnode(Route **cur, Route *new)
+addnode(Fs *f, Route **cur, Route *new)
{
Route *p;
@@ 251,10 245,10 @@ addnode(Route **cur, Route *new)
switch(rangecompare(new, p)){
case Rpreceeds:
- addnode(&p->left, new);
+ addnode(f, &p->left, new);
break;
case Rfollows:
- addnode(&p->right, new);
+ addnode(f, &p->right, new);
break;
case Rcontains:
/*
@@ 266,14 260,14 @@ addnode(Route **cur, Route *new)
*/
*cur = new;
new->depth = 1;
- addqueue(&queue, p);
+ addqueue(&f->queue, p);
break;
case Requals:
copygate(p, new);
freeroute(new);
break;
case Rcontained:
- addnode(&p->mid, new);
+ addnode(f, &p->mid, new);
break;
}
@@ 283,7 277,7 @@ addnode(Route **cur, Route *new)
#define V4H(a) ((a&0x07ffffff)>>(32-Lroot-5))
void
-v4addroute(char *tag, uchar *a, uchar *mask, uchar *gate, int type)
+v4addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type)
{
Route *p;
ulong sa;
@@ 304,22 298,22 @@ v4addroute(char *tag, uchar *a, uchar *mask, uchar *gate, int type)
memmove(p->tag, tag, sizeof(p->tag));
wlock(&routelock);
- addnode(&v4root[h], p);
- while(p = queue) {
- queue = p->mid;
- walkadd(&v4root[h], p->left);
+ addnode(f, &f->v4root[h], p);
+ while(p = f->queue) {
+ f->queue = p->mid;
+ walkadd(f, &f->v4root[h], p->left);
freeroute(p);
}
wunlock(&routelock);
}
- ipifcaddroute(Rv4, a, mask, gate, type);
+ ipifcaddroute(f, Rv4, a, mask, gate, type);
}
#define V6H(a) (((a)[IPllen-1] & 0x07ffffff)>>(32-Lroot-5))
void
-v6addroute(char *tag, uchar *a, uchar *mask, uchar *gate, int type)
+v6addroute(Fs *f, char *tag, uchar *a, uchar *mask, uchar *gate, int type)
{
Route *p;
ulong sa[IPllen], ea[IPllen];
@@ 342,16 336,16 @@ v6addroute(char *tag, uchar *a, uchar *mask, uchar *gate, int type)
memmove(p->tag, tag, sizeof(p->tag));
wlock(&routelock);
- addnode(&v6root[h], p);
- while(p = queue) {
- queue = p->mid;
- walkadd(&v6root[h], p->left);
+ addnode(f, &f->v6root[h], p);
+ while(p = f->queue) {
+ f->queue = p->mid;
+ walkadd(f, &f->v6root[h], p->left);
freeroute(p);
}
wunlock(&routelock);
}
- ipifcaddroute(0, a, mask, gate, type);
+ ipifcaddroute(f, 0, a, mask, gate, type);
}
Route**
@@ 383,7 377,7 @@ looknode(Route **cur, Route *r)
}
void
-v4delroute(uchar *a, uchar *mask)
+v4delroute(Fs *f, uchar *a, uchar *mask)
{
Route **r, *p;
Route rt;
@@ 398,28 392,28 @@ v4delroute(uchar *a, uchar *mask)
eh = V4H(rt.v4.endaddress);
for(h=V4H(rt.v4.address); h<=eh; h++) {
wlock(&routelock);
- r = looknode(&v4root[h], &rt);
+ r = looknode(&f->v4root[h], &rt);
if(r) {
p = *r;
*r = 0;
- addqueue(&queue, p->left);
- addqueue(&queue, p->mid);
- addqueue(&queue, p->right);
+ addqueue(&f->queue, p->left);
+ addqueue(&f->queue, p->mid);
+ addqueue(&f->queue, p->right);
freeroute(p);
- while(p = queue) {
- queue = p->mid;
- walkadd(&v4root[h], p->left);
+ while(p = f->queue) {
+ f->queue = p->mid;
+ walkadd(f, &f->v4root[h], p->left);
freeroute(p);
}
}
wunlock(&routelock);
}
- ipifcremroute(Rv4, a, mask);
+ ipifcremroute(f, Rv4, a, mask);
}
void
-v6delroute(uchar *a, uchar *mask)
+v6delroute(Fs *f, uchar *a, uchar *mask)
{
Route **r, *p;
Route rt;
@@ 437,28 431,28 @@ v6delroute(uchar *a, uchar *mask)
eh = V6H(rt.v6.endaddress);
for(h=V6H(rt.v6.address); h<=eh; h++) {
wlock(&routelock);
- r = looknode(&v6root[h], &rt);
+ r = looknode(&f->v6root[h], &rt);
if(r) {
p = *r;
*r = 0;
- addqueue(&queue, p->left);
- addqueue(&queue, p->mid);
- addqueue(&queue, p->right);
+ addqueue(&f->queue, p->left);
+ addqueue(&f->queue, p->mid);
+ addqueue(&f->queue, p->right);
freeroute(p);
- while(p = queue) {
- queue = p->mid;
- walkadd(&v6root[h], p->left);
+ while(p = f->queue) {
+ f->queue = p->mid;
+ walkadd(f, &f->v6root[h], p->left);
freeroute(p);
}
}
wunlock(&routelock);
}
- ipifcremroute(0, a, mask);
+ ipifcremroute(f, 0, a, mask);
}
Route*
-v4lookup(uchar *a)
+v4lookup(Fs *f, uchar *a)
{
Route *p, *q;
ulong la;
@@ 466,7 460,7 @@ v4lookup(uchar *a)
la = nhgetl(a);
q = nil;
- for(p=v4root[V4H(la)]; p;)
+ for(p=f->v4root[V4H(la)]; p;)
if(la >= p->v4.address) {
if(la <= p->v4.endaddress) {
q = p;
@@ 478,7 472,7 @@ v4lookup(uchar *a)
if(q && (q->ifc == nil || q->ifcid != q->ifc->ifcid)){
v4tov6(gate, q->v4.gate);
- q->ifc = findipifc(gate, q->type);
+ q->ifc = findipifc(f, gate, q->type);
if(q->ifc == nil)
return nil;
q->ifcid = q->ifc->ifcid;
@@ 488,7 482,7 @@ v4lookup(uchar *a)
}
Route*
-v6lookup(uchar *a)
+v6lookup(Fs *f, uchar *a)
{
Route *p, *q;
ulong la[IPllen];
@@ 496,7 490,7 @@ v6lookup(uchar *a)
ulong x, y;
if(memcmp(a, v4prefix, 12) == 0){
- q = v4lookup(a+12);
+ q = v4lookup(f, a+12);
if(q != nil)
return q;
}
@@ 505,7 499,7 @@ v6lookup(uchar *a)
la[h] = nhgetl(a+4*h);
q = 0;
- for(p=v6root[V6H(la)]; p;){
+ for(p=f->v6root[V6H(la)]; p;){
for(h = 0; h < IPllen; h++){
x = la[h];
y = p->v6.address[h];
@@ 534,7 528,7 @@ next: ;
}
if(q && q->ifc == nil){
- q->ifc = findipifc(q->v6.gate, q->type);
+ q->ifc = findipifc(f, q->v6.gate, q->type);
if(q->ifc == nil)
return nil;
if(q->ifcid != q->ifc->ifcid)
@@ 654,24 648,24 @@ rr(Route *r, Routewalk *rw)
}
void
-ipwalkroutes(Routewalk *rw)
+ipwalkroutes(Fs *f, Routewalk *rw)
{
rlock(&routelock);
if(rw->n > rw->o) {
- for(rw->h = 0; rw->h < nelem(v4root); rw->h++)
- if(rr(v4root[rw->h], rw) == 0)
+ for(rw->h = 0; rw->h < nelem(f->v4root); rw->h++)
+ if(rr(f->v4root[rw->h], rw) == 0)
break;
}
if(rw->n > rw->o) {
- for(rw->h = 0; rw->h < nelem(v6root); rw->h++)
- if(rr(v6root[rw->h], rw) == 0)
+ for(rw->h = 0; rw->h < nelem(f->v6root); rw->h++)
+ if(rr(f->v6root[rw->h], rw) == 0)
break;
}
runlock(&routelock);
}
long
-routeread(char *p, ulong offset, int n)
+routeread(Fs *f, char *p, ulong offset, int n)
{
Routewalk rw;
@@ 683,7 677,7 @@ routeread(char *p, ulong offset, int n)
rw.o = -(offset/Rlinelen);
rw.walk = sprintroute;
- ipwalkroutes(&rw);
+ ipwalkroutes(f, &rw);
if(rw.o < 0)
rw.o = 0;
@@ 695,7 689,7 @@ routeread(char *p, ulong offset, int n)
* this code is not in routeflush to reduce stack size
*/
void
-delroute(Route *r)
+delroute(Fs *f, Route *r)
{
uchar addr[IPaddrlen];
uchar mask[IPaddrlen];
@@ 705,9 699,9 @@ delroute(Route *r)
convroute(r, addr, mask, gate, t, &nifc);
if(r->type & Rv4)
- v4delroute(addr+IPv4off, mask+IPv4off);
+ v4delroute(f, addr+IPv4off, mask+IPv4off);
else
- v6delroute(addr, mask);
+ v6delroute(f, addr, mask);
}
/*
@@ 715,25 709,25 @@ delroute(Route *r)
* returns 0 if nothing is deleted, 1 otherwise
*/
int
-routeflush(Route *r)
+routeflush(Fs *f, Route *r)
{
if(r == nil)
return 0;
- if(routeflush(r->mid))
+ if(routeflush(f, r->mid))
return 1;
- if(routeflush(r->left))
+ if(routeflush(f, r->left))
return 1;
- if(routeflush(r->right))
+ if(routeflush(f, r->right))
return 1;
if((r->type & Rifc) == 0){
- delroute(r);
+ delroute(f, r);
return 1;
}
return 0;
}
long
-routewrite(Chan *c, char *p, int n)
+routewrite(Fs *f, Chan *c, char *p, int n)
{
int h;
char *tag;
@@ 750,11 744,11 @@ routewrite(Chan *c, char *p, int n)
if(strcmp(cb->f[0], "flush") == 0){
wlock(&routelock);
- for(h = 0; h < nelem(v4root); h++)
- while(routeflush(v4root[h]) == 1)
+ for(h = 0; h < nelem(f->v4root); h++)
+ while(routeflush(f, f->v4root[h]) == 1)
;
- for(h = 0; h < nelem(v6root); h++)
- while(routeflush(v6root[h]) == 1)
+ for(h = 0; h < nelem(f->v6root); h++)
+ while(routeflush(f, f->v6root[h]) == 1)
;
wunlock(&routelock);
} else if(strcmp(cb->f[0], "remove") == 0){
@@ 763,9 757,9 @@ routewrite(Chan *c, char *p, int n)
parseip(addr, cb->f[1]);
parseipmask(mask, cb->f[2]);
if(memcmp(addr, v4prefix, IPv4off) == 0)
- v4delroute(addr+IPv4off, mask+IPv4off);
+ v4delroute(f, addr+IPv4off, mask+IPv4off);
else
- v6delroute(addr, mask);
+ v6delroute(f, addr, mask);
} else if(strcmp(cb->f[0], "add") == 0){
if(cb->nf < 4)
error(Ebadarg);
@@ 776,9 770,9 @@ routewrite(Chan *c, char *p, int n)
if(c != nil)
tag = c->tag;
if(memcmp(addr, v4prefix, IPv4off) == 0)
- v4addroute(tag, addr+IPv4off, mask+IPv4off, gate+IPv4off, 0);
+ v4addroute(f, tag, addr+IPv4off, mask+IPv4off, gate+IPv4off, 0);
else
- v6addroute(tag, addr, mask, gate, 0);
+ v6addroute(f, tag, addr, mask, gate, 0);
} else if(strcmp(cb->f[0], "tag") == 0) {
if(cb->nf < 2)
error(Ebadarg);
M ip/netlog.c => ip/netlog.c +82 -76
@@ 6,10 6,6 @@
#include "../port/error.h"
#include "../ip/ip.h"
-int logmask; /* mask of things to debug */
-uchar iponly[IPaddrlen]; /* ip address to print debugging for */
-int iponlyset;
-
enum {
Nlog = 4*1024,
};
@@ 17,7 13,7 @@ enum {
/*
* action log
*/
-typedef struct Log {
+struct Log {
Lock;
int opens;
char* buf;
@@ 25,15 21,19 @@ typedef struct Log {
char *rptr;
int len;
+ int logmask; /* mask of things to debug */
+ uchar iponly[IPaddrlen]; /* ip address to print debugging for */
+ int iponlyset;
+
QLock;
Rendez;
-} Log;
-static Log alog;
+};
typedef struct Logflag {
char* name;
int mask;
} Logflag;
+
static Logflag flags[] =
{
{ "ppp", Logppp, },
@@ 55,73 55,81 @@ static Logflag flags[] =
static char Ebadnetctl[] = "unknown netlog ctl message";
void
-netlogopen(void)
+netloginit(Fs *f)
+{
+ f->alog = smalloc(sizeof(Log));
+}
+
+void
+netlogopen(Fs *f)
{
- lock(&alog);
+ lock(f->alog);
if(waserror()){
- unlock(&alog);
+ unlock(f->alog);
nexterror();
}
- if(alog.opens == 0){
- if(alog.buf == nil)
- alog.buf = malloc(Nlog);
- alog.rptr = alog.buf;
- alog.end = alog.buf + Nlog;
+ if(f->alog->opens == 0){
+ if(f->alog->buf == nil)
+ f->alog->buf = malloc(Nlog);
+ f->alog->rptr = f->alog->buf;
+ f->alog->end = f->alog->buf + Nlog;
}
- alog.opens++;
- unlock(&alog);
+ f->alog->opens++;
+ unlock(f->alog);
poperror();
}
void
-netlogclose(void)
+netlogclose(Fs *f)
{
- lock(&alog);
+ lock(f->alog);
if(waserror()){
- unlock(&alog);
+ unlock(f->alog);
nexterror();
}
- alog.opens--;
- if(alog.opens == 0){
- free(alog.buf);
- alog.buf = nil;
+ f->alog->opens--;
+ if(f->alog->opens == 0){
+ free(f->alog->buf);
+ f->alog->buf = nil;
}
- unlock(&alog);
+ unlock(f->alog);
poperror();
}
static int
-netlogready(void*)
+netlogready(void *a)
{
- return alog.len;
+ Fs *f = a;
+
+ return f->alog->len;
}
long
-netlogread(void* a, ulong, long n)
+netlogread(Fs *f, void *a, ulong, long n)
{
int i, d;
char *p, *rptr;
- qlock(&alog);
+ qlock(f->alog);
if(waserror()){
- qunlock(&alog);
+ qunlock(f->alog);
nexterror();
}
for(;;){
- lock(&alog);
- if(alog.len){
- if(n > alog.len)
- n = alog.len;
+ lock(f->alog);
+ if(f->alog->len){
+ if(n > f->alog->len)
+ n = f->alog->len;
d = 0;
- rptr = alog.rptr;
- alog.rptr += n;
- if(alog.rptr >= alog.end){
- d = alog.rptr - alog.end;
- alog.rptr = alog.buf + d;
+ rptr = f->alog->rptr;
+ f->alog->rptr += n;
+ if(f->alog->rptr >= f->alog->end){
+ d = f->alog->rptr - f->alog->end;
+ f->alog->rptr = f->alog->buf + d;
}
- alog.len -= n;
- unlock(&alog);
+ f->alog->len -= n;
+ unlock(f->alog);
i = n;
p = a;
@@ 129,28 137,28 @@ netlogread(void* a, ulong, long n)
memmove(p, rptr, d);
i -= d;
p += d;
- rptr = alog.buf;
+ rptr = f->alog->buf;
}
memmove(p, rptr, i);
break;
}
else
- unlock(&alog);
+ unlock(f->alog);
- sleep(&alog, netlogready, 0);
+ sleep(f->alog, netlogready, 0);
}
- qunlock(&alog);
+ qunlock(f->alog);
poperror();
return n;
}
char*
-netlogctl(char* s, int len)
+netlogctl(Fs *f, char* s, int len)
{
int i, n, set;
- Logflag *f;
+ Logflag *fp;
char *fields[10], *p, buf[256];
if(len == 0)
@@ 172,11 180,11 @@ netlogctl(char* s, int len)
else if(strcmp("clear", fields[0]) == 0)
set = 0;
else if(strcmp("only", fields[0]) == 0){
- parseip(iponly, fields[1]);
- if(ipcmp(iponly, IPnoaddr) == 0)
- iponlyset = 0;
+ parseip(f->alog->iponly, fields[1]);
+ if(ipcmp(f->alog->iponly, IPnoaddr) == 0)
+ f->alog->iponlyset = 0;
else
- iponlyset = 1;
+ f->alog->iponlyset = 1;
return nil;
} else
return Ebadnetctl;
@@ 186,56 194,54 @@ netlogctl(char* s, int len)
*p = 0;
for(i = 1; i < n; i++){
- for(f = flags; f->name; f++)
- if(strcmp(f->name, fields[i]) == 0)
+ for(fp = flags; fp->name; fp++)
+ if(strcmp(fp->name, fields[i]) == 0)
break;
- if(f->name == nil)
+ if(fp->name == nil)
continue;
if(set)
- logmask |= f->mask;
+ f->alog->logmask |= fp->mask;
else
- logmask &= ~f->mask;
+ f->alog->logmask &= ~fp->mask;
}
return nil;
}
void
-netlog(int mask, char *fmt, ...)
+netlog(Fs *f, int mask, char *fmt, ...)
{
- char buf[128], *t, *f;
+ char buf[128], *t, *fp;
int i, n;
va_list arg;
- if(!(logmask & mask))
+ if(!(f->alog->logmask & mask))
return;
va_start(arg, fmt);
n = doprint(buf, buf+sizeof(buf), fmt, arg) - buf;
va_end(arg);
-print("%s", buf);
-
- if(alog.opens == 0)
+ if(f->alog->opens == 0)
return;
- lock(&alog);
- i = alog.len + n - Nlog;
+ lock(f->alog);
+ i = f->alog->len + n - Nlog;
if(i > 0){
- alog.len -= i;
- alog.rptr += i;
- if(alog.rptr >= alog.end)
- alog.rptr = alog.buf + (alog.rptr - alog.end);
+ f->alog->len -= i;
+ f->alog->rptr += i;
+ if(f->alog->rptr >= f->alog->end)
+ f->alog->rptr = f->alog->buf + (f->alog->rptr - f->alog->end);
}
- t = alog.rptr + alog.len;
- f = buf;
- alog.len += n;
+ t = f->alog->rptr + f->alog->len;
+ fp = buf;
+ f->alog->len += n;
while(n-- > 0){
- if(t >= alog.end)
- t = alog.buf + (t - alog.end);
- *t++ = *f++;
+ if(t >= f->alog->end)
+ t = f->alog->buf + (t - f->alog->end);
+ *t++ = *fp++;
}
- unlock(&alog);
+ unlock(f->alog);
- wakeup(&alog);
+ wakeup(f->alog);
}
M ip/pktmedium.c => ip/pktmedium.c +4 -4
@@ 12,7 12,7 @@
static void pktbind(Ipifc *ifc, int argc, char **argv);
static void pktunbind(Ipifc *ifc);
static void pktbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip);
-static void pktin(Ipifc *ifc, Block *bp);
+static void pktin(Fs*, Ipifc *ifc, Block *bp);
Medium pktmedium =
{
@@ 64,13 64,13 @@ pktbwrite(Ipifc *ifc, Block *bp, int, uchar*)
}
/*
- * called when someone write's to 'data' with ifc rlocked
+ * called with ifc rlocked when someone write's to 'data'
*/
static void
-pktin(Ipifc *ifc, Block *bp)
+pktin(Fs *f, Ipifc *ifc, Block *bp)
{
if(ifc->lifc == nil)
freeb(bp);
else
- ipiput(ifc->lifc->local, bp);
+ ipiput(f, ifc->lifc->local, bp);
}
M ip/tcp.c => ip/tcp.c +201 -119
@@ 180,25 180,52 @@ struct Tcpctl
Tcphdr protohdr; /* prototype header */
};
-#define DBG(x) if((logmask & Logtcpmsg) && (iponlyset == 0 || memcmp(x, iponly+12, 4) == 0))netlog
-
-Proto tcp;
int tcp_irtt = DEF_RTT; /* Initial guess at round trip time */
ushort tcp_mss = DEF_MSS; /* Maximum segment size to be sent */
-Timer *timers; /* List of active timers */
-QLock tl; /* Protect timer list */
-static struct Tcpstats
+/* MIB II counters */
+typedef struct Tcpstats Tcpstats;
+struct Tcpstats
{
- ulong dup; /* (partially) duplicated packets */
- ulong dupb; /* duplicated uchars */
-} tstats;
+ ulong tcpRtoAlgorithm;
+ ulong tcpRtoMin;
+ ulong tcpRtoMax;
+ ulong tcpMaxConn;
+ ulong tcpActiveOpens;
+ ulong tcpPassiveOpens;
+ ulong tcpAttemptFails;
+ ulong tcpEstabResets;
+ ulong tcpCurrEstab;
+ ulong tcpInSegs;
+ ulong tcpOutSegs;
+ ulong tcpRetransSegs;
+ ulong InErrs;
+ ulong OutRsts;
+};
+
+typedef struct Tcppriv Tcppriv;
+struct Tcppriv
+{
+ Timer *timers; /* List of active timers */
+ QLock tl; /* Protect timer list */
+ Rendez tcpr; /* used by tcpackproc */
+
+ /* MIB stats */
+ Tcpstats tstats;
+
+ /* non-MIB stats */
+ ulong csumerr; /* checksum errors */
+ ulong hlenerr; /* header length error */
+ ulong lenerr; /* short packet */
+ ulong order; /* out of order */
+
+};
void addreseq(Tcpctl*, Tcp*, Block*, ushort);
void getreseq(Tcpctl*, Tcp*, Block**, ushort*);
void localclose(Conv*, char*);
void procsyn(Conv*, Tcp*);
-void tcpiput(uchar*, Block*);
+void tcpiput(Proto*, uchar*, Block*);
void tcpoutput(Conv*);
int tcptrim(Tcpctl*, Tcp*, Block**, ushort*);
void tcpstart(Conv*, int, ushort);
@@ 212,6 239,9 @@ tcpsetstate(Conv *s, uchar newstate)
{
Tcpctl *tcb;
uchar oldstate;
+ Tcppriv *tpriv;
+
+ tpriv = s->p->priv;
tcb = (Tcpctl*)s->ptcl;
@@ 219,6 249,11 @@ tcpsetstate(Conv *s, uchar newstate)
if(oldstate == newstate)
return;
+ if(oldstate == Established)
+ tpriv->tstats.tcpCurrEstab--;
+ if(newstate == Established)
+ tpriv->tstats.tcpCurrEstab++;
+
/*
print("%d/%d %s->%s\n", s->lport, s->rport,
tcpstates[oldstate], tcpstates[newstate]);
@@ 241,7 276,7 @@ tcpsetstate(Conv *s, uchar newstate)
}
if(oldstate == Syn_sent && newstate != Closed)
- Fsconnected(&fs, s, nil);
+ Fsconnected(s, nil);
}
static char*
@@ 288,7 323,7 @@ tcpannounce(Conv *c, char **argv, int argc)
if(e != nil)
return e;
tcpstart(c, TCP_LISTEN, QMAX);
- Fsconnected(&fs, c, nil);
+ Fsconnected(c, nil);
return nil;
}
@@ 311,7 346,7 @@ tcpclose(Conv *c)
/*
* reset any incoming calls to this listener
*/
- Fsconnected(&fs, c, "Hangup");
+ Fsconnected(c, "Hangup");
qlock(tcb);
localclose(c, nil);
@@ 376,10 411,10 @@ tcpkick(Conv *s, int len)
* get remote sender going if it was flow controlled due to a closed window
*/
static void
-deltimer(Timer *t)
+deltimer(Tcppriv *tpriv, Timer *t)
{
- if(timers == t)
- timers = t->next;
+ if(tpriv->timers == t)
+ tpriv->timers = t->next;
if(t->next)
t->next->prev = t->prev;
if(t->prev)
@@ 423,29 458,33 @@ tcpcreate(Conv *c)
}
void
-tcpackproc(void*)
+tcpackproc(void *a)
{
Timer *t, *tp, *timeo;
- static Rendez tcpr;
+ Proto *tcp;
+ Tcppriv *tpriv;
+
+ tcp = a;
+ tpriv = tcp->priv;
for(;;) {
- tsleep(&tcpr, return0, 0, MSPTICK);
+ tsleep(&tpriv->tcpr, return0, 0, MSPTICK);
- qlock(&tl);
+ qlock(&tpriv->tl);
timeo = nil;
- for(t = timers; t != nil; t = tp) {
+ for(t = tpriv->timers; t != nil; t = tp) {
tp = t->next;
if(t->state == TimerON) {
t->count--;
if(t->count == 0) {
- deltimer(t);
+ deltimer(tpriv, t);
t->state = TimerDONE;
t->next = timeo;
timeo = t;
}
}
}
- qunlock(&tl);
+ qunlock(&tpriv->tl);
for(;;) {
t = timeo;
@@ 460,35 499,35 @@ tcpackproc(void*)
}
void
-tcpgo(Timer *t)
+tcpgo(Tcppriv *tpriv, Timer *t)
{
if(t == nil || t->start == 0)
return;
- qlock(&tl);
+ qlock(&tpriv->tl);
t->count = t->start;
if(t->state != TimerON) {
t->state = TimerON;
t->prev = nil;
- t->next = timers;
+ t->next = tpriv->timers;
if(t->next)
t->next->prev = t;
- timers = t;
+ tpriv->timers = t;
}
- qunlock(&tl);
+ qunlock(&tpriv->tl);
}
void
-tcphalt(Timer *t)
+tcphalt(Tcppriv *tpriv, Timer *t)
{
if(t == nil)
return;
- qlock(&tl);
+ qlock(&tpriv->tl);
if(t->state == TimerON)
- deltimer(t);
+ deltimer(tpriv, t);
t->state = TimerOFF;
- qunlock(&tl);
+ qunlock(&tpriv->tl);
}
int
@@ 505,11 544,13 @@ localclose(Conv *s, char *reason) /* called with tcb locked */
{
Tcpctl *tcb;
Reseq *rp,*rp1;
+ Tcppriv *tpriv;
+ tpriv = s->p->priv;
tcb = (Tcpctl*)s->ptcl;
- tcphalt(&tcb->timer);
- tcphalt(&tcb->rtt_timer);
+ tcphalt(tpriv, &tcb->timer);
+ tcphalt(tpriv, &tcb->rtt_timer);
/* Flush reassembly queue; nothing more can arrive */
for(rp = tcb->reseq; rp != nil; rp = rp1) {
@@ 519,7 560,7 @@ localclose(Conv *s, char *reason) /* called with tcb locked */
}
if(tcb->state == Syn_sent)
- Fsconnected(&fs, s, reason);
+ Fsconnected(s, reason);
qhangup(s->rq, reason);
qhangup(s->wq, reason);
@@ 553,7 594,7 @@ inittcpctl(Conv *s)
/* create a prototype(pseudo) header */
if(ipcmp(s->laddr, IPnoaddr) == 0)
- findlocalip(s->laddr, s->raddr);
+ findlocalip(s->p->f, s->laddr, s->raddr);
h = &tcb->protohdr;
memset(h, 0, sizeof(*h));
h->proto = IP_TCPPROTO;
@@ 571,7 612,7 @@ tcpmtu(Conv *s)
int mtu;
mtu = 0;
- ifc = findipifc(s->raddr, 0);
+ ifc = findipifc(s->p->f, s->raddr, 0);
if(ifc != nil)
mtu = ifc->maxmtu - ifc->m->hsize - (TCP_PKT + TCP_HDRSIZE);
if(mtu < 4)
@@ 583,6 624,9 @@ void
tcpstart(Conv *s, int mode, ushort window)
{
Tcpctl *tcb;
+ Tcppriv *tpriv;
+
+ tpriv = s->p->priv;
tcb = (Tcpctl*)s->ptcl;
@@ 592,11 636,13 @@ tcpstart(Conv *s, int mode, ushort window)
switch(mode) {
case TCP_LISTEN:
+ tpriv->tstats.tcpPassiveOpens++;
tcb->flags |= CLONE;
tcpsetstate(s, Listen);
break;
case TCP_CONNECT:
+ tpriv->tstats.tcpActiveOpens++;
/* Send SYN, go into SYN_SENT state */
qlock(tcb);
tcb->flags |= ACTIVE;
@@ 676,10 722,10 @@ htontcp(Tcp *tcph, Block *data, Tcphdr *ph)
csum = ptclcsum(data, TCP_IPLEN, hdrlen+dlen+TCP_PHDRSIZE);
hnputs(h->tcpcksum, csum);
- DBG(h->tcpdst)(Logtcpmsg, "%d > %d s %l8.8ux a %8.8lux %s w %.4ux l %d\n",
+/* netlog(f, Logtcpmsg, "%d > %d s %l8.8ux a %8.8lux %s w %.4ux l %d\n",
tcph->source, tcph->dest,
tcph->seq, tcph->ack, tcpflag((hdrlen<<10)|tcph->flags),
- tcph->wnd, dlen);
+ tcph->wnd, dlen); */
return data;
}
@@ 717,10 763,10 @@ ntohtcp(Tcp *tcph, Block **bpp)
if(*bpp == nil)
return -1;
- DBG(h->tcpsrc)(Logtcpmsg, "%d > %d s %l8.8ux a %8.8lux %s w %.4ux l %d\n",
+/* netlog(Logtcpmsg, "%d > %d s %l8.8ux a %8.8lux %s w %.4ux l %d\n",
tcph->source, tcph->dest,
tcph->seq, tcph->ack, tcpflag((hdrlen<<10)|tcph->flags),
- tcph->wnd, nhgets(h->length)-hdrlen-TCP_PKT);
+ tcph->wnd, nhgets(h->length)-hdrlen-TCP_PKT); */
optr = h->tcpopt;
for(i = TCP_HDRSIZE; i < hdrlen;) {
@@ 761,11 807,14 @@ tcpsndsyn(Tcpctl *tcb)
* called with v4 (4 byte) addresses
*/
void
-sndrst(uchar *source, uchar *dest, ushort length, Tcp *seg)
+sndrst(Proto *tcp, uchar *source, uchar *dest, ushort length, Tcp *seg)
{
Tcphdr ph;
Block *hbp;
uchar rflags;
+ Tcppriv *tpriv;
+
+ tpriv = tcp->priv;
if(seg->flags & RST)
return;
@@ 779,6 828,7 @@ sndrst(uchar *source, uchar *dest, ushort length, Tcp *seg)
hnputs(ph.tcpsport, seg->dest);
hnputs(ph.tcpdport, seg->source);
+ tpriv->tstats.OutRsts++;
rflags = RST;
/* convince the other end that this reset is in band */
@@ 804,7 854,7 @@ sndrst(uchar *source, uchar *dest, ushort length, Tcp *seg)
if(hbp == nil)
return;
- ipoput(hbp, 0, MAXTTL);
+ ipoput(tcp->f, hbp, 0, MAXTTL);
}
/*
@@ 821,7 871,7 @@ tcphangup(Conv *s)
tcb = (Tcpctl*)s->ptcl;
if(waserror()){
qunlock(tcb);
- return up->error;
+ return commonerror();
}
qlock(tcb);
if(s->raddr != 0) {
@@ 834,7 884,7 @@ tcphangup(Conv *s)
tcb->last_ack = tcb->rcv.nxt;
hnputs(ph.tcplen, TCP_HDRSIZE);
hbp = htontcp(&seg, nil, &tcb->protohdr);
- ipoput(hbp, 0, s->ttl);
+ ipoput(s->p->f, hbp, 0, s->ttl);
}
localclose(s, nil);
poperror();
@@ 849,7 899,7 @@ tcpincoming(Conv *s, Tcp *segp, uchar *src, uchar *dst)
Tcpctl *tcb;
Tcphdr *h;
- new = Fsnewcall(&fs, s, src, segp->source, dst, segp->dest);
+ new = Fsnewcall(s, src, segp->source, dst, segp->dest);
if(new == nil)
return nil;
@@ 919,15 969,17 @@ tcpsynackrtt(Conv *s)
{
Tcpctl *tcb;
int delta;
+ Tcppriv *tpriv;
tcb = (Tcpctl*)s->ptcl;
+ tpriv = s->p->priv;
delta = msec - tcb->sndsyntime;
tcb->srtt = delta<<LOGAGAIN;
tcb->mdev = delta<<LOGDGAIN;
/* halt round trip timer */
- tcphalt(&tcb->rtt_timer);
+ tcphalt(tpriv, &tcb->rtt_timer);
}
void
@@ 936,7 988,9 @@ update(Conv *s, Tcp *seg)
int rtt, delta;
Tcpctl *tcb;
ushort acked, expand;
+ Tcppriv *tpriv;
+ tpriv = s->p->priv;
tcb = (Tcpctl*)s->ptcl;
tcb->kacounter = MAXBACKOFF; /* keep alive count down */
@@ 983,7 1037,7 @@ update(Conv *s, Tcp *seg)
/* Adjust the timers according to the round trip time */
if(tcb->rtt_timer.state == TimerON && seq_ge(seg->ack, tcb->rttseq)) {
- tcphalt(&tcb->rtt_timer);
+ tcphalt(tpriv, &tcb->rtt_timer);
if((tcb->flags&RETRAN) == 0) {
tcb->backoff = 0;
rtt = tcb->rtt_timer.start - tcb->rtt_timer.count;
@@ 1020,9 1074,9 @@ update(Conv *s, Tcp *seg)
if(seq_gt(seg->ack, tcb->snd.urg))
tcb->snd.urg = seg->ack;
- tcphalt(&tcb->timer);
+ tcphalt(tpriv, &tcb->timer);
if(tcb->snd.una != tcb->snd.nxt)
- tcpgo(&tcb->timer);
+ tcpgo(tpriv, &tcb->timer);
if(seq_lt(tcb->snd.ptr, tcb->snd.una))
tcb->snd.ptr = tcb->snd.una;
@@ 1032,7 1086,7 @@ update(Conv *s, Tcp *seg)
}
void
-tcpiput(uchar*, Block *bp)
+tcpiput(Proto *tcp, uchar*, Block *bp)
{
Tcp seg;
Tcphdr *h;
@@ 1041,6 1095,13 @@ tcpiput(uchar*, Block *bp)
ushort length;
uchar source[IPaddrlen], dest[IPaddrlen];
Conv *spec, *gen, *s, **p;
+ Fs *f;
+ Tcppriv *tpriv;
+
+ f = tcp->f;
+ tpriv = tcp->priv;
+
+ tpriv->tstats.tcpInSegs++;
h = (Tcphdr*)(bp->rp);
@@ 1051,16 1112,16 @@ tcpiput(uchar*, Block *bp)
h->Unused = 0;
hnputs(h->tcplen, length-TCP_PKT);
if(ptclcsum(bp, TCP_IPLEN, length-TCP_IPLEN)) {
- tcp.csumerr++;
- netlog(Logtcp, "bad tcp proto cksum\n");
+ tpriv->csumerr++;
+ netlog(f, Logtcp, "bad tcp proto cksum\n");
freeblist(bp);
return;
}
hdrlen = ntohtcp(&seg, &bp);
if(hdrlen < 0){
- tcp.hlenerr++;
- netlog(Logtcp, "bad tcp hdr len\n");
+ tpriv->hlenerr++;
+ netlog(f, Logtcp, "bad tcp hdr len\n");
return;
}
@@ 1068,14 1129,14 @@ tcpiput(uchar*, Block *bp)
length -= hdrlen+TCP_PKT;
bp = trimblock(bp, hdrlen+TCP_PKT, length);
if(bp == nil){
- tcp.lenerr++;
- netlog(Logtcp, "tcp len < 0 after trim\n");
+ tpriv->lenerr++;
+ netlog(f, Logtcp, "tcp len < 0 after trim\n");
return;
}
/* Look for a connection. failing that look for a listener. */
- for(p = tcp.conv; *p; p++) {
+ for(p = tcp->conv; *p; p++) {
s = *p;
if(s->rport == seg.source)
if(s->lport == seg.dest)
@@ 1100,7 1161,7 @@ tcpiput(uchar*, Block *bp)
return;
}
if(seg.flags & ACK) {
- sndrst(source, dest, length, &seg);
+ sndrst(tcp, source, dest, length, &seg);
freeblist(bp);
return;
}
@@ 1111,7 1172,7 @@ tcpiput(uchar*, Block *bp)
*/
gen = nil;
spec = nil;
- for(p = tcp.conv; *p; p++) {
+ for(p = tcp->conv; *p; p++) {
s = *p;
tcb = (Tcpctl*)s->ptcl;
if((tcb->flags & CLONE) == 0)
@@ 1136,7 1197,7 @@ tcpiput(uchar*, Block *bp)
}
if(s == nil) {
freeblist(bp);
- sndrst(source, dest, length, &seg);
+ sndrst(tcp, source, dest, length, &seg);
return;
}
@@ 1149,7 1210,7 @@ tcpiput(uchar*, Block *bp)
switch(tcb->state) {
case Closed:
- sndrst(source, dest, length, &seg);
+ sndrst(tcp, source, dest, length, &seg);
goto raise;
case Listen:
if(seg.flags & SYN) {
@@ 1163,7 1224,7 @@ tcpiput(uchar*, Block *bp)
case Syn_sent:
if(seg.flags & ACK) {
if(!seq_within(seg.ack, tcb->iss+1, tcb->snd.nxt)) {
- sndrst(source, dest, length, &seg);
+ sndrst(tcp, source, dest, length, &seg);
goto raise;
}
}
@@ 1203,12 1264,12 @@ tcpiput(uchar*, Block *bp)
/* Cut the data to fit the receive window */
if(tcptrim(tcb, &seg, &bp, &length) == -1) {
- netlog(Logtcp, "tcp len < 0, %lux\n", seg.seq);
+ netlog(f, Logtcp, "tcp len < 0, %lux\n", seg.seq);
update(s, &seg);
if(tcb->sndcnt == 0 && tcb->state == Closing) {
tcpsetstate(s, Time_wait);
tcb->timer.start = MSL2*(1000 / MSPTICK);
- tcpgo(&tcb->timer);
+ tcpgo(tpriv, &tcb->timer);
}
if(!(seg.flags & RST)) {
tcb->flags |= FORCE;
@@ 1220,7 1281,7 @@ tcpiput(uchar*, Block *bp)
/* Cannot accept so answer with a rst */
if(length && tcb->state == Closed) {
- sndrst(source, dest, length, &seg);
+ sndrst(tcp, source, dest, length, &seg);
goto raise;
}
@@ 1230,7 1291,7 @@ tcpiput(uchar*, Block *bp)
if(seg.seq != tcb->rcv.nxt)
if(length != 0 || (seg.flags & (SYN|FIN))) {
update(s, &seg);
- tcp.order++;
+ tpriv->order++;
addreseq(tcb, &seg, bp, length);
tcb->flags |= FORCE;
goto output;
@@ 1242,6 1303,8 @@ tcpiput(uchar*, Block *bp)
*/
for(;;) {
if(seg.flags & RST) {
+ if(tcb->state == Established)
+ tpriv->tstats.tcpEstabResets++;
localclose(s, Econrefused);
goto raise;
}
@@ 1252,7 1315,7 @@ tcpiput(uchar*, Block *bp)
switch(tcb->state) {
case Syn_received:
if(!seq_within(seg.ack, tcb->snd.una+1, tcb->snd.nxt)){
- sndrst(source, dest, length, &seg);
+ sndrst(tcp, source, dest, length, &seg);
goto raise;
}
update(s, &seg);
@@ 1267,7 1330,7 @@ tcpiput(uchar*, Block *bp)
tcb->f2counter = MAXBACKOFF;
tcpsetstate(s, Finwait2);
tcb->timer.start = MSL2 * (1000 / MSPTICK);
- tcpgo(&tcb->timer);
+ tcpgo(tpriv, &tcb->timer);
}
break;
case Finwait2:
@@ 1278,7 1341,7 @@ tcpiput(uchar*, Block *bp)
if(tcb->sndcnt == 0) {
tcpsetstate(s, Time_wait);
tcb->timer.start = MSL2*(1000 / MSPTICK);
- tcpgo(&tcb->timer);
+ tcpgo(tpriv, &tcb->timer);
}
break;
case Last_ack:
@@ 1290,7 1353,7 @@ tcpiput(uchar*, Block *bp)
case Time_wait:
tcb->flags |= FORCE;
if(tcb->timer.state != TimerON)
- tcpgo(&tcb->timer);
+ tcpgo(tpriv, &tcb->timer);
}
if((seg.flags&URG) && seg.urg) {
@@ 1328,7 1391,7 @@ tcpiput(uchar*, Block *bp)
tcb->rcv.nxt += length;
tcprcvwin(s);
if(tcb->acktimer.state != TimerON)
- tcpgo(&tcb->acktimer);
+ tcpgo(tpriv, &tcb->acktimer);
/* force an ack if there's a lot of unacked data */
if(tcb->rcv.nxt-tcb->last_ack > (QMAX>>4))
@@ 1339,7 1402,7 @@ tcpiput(uchar*, Block *bp)
/* no process to read the data, send a reset */
if(bp != nil)
freeblist(bp);
- sndrst(source, dest, length, &seg);
+ sndrst(tcp, source, dest, length, &seg);
qunlock(tcb);
return;
}
@@ 1359,7 1422,7 @@ tcpiput(uchar*, Block *bp)
if(tcb->sndcnt == 0) {
tcpsetstate(s, Time_wait);
tcb->timer.start = MSL2*(1000/MSPTICK);
- tcpgo(&tcb->timer);
+ tcpgo(tpriv, &tcb->timer);
}
else
tcpsetstate(s, Closing);
@@ 1368,14 1431,14 @@ tcpiput(uchar*, Block *bp)
tcb->rcv.nxt++;
tcpsetstate(s, Time_wait);
tcb->timer.start = MSL2 * (1000/MSPTICK);
- tcpgo(&tcb->timer);
+ tcpgo(tpriv, &tcb->timer);
break;
case Close_wait:
case Closing:
case Last_ack:
break;
case Time_wait:
- tcpgo(&tcb->timer);
+ tcpgo(tpriv, &tcb->timer);
break;
}
}
@@ 1420,6 1483,11 @@ tcpoutput(Conv *s)
Block *hbp, *bp;
int sndcnt, n, first;
ulong ssize, dsize, usable, sent;
+ Fs *f;
+ Tcppriv *tpriv;
+
+ f = s->p->f;
+ tpriv = s->p->priv;
tcb = (Tcpctl*)s->ptcl;
@@ 1489,7 1557,7 @@ tcpoutput(Conv *s)
if((tcb->flags&FORCE) == 0)
break;
- tcphalt(&tcb->acktimer);
+ tcphalt(tpriv, &tcb->acktimer);
tcb->flags &= ~FORCE;
tcprcvwin(s);
@@ 1525,7 1593,7 @@ tcpoutput(Conv *s)
seg.flags |= FIN;
dsize--;
}
- netlog(Logtcp, "qcopy: dlen %d blen %d sndcnt %d qlen %d sent %d rp[0] %d\n",
+ netlog(f, Logtcp, "qcopy: dlen %d blen %d sndcnt %d qlen %d sent %d rp[0] %d\n",
dsize, BLEN(bp), sndcnt, qlen(s->wq), sent, bp->rp[0]);
}
@@ 1566,16 1634,17 @@ tcpoutput(Conv *s)
tcb->timer.start = x;
if(tcb->timer.state != TimerON)
- tcpgo(&tcb->timer);
+ tcpgo(tpriv, &tcb->timer);
/* If round trip timer isn't running, start it */
if(tcb->rtt_timer.state != TimerON) {
- tcpgo(&tcb->rtt_timer);
+ tcpgo(tpriv, &tcb->rtt_timer);
tcb->rttseq = tcb->snd.ptr;
}
}
- ipoput(hbp, 0, s->ttl);
+ tpriv->tstats.tcpOutSegs++;
+ ipoput(f, hbp, 0, s->ttl);
}
}
@@ 1616,17 1685,18 @@ tcpkeepalive(Conv *s)
return;
}
- ipoput(hbp, 0, s->ttl);
+ ipoput(s->p->f, hbp, 0, s->ttl);
}
void
tcprxmit(Conv *s)
{
Tcpctl *tcb;
+ Tcppriv *tpriv;
+ tpriv = s->p->priv;
tcb = (Tcpctl*)s->ptcl;
-
qlock(tcb);
tcb->flags |= RETRAN|FORCE;
tcb->snd.ptr = tcb->snd.una;
@@ 1642,8 1712,7 @@ tcprxmit(Conv *s)
tcb->cwind = tcb->mss;
tcpoutput(s);
- tcp.rexmit++;
-
+ tpriv->tstats.tcpRetransSegs++;
qunlock(tcb);
}
@@ 1678,7 1747,7 @@ tcptimeout(void *arg)
qlock(tcb);
tcpkeepalive(s);
qunlock(tcb);
- tcpgo(&tcb->timer);
+ tcpgo(s->p->priv, &tcb->timer);
}
break;
case Time_wait:
@@ 1807,8 1876,6 @@ tcptrim(Tcpctl *tcb, Tcp *seg, Block **bp, ushort *length)
dupcnt = tcb->rcv.nxt - seg->seq;
if(dupcnt > 0){
tcb->rerecv += dupcnt;
- tstats.dup++;
- tstats.dupb += dupcnt;
if(seg->flags & SYN){
seg->flags &= ~SYN;
seg->seq++;
@@ 1845,7 1912,7 @@ tcptrim(Tcpctl *tcb, Tcp *seg, Block **bp, ushort *length)
}
void
-tcpadvise(Block *bp, char *msg)
+tcpadvise(Proto *tcp, Block *bp, char *msg)
{
Tcphdr *h;
Tcpctl *tcb;
@@ 1862,7 1929,7 @@ tcpadvise(Block *bp, char *msg)
pdest = nhgets(h->tcpdport);
/* Look for a connection */
- for(p = tcp.conv; *p; p++) {
+ for(p = tcp->conv; *p; p++) {
s = *p;
if(s->rport == pdest)
if(s->lport == psource)
@@ 1892,39 1959,54 @@ tcpctl(Conv* c, char** f, int n)
}
int
-tcpstats(char *buf, int len)
+tcpstats(Proto *tcp, char *buf, int len)
{
- int n;
-
- n = snprint(buf, len,
- "tcp: csum %d hlen %d len %d order %d rexmit %d",
- tcp.csumerr, tcp.hlenerr, tcp.lenerr, tcp.order, tcp.rexmit);
- n += snprint(buf+n, len-n, " dupp %d dupb %d\n",
- tstats.dup, tstats.dupb);
- return n;
+ Tcpstats *tstats;
+
+ tstats = tcp->priv;
+ return snprint(buf, len, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d",
+ tstats->tcpRtoAlgorithm,
+ tstats->tcpRtoMin,
+ tstats->tcpRtoMax,
+ tstats->tcpMaxConn,
+ tstats->tcpActiveOpens,
+ tstats->tcpPassiveOpens,
+ tstats->tcpAttemptFails,
+ tstats->tcpEstabResets,
+ tstats->tcpCurrEstab,
+ tstats->tcpInSegs,
+ tstats->tcpOutSegs,
+ tstats->tcpRetransSegs,
+ tstats->InErrs,
+ tstats->OutRsts);
}
void
tcpinit(Fs *fs)
{
- tcp.name = "tcp";
- tcp.kick = tcpkick;
- tcp.connect = tcpconnect;
- tcp.announce = tcpannounce;
- tcp.ctl = tcpctl;
- tcp.state = tcpstate;
- tcp.create = tcpcreate;
- tcp.close = tcpclose;
- tcp.rcv = tcpiput;
- tcp.advise = tcpadvise;
- tcp.stats = tcpstats;
- tcp.inuse = tcpinuse;
- tcp.ipproto = IP_TCPPROTO;
- tcp.nc = Nchans;
- tcp.ptclsize = sizeof(Tcpctl);
-
- kproc("tcpack", tcpackproc, 0);
-
- Fsproto(fs, &tcp);
+ Proto *tcp;
+ Tcppriv *tpriv;
+
+ tcp = smalloc(sizeof(Proto));
+ tpriv = tcp->priv = smalloc(sizeof(Tcppriv));
+ tcp->name = "tcp";
+ tcp->kick = tcpkick;
+ tcp->connect = tcpconnect;
+ tcp->announce = tcpannounce;
+ tcp->ctl = tcpctl;
+ tcp->state = tcpstate;
+ tcp->create = tcpcreate;
+ tcp->close = tcpclose;
+ tcp->rcv = tcpiput;
+ tcp->advise = tcpadvise;
+ tcp->stats = tcpstats;
+ tcp->inuse = tcpinuse;
+ tcp->ipproto = IP_TCPPROTO;
+ tcp->nc = Nchans;
+ tcp->ptclsize = sizeof(Tcpctl);
+ tpriv->tstats.tcpMaxConn = Nchans;
+
+ Fsproto(fs, tcp);
+
+ kproc("tcpack", tcpackproc, tcp);
}
-
M ip/udp.c => ip/udp.c +148 -66
@@ 15,7 15,8 @@ enum
UDP_HDRSIZE = 20,
UDP_IPHDR = 8,
IP_UDPPROTO = 17,
- UDP_USEAD = 12,
+ UDP_USEAD6 = 36,
+ UDP_USEAD4 = 12,
Udprxms = 200,
Udptickms = 100,
@@ 44,6 45,27 @@ struct Udphdr
uchar udpcksum[2]; /* Checksum */
};
+/* MIB II counters */
+typedef struct Udpstats Udpstats;
+struct Udpstats
+{
+ ulong udpInDatagrams;
+ ulong udpNoPorts;
+ ulong udpInErrors;
+ ulong udpOutDatagrams;
+};
+
+typedef struct Udppriv Udppriv;
+struct Udppriv
+{
+ /* MIB counters */
+ Udpstats ustats;
+
+ /* non-MIB stats */
+ ulong csumerr; /* checksum errors */
+ ulong lenerr; /* short packet */
+};
+
/*
* protocol specific part of Conv
*/
@@ 54,23 76,18 @@ struct Udpcb
uchar headers;
};
- Proto udp;
- int udpsum;
- uint generation;
-extern Fs fs;
- int udpdebug;
-
static char*
udpconnect(Conv *c, char **argv, int argc)
{
char *e;
e = Fsstdconnect(c, argv, argc);
- Fsconnected(&fs, c, e);
+ Fsconnected(c, e);
return e;
}
+
static int
udpstate(Conv *c, char *state, int n)
{
@@ 86,7 103,7 @@ udpannounce(Conv *c, char** argv, int argc)
e = Fsstdannounce(c, argv, argc);
if(e != nil)
return e;
- Fsconnected(&fs, c, nil);
+ Fsconnected(c, nil);
return nil;
}
@@ 126,30 143,54 @@ udpkick(Conv *c, int)
Block *bp;
Udpcb *ucb;
int dlen, ptcllen;
+ Udppriv *upriv;
+ Fs *f;
- netlog(Logudp, "udp: kick\n");
+ upriv = c->p->priv;
+ f = c->p->f;
+
+ netlog(c->p->f, Logudp, "udp: kick\n");
bp = qget(c->wq);
if(bp == nil)
return;
ucb = (Udpcb*)c->ptcl;
- if(ucb->headers) {
+ switch(ucb->headers) {
+ case 6:
/* get user specified addresses */
- bp = pullupblock(bp, UDP_USEAD);
+ bp = pullupblock(bp, UDP_USEAD6);
if(bp == nil)
return;
ipmove(raddr, bp->rp);
bp->rp += IPaddrlen;
ipmove(laddr, bp->rp);
bp->rp += IPaddrlen;
- if(ipforme(laddr) != Runi)
- findlocalip(laddr, raddr); /* pick interface closest to dest */
+ if(ipforme(f, laddr) != Runi)
+ findlocalip(f, laddr, raddr); /* pick interface closest to dest */
+ rport = nhgets(bp->rp);
+ bp->rp += 2;
+ /* ignore local port number */
+ bp->rp += 2;
+ break;
+ case 4:
+ /* get user specified addresses */
+ bp = pullupblock(bp, UDP_USEAD4);
+ if(bp == nil)
+ return;
+ v4tov6(raddr, bp->rp);
+ bp->rp += IPv4addrlen;
+ v4tov6(laddr, bp->rp);
+ bp->rp += IPv4addrlen;
+ if(ipforme(f, laddr) != Runi)
+ findlocalip(f, laddr, raddr); /* pick interface closest to dest */
rport = nhgets(bp->rp);
bp->rp += 2;
/* ignore local port number */
bp->rp += 2;
- } else {
+ break;
+ default:
rport = 0;
+ break;
}
dlen = blocklen(bp);
@@ 167,16 208,24 @@ udpkick(Conv *c, int)
uh->frag[0] = 0;
uh->frag[1] = 0;
hnputs(uh->udpplen, ptcllen);
- if(ucb->headers) {
+ switch(ucb->headers){
+ case 6:
v6tov4(uh->udpdst, raddr);
hnputs(uh->udpdport, rport);
v6tov4(uh->udpsrc, laddr);
- } else {
+ break;
+ case 4:
+ memmove(uh->udpdst, raddr, IPv4addrlen);
+ hnputs(uh->udpdport, rport);
+ memmove(uh->udpsrc, laddr, IPv4addrlen);
+ break;
+ default:
v6tov4(uh->udpdst, c->raddr);
hnputs(uh->udpdport, c->rport);
if(ipcmp(c->laddr, IPnoaddr) == 0)
- findlocalip(c->laddr, c->raddr); /* pick interface closest to dest */
+ findlocalip(f, c->laddr, c->raddr); /* pick interface closest to dest */
v6tov4(uh->udpsrc, c->laddr);
+ break;
}
hnputs(uh->udpsport, c->lport);
hnputs(uh->udplen, ptcllen);
@@ 185,11 234,12 @@ udpkick(Conv *c, int)
hnputs(uh->udpcksum, ptclcsum(bp, UDP_IPHDR, dlen+UDP_HDRSIZE));
- ipoput(bp, 0, c->ttl);
+ upriv->ustats.udpOutDatagrams++;
+ ipoput(f, bp, 0, c->ttl);
}
void
-udpiput(uchar *ia, Block *bp)
+udpiput(Proto *udp, uchar *ia, Block *bp)
{
int len, olen, ottl;
Udphdr *uh;
@@ 197,6 247,13 @@ udpiput(uchar *ia, Block *bp)
Udpcb *ucb;
uchar raddr[IPaddrlen], laddr[IPaddrlen];
ushort rport, lport;
+ Udppriv *upriv;
+ Fs *f;
+
+ upriv = udp->priv;
+ f = udp->f;
+
+ upriv->ustats.udpInDatagrams++;
uh = (Udphdr*)(bp->rp);
@@ 212,10 269,10 @@ udpiput(uchar *ia, Block *bp)
lport = nhgets(uh->udpdport);
rport = nhgets(uh->udpsport);
- if(udpsum && nhgets(uh->udpcksum)) {
+ if(nhgets(uh->udpcksum)) {
if(ptclcsum(bp, UDP_IPHDR, len+UDP_PHDRSIZE)) {
- udp.csumerr++;
- netlog(Logudp, "udp: checksum error %I\n", raddr);
+ upriv->ustats.udpInErrors++;
+ netlog(f, Logudp, "udp: checksum error %I\n", raddr);
freeblist(bp);
return;
}
@@ 223,7 280,7 @@ udpiput(uchar *ia, Block *bp)
/* Look for a conversation structure for this port */
c = nil;
- for(p = udp.conv; *p; p++) {
+ for(p = udp->conv; *p; p++) {
c = *p;
if(c->inuse == 0)
continue;
@@ 232,13 289,14 @@ udpiput(uchar *ia, Block *bp)
}
if(*p == nil) {
- netlog(Logudp, "udp: no conv %I.%d -> %I.%d\n", raddr, rport,
+ upriv->ustats.udpNoPorts++;
+ netlog(f, Logudp, "udp: no conv %I.%d -> %I.%d\n", raddr, rport,
laddr, lport);
/* don't complain about broadcasts... */
- if(ipforme(raddr) == 0){
+ if(ipforme(f, raddr) == 0){
uh->Unused = ottl;
hnputs(uh->udpplen, olen);
- icmpnoconv(bp);
+ icmpnoconv(f, bp);
}
freeblist(bp);
return;
@@ 250,28 308,41 @@ udpiput(uchar *ia, Block *bp)
len -= (UDP_HDRSIZE-UDP_PHDRSIZE);
bp = trimblock(bp, UDP_IPHDR+UDP_HDRSIZE, len);
if(bp == nil){
- netlog(Logudp, "udp: len err %I.%d -> %I.%d\n", raddr, rport,
+ netlog(f, Logudp, "udp: len err %I.%d -> %I.%d\n", raddr, rport,
laddr, lport);
- udp.lenerr++;
+ upriv->lenerr++;
return;
}
- netlog(Logudpmsg, "udp: %I.%d -> %I.%d l %d\n", raddr, rport,
+ netlog(f, Logudpmsg, "udp: %I.%d -> %I.%d l %d\n", raddr, rport,
laddr, lport, len);
ucb = (Udpcb*)c->ptcl;
- if(ucb->headers) {
+ switch(ucb->headers){
+ case 6:
/* pass the src address */
- bp = padblock(bp, UDP_USEAD);
+ bp = padblock(bp, UDP_USEAD6);
ipmove(bp->rp, raddr);
- if(ipforme(laddr) == Runi)
+ if(ipforme(f, laddr) == Runi)
ipmove(bp->rp+IPaddrlen, laddr);
else
ipmove(bp->rp+IPaddrlen, ia);
hnputs(bp->rp+2*IPaddrlen, rport);
hnputs(bp->rp+2*IPaddrlen+2, lport);
- } else {
+ break;
+ case 4:
+ /* pass the src address */
+ bp = padblock(bp, UDP_USEAD4);
+ memmove(bp->rp, raddr, IPv4addrlen);
+ if(ipforme(f, laddr) == Runi)
+ memmove(bp->rp+IPv4addrlen, laddr, IPv4addrlen);
+ else
+ memmove(bp->rp+IPv4addrlen, ia, IPv4addrlen);
+ hnputs(bp->rp + 2*IPv4addrlen, rport);
+ hnputs(bp->rp + 2*IPv4addrlen + 2, lport);
+ break;
+ default:
/* connection oriented udp */
if(c->raddr == 0){
/* save the src address in the conversation */
@@ 279,17 350,18 @@ udpiput(uchar *ia, Block *bp)
c->rport = rport;
/* reply with the same ip address (if not broadcast) */
- if(ipforme(laddr) == Runi)
+ if(ipforme(f, laddr) == Runi)
ipmove(c->laddr, laddr);
else
- ipmove(c->laddr, ia);
+ v4tov6(c->laddr, ia);
}
+ break;
}
if(bp->next)
bp = concatblock(bp);
if(qfull(c->rq)){
- netlog(Logudp, "udp: qfull %I.%d -> %I.%d\n", raddr, rport,
+ netlog(f, Logudp, "udp: qfull %I.%d -> %I.%d\n", raddr, rport,
laddr, lport);
freeblist(bp);
}else
@@ 302,19 374,20 @@ udpctl(Conv *c, char **f, int n)
Udpcb *ucb;
ucb = (Udpcb*)c->ptcl;
- if(n == 1 && strcmp(f[0], "headers") == 0){
- ucb->headers = 1;
- return nil;
- }
- if(n == 1 && strcmp(f[0], "debug") == 0){
- udpdebug = 1;
- return nil;
+ if(n == 1){
+ if(strcmp(f[0], "headers4") == 0){
+ ucb->headers = 4;
+ return nil;
+ } else if(strcmp(f[0], "headers") == 0){
+ ucb->headers = 6;
+ return nil;
+ }
}
return "unknown control request";
}
void
-udpadvise(Block *bp, char *msg)
+udpadvise(Proto *udp, Block *bp, char *msg)
{
Udphdr *h;
uchar source[IPaddrlen], dest[IPaddrlen];
@@ 329,7 402,7 @@ udpadvise(Block *bp, char *msg)
pdest = nhgets(h->udpdport);
/* Look for a connection */
- for(p = udp.conv; *p; p++) {
+ for(p = udp->conv; *p; p++) {
s = *p;
if(s->rport == pdest)
if(s->lport == psource)
@@ 344,30 417,39 @@ udpadvise(Block *bp, char *msg)
}
int
-udpstats(char *buf, int len)
+udpstats(Proto *udp, char *buf, int len)
{
- return snprint(buf, len,
- "udp: csum %d hlen %d len %d order %d rexmit %d\n",
- udp.csumerr, udp.hlenerr, udp.lenerr, udp.order, udp.rexmit);
+ Udppriv *upriv;
+
+ upriv = udp->priv;
+ return snprint(buf, len, "%d %d %d %d",
+ upriv->ustats.udpInDatagrams,
+ upriv->ustats.udpNoPorts,
+ upriv->ustats.udpInErrors,
+ upriv->ustats.udpOutDatagrams);
}
void
udpinit(Fs *fs)
{
- udp.name = "udp";
- udp.kick = udpkick;
- udp.connect = udpconnect;
- udp.announce = udpannounce;
- udp.ctl = udpctl;
- udp.state = udpstate;
- udp.create = udpcreate;
- udp.close = udpclose;
- udp.rcv = udpiput;
- udp.advise = udpadvise;
- udp.stats = udpstats;
- udp.ipproto = IP_UDPPROTO;
- udp.nc = 16;
- udp.ptclsize = sizeof(Udpcb);
-
- Fsproto(fs, &udp);
+ Proto *udp;
+
+ udp = smalloc(sizeof(Proto));
+ udp->priv = smalloc(sizeof(Udppriv));
+ udp->name = "udp";
+ udp->kick = udpkick;
+ udp->connect = udpconnect;
+ udp->announce = udpannounce;
+ udp->ctl = udpctl;
+ udp->state = udpstate;
+ udp->create = udpcreate;
+ udp->close = udpclose;
+ udp->rcv = udpiput;
+ udp->advise = udpadvise;
+ udp->stats = udpstats;
+ udp->ipproto = IP_UDPPROTO;
+ udp->nc = 16;
+ udp->ptclsize = sizeof(Udpcb);
+
+ Fsproto(fs, udp);
}