| plan 9 kernel history: overview | file list | diff list |
1992/0626/port/devip.c (diff list | history)
| 1992/0625/sys/src/9/port/devip.c:13,27 – 1992/0626/sys/src/9/port/devip.c:13,27 (short | long | prev | next) | ||
| 1991/1012 | { | |
| 1992/0318 | Nrprotocol = 3, /* Number of protocols supported by this driver */ Nipsubdir = 4, /* Number of subdirectory entries per connection */ | |
| 1992/0626 | Nfrag = 32, /* Ip reassembly queue entries */ Nifc = 4, /* max interfaces */ | |
| 1991/0424 | }; | |
| 1991/1030 | int udpsum = 1; | |
| 1991/12171 | Queue *Ipoutput; /* Control message stream for tcp/il */ | |
| 1992/0626 | Ipifc *ipifc[Nrprotocol+1]; | |
| 1991/12171 | QLock ipalloc; /* Protocol port allocation lock */ | |
| 1992/0416 |
| |
| 1992/0626 | Ipconv **tcpbase; | |
| 1991/0424 | ||
| 1992/0625 | Streamput udpstiput, udpstoput, tcpstiput, tcpstoput, iliput, iloput, bsdiput, bsdoput; Streamopen udpstopen, tcpstopen, ilopen, bsdopen; | |
| 1992/0625/sys/src/9/port/devip.c:35,80 – 1992/0626/sys/src/9/port/devip.c:35,73 | ||
| 1991/1012 | Qinfo *protocols[] = { &tcpinfo, &udpinfo, &ilinfo, 0 }; | |
| 1991/0424 | ||
| 1991/1114 | void | |
| 1991/1126 |
| |
| 1992/0626 | ipinitifc(Ipifc *ifc, Qinfo *stproto) | |
| 1991/1012 | { | |
| 1991/1114 | int j; | |
| 1991/0424 | ||
| 1991/1115 |
| |
| 1991/1114 |
| |
| 1991/1126 |
| |
| 1992/0623 |
| |
| 1991/1115 |
| |
| 1991/1126 |
| |
| 1992/0626 | ifc->conv = xalloc(Nipconv * sizeof(Ipconv*)); ifc->protop = stproto; ifc->nconv = Nipconv; ifc->devp = &ipinfo; | |
| 1991/1114 | if(stproto != &udpinfo) | |
| 1991/1126 |
| |
| 1992/0626 | ifc->listen = iplisten; ifc->clone = ipclonecon; ifc->ninfo = 3; ifc->info[0].name = "remote"; ifc->info[0].fill = ipremotefill; ifc->info[1].name = "local"; ifc->info[1].fill = iplocalfill; ifc->info[2].name = "status"; ifc->info[2].fill = ipstatusfill; ifc->name = stproto->name; | |
| 1991/1114 | } | |
| 1991/0424 | void ipreset(void) { | |
| 1991/1114 |
| |
| 1992/0626 | int i; | |
| 1991/0424 | ||
| 1992/0622 |
| |
| 1991/0424 | ||
| 1991/1012 | for(i = 0; protocols[i]; i++) { | |
| 1992/0622 |
| |
| 1991/1126 |
| |
| 1992/0626 | ipifc[i] = xalloc(sizeof(Ipifc)); ipinitifc(ipifc[i], protocols[i]); | |
| 1991/0424 | newqinfo(protocols[i]); } | |
| 1992/0626 | initfrag(Nfrag); | |
| 1991/0424 | } void | |
| 1992/0625/sys/src/9/port/devip.c:114,153 – 1992/0626/sys/src/9/port/devip.c:107,185 | ||
| 1991/0424 | int ipwalk(Chan *c, char *name) { | |
| 1991/1126 |
| |
| 1992/0626 | return netwalk(c, name, ipifc[c->dev]); | |
| 1991/0424 | } void ipstat(Chan *c, char *db) { | |
| 1991/1126 |
| |
| 1992/0626 | netstat(c, db, ipifc[c->dev]); | |
| 1991/0424 | } Chan * ipopen(Chan *c, int omode) { | |
| 1991/1126 |
| |
| 1992/0626 | return netopen(c, omode, ipifc[c->dev]); | |
| 1991/0424 | } | |
| 1991/1114 | int | |
| 1991/0424 | ipclonecon(Chan *c) { | |
| 1991/1108 |
| |
| 1992/0626 | Ipconv *new; | |
| 1991/0424 |
| |
| 1991/1115 |
| |
| 1992/0626 | new = ipincoming(ipifc[c->dev], 0); | |
| 1991/1108 | if(new == 0) error(Enodev); | |
| 1991/1114 |
| |
| 1992/0626 | return new->id; | |
| 1991/1023 | } | |
| 1991/1115 |
| |
| 1992/0626 | /* * create a new conversation structure if none exists for this conversation slot */ Ipconv* ipcreateconv(Ipifc *ifc, int id) | |
| 1991/1023 | { | |
| 1991/1024 |
| |
| 1992/0626 | Ipconv **p; Ipconv *new; | |
| 1991/1023 |
| |
| 1992/0626 | p = &ifc->conv[id]; if(*p) return *p; qlock(ifc); p = &ifc->conv[id]; if(*p){ qunlock(ifc); return *p; } if(waserror()){ qunlock(ifc); nexterror(); } new = smalloc(sizeof(Ipconv)); new->ifc = ifc; netadd(ifc, new, p - ifc->conv); new->ref = 1; *p = new; qunlock(ifc); poperror(); return new; } /* * allocate a conversation structure. */ Ipconv* ipincoming(Ipifc *ifc, Ipconv *from) { Ipconv **p, **etab; Ipconv *new; /* look for an unused existing conversation */ etab = &ifc->conv[Nipconv]; for(p = ifc->conv; p < etab; p++) { new = *p; if(new == 0) break; | |
| 1991/0424 | if(new->ref == 0 && canqlock(new)) { | |
| 1992/0313 | if(new->ref || ipconbusy(new)) { | |
| 1991/0424 | qunlock(new); | |
| 1992/0625/sys/src/9/port/devip.c:163,169 – 1992/0626/sys/src/9/port/devip.c:195,229 | ||
| 1991/0424 | return new; } } | |
| 1991/1023 |
| |
| 1992/0626 | /* create one */ qlock(ifc); etab = &ifc->conv[Nipconv]; for(p = ifc->conv; ; p++){ if(p == etab){ qunlock(ifc); return 0; } if(*p == 0) break; } if(waserror()){ qunlock(ifc); nexterror(); } new = smalloc(sizeof(Ipconv)); new->ifc = ifc; netadd(ifc, new, p - ifc->conv); qlock(new); *p = new; qunlock(ifc); if(from) /* copy ownership from listening channel */ netown(new, from->owner, 0); else /* current user becomes owner */ netown(new, u->p->user, 0); new->ref = 1; qunlock(new); return new; | |
| 1991/0424 | } void | |
| 1992/0625/sys/src/9/port/devip.c:183,189 – 1992/0626/sys/src/9/port/devip.c:243,249 | ||
| 1991/0424 | void ipwstat(Chan *c, char *dp) { | |
| 1991/1126 |
| |
| 1992/0626 | netwstat(c, dp, ipifc[c->dev]); | |
| 1991/0424 | } void | |
| 1992/0625/sys/src/9/port/devip.c:196,202 – 1992/0626/sys/src/9/port/devip.c:256,262 | ||
| 1991/0424 | long ipread(Chan *c, void *a, long n, ulong offset) { | |
| 1991/1126 |
| |
| 1992/0626 | return netread(c, a, n, offset, ipifc[c->dev]); | |
| 1991/0424 | } long | |
| 1992/0625/sys/src/9/port/devip.c:214,220 – 1992/0626/sys/src/9/port/devip.c:274,280 | ||
| 1991/1024 | if (type != Sctlqid) error(Eperm); | |
| 1991/0424 | ||
| 1991/1024 |
| |
| 1992/0626 | cp = ipcreateconv(ipifc[c->dev], STREAMID(c->qid.path)); | |
| 1991/0424 | ||
| 1991/1024 | m = n; if(m > sizeof(buf)-1) | |
| 1992/0625/sys/src/9/port/devip.c:251,263 – 1992/0626/sys/src/9/port/devip.c:311,323 | ||
| 1991/1024 | /* If we have no local port assign one */ | |
| 1992/0416 | if(cp->psrc == 0){ qlock(&ipalloc); | |
| 1992/0128 |
| |
| 1992/0626 | cp->psrc = nextport(ipifc[c->dev], priv); | |
| 1992/0416 | qunlock(&ipalloc); } | |
| 1991/0424 | ||
| 1991/1114 |
| |
| 1992/0626 | if(cp->ifc->protop == &tcpinfo) | |
| 1991/1114 | tcpstart(cp, TCP_ACTIVE, Streamhi, 0); | |
| 1992/0626 | else if(cp->ifc->protop == &ilinfo) | |
| 1991/1124 | ilstart(cp, IL_ACTIVE, 20); | |
| 1991/1114 | ||
| 1992/0529 | /* | |
| 1992/0625/sys/src/9/port/devip.c:274,280 – 1992/0626/sys/src/9/port/devip.c:334,340 | ||
| 1992/0529 | } | |
| 1991/1024 | } | |
| 1991/1125 | else if(strcmp(field[0], "disconnect") == 0) { | |
| 1992/0626 | if(cp->ifc->protop != &udpinfo) | |
| 1991/1125 | error(Eperm); cp->dst = 0; | |
| 1992/0625/sys/src/9/port/devip.c:291,297 – 1992/0626/sys/src/9/port/devip.c:351,357 | ||
| 1991/1024 | ||
| 1992/0416 | if(port){ qlock(&ipalloc); | |
| 1992/0626 | if(portused(ipifc[c->dev], port)) { | |
| 1992/0416 | qunlock(&ipalloc); error(Einuse); } | |
| 1992/0625/sys/src/9/port/devip.c:299,312 – 1992/0626/sys/src/9/port/devip.c:359,372 | ||
| 1992/0416 | qunlock(&ipalloc); } else if(*field[1] != '*'){ qlock(&ipalloc); | |
| 1992/0626 | cp->psrc = nextport(ipifc[c->dev], 0); | |
| 1992/0416 | qunlock(&ipalloc); } else cp->psrc = 0; | |
| 1991/1114 |
| |
| 1992/0626 | if(cp->ifc->protop == &tcpinfo) | |
| 1991/1114 | tcpstart(cp, TCP_PASSIVE, Streamhi, 0); | |
| 1992/0626 | else if(cp->ifc->protop == &ilinfo) | |
| 1991/1114 | ilstart(cp, IL_PASSIVE, 10); if(cp->backlog == 0) | |
| 1992/0625/sys/src/9/port/devip.c:331,341 – 1992/0626/sys/src/9/port/devip.c:391,401 | ||
| 1992/0313 | int ipconbusy(Ipconv *cp) { | |
| 1992/0626 | if(cp->ifc->protop == &tcpinfo) | |
| 1992/0313 | if(cp->tcpctl.state != Closed) return 1; | |
| 1991/0424 | ||
| 1992/0313 |
| |
| 1992/0626 | if(cp->ifc->protop == &ilinfo) | |
| 1992/0313 | if(cp->ilctl.state != Ilclosed) return 1; | |
| 1992/0625/sys/src/9/port/devip.c:352,360 – 1992/0626/sys/src/9/port/devip.c:412,420 | ||
| 1991/0424 | * udprcvmsg - called by stip to multiplex udp ports onto conversations */ void | |
| 1992/0626 | udprcvmsg(Ipifc *ifc, Block *bp) | |
| 1991/0424 | { | |
| 1992/0626 | Ipconv *cp, **p, **etab; | |
| 1991/0424 | Udphdr *uh; | |
| 1991/1125 | Port dport, sport; | |
| 1991/0424 | ushort sum, len; | |
| 1992/0625/sys/src/9/port/devip.c:383,393 – 1992/0626/sys/src/9/port/devip.c:443,456 | ||
| 1991/1125 | sport = nhgets(uh->udpsport); | |
| 1991/0424 | /* Look for a conversation structure for this port */ | |
| 1992/0313 |
| |
| 1992/0626 | etab = &ifc->conv[Nipconv]; for(p = ifc->conv; p < etab; p++) { cp = *p; if(cp == 0) break; if(cp->ref) if(cp->psrc == dport) if(cp->pdst == 0 || cp->pdst == sport) { | |
| 1991/0424 | /* Trim the packet down to data size */ len = len - (UDP_HDRSIZE-UDP_PHDRSIZE); bp = btrim(bp, UDP_EHSIZE+UDP_HDRSIZE, len); | |
| 1992/0625/sys/src/9/port/devip.c:395,403 – 1992/0626/sys/src/9/port/devip.c:458,466 | ||
| 1991/0424 | return; /* Stuff the src address into the remote file */ | |
| 1991/1125 |
| |
| 1991/0424 |
| |
| 1992/0626 | cp->dst = addr; cp->pdst = sport; PUTNEXT(cp->readq, bp); | |
| 1991/0424 | return; } } | |
| 1992/0625/sys/src/9/port/devip.c:476,483 – 1992/0626/sys/src/9/port/devip.c:539,544 | ||
| 1991/1114 | ipc->psrc = 0; ipc->pdst = 0; ipc->dst = 0; | |
| 1991/0424 |
| |
| 1992/0625/sys/src/9/port/devip.c:485,497 – 1992/0626/sys/src/9/port/devip.c:546,557 | ||
| 1991/0424 | { Ipconv *ipc; | |
| 1992/0626 | ipc = ipcreateconv(ipifc[s->dev], s->id); initipifc(ipifc[s->dev], IP_UDPPROTO, udprcvmsg, 1500, 512, ETHER_HDR, "UDP"); | |
| 1991/0424 | ipc->readq = RD(q); RD(q)->ptr = (void *)ipc; | |
| 1992/0626 | WR(q)->next->ptr = (void *)ipc->ifc; | |
| 1991/0424 | WR(q)->ptr = (void *)ipc; } | |
| 1992/0625/sys/src/9/port/devip.c:564,569 – 1992/0626/sys/src/9/port/devip.c:624,630 | ||
| 1991/0424 | tcpstopen(Queue *q, Stream *s) { Ipconv *ipc; | |
| 1992/0626 | Ipifc *ifc; | |
| 1992/0416 | Tcpctl *tcb; Block *bp; | |
| 1991/1019 | static int tcpkprocs; | |
| 1992/0625/sys/src/9/port/devip.c:578,592 – 1992/0626/sys/src/9/port/devip.c:639,653 | ||
| 1991/1019 | if(tcpkprocs == 0) { tcpkprocs = 1; | |
| 1991/0424 | kproc("tcpack", tcpackproc, 0); | |
| 1992/0626 | kproc("tcpflow", tcpflow, ipifc[s->dev]); | |
| 1991/0430 | ||
| 1991/0424 | } | |
| 1992/0416 | if(tcpbase == 0) | |
| 1991/0424 |
| |
| 1992/0626 | tcpbase = ipifc[s->dev]->conv; ifc = ipifc[s->dev]; initipifc(ifc, IP_TCPPROTO, tcp_input, 1500, 512, ETHER_HDR, "TCP"); ipc = ipcreateconv(ifc, s->id); | |
| 1991/0424 | ipc->readq = RD(q); ipc->readq->rp = &tcpflowr; | |
| 1992/0625/sys/src/9/port/devip.c:593,599 – 1992/0626/sys/src/9/port/devip.c:654,660 | ||
| 1992/0128 | ipc->err = 0; | |
| 1991/0424 | RD(q)->ptr = (void *)ipc; | |
| 1992/0626 | WR(q)->next->ptr = (void *)ipc->ifc; | |
| 1991/0424 | WR(q)->ptr = (void *)ipc; | |
| 1992/0416 | /* pass any waiting data upstream */ | |
| 1992/0625/sys/src/9/port/devip.c:607,617 – 1992/0626/sys/src/9/port/devip.c:668,676 | ||
| 1991/1114 | void ipremotefill(Chan *c, char *buf, int len) { | |
| 1992/0626 | cp = ipcreateconv(ipifc[c->dev], STREAMID(c->qid.path)); | |
| 1991/1114 | sprint(buf, "%d.%d.%d.%d %d\n", fmtaddr(cp->dst), cp->pdst); } | |
| 1991/1124 | ||
| 1992/0625/sys/src/9/port/devip.c:618,628 – 1992/0626/sys/src/9/port/devip.c:677,685 | ||
| 1991/1114 | void iplocalfill(Chan *c, char *buf, int len) { | |
| 1992/0626 | cp = ipcreateconv(ipifc[c->dev], STREAMID(c->qid.path)); | |
| 1992/0213 | sprint(buf, "%d.%d.%d.%d %d\n", fmtaddr(Myip[Myself]), cp->psrc); | |
| 1991/1114 | } | |
| 1991/1124 | ||
| 1992/0625/sys/src/9/port/devip.c:633,649 – 1992/0626/sys/src/9/port/devip.c:690,706 | ||
| 1991/1114 | Ipconv *cp; connection = STREAMID(c->qid.path); | |
| 1992/0626 | cp = ipcreateconv(ipifc[c->dev], connection); if(cp->ifc->protop == &tcpinfo) | |
| 1991/1114 | sprint(buf, "tcp/%d %d %s %s\n", connection, cp->ref, tcpstate[cp->tcpctl.state], cp->tcpctl.flags & CLONE ? "listen" : "connect"); | |
| 1992/0626 | else if(cp->ifc->protop == &ilinfo) | |
| 1992/0307 | sprint(buf, "il/%d %d %s rtt %d ms %d csum\n", connection, cp->ref, ilstate[cp->ilctl.state], cp->ilctl.rtt, | |
| 1992/0626 | cp->ifc ? cp->ifc->chkerrs : 0); | |
| 1991/1114 | else | |
| 1992/0626 | sprint(buf, "%s/%d %d\n", cp->ifc->protop->name, connection, cp->ref); | |
| 1991/1114 | } | |
| 1991/0424 | int | |
| 1992/0625/sys/src/9/port/devip.c:655,674 – 1992/0626/sys/src/9/port/devip.c:712,730 | ||
| 1991/1114 | int iplisten(Chan *c) | |
| 1991/0424 | { | |
| 1991/1114 |
| |
| 1992/0626 | Ipconv **p, **etab, *new; Ipconv *s; | |
| 1991/1114 | int connection; Ipconv *cp; | |
| 1991/0424 | ||
| 1991/1114 | connection = STREAMID(c->qid.path); | |
| 1992/0626 | s = ipcreateconv(ipifc[c->dev], connection); | |
| 1991/1114 | ||
| 1992/0313 |
| |
| 1992/0626 | if(s->ifc->protop == &tcpinfo) | |
| 1992/0313 | if(s->tcpctl.state != Listen) | |
| 1992/0112 | error(Enolisten); | |
| 1991/1114 | ||
| 1992/0313 |
| |
| 1992/0626 | if(s->ifc->protop == &ilinfo) | |
| 1992/0313 | if(s->ilctl.state != Illistening) error(Enolisten); | |
| 1992/0625/sys/src/9/port/devip.c:680,687 – 1992/0626/sys/src/9/port/devip.c:736,746 | ||
| 1992/0414 | } | |
| 1991/1023 | sleep(&s->listenr, iphavecon, s); | |
| 1991/1025 | poperror(); | |
| 1991/1023 |
| |
| 1992/0626 | etab = &ipifc[c->dev]->conv[Nipconv]; for(p = ipifc[c->dev]->conv; p < etab; p++) { new = *p; if(new == 0) break; | |
| 1992/0414 | if(new->newcon == s) { | |
| 1992/0306 | qlock(s); | |
| 1991/0424 | s->curlog--; | |
| 1992/0625/sys/src/9/port/devip.c:688,694 – 1992/0626/sys/src/9/port/devip.c:747,753 | ||
| 1992/0306 | qunlock(s); | |
| 1991/1023 | new->newcon = 0; | |
| 1991/0424 | qunlock(&s->listenq); | |
| 1991/1114 |
| |
| 1992/0626 | return new->id; | |
| 1991/0424 | } } | |
| 1992/0414 | qunlock(&s->listenq); | |
| 1992/0625/sys/src/9/port/devip.c:701,707 – 1992/0626/sys/src/9/port/devip.c:760,766 | ||
| 1991/0424 | tcpstclose(Queue *q) { Ipconv *s; | |
| 1992/0416 |
| |
| 1992/0626 | Ipconv **etab, **p; | |
| 1991/0424 | Tcpctl *tcb; s = (Ipconv *)(q->ptr); | |
| 1992/0625/sys/src/9/port/devip.c:720,730 – 1992/0626/sys/src/9/port/devip.c:779,789 | ||
| 1992/0416 | qlock(s); s->backlog = 0; s->curlog = 0; | |
| 1992/0626 | etab = &tcpbase[Nipconv]; for(p = tcpbase; p < etab && *p; p++){ if((*p)->newcon == s) { (*p)->newcon = 0; tcpflushincoming(*p); | |
| 1992/0416 | } } qunlock(s); | |
| 1992/0625/sys/src/9/port/devip.c:921,937 – 1992/0626/sys/src/9/port/devip.c:980,1001 | ||
| 1991/0424 | } Ipconv * | |
| 1992/0626 | portused(Ipifc *ifc, Port port) | |
| 1991/0424 | { | |
| 1992/0626 | Ipconv **p, **etab; Ipconv *cp; | |
| 1991/0424 | ||
| 1992/0406 | if(port == 0) return 0; | |
| 1991/0424 |
| |
| 1991/12171 |
| |
| 1991/0424 |
| |
| 1992/0626 | etab = &ifc->conv[Nipconv]; for(p = ifc->conv; p < etab; p++){ cp = *p; if(cp == 0) break; if(cp->psrc == port) return cp; } | |
| 1991/0424 | return 0; } | |
| 1992/0625/sys/src/9/port/devip.c:939,945 – 1992/0626/sys/src/9/port/devip.c:1003,1009 | ||
| 1992/0128 | static Port lastport[2] = { PORTALLOC-1, PRIVPORTALLOC-1 }; | |
| 1991/0424 | Port | |
| 1992/0128 |
| |
| 1992/0626 | nextport(Ipifc *ifc, int priv) | |
| 1991/0424 | { | |
| 1992/0128 | Port base; Port max; | |
| 1992/0625/sys/src/9/port/devip.c:957,966 – 1992/0626/sys/src/9/port/devip.c:1021,1030 | ||
| 1992/0128 | } for(i = *p + 1; i < max; i++) | |
| 1991/0424 |
| |
| 1992/0626 | if(!portused(ifc, i)) | |
| 1992/0128 | return(*p = i); for(i = base ; i <= *p; i++) | |
| 1992/0626 | if(!portused(ifc, i)) | |
| 1992/0128 | return(*p = i); | |
| 1991/12171 | ||
| 1991/0424 | return(0); | |
| 1992/0625/sys/src/9/port/devip.c:968,981 – 1992/0626/sys/src/9/port/devip.c:1032,1048 | ||
| 1991/0424 | /* NEEDS HASHING ! */ | |
| 1992/0626 | Ipconv* ip_conn(Ipifc *ifc, Port dst, Port src, Ipaddr dest, char proto) | |
| 1991/0424 | { | |
| 1992/0626 | Ipconv **p, *s, **etab; | |
| 1991/0424 | /* Look for a conversation structure for this port */ | |
| 1992/0626 | etab = &ifc->conv[Nipconv]; for(p = ifc->conv; p < etab; p++) { s = *p; if(s == 0) break; | |
| 1991/12171 | if(s->psrc == dst) if(s->pdst == src) if(s->dst == dest || dest == 0) | |