## diffname ip/devip.c 1997/0327 ## diff -e /dev/null /n/emeliedump/1997/0327/sys/src/brazil/ip/devip.c 0a #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" #include "../ip/ip.h" Fs fs; Queue* qlog; enum { Qtopdir= 1, /* top level directory */ Qtopbase, Qarp= Qtopbase, Qipifc, Qiproute, Qlog, Qprotodir, /* directory for a protocol */ Qprotobase, Qclone= Qprotobase, Qconvdir, /* directory for a conversation */ Qconvbase, Qctl= Qconvbase, Qdata, Qerr, Qlisten, Qlocal, Qremote, Qstatus, }; #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)) static char network[] = "network"; static int ip3gen(Chan *c, int i, Dir *dp) { Qid q; Conv *cv; char *p; cv = fs.p[PROTO(c->qid)]->conv[CONV(c->qid)]; switch(i) { default: return -1; case Qctl: q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qctl), 0}; devdir(c, q, "ctl", 0, cv->owner, cv->perm, dp); return 1; case Qdata: q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qdata), 0}; devdir(c, q, "data", qlen(cv->rq), cv->owner, cv->perm, dp); return 1; case Qerr: q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qerr), 0}; devdir(c, q, "err", qlen(cv->eq), cv->owner, cv->perm, dp); return 1; case Qlisten: p = "listen"; q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qlisten), 0}; break; case Qlocal: p = "local"; q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qlocal), 0}; break; case Qremote: p = "remote"; q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qremote), 0}; break; case Qstatus: p = "status"; q = (Qid){QID(PROTO(c->qid), CONV(c->qid), Qstatus), 0}; break; } devdir(c, q, p, 0, cv->owner, 0444, dp); return 1; } static int ip2gen(Chan *c, int i, Dir *dp) { Qid q; switch(i) { case Qclone: q = (Qid){QID(PROTO(c->qid), 0, Qclone), 0}; devdir(c, q, "clone", 0, network, 0444, dp); return 1; } return -1; } static int ip1gen(Chan *c, int i, Dir *dp) { Qid q; char *p; switch(i) { default: return -1; case Qarp: p = "arp"; q = (Qid){QID(0, 0, Qarp), 0}; break; case Qipifc: p = "ipifc"; q = (Qid){QID(0, 0, Qipifc), 0}; break; case Qiproute: p = "iproute"; q = (Qid){QID(0, 0, Qiproute), 0}; break; case Qlog: p = "log"; q = (Qid){QID(0, 0, Qlog), 0}; break; } devdir(c, q, p, 0, network, 0444, dp); return 1; } static int ipgen(Chan *c, Dirtab*, int, int s, Dir *dp) { Qid q; Conv *cv; char name[16]; switch(TYPE(c->qid)) { case Qtopdir: if(s < fs.np) { q = (Qid){QID(s, 0, Qprotodir)|CHDIR, 0}; devdir(c, q, fs.p[s]->name, 0, network, CHDIR|0555, dp); return 1; } s -= fs.np; return ip1gen(c, s+Qtopbase, dp); case Qarp: case Qipifc: case Qlog: case Qiproute: 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]; 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; return ip2gen(c, s+Qprotobase, dp); case Qclone: return ip2gen(c, TYPE(c->qid), dp); case Qconvdir: return ip3gen(c, s+Qconvbase, dp); case Qctl: case Qdata: case Qerr: case Qlisten: case Qlocal: case Qremote: case Qstatus: return ip3gen(c, TYPE(c->qid), dp); } return -1; } static void 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); } static Chan* ipattach(char* spec) { Chan *c; c = devattach('I', spec); c->qid = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; return c; } static Chan* ipclone(Chan* c, Chan* nc) { return devclone(c, nc); } static int ipwalk(Chan* c, char* name) { Path *op; if(strcmp(name, "..") == 0){ switch(TYPE(c->qid)){ case Qtopdir: case Qprotodir: c->qid = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; break; case Qconvdir: c->qid = (Qid){QID(0, 0, Qprotodir)|CHDIR, 0}; break; default: panic("ipwalk %lux", c->qid.path); } op = c->path; c->path = ptenter(&syspt, op, name); decref(op); return 1; } return devwalk(c, name, nil, 0, ipgen); } static void ipstat(Chan* c, char* db) { devstat(c, db, nil, 0, ipgen); } static int incoming(void* arg) { Conv *conv; conv = arg; return conv->incall != nil; } static int m2p[] = { [OREAD] 4, [OWRITE] 2, [ORDWR] 6 }; static Chan* ipopen(Chan* c, int omode) { Conv *cv, *nc; Proto *p; int perm; omode &= 3; perm = m2p[omode]; switch(TYPE(c->qid)) { default: break; case Qlog: netlogopen(); break; case Qtopdir: case Qprotodir: case Qconvdir: case Qstatus: case Qremote: case Qlocal: if(omode != OREAD) error(Eperm); break; case Qclone: p = fs.p[PROTO(c->qid)]; cv = Fsprotoclone(p, up->user); if(cv == nil) { error(Enodev); break; } c->qid = (Qid){QID(p->x, cv->x, Qctl), 0}; break; case Qdata: case Qctl: case Qerr: p = fs.p[PROTO(c->qid)]; lock(p); cv = p->conv[CONV(c->qid)]; lock(cv); if(waserror()) { unlock(cv); unlock(p); nexterror(); } if((perm & (cv->perm>>6)) != perm) { if(strcmp(up->user, cv->owner) != 0) error(Eperm); if((perm & cv->perm) != perm) error(Eperm); } cv->inuse++; if(cv->inuse == 1){ memmove(cv->owner, up->user, NAMELEN); cv->perm = 0660; } unlock(cv); unlock(p); poperror(); break; case Qlisten: cv = fs.p[PROTO(c->qid)]->conv[CONV(c->qid)]; if(cv->state != Announced) error("not announced"); nc = nil; while(nc == nil) { qlock(&cv->listenq); if(waserror()) { qunlock(&cv->listenq); nexterror(); } sleep(&cv->listenr, incoming, cv); lock(cv); nc = cv->incall; if(nc != nil){ cv->incall = nc->next; c->qid = (Qid){QID(PROTO(c->qid), nc->x, Qctl), 0}; memmove(cv->owner, up->user, NAMELEN); } unlock(cv); qunlock(&cv->listenq); poperror(); } break; } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; } static void ipcreate(Chan*, char*, int, ulong) { error(Eperm); } static void ipremove(Chan*) { error(Eperm); } static void ipwstat(Chan*, char*) { error(Eperm); } static void closeconv(Conv *cv) { Conv *nc; lock(cv); if(--cv->inuse > 0) { unlock(cv); return; } /* close all incoming calls since no listen will ever happen */ for(nc = cv->incall; nc; nc = cv->incall){ cv->incall = nc->next; closeconv(nc); } strcpy(cv->owner, network); cv->perm = 0660; /* The close routine will unlock the conv */ cv->p->close(cv); } static void ipclose(Chan* c) { switch(TYPE(c->qid)) { default: break; case Qlog: netlogclose(); break; case Qdata: case Qctl: case Qerr: if(c->flag & COPEN) closeconv(fs.p[PROTO(c->qid)]->conv[CONV(c->qid)]); } } static long ipread(Chan *ch, void *a, long n, ulong offset) { Conv *c; Proto *x; byte ip[4]; char buf[256], *p, *statename; p = a; switch(TYPE(ch->qid)) { default: error(Eperm); case Qtopdir: case Qprotodir: case Qconvdir: return devdirread(ch, a, n, 0, 0, ipgen); case Qarp: return arpread(a, offset, n); case Qipifc: return Mediaifcread(a, offset, n); case Qiproute: return routeread(a, offset, n); case Qlog: return netlogread(a, offset, n); case Qctl: sprint(buf, "%d", CONV(ch->qid)); return readstr(offset, p, n, buf); case Qremote: c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; hnputl(ip, c->raddr); sprint(buf, "%I!%d\n", ip, c->rport); return readstr(offset, p, n, buf); case Qlocal: c = fs.p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; if(media != nil && c->laddr == 0) hnputl(ip, Mediagetaddr(media)); else hnputl(ip, c->laddr); sprint(buf, "%I!%d\n", ip, c->lport); return readstr(offset, p, n, buf); case Qstatus: x = fs.p[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; x->state(&statename, c); sprint(buf, "%s/%d %d %s \n", c->p->name, c->x, c->inuse, statename); return readstr(offset, p, n, buf); case Qdata: c = fs.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)]; return qread(c->eq, a, n); } } static Block* ipbread(Chan* c, long n, ulong offset) { return devbread(c, n, offset); } static void setladdr(Conv* c) { byte rem[4]; hnputl(rem, c->raddr); c->laddr = Mediagetsrc(rem); } static void setlport(Conv* c) { Proto *p; ushort *pp; int x, found; p = c->p; /* * For compatibility with old Plan9/Brazil systems restrict * the port number for now such that it can't sign-extend on * the other end. */ while(p->nextport < 5000 || p->nextport >= (1<<15)) p->nextport = nrand(1<<16); if(c->restricted) pp = &p->nextrport; else pp = &p->nextport; lock(p); for(;;(*pp)++){ if(*pp == 0 || *pp >= (1<<15)) { /* BSD hack */ if(c->restricted) *pp = 600; else *pp = 5000; } found = 0; for(x = 0; x < p->nc; x++){ if(p->conv[x] == nil) break; if(p->conv[x]->lport == *pp){ found = 1; break; } } if(!found) break; } c->lport = (*pp)++; unlock(p); } static void setladdrport(Conv* c, char* str) { char *p, addr[4]; p = strchr(str, '!'); if(p == nil) { p = str; c->laddr = 0; } else { *p++ = 0; parseip(addr, str); c->laddr = nhgetl((byte*)addr); } if(*p == '*') c->lport = 0; else { c->lport = atoi(p); if(c->lport == 0) setlport(c); } } static char* setraddrport(Conv* c, char* str) { char *p, addr[4]; p = strchr(str, '!'); if(p == nil) return "malformed address"; *p++ = 0; parseip(addr, str); c->raddr = nhgetl((byte*)addr); c->rport = atoi(p); p = strchr(p, '!'); if(p){ if(strcmp(p, "!r") == 0) c->restricted = 1; } return nil; } static int connected(void* a) { return ((Conv*)a)->state == Connected; } static int announced(void* a) { return ((Conv*)a)->state == Announced; } static long ipwrite(Chan* ch, char* a, long n, ulong) { Conv *c; Proto *x; int nfield; char *p, *fields[10], buf[128]; switch(TYPE(ch->qid)){ default: error(Eperm); case Qarp: p = arpwrite(a, n); if(p != nil) error(p); return n; case Qipifc: p = Mediaifcwrite(a, n); if(p != nil) error(p); return n; case Qiproute: p = routewrite(a, n); if(p != nil) error(p); return n; case Qlog: p = netlogctl(a, n); if(p != nil) error(p); return n; case Qctl: x = fs.p[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; if(n > sizeof(buf)-1) n = sizeof(buf)-1; memmove(buf, a, n); buf[n] = '\0'; nfield = parsefields(buf, fields, 10, " "); if(strcmp(fields[0], "connect") == 0){ if(canqlock(&c->car) == 0) error("connect/announce in progress"); if(waserror()) { qunlock(&c->car); nexterror(); } c->state = Connecting; c->cerr[0] = '\0'; p = x->connect(c, fields, nfield); if(p != nil) error(p); sleep(&c->cr, connected, c); if(c->cerr[0] != '\0') error(c->cerr); qunlock(&c->car); poperror(); return n; } if(strcmp(fields[0], "announce") == 0){ if(canqlock(&c->car) == 0) error("connect/announce in progress"); if(waserror()) { qunlock(&c->car); nexterror(); } switch(nfield){ default: error("bad args to announce"); case 2: setladdrport(c, fields[1]); break; } c->state = Announcing; c->cerr[0] = '\0'; x->announce(c); sleep(&c->cr, announced, c); if(c->cerr[0] != '\0') error(c->cerr); qunlock(&c->car); poperror(); return n; } if(strcmp(fields[0], "bind") == 0){ if(canqlock(&c->car) == 0) error("connect/announce in progress"); if(waserror()) { qunlock(&c->car); nexterror(); } switch(nfield){ default: error("bad args to bind"); case 2: setladdr(c); c->lport = atoi(fields[1]); if(c->lport == 0) setlport(c); break; } qunlock(&c->car); poperror(); return n; } if(strcmp(fields[0], "ttl") == 0){ if(nfield < 2) c->ttl = MAXTTL; else c->ttl = atoi(fields[1]); return n; } if(x->ctl != nil) { p = x->ctl(c, fields, nfield); if(p != nil) error(p); return n; } error("unknown control request"); case Qdata: x = fs.p[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; qwrite(c->wq, a, n); x->kick(c, n); } return n; } static long ipbwrite(Chan* c, Block* bp, ulong offset) { return devbwrite(c, bp, offset); } Dev ipdevtab = { ipreset, ipinit, ipattach, ipclone, ipwalk, ipstat, ipopen, ipcreate, ipclose, ipread, ipbread, ipwrite, ipbwrite, ipremove, ipwstat, }; int Fsproto(Fs *fs, Proto *p) { if(fs->np >= Maxproto) return -1; if(p->ipproto > 0){ if(fs->t2p[p->ipproto] != nil) return -1; fs->t2p[p->ipproto] = p; } p->qid.path = CHDIR|QID(fs->np, 0, Qprotodir); p->conv = malloc(sizeof(Conv*)*(p->nc+1)); if(p->conv == nil) panic("Fsproto"); p->x = fs->np; p->nextport = 0; p->nextrport = 600; fs->p[fs->np++] = p; return 0; } /* * return true if this protocol is * built in */ int Fsbuiltinproto(Fs* fs, byte proto) { return fs->t2p[proto] != nil; } Conv* Fsprotoclone(Proto *p, char *user) { char *junk; int unused; Conv *c, **pp, **ep; c = nil; lock(p); if(waserror()) { unlock(p); nexterror(); } ep = &p->conv[p->nc]; for(pp = p->conv; pp < ep; pp++) { c = *pp; if(c == nil){ c = malloc(sizeof(Conv)); if(c == nil) error(Enomem); lock(c); c->p = p; c->x = pp - p->conv; c->ptcl = malloc(p->ptclsize); if(c->ptcl == nil) { free(c); error(Enomem); } *pp = c; p->ac++; c->eq = qopen(1024, 1, 0, 0); (*p->create)(c); break; } if(canlock(c)){ unused = p->state(&junk, c); if(c->inuse == 0 && unused) break; unlock(c); } } if(pp >= ep) { unlock(p); poperror(); return nil; } c->inuse = 1; strcpy(c->owner, user); c->perm = 0660; c->state = 0; c->laddr = 0; c->raddr = 0; c->lport = 0; c->rport = 0; c->restricted = 0; c->ttl = MAXTTL; qreopen(c->rq); qreopen(c->wq); qreopen(c->eq); unlock(c); unlock(p); poperror(); return c; } int Fsconnected(Fs*, Conv* c, char* msg) { if(msg != nil && *msg != '\0') strncpy(c->cerr, msg, ERRLEN-1); switch(c->state){ case Announcing: c->state = Announced; break; case Connecting: c->state = Connected; break; } wakeup(&c->cr); return 0; } Proto* Fsrcvpcol(Fs* fs, byte proto) { return fs->t2p[proto]; } Conv* Fsnewcall(Fs*, Conv *c, Ipaddr raddr, ushort rport, Ipaddr laddr, ushort lport) { Conv *nc; Conv **l; int i; lock(c); i = 0; for(l = &c->incall; *l; l = &(*l)->next) i++; if(i >= Maxincall) { unlock(c); return nil; } /* find a free conversation */ nc = Fsprotoclone(c->p, network); if(nc == nil) { unlock(c); return nil; } nc->raddr = raddr; nc->rport = rport; nc->laddr = laddr; nc->lport = lport; nc->next = nil; *l = nc; unlock(c); wakeup(&c->listenr); return nc; } int Fspcolstats(char *buf, int len) { Proto **p; int n; n = 0; for(p = fs.p; *p; p++) n += snprint(buf + n, len - n, "%s: csum %d hlen %d len %d order %d rexmit %d\n", (*p)->name, (*p)->csumerr, (*p)->hlenerr, (*p)->lenerr, (*p)->order, (*p)->rexmit); return n; } char* Fsstdconnect(Conv *c, char *argv[], int argc) { char *p; switch(argc) { default: return "bad args to connect"; case 2: p = setraddrport(c, argv[1]); if(p != nil) return p; setladdr(c); setlport(c); break; case 3: p = setraddrport(c, argv[1]); if(p != nil) return p; setladdr(c); c->lport = atoi(argv[2]); break; } return nil; } . ## diffname ip/devip.c 1997/0403 ## diff -e /n/emeliedump/1997/0327/sys/src/brazil/ip/devip.c /n/emeliedump/1997/0403/sys/src/brazil/ip/devip.c 936a break; } return nil; } char* Fsstdannounce(Conv* c, char* argv[], int argc) { switch(argc){ default: return "bad args to announce"; case 2: setladdrport(c, argv[1]); . 660c p = x->announce(c, fields, nfield); if(p != nil) error(p); . 651,657d ## diffname ip/devip.c 1997/0408 ## diff -e /n/emeliedump/1997/0403/sys/src/brazil/ip/devip.c /n/emeliedump/1997/0408/sys/src/brazil/ip/devip.c 714a 'I', "ip", . ## diffname ip/devip.c 1997/0423 ## diff -e /n/emeliedump/1997/0408/sys/src/brazil/ip/devip.c /n/emeliedump/1997/0423/sys/src/brazil/ip/devip.c 603c p = Mediaifcwrite(ch->aux, a, n); . 564c c->raddr = nhgetl(addr); . 557c char *p; uchar addr[Ipaddrlen]; . 543c c->laddr = nhgetl(addr); . 533c char *p; uchar addr[Ipaddrlen]; . 404a case Qipifc: closeifcconv(c->aux); c->aux = nil; break; . 272a case Qipifc: c->aux = newifcconv(); break; . 139a if(fs.p[s]->connect == nil) return 0; /* protocol with no user interface */ . ## diffname ip/devip.c 1997/0508 ## diff -e /n/emeliedump/1997/0423/sys/src/brazil/ip/devip.c /n/emeliedump/1997/0508/sys/src/brazil/ip/devip.c 522a else while(*pp < 5000) *pp = nrand(1<<16); . 520,521d 517,518c /* * Fsproto initialises p->nextport to 0 and the restricted * ports (p->nextrport) to 600. * Restricted ports must lie between 600 and 1024. * For the initial condition or if the unrestricted port number * has wrapped round, select a random port between 5000 and 1<<16 * to start at. */ if(c->restricted){ if(*pp >= 1024) . 503,510d ## diffname ip/devip.c 1997/0531 ## diff -e /n/emeliedump/1997/0508/sys/src/brazil/ip/devip.c /n/emeliedump/1997/0531/sys/src/brazil/ip/devip.c 411c if(c->flag & COPEN) closeifcconv(c->aux); . ## diffname ip/devip.c 1997/0806 ## diff -e /n/emeliedump/1997/0531/sys/src/brazil/ip/devip.c /n/emeliedump/1997/0806/sys/src/brazil/ip/devip.c 923c (*p)->order, (*p)->rexmit, (*p)->wclosed); . 921c "%s: csum %d hlen %d len %d order %d rexmit %d wc %d\n", . ## diffname ip/devip.c 1997/0811 ## diff -e /n/emeliedump/1997/0806/sys/src/brazil/ip/devip.c /n/emeliedump/1997/0811/sys/src/brazil/ip/devip.c 523c *pp = nrand(1<<15); . 515c * has wrapped round, select a random port between 5000 and 1<<15 . ## diffname ip/devip.c 1997/0815 ## diff -e /n/emeliedump/1997/0811/sys/src/brazil/ip/devip.c /n/emeliedump/1997/0815/sys/src/brazil/ip/devip.c 570c uchar addr[IPaddrlen]; . 545c uchar addr[IPaddrlen]; . ## diffname ip/devip.c 1997/0823 ## diff -e /n/emeliedump/1997/0815/sys/src/brazil/ip/devip.c /n/emeliedump/1997/0823/sys/src/brazil/ip/devip.c 227c c->qid = (Qid){QID(PROTO(c->qid), 0, Qprotodir)|CHDIR, 0}; . ## diffname ip/devip.c 1997/0916 ## diff -e /n/emeliedump/1997/0823/sys/src/brazil/ip/devip.c /n/emeliedump/1997/0916/sys/src/brazil/ip/devip.c 923c (*p)->order, (*p)->rexmit); if((*p)->stats) n += (*(*p)->stats)(buf + n, len - n); } . 921c "%s: csum %d hlen %d len %d order %d rexmit %d\n", . 919c for(p = fs.p; *p; p++){ . ## diffname ip/devip.c 1997/1030 ## diff -e /n/emeliedump/1997/0916/sys/src/brazil/ip/devip.c /n/emeliedump/1997/1030/sys/src/brazil/ip/devip.c 963c setladdrport(c, argv[1], 0); . 949,950c setladdrport(c, argv[2], 1); . 550c if(nodefault) setladdr(c); else c->laddr = 0; . 542c setladdrport(Conv* c, char* str, int nodefault) . ## diffname ip/devip.c 1997/1104 ## diff -e /n/emeliedump/1997/1030/sys/src/brazil/ip/devip.c /n/emeliedump/1997/1104/sys/src/brazil/ip/devip.c 809a unlock(c); . 474c // return qread(c->rq, a, n); xxx = qread(c->rq, a, n); poot("ipread 2", 0); return xxx; } . 472a {int xxx; poot("ipread 1", 0); . ## diffname ip/devip.c 1997/1105 ## diff -e /n/emeliedump/1997/1104/sys/src/brazil/ip/devip.c /n/emeliedump/1997/1105/sys/src/brazil/ip/devip.c 476,480c return qread(c->rq, a, n); . 473,474d ## diffname ip/devip.c 1997/1128 ## diff -e /n/emeliedump/1997/1105/sys/src/brazil/ip/devip.c /n/emeliedump/1997/1128/sys/src/brazil/ip/devip.c 549c if(p == nil || strcmp(p, "!r") == 0) { . 547a /* * ignore restricted part if it exists. it's * meaningless on local ports. */ . ## diffname ip/devip.c 1998/0306 ## diff -e /n/emeliedump/1997/1128/sys/src/brazil/ip/devip.c /n/emeliedump/1998/0306/sys/src/brazil/ip/devip.c 919,974d 910c ipmove(nc->laddr, laddr); . 908c ipmove(nc->raddr, raddr); . 887c Fsnewcall(Fs*, Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport) . 881c Fsrcvpcol(Fs* fs, uchar proto) . 854c qunlock(p); . 843,844c ipmove(c->laddr, IPnoaddr); ipmove(c->raddr, IPnoaddr); . 834c qunlock(p); . 826,827c /* * make sure both processes and protocol * are done with this Conv */ if(c->inuse == 0 && (p->inuse == nil || (*p->inuse)(c) == 0)) . 815d 800c qunlock(p); . 798c qlock(p); . 793,794d 785c Fsbuiltinproto(Fs* fs, uchar proto) . 716,724c } else error("unknown control request"); qunlock(&c->car); free(cb); poperror(); . 684,713c if(strcmp(cb->f[0], "connect") == 0) connectctlmsg(x, c, cb); else if(strcmp(cb->f[0], "announce") == 0) announcectlmsg(x, c, cb); else if(strcmp(cb->f[0], "bind") == 0) bindctlmsg(x, c, cb); else if(strcmp(cb->f[0], "ttl") == 0) ttlctlmsg(c, cb); else if(strcmp(cb->f[0], "addmulti") == 0){ if(cb->nf < 2) error("addmulti needs interface address"); if(!ipismulticast(c->raddr)) error("addmulti for a non multicast address"); parseip(ia, cb->f[1]); ipifcaddmulti(c, c->raddr, ia); } else if(strcmp(cb->f[0], "remmulti") == 0){ if(cb->nf < 2) error("remmulti needs interface address"); if(!ipismulticast(c->raddr)) error("remmulti for a non multicast address"); parseip(ia, cb->f[1]); ipifcremmulti(c, c->raddr, ia); } else if(x->ctl != nil) { p = x->ctl(c, cb->f, cb->nf); . 681,682c free(cb); nexterror(); . 665,679c if(waserror()) { . 641,663c cb = parsecmd(a, n); if(canqlock(&c->car) == 0){ free(cb); error("connect/announce in progress"); . 629,632c return routewrite(ch, a, n); . 619,627c return arpwrite(a, n); . 617a case Qdata: x = fs.p[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; if(c->wq == nil) error(Eperm); qwrite(c->wq, a, n); x->kick(c, n); break; . 612,613c char *p; Cmdbuf *cb; uchar ia[IPaddrlen]; . 606a c->state = Announcing; c->cerr[0] = '\0'; if(x->announce == nil) error("announce not supported"); p = x->announce(c, cb->f, cb->nf); if(p != nil) error(p); sleep(&c->cr, announced, c); if(c->cerr[0] != '\0') error(c->cerr); } /* * called by protocol bide routine to set addresses */ char* Fsstdbind(Conv* c, char* argv[], int argc) { switch(argc){ default: return "bad args to bind"; case 2: setladdrport(c, argv[1], 0); break; } return nil; } static void bindctlmsg(Proto *x, Conv *c, Cmdbuf *cb) { char *p; if(x->bind == nil) p = Fsstdbind(c, cb->f, cb->nf); else p = x->bind(c, cb->f, cb->nf); if(p != nil) error(p); } static void ttlctlmsg(Conv *c, Cmdbuf *cb) { if(cb->nf < 2) c->ttl = MAXTTL; else c->ttl = atoi(cb->f[1]); } . 605a static void announcectlmsg(Proto *x, Conv *c, Cmdbuf *cb) { char *p; . 600a c->state = Connecting; c->cerr[0] = '\0'; if(x->connect == nil) error("connect not supported"); p = x->connect(c, cb->f, cb->nf); if(p != nil) error(p); sleep(&c->cr, connected, c); if(c->cerr[0] != '\0') error(c->cerr); } /* * called by protocol announce routine to set addresses */ char* Fsstdannounce(Conv* c, char* argv[], int argc) { switch(argc){ default: return "bad args to announce"; case 2: setladdrport(c, argv[1], 1); break; } return nil; } /* * initiate announcement and sleep till its set up */ . 599a static void connectctlmsg(Proto *x, Conv *c, Cmdbuf *cb) { char *p; . 594a /* * called by protocol connect routine to set addresses */ char* Fsstdconnect(Conv *c, char *argv[], int argc) { char *p; switch(argc) { default: return "bad args to connect"; case 2: p = setraddrport(c, argv[1]); if(p != nil) return p; setladdr(c); setlport(c); break; case 3: p = setraddrport(c, argv[1]); if(p != nil) return p; setladdrport(c, argv[2], 0); break; } return nil; } /* * initiate connection and sleep till its set up */ . 584,585c parseip(c->raddr, str); . 578d 565,567c c->lport = 0; if(*p != '*'){ . 562,563c parseip(c->laddr, str); . 557,560c } else { . 555c memset(c->laddr, 0, sizeof(c->laddr)); if(!announcing) . 546d 543c setladdrport(Conv* c, char* str, int announcing) . 541a /* * set a local address and port from a string of the form * address!port * if address is missing and not announcing, pick one * if address is missing and announcing, leave address as zero (i.e. matches anything) * if port is 0, pick a free one * if port is '*', leave port as zero (i.e. matches anything) */ . 539c qunlock(p); . 509c qlock(p); . 496a /* * pick a local port and set it */ . 491,494c findlocalip(c->laddr, c->raddr); . 487a /* * set local address to be that of the ifc closest to remote address */ . 478a case Qstats: x = fs.p[PROTO(ch->qid)]; if(x->stats == nil) error("stats not implemented"); buf = smalloc(Statelen); (*x->stats)(buf, Statelen); rv = readstr(offset, p, n, buf); free(buf); return rv; . 475d 469,471c m = sprint(buf, "%s/%d %d ", c->p->name, c->x, c->inuse); (*x->state)(c, buf, Statelen-m-2); rv = readstr(offset, p, n, buf); free(buf); return rv; . 466a buf = smalloc(Statelen); . 459,465c buf = smalloc(Statelen); x = fs.p[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; if(x->local == nil) { sprint(buf, "%I!%d\n", c->laddr, c->lport); } else { (*x->local)(c, buf, Statelen-2); } rv = readstr(offset, p, n, buf); free(buf); return rv; . 455,457c sprint(buf, "%I!%d\n", c->raddr, c->rport); rv = readstr(offset, p, n, buf); free(buf); return rv; . 453a buf = smalloc(Statelen); . 452c rv = readstr(offset, p, n, buf); free(buf); return rv; . 450a buf = smalloc(16); . 447a case Qiprouter: return iprouterread(a, n); . 444,445d 431,432c char *buf, *p; long m, rv; . 425a enum { Statelen= 1024, }; . 415,416c case Qiprouter: if(c->flag & COPEN) iprouterclose(); . 412,413c netlogclose(); . 410c case Qlog: . 399a while((mp = cv->multi) != nil) ipifcremmulti(cv, mp->ma, mp->ia); . 385a . 383a Ipmulti *mp; . 324c qunlock(p); . 308c qunlock(p); . 303c qlock(p); . 286a case Qstats: . 280a case Qiprouter: iprouteropen(); break; case Qiproute: memmove(c->tag, "none", sizeof(c->tag)); break; . 275,277d 238c switch(TYPE(c->qid)){ case Qtopdir: case Qprotodir: c->qid = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; break; case Qconvdir: c->qid = (Qid){QID(PROTO(c->qid), 0, Qprotodir)|CHDIR, 0}; break; default: panic("ipwalk %lux", c->qid.path); } op = c->path; c->path = ptenter(&syspt, op, name); decref(op); return 1; . 220,236c if(strcmp(name, "..") != 0) return devwalk(c, name, nil, 0, ipgen); . 195a fmtinstall('V', eipconv); fmtinstall('M', eipconv); . 163a case Qstats: . 151a case Qiprouter: . 149d 126c devdir(c, q, p, 0, network, 0666, dp); . 120a case Qiprouter: p = "iprouter"; q = (Qid){QID(0, 0, Qiprouter), 0}; break; . 113,116d 95a case Qstats: q = (Qid){QID(PROTO(c->qid), 0, Qstats), 0}; devdir(c, q, "stats", 0, network, 0444, dp); return 1; . 94c devdir(c, q, "clone", 0, network, 0666, dp); . 82c devdir(c, q, p, 0, cv->owner, 0666, dp); . 23a Qstats, . 18a Qiprouter, . 17d ## diffname ip/devip.c 1998/0310 ## diff -e /n/emeliedump/1998/0306/sys/src/brazil/ip/devip.c /n/emeliedump/1998/0310/sys/src/brazil/ip/devip.c 467,468c case Qipselftab: return ipselftabread(a, offset, n); . 297a case Qipselftab: . 156a case Qipselftab: . 131c devdir(c, q, p, 0, network, prot, dp); . 121a case Qipselftab: p = "ipselftab"; prot = 0444; q = (Qid){QID(0, 0, Qipselftab), 0}; break; . 110a prot = 0666; . 109a int prot; . 18a Qipselftab, . ## diffname ip/devip.c 1998/0313 ## diff -e /n/emeliedump/1998/0310/sys/src/brazil/ip/devip.c /n/emeliedump/1998/0313/sys/src/brazil/ip/devip.c 1020c Fsnewcall(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport) . 1016c return f->t2p[proto]; . 1014c Fsrcvpcol(Fs* f, uchar proto) . 993c Fsconnected(Conv* c, char* msg) . 920c return f->t2p[proto] != nil; . 918c Fsbuiltinproto(Fs* f, uchar proto) . 909c f->p[f->np++] = p; . 906c p->x = f->np; . 901c p->qid.path = CHDIR|QID(f->np, 0, Qprotodir); . 898c f->t2p[p->ipproto] = p; . 896c if(f->t2p[p->ipproto] != nil) . 894a p->f = f; . 892c if(f->np >= Maxproto) . 890c Fsproto(Fs *f, Proto *p) . 814c x = f->p[PROTO(ch->qid)]; . 809c p = netlogctl(f, a, n); . 807c return routewrite(f, ch, a, n); . 805c return arpwrite(f->arp, a, n); . 795c x = f->p[PROTO(ch->qid)]; . 790a f = ipfs[ch->dev]; . 789a Fs *f; . 545c findlocalip(c->p->f, c->laddr, c->raddr); . 526c (*x->stats)(x, buf, Statelen); . 522c x = f->p[PROTO(ch->qid)]; . 519c c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; . 516c c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; . 508c x = f->p[PROTO(ch->qid)]; . 496c x = f->p[PROTO(ch->qid)]; . 489c c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; . 480c return netlogread(f, a, offset, n); . 478c return ipselftabread(f, a, offset, n); . 476c return routeread(f, a, offset, n); . 474c return arpread(f->arp, a, offset, n); case Qbootp: return bootpread(a, offset, n); . 464a f = ipfs[ch->dev]; . 463a Fs *f; . 448c closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]); . 442c iprouterclose(f); . 438c netlogclose(f); . 432a Fs *f; f = ipfs[c->dev]; . 368c memmove(cv->owner, commonuser(), NAMELEN); . 349c cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)]; . 341c memmove(cv->owner, commonuser(), NAMELEN); . 333c if(strcmp(commonuser(), cv->owner) != 0) . 323c p = f->p[PROTO(c->qid)]; . 312,313c p = f->p[PROTO(c->qid)]; cv = Fsprotoclone(p, commonuser()); . 306a case Qbootp: . 295c iprouteropen(f); . 292c netlogopen(f); . 287a f = ipfs[c->dev]; . 283a Fs *f; . 221a c->dev = dev; . 219a dev = atoi(spec); if(dev >= 16) error("bad specification"); ipgetfs(dev); . 218a int dev; . 214a 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]; } . 202,207d 175c s -= f->p[PROTO(c->qid)]->ac; . 168,169c if(s < f->p[PROTO(c->qid)]->ac) { cv = f->p[PROTO(c->qid)]->conv[s]; . 161a case Qbootp: . 159c s -= f->np; . 156c devdir(c, q, f->p[s]->name, 0, network, CHDIR|0555, dp); . 152,153c if(s < f->np) { if(f->p[s]->connect == nil) . 149a f = ipfs[c->dev]; . 148a Fs *f; . 120a case Qbootp: p = "bootp"; q = (Qid){QID(0, 0, Qbootp), 0}; break; . 51c cv = ipfs[c->dev]->p[PROTO(c->qid)]->conv[CONV(c->qid)]; . 43a QLock fslock; Fs *ipfs[Nfs]; /* attached fs's */ Queue *qlog; . 37,40c #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)<incall = nil; . ## diffname ip/devip.c 1998/0324 ## diff -e /n/emeliedump/1998/0321/sys/src/brazil/ip/devip.c /n/emeliedump/1998/0324/sys/src/brazil/ip/devip.c 1083c if(f->t2m[proto] && f->ipmux) return f->ipmux; else return f->t2p[proto]; . ## diffname ip/devip.c 1998/0327 ## diff -e /n/emeliedump/1998/0324/sys/src/brazil/ip/devip.c /n/emeliedump/1998/0327/sys/src/brazil/ip/devip.c 1083c if(f->ipmux) . ## diffname ip/devip.c 1998/0423 ## diff -e /n/emeliedump/1998/0327/sys/src/brazil/ip/devip.c /n/emeliedump/1998/0423/sys/src/brazil/ip/devip.c 217a nullmediumlink(); pktmediumlink(); . 56a extern void nullmediumlink(void); extern void pktmediumlink(void); . ## diffname ip/devip.c 1998/0502 ## diff -e /n/emeliedump/1998/0423/sys/src/brazil/ip/devip.c /n/emeliedump/1998/0502/sys/src/brazil/ip/devip.c 907,910c if(cb->nf == 2){ if(!ipismulticast(c->raddr)) error("addmulti for a non multicast address"); parseip(ia, cb->f[1]); ipifcaddmulti(c, c->raddr, ia); } else { parseip(ma, cb->f[2]); if(!ipismulticast(ma)) error("addmulti for a non multicast address"); parseip(ia, cb->f[1]); ipifcaddmulti(c, ma, ia); } . 855c uchar ia[IPaddrlen], ma[IPaddrlen]; . ## diffname ip/devip.c 1998/0509 ## diff -e /n/emeliedump/1998/0502/sys/src/brazil/ip/devip.c /n/emeliedump/1998/0509/sys/src/brazil/ip/devip.c 1101a Proto* Fsrcvpcolx(Fs *f, uchar proto) { return f->t2p[proto]; } . ## diffname ip/devip.c 1998/0630 ## diff -e /n/emeliedump/1998/0509/sys/src/brazil/ip/devip.c /n/emeliedump/1998/0630/sys/src/brazil/ip/devip.c 874c return arpwrite(f, a, n); . ## diffname ip/devip.c 1998/0709 ## diff -e /n/emeliedump/1998/0630/sys/src/brazil/ip/devip.c /n/emeliedump/1998/0709/sys/src/brazil/ip/devip.c 576,577c (*x->state)(c, buf, Statelen-2); . ## diffname ip/devip.c 1998/0710 ## diff -e /n/emeliedump/1998/0709/sys/src/brazil/ip/devip.c /n/emeliedump/1998/0710/sys/src/brazil/ip/devip.c 523c long rv; . ## diffname ip/devip.c 1998/0717 ## diff -e /n/emeliedump/1998/0710/sys/src/brazil/ip/devip.c /n/emeliedump/1998/0717/sys/src/brazil/ip/devip.c 514c Statelen= 32*1024, . ## diffname ip/devip.c 1998/0825 ## diff -e /n/emeliedump/1998/0717/sys/src/brazil/ip/devip.c /n/emeliedump/1998/0825/sys/src/brazil/ip/devip.c 549c sprint(buf, "%lud", CONV(ch->qid)); . ## diffname ip/devip.c 1998/0924 ## diff -e /n/emeliedump/1998/0825/sys/src/brazil/ip/devip.c /n/emeliedump/1998/0924/sys/src/brazil/ip/devip.c 252a f->dev = dev; . ## diffname ip/devip.c 1998/1127 ## diff -e /n/emeliedump/1998/0924/sys/src/brazil/ip/devip.c /n/emeliedump/1998/1127/sys/src/brazil/ip/devip.c 417a /* wait for a connect */ . 411a /* give up if we got a hangup */ if(qisclosed(cv->rq)) error("listen hungup"); . ## diffname ip/devip.c 1999/0302 ## diff -e /n/emeliedump/1998/1127/sys/src/brazil/ip/devip.c /n/emeliedump/1999/0302/sys/src/brazil/ip/devip.c 1141c qunlock(c); . 1132c qunlock(c); . 1125c qunlock(c); . 1120c qlock(c); . 1112a /* * called with protocol locked */ . 1071,1073c qunlock(c); . 1052,1053d 1048c qunlock(c); . 1040c if(canqlock(c)){ . 1026c qlock(c); . 1014,1018d 1007a /* * called with protocol locked */ . 472c qunlock(cv); . 469c qlock(cv); . 432c qunlock(cv); . 425c qlock(cv); . 401c qunlock(cv); . 385c qunlock(cv); . 383c qlock(cv); . 370a qunlock(p); poperror(); . 369a qlock(p); if(waserror()){ qunlock(p); nexterror(); } . ## diffname ip/devip.c 1999/0316 ## diff -e /n/emeliedump/1999/0302/sys/src/brazil/ip/devip.c /n/emeliedump/1999/0316/sys/src/brazil/ip/devip.c 907a if(cb->nf < 1) error("short control request"); . 568,569c x = f->p[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; if(x->remote == nil) { sprint(buf, "%I!%d\n", c->raddr, c->rport); } else { (*x->remote)(c, buf, Statelen-2); } . ## diffname ip/devip.c 1999/0320 ## diff -e /n/emeliedump/1999/0316/sys/src/brazil/ip/devip.c /n/emeliedump/1999/0320/sys/src/brazil/ip/devip.c 874a a = v; . 873a char *a; . 866c ipwrite(Chan* ch, void *v, long n, vlong) . ## diffname ip/devip.c 1999/0629 ## diff -e /n/emeliedump/1999/0320/sys/src/brazil/ip/devip.c /n/emeliedump/1999/0629/sys/src/brazil/ip/devip.c 304,306d 288,289d ## diffname ip/devip.c 1999/0711 ## diff -e /n/emeliedump/1999/0629/sys/src/brazil/ip/devip.c /n/emeliedump/1999/0711/sys/src/brazil/ip/devip.c 1038,1041c if(p->ptclsize != 0){ c->ptcl = malloc(p->ptclsize); if(c->ptcl == nil) { free(c); error(Enomem); } . ## diffname ip/devip.c 1999/0817 ## diff -e /n/emeliedump/1999/0711/sys/src/brazil/ip/devip.c /n/emeliedump/1999/0817/sys/src/brazil/ip/devip.c 919a else if(strcmp(cb->f[0], "tos") == 0) tosctlmsg(c, cb); . 851a tosctlmsg(Conv *c, Cmdbuf *cb) { if(cb->nf < 2) c->tos = 0; else c->tos = atoi(cb->f[1]); } static void . ## diffname ip/devip.c 1999/0901 ## diff -e /n/emeliedump/1999/0817/sys/src/brazil/ip/devip.c /n/emeliedump/1999/0901/sys/src/brazil/ip/devip.c 969c Conv *c; Proto *x; Fs *f; int n; switch(TYPE(ch->qid)){ case Qdata: f = ipfs[ch->dev]; x = f->p[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; if(c->wq == nil) error(Eperm); if(bp->next) bp = concatblock(bp); n = BLEN(bp); qbwrite(c->wq, bp); x->kick(c, n); return n; default: return devbwrite(ch, bp, offset); } . 967c ipbwrite(Chan* ch, Block* bp, ulong offset) . 614c Conv *c; Proto *x; Fs *f; switch(TYPE(ch->qid)){ case Qdata: f = ipfs[ch->dev]; x = f->p[PROTO(ch->qid)]; c = x->conv[CONV(ch->qid)]; return qbread(c->rq, n); default: return devbread(ch, n, offset); } . 612c ipbread(Chan* ch, long n, ulong offset) . ## diffname ip/devip.c 1999/0910 ## diff -e /n/emeliedump/1999/0901/sys/src/brazil/ip/devip.c /n/emeliedump/1999/0910/sys/src/brazil/ip/devip.c 465c void . ## diffname ip/devip.c 1999/1230 ## diff -e /n/emeliedump/1999/0910/sys/src/brazil/ip/devip.c /n/emeliedump/1999/1230/sys/src/9/ip/devip.c 288,302c return devwalk(c, name, nil, 0, ipgen); . 204a if(s == DEVDOTDOT){ s = PROTO(c->qid); q = (Qid){QID(s, 0, Qprotodir)|CHDIR, 0}; devdir(c, q, f->p[s]->name, 0, network, 0555, dp); return 1; } . 196c devdir(c, q, name, 0, cv->owner, 0555, dp); . 191a if(s == DEVDOTDOT){ q = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; sprint(name, "#I%lud", c->dev); devdir(c, q, name, 0, network, 0555, dp); return 1; } . 179c devdir(c, q, f->p[s]->name, 0, network, 0555, dp); . 174a if(s == DEVDOTDOT){ q = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; sprint(name, "#I%lud", c->dev); devdir(c, q, name, 0, network, 0555, dp); return 1; } . ## diffname ip/devip.c 2000/0116 ## diff -e /n/emeliedump/1999/1230/sys/src/9/ip/devip.c /n/emeliedump/2000/0116/sys/src/9/ip/devip.c 1204a } long ndbwrite(Fs *f, char *a, ulong off, int n) { if(off != 0) error(Eio); if(n >= sizeof(f->ndb)) error(Eio); memmove(f->ndb, a, n); f->ndb[n] = 0; return n; . 920a case Qndb: return ndbwrite(f, a, offset, n); break; . 894a ulong offset = off; . 886c ipwrite(Chan* ch, void *v, long n, vlong off) . 552a case Qndb: return readstr(offset, a, n, f->ndb); . 191a case Qndb: . 140a case Qndb: p = "ndb"; q = (Qid){QID(0, 0, Qndb), 0}; break; . 57,58c extern void nullmediumlink(void); extern void pktmediumlink(void); long ndbwrite(Fs *f, char *a, ulong off, int n); . 14a Qndb, . ## diffname ip/devip.c 2000/0126 ## diff -e /n/emeliedump/2000/0116/sys/src/9/ip/devip.c /n/emeliedump/2000/0126/sys/src/9/ip/devip.c 1227,1228c memmove(f->ndb+off, a, n); f->ndb[off+n] = 0; . 1225c if(off+n >= sizeof(f->ndb)) . 1223c if(off > strlen(f->ndb)) . 352a case Qndb: if(omode & (OWRITE|OTRUNC) && !iseve()) error(Eperm); if((omode & (OWRITE|OTRUNC)) == (OWRITE|OTRUNC)) f->ndb[0] = 0; break; . 165c devdir(c, q, p, len, network, prot, dp); . 145a len = strlen(f->ndb); . 130a f = ipfs[c->dev]; . 129a int len = 0; Fs *f; . ## diffname ip/devip.c 2000/0220 ## diff -e /n/emeliedump/2000/0126/sys/src/9/ip/devip.c /n/emeliedump/2000/0220/sys/src/9/ip/devip.c 529,532d 367,369d 206d 161,164d 17d ## diffname ip/devip.c 2000/0424 ## diff -e /n/emeliedump/2000/0220/sys/src/9/ip/devip.c /n/emeliedump/2000/0424/sys/src/9/ip/devip.c 1122a if(p->gc != nil && (*p->gc)(p)) goto retry; . 1086a retry: . ## diffname ip/devip.c 2000/1220 ## diff -e /n/emeliedump/2000/0424/sys/src/9/ip/devip.c /n/emeliedump/2000/1220/sys/src/9/ip/devip.c 1213a c->state = Connected; . 1132c c->state = Idle; . 986c qunlock(c); . 942c qunlock(c); . 937,940c qlock(c); . 840a qlock(c); . 839a qunlock(c); . 832a if(c->state != 0) error(Econinuse); . 799a qlock(c); . 798a qunlock(c); . 791a if(c->state != 0) error(Econinuse); . 505a cv->state = Idle; qunlock(cv); . 504d ## diffname ip/devip.c 2000/1221 ## diff -e /n/emeliedump/2000/1220/sys/src/9/ip/devip.c /n/emeliedump/2000/1221/sys/src/9/ip/devip.c 853a poperror(); . 852d 850a qunlock(c); if(waserror()){ qlock(c); nexterror(); } . 849d 806a poperror(); . 805d 803a qunlock(c); if(waserror()){ qlock(c); nexterror(); } . 802d ## diffname ip/devip.c 2000/1227 ## diff -e /n/emeliedump/2000/1221/sys/src/9/ip/devip.c /n/emeliedump/2000/1227/sys/src/9/ip/devip.c 1234c nc->state = Connected; . ## diffname ip/devip.c 2001/0118 ## diff -e /n/emeliedump/2000/1227/sys/src/9/ip/devip.c /n/emeliedump/2001/0118/sys/src/9/ip/devip.c 869c * called by protocol bind routine to set addresses . 821a memset(c->raddr, 0, sizeof(c->raddr)); c->rport = 0; . 728,729c lport = atoi(p); if(lport != 0) setluniqueport(c, lport); else . 709a ushort lport; . 650a * set a local port making sure the quad of raddr,rport,laddr,lport is unique */ static void setluniqueport(Conv* c, int lport) { Proto *p; Conv *xp; int x; p = c->p; qlock(p); for(x = 0; x < p->nc; x++){ xp = p->conv[x]; if(xp == nil) break; if((xp->state == Connected || xp->state == Announced) && xp->lport == lport && xp->rport == c->rport && ipcmp(xp->raddr, c->raddr) == 0 && ipcmp(xp->laddr, c->laddr) == 0){ qunlock(p); error("address in use"); } } c->lport = lport; qunlock(p); } /* . ## diffname ip/devip.c 2001/0126 ## diff -e /n/emeliedump/2001/0118/sys/src/9/ip/devip.c /n/emeliedump/2001/0126/sys/src/9/ip/devip.c 914,915c return setladdrport(c, argv[1], 0); . 862,863c return setladdrport(c, argv[1], 1); . 809,810c return setladdrport(c, argv[2], 0); . 765c } else rv = setluniqueport(c, 0); return rv; . 761,762c if(lport > 0) rv = setluniqueport(c, lport); . 742a rv = nil; . 740a char *rv; . 737c static char* . 677a return nil; . 673c return "address in use"; . 666a if(xp == c) continue; . 653c static char* . ## diffname ip/devip.c 2001/0209 ## diff -e /n/emeliedump/2001/0126/sys/src/9/ip/devip.c /n/emeliedump/2001/0209/sys/src/9/ip/devip.c 771,772c else rv = setluniqueport(c, lport); } . 765,769c if(announcing){ if(p == nil){ ipmove(c->laddr, IPnoaddr); lport = atoi(str); } else { if(strcmp(str, "*") == 0) ipmove(c->laddr, IPnoaddr); else parseip(c->laddr, str); lport = atoi(p); } rv = setluniqueport(c, lport); } else { if(p == nil){ setladdr(c); lport = atoi(str); } else { if(strcmp(str, "*") == 0) setladdr(c); else parseip(c->laddr, str); lport = atoi(p); } if(lport <= 0) . 761c if(strcmp(p, "r") == 0) p = nil; . 754,759c if(p != nil){ . 734,738c * [address!]port[!r] . ## diffname ip/devip.c 2001/0210 ## diff -e /n/emeliedump/2001/0209/sys/src/9/ip/devip.c /n/emeliedump/2001/0210/sys/src/9/ip/devip.c 784a if(lport <= 0) setlport(c); else rv = setluniqueport(c, lport); . 780,783d 768d ## diffname ip/devip.c 2001/0227 ## diff -e /n/emeliedump/2001/0210/sys/src/9/ip/devip.c /n/emeliedump/2001/0227/sys/src/9/ip/devip.c 800c if(strstr(p, "!r") != nil) . ## diffname ip/devip.c 2001/0301 ## diff -e /n/emeliedump/2001/0227/sys/src/9/ip/devip.c /n/emeliedump/2001/0301/sys/src/9/ip/devip.c 779a /* one process can get all connections */ if(announcing && strcmp(p, "*") == 0){ if(!iseve()) error(Eperm); return setluniqueport(c, 0); } lport = atoi(p); . 771,778c p = str; } else { if(strcmp(str, "*") == 0) ipmove(c->laddr, IPnoaddr); else parseip(c->laddr, str); . 760,769c else . 757,758c if(p == nil){ if(announcing) . ## diffname ip/devip.c 2001/0306 ## diff -e /n/emeliedump/2001/0301/sys/src/9/ip/devip.c /n/emeliedump/2001/0306/sys/src/9/ip/devip.c 1084c x->kick(c); . 991c x->kick(c); . ## diffname ip/devip.c 2001/0403 ## diff -e /n/emeliedump/2001/0306/sys/src/9/ip/devip.c /n/emeliedump/2001/0403/sys/src/9/ip/devip.c 475c Dir d; Conv *cv; Fs *f; Proto *p; f = ipfs[c->dev]; switch(TYPE(c->qid)) { default: error(Eperm); break; case Qctl: case Qdata: break; } convM2D(dp, &d); p = f->p[PROTO(c->qid)]; cv = p->conv[CONV(c->qid)]; if(!iseve() && strcmp(commonuser(), cv->owner) != 0) error(Eperm); if(d.uid[0]){ strncpy(cv->owner, d.uid, sizeof(cv->owner)); cv->owner[sizeof(cv->owner)-1] = 0; } cv->perm = d.mode & 0777; . 473c ipwstat(Chan *c, char *dp) . 421a if((perm & (cv->perm>>6)) != perm) { if(strcmp(commonuser(), cv->owner) != 0) error(Eperm); if((perm & cv->perm) != perm) error(Eperm); } . 101c devdir(c, q, p, 0, cv->owner, 0444, dp); . 87c devdir(c, q, "listen", qlen(cv->eq), cv->owner, cv->perm, dp); return 1; . 85d ## diffname ip/devip.c 2001/0405 ## diff -e /n/emeliedump/2001/0403/sys/src/9/ip/devip.c /n/emeliedump/2001/0405/sys/src/9/ip/devip.c 560a free(c->aux); . 502c if(!iseve() && strcmp(ATTACHER(c), cv->owner) != 0) . 453c memmove(nc->owner, ATTACHER(c), NAMELEN); . 423c if(strcmp(ATTACHER(c), cv->owner) != 0) . 413c memmove(cv->owner, ATTACHER(c), NAMELEN); . 405c if(strcmp(ATTACHER(c), cv->owner) != 0) . 383c cv = Fsprotoclone(p, ATTACHER(c)); . 362d 306c IPaux *a = c->aux; nc = devclone(c, nc); nc->aux = newipaux(a->owner, a->tag); return nc; . 299a c->aux = newipaux(commonuser(), "none"); . 284a IPaux* newipaux(char *owner, char *tag) { IPaux *a; int n; a = smalloc(sizeof(*a)); memmove(a->owner, owner, NAMELEN); memset(a->tag, ' ', sizeof(a->tag)); n = strlen(tag); if(n > sizeof(a->tag)) n = sizeof(a->tag); memmove(a->tag, tag, n); return a; } #define ATTACHER(c) (((IPaux*)((c)->aux))->owner) . 68a if(cv->owner[0] == 0) memmove(cv->owner, eve, NAMELEN); . ## diffname ip/devip.c 2001/0430 ## diff -e /n/emeliedump/2001/0405/sys/src/9/ip/devip.c /n/emeliedump/2001/0430/sys/src/9/ip/devip.c 370,371c perm = m2p[omode&3]; . ## diffname ip/devip.c 2001/0527 ## diff -e /n/emeliedump/2001/0430/sys/src/9/ip/devip.c /n/emeliedump/2001/0527/sys/src/9/ip/devip.c 1279c strncpy(c->cerr, msg, ERRMAX-1); . 1258c kstrdup(&c->owner, user); . 1184c p->qid.type = QTDIR; p->qid.path = QID(f->np, 0, Qprotodir); . 1156d 741d 584a free(((IPaux*)c->aux)->owner); . 555c kstrdup(&cv->owner, network); . 532c return n; . 522,530c n = convM2D(dp, n, &d, nil); if(n > 0){ p = f->p[PROTO(c->qid)]; cv = p->conv[CONV(c->qid)]; if(!iseve() && strcmp(ATTACHER(c), cv->owner) != 0) error(Eperm); if(d.uid[0]) kstrdup(&cv->owner, d.uid); cv->perm = d.mode & 0777; . 504,505c static int ipwstat(Chan *c, uchar *dp, int n) . 476,477c mkqid(&c->qid, QID(PROTO(c->qid), nc->x, Qctl), 0, QTFILE); kstrdup(&cv->owner, ATTACHER(c)); . 437c kstrdup(&cv->owner, ATTACHER(c)); . 414c mkqid(&c->qid, QID(p->x, cv->x, Qctl), 0, QTFILE); . 370c omode &= 3; perm = m2p[omode]; . 341,346d 338c return devstat(c, db, n, nil, 0, ipgen); . 336c ipstat(Chan* c, uchar* db, int n) . 330,332c w = devwalk(c, nc, name, nname, nil, 0, ipgen); if(w != nil && w->clone != nil) w->clone->aux = newipaux(a->owner, a->tag); return w; . 328a Walkqid* w; . 325,326c static Walkqid* ipwalk(Chan* c, Chan *nc, char **name, int nname) . 317c mkqid(&c->qid, QID(0, 0, Qtopdir), 0, QTDIR); . 294c kstrdup(&a->owner, owner); . 227c mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR); . 214,216c sprint(up->genbuf, "%d", s); mkqid(&q, QID(PROTO(c->qid), s, Qconvdir), 0, QTDIR); devdir(c, q, up->genbuf, 0, cv->owner, 0555, dp); . 207,209c mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR); sprint(up->genbuf, "#I%lud", c->dev); devdir(c, q, up->genbuf, 0, network, 0555, dp); . 192c mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR); . 184,186c mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR); sprint(up->genbuf, "#I%lud", c->dev); devdir(c, q, up->genbuf, 0, network, 0555, dp); . 176d 172c ipgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) . 164d 160d 155d 150d 146d 142d 136a mkqid(&q, QID(0, 0, i), 0, QTFILE); . 118c mkqid(&q, QID(PROTO(c->qid), 0, Qstats), 0, QTFILE); . 114c mkqid(&q, QID(PROTO(c->qid), 0, Qclone), 0, QTFILE); . 100d 96d 92d 87d 83d 79d 75d 69,70c if(cv->owner == nil) kstrdup(&cv->owner, eve); mkqid(&q, QID(PROTO(c->qid), CONV(c->qid), i), 0, QTFILE); . 46,48c #define TYPE(x) ( ((ulong)(x).path) & Masktype ) #define CONV(x) ( (((ulong)(x).path) >> Shiftconv) & Maskconv ) #define PROTO(x) ( (((ulong)(x).path) >> Shiftproto) & Maskproto ) . ## diffname ip/devip.c 2001/0922 ## diff -e /n/emeliedump/2001/0527/sys/src/9/ip/devip.c /n/emeliedump/2001/0922/sys/src/9/ip/devip.c 1346a ulong scalednconv(void) { if(cpuserver && conf.npage*BY2PG >= 128*MB) return Nchans*4; return Nchans; } . ## diffname ip/devip.c 2001/1106 ## diff -e /n/emeliedump/2001/0922/sys/src/9/ip/devip.c /n/emeliedump/2001/1106/sys/src/9/ip/devip.c 517a n = convM2D(dp, n, d, nil); if(n == 0) error(Eshortstat); p = f->p[PROTO(c->qid)]; cv = p->conv[CONV(c->qid)]; if(!iseve() && strcmp(ATTACHER(c), cv->owner) != 0) error(Eperm); if(!emptystr(d->uid)) kstrdup(&cv->owner, d->uid); if(d->mode != ~0UL) cv->perm = d->mode & 0777; poperror(); free(d); . 508,516c d = smalloc(n + sizeof(Dir)); if(waserror()){ free(d); nexterror(); . 493c Dir *d; . ## diffname ip/devip.c 2001/1120 ## diff -e /n/emeliedump/2001/1106/sys/src/9/ip/devip.c /n/emeliedump/2001/1120/sys/src/9/ip/devip.c 1108,1109c } . 1104c break; case CMwildcard: if(x->ctl == nil) cmderror(cb, "unknown control request"); . 1097c break; case CMremmulti: . 1082,1084c break; case CMaddmulti: if(cb->nf != 2 && cb->nf != 3) cmderror(cb, Ecmdargs); . 1080c break; case CMtos: . 1078c break; case CMttl: . 1076c break; case CMbind: . 1074c break; case CMannounce: . 1072c ct = lookupcmd(cb, ipctlmsg, nelem(ipctlmsg)); switch(ct->index){ case CMconnect: . 1052,1054c netlogctl(f, a, n); . 1025a Cmdtab *ct; . 56a enum { CMaddmulti, CMannounce, CMbind, CMconnect, CMremmulti, CMtos, CMttl, CMwildcard, }; Cmdtab ipctlmsg[] = { CMaddmulti, "addmulti", 0, CMannounce, "announce", 0, CMbind, "bind", 0, CMconnect, "connect", 0, CMremmulti, "remmulti", 0, CMtos, "tos", 0, CMttl, "ttl", 0, CMwildcard, "*", 0, }; . ## diffname ip/devip.c 2001/1204 ## diff -e /n/emeliedump/2001/1120/sys/src/9/ip/devip.c /n/emeliedump/2001/1204/sys/src/9/ip/devip.c 1196c devremove, . 1190c devcreate, . 502,513d ## diffname ip/devip.c 2001/1207 ## diff -e /n/emeliedump/2001/1204/sys/src/9/ip/devip.c /n/emeliedump/2001/1207/sys/src/9/ip/devip.c 498a c->iounit = qiomaxatomic; . ## diffname ip/devip.c 2002/0109 ## diff -e /n/emeliedump/2001/1207/sys/src/9/ip/devip.c /n/emeliedump/2002/0109/sys/src/9/ip/devip.c 1174c devinit, devshutdown, . 1082,1084d 264,266d 262d ## diffname ip/devip.c 2002/0217 ## diff -e /n/emeliedump/2002/0109/sys/src/9/ip/devip.c /n/emeliedump/2002/0217/sys/src/9/ip/devip.c 263,267c fmtinstall('i', eipfmt); fmtinstall('I', eipfmt); fmtinstall('E', eipfmt); fmtinstall('V', eipfmt); fmtinstall('M', eipfmt); . ## diffname ip/devip.c 2002/0324 ## diff -e /n/emeliedump/2002/0217/sys/src/9/ip/devip.c /n/emeliedump/2002/0324/sys/src/9/ip/devip.c 1372a f->ndbvers++; . 387a f->ndbvers++; } . 386c if((omode & (OWRITE|OTRUNC)) == (OWRITE|OTRUNC)){ . 384c if((omode & (OWRITE|OTRUNC)) && !iseve()) . 168a q.vers = f->ndbvers; . ## diffname ip/devip.c 2002/0325 ## diff -e /n/emeliedump/2002/0324/sys/src/9/ip/devip.c /n/emeliedump/2002/0325/sys/src/9/ip/devip.c 1376a f->ndbmtime = seconds(); . 182a if(i == Qndb) dp->mtime = f->ndbmtime; . ## diffname ip/devip.c 2002/0507 ## diff -e /n/emeliedump/2002/0325/sys/src/9/ip/devip.c /n/emeliedump/2002/0507/sys/src/9/ip/devip.c 1378,1379d 1184c ipremove, . 1178c ipcreate, . 1130,1131c } else error("unknown control request"); . 1123,1126c } else if(x->ctl != nil) { . 1115,1116c } else if(strcmp(cb->f[0], "remmulti") == 0){ . 1099,1102c else if(strcmp(cb->f[0], "addmulti") == 0){ if(cb->nf < 2) error("addmulti needs interface address"); . 1096,1097c else if(strcmp(cb->f[0], "tos") == 0) . 1093,1094c else if(strcmp(cb->f[0], "ttl") == 0) . 1090,1091c else if(strcmp(cb->f[0], "bind") == 0) . 1087,1088c else if(strcmp(cb->f[0], "announce") == 0) . 1083,1085c if(cb->nf < 1) error("short control request"); if(strcmp(cb->f[0], "connect") == 0) . 1040d 751a . 633a case Qipgate6: return ipgateread6(f, a, offset, n); . 527,541d 522,525c n = convM2D(dp, n, &d, nil); if(n > 0){ p = f->p[PROTO(c->qid)]; cv = p->conv[CONV(c->qid)]; if(!iseve() && strcmp(ATTACHER(c), cv->owner) != 0) error(Eperm); if(d.uid[0]) kstrdup(&cv->owner, d.uid); cv->perm = d.mode & 0777; . 507c Dir d; . 503a static void ipcreate(Chan*, char*, int, ulong) { error(Eperm); } static void ipremove(Chan*) { error(Eperm); } . 500d 407a case Qipgate6: . 391,392d 389c if((omode & (OWRITE|OTRUNC)) == (OWRITE|OTRUNC)) . 387c if(omode & (OWRITE|OTRUNC) && !iseve()) . 348a . 219a case Qipgate6: . 183,184d 177a case Qipgate6: p = "ipgate6"; prot = 0444; break; . 169d 57,80d 17a Qipgate6, . ## diffname ip/devip.c 2002/0514 ## diff -e /n/emeliedump/2002/0507/sys/src/9/ip/devip.c /n/emeliedump/2002/0514/sys/src/9/ip/devip.c 1350a f->ndbvers++; f->ndbmtime = seconds(); . 162a if(i == Qndb) dp->mtime = f->ndbmtime; . 145a q.vers = f->ndbvers; . ## diffname ip/devip.c 2002/0516 ## diff -e /n/emeliedump/2002/0514/sys/src/9/ip/devip.c /n/emeliedump/2002/0516/sys/src/9/ip/devip.c 164c if(i == Qndb && f->ndbmtime > kerndate) . 128a extern ulong kerndate; . ## diffname ip/devip.c 2002/0601 ## diff -e /n/emeliedump/2002/0516/sys/src/9/ip/devip.c /n/emeliedump/2002/0601/sys/src/9/ip/devip.c 1338a nc->ipversion = version; . 1311c Fsnewcall(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport, uchar version) . 882a if( (memcmp(c->raddr, v4prefix, IPv4off) == 0 && memcmp(c->laddr, v4prefix, IPv4off) == 0) || ipcmp(c->raddr, IPnoaddr) == 0) c->ipversion = V4; else c->ipversion = V6; . 881c p = setladdrport(c, argv[2], 0); if(p != nil) return p; . ## diffname ip/devip.c 2002/0625 ## diff -e /n/emeliedump/2002/0601/sys/src/9/ip/devip.c /n/emeliedump/2002/0625/sys/src/9/ip/devip.c 1090a else if(strcmp(cb->f[0], "ignoreadvice") == 0) c->ignoreadvice = 1; . ## diffname ip/devip.c 2002/0711 ## diff -e /n/emeliedump/2002/0625/sys/src/9/ip/devip.c /n/emeliedump/2002/0711/sys/src/9/ip/devip.c 1244c c->eq = qopen(1024, Qmsg, 0, 0); . 1149c if(x->kick != nil) x->kick(c); . 1056c if(x->kick != nil) x->kick(c); . ## diffname ip/devip.c 2002/0712 ## diff -e /n/emeliedump/2002/0711/sys/src/9/ip/devip.c /n/emeliedump/2002/0712/sys/src/9/ip/devip.c 1150,1151d 1056,1057d ## diffname ip/devip.c 2002/1110 ## diff -e /n/emeliedump/2002/0712/sys/src/9/ip/devip.c /n/emeliedump/2002/1110/sys/src/9/ip/devip.c 665a case Qsnoop: c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)]; return qread(c->sq, a, n); . 577a break; case Qsnoop: if(c->flag & COPEN) decref(&f->p[PROTO(c->qid)]->conv[CONV(c->qid)]->snoopers); break; . 393a case Qsnoop: if(omode != OREAD) error(Eperm); p = f->p[PROTO(c->qid)]; cv = p->conv[CONV(c->qid)]; if(strcmp(ATTACHER(c), cv->owner) != 0 && !iseve()) error(Eperm); incref(&cv->snoopers); break; . 237a case Qsnoop: . 94a case Qsnoop: if(strcmp(cv->p->name, "ipifc") != 0) return -1; devdir(c, q, "snoop", qlen(cv->sq), cv->owner, 0400, dp); return 1; . 87c devdir(c, q, "listen", 0, cv->owner, cv->perm, dp); . 34a Qsnoop, . ## diffname ip/devip.c 2003/0308 ## diff -e /n/emeliedump/2002/1110/sys/src/9/ip/devip.c /n/emeliedump/2003/0308/sys/src/9/ip/devip.c 1292a c->r = nil; c->rgen = 0; . 570a cv->r = nil; cv->rgen = 0; . ## diffname ip/devip.c 2003/0423 ## diff -e /n/emeliedump/2003/0308/sys/src/9/ip/devip.c /n/emeliedump/2003/0423/sys/src/9/ip/devip.c 847,848c else { parseip(addr, str); if(ipforme(c->p->f, addr)) ipmove(c->laddr, addr); else return "not a local IP address"; } . 822a uchar addr[IPaddrlen]; .