From 07f3dd072d551a5840a1e365c20c93690fdda7f6 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 12 Oct 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-10-12 --- port/devip.c | 21 +++++++--- port/ipdat.h | 108 ++++++++++++++++++++++++++++++++++++++++---------- port/stil.c | 92 ++++++++++++++++++++++++++++++++++++++++++ port/stream.c | 3 ++ 4 files changed, 197 insertions(+), 27 deletions(-) create mode 100644 port/stil.c diff --git a/port/devip.c b/port/devip.c index b212e233d8c7b18bbc5020654fd5c3188bc49d50..8a9806ccf94107e0549253e4bb107d49082b1fbc 100644 --- a/port/devip.c +++ b/port/devip.c @@ -9,9 +9,11 @@ #include "devtab.h" -enum{ - Nrprotocol = 2, /* Number of protocols supported by this driver */ - Nipsubdir = 4, /* Number of subdirectory entries per connection */ + +enum +{ + Nrprotocol = 3, /* Number of protocols supported by this driver */ + Nipsubdir = 4, /* Number of subdirectory entries per connection */ }; int udpsum = 1; @@ -32,13 +34,20 @@ void tcpstiput(Queue *, Block *); void tcpstoput(Queue *, Block *); void tcpstopen(Queue *, Stream *); void tcpstclose(Queue *); +/* Plan9 Reliable Datagram Protocol */ +void iliput(Queue *, Block *); +void iloput(Queue *, Block *); +void ilopen(Queue *, Stream *); +void ilclose(Queue *); Qinfo tcpinfo = { tcpstiput, tcpstoput, tcpstopen, tcpstclose, "tcp" }; Qinfo udpinfo = { udpstiput, udpstoput, udpstopen, udpstclose, "udp" }; +Qinfo ilinfo = { iliput, iloput, ilopen, ilclose, "il" }; -Qinfo *protocols[] = { &tcpinfo, &udpinfo, 0 }; +Qinfo *protocols[] = { &tcpinfo, &udpinfo, &ilinfo, 0 }; -enum{ +enum +{ ipdirqid, iplistenqid, iplportqid, @@ -63,7 +72,7 @@ ipreset(void) ipifc = (Ipifc *)ialloc(sizeof(Ipifc) * conf.ip, 0); - for(i = 0; i < Nrprotocol; i++) { + for(i = 0; protocols[i]; i++) { ipconv[i] = (Ipconv *)ialloc(sizeof(Ipconv) * conf.ip, 0); ipdir[i] = (Dirtab *)ialloc(sizeof(Dirtab) * (conf.ip+1), 0); ipmkdir(protocols[i], ipdir[i], ipconv[i]); diff --git a/port/ipdat.h b/port/ipdat.h index 92f9da266ad33d16fbdbc8a9a956722f662355e1..3a2ba84f28541407d6e2b0850221713564c94f74 100644 --- a/port/ipdat.h +++ b/port/ipdat.h @@ -12,8 +12,11 @@ typedef struct Tcp Tcp; typedef struct Tcpctl Tcpctl; typedef struct Tcphdr Tcphdr; typedef struct Timer Timer; +typedef struct Ilhdr Ilhdr; +typedef struct Ilcb Ilcb; -struct Etherhdr { +struct Etherhdr +{ #define ETHER_HDR 14 uchar d[6]; uchar s[6]; @@ -37,7 +40,8 @@ struct Etherhdr { #define ET_IP 0x0800 /* A userlevel data gram */ -struct Udphdr { +struct Udphdr +{ #define UDP_EHSIZE 22 uchar d[6]; /* Ethernet destination */ uchar s[6]; /* Ethernet source */ @@ -62,9 +66,54 @@ struct Udphdr { uchar udpcksum[2]; /* Checksum */ }; +struct Ilhdr +{ +#define IL_EHSIZE 22 + uchar d[6]; /* Ethernet destination */ + uchar s[6]; /* Ethernet source */ + uchar type[2]; /* Ethernet packet type */ + uchar vihl; /* Version and header length */ + uchar tos; /* Type of service */ + uchar length[2]; /* packet length */ + uchar id[2]; /* Identification */ + uchar frag[2]; /* Fragment information */ +#define IL_HDRSIZE 16 + uchar ilsum[2]; /* Checksum including header */ + uchar illen[2]; /* Packet length */ + uchar iltype; /* Packet type */ + uchar ilspec; /* Special */ + uchar ilsrc[2]; /* Src port */ + uchar ildst[2]; /* Dst port */ + uchar ilid[4]; /* Sequence id */ + uchar ilack[4]; /* Acked sequence */ +}; + +struct Ilcb +{ + int state; + Block *unacked; + Block *unackedtail; + Block *outoforder; + Block *outofordertail; + ulong sent; + ulong recvd; + ulong lastack; +}; + +enum +{ + Ilsync, + Ildata, + Ildataquery, + Ilack, + Ilquerey, + Ilstate, +}; + #define TCP_PKT (TCP_EHSIZE+TCP_IPLEN+TCP_PHDRSIZE) -struct Tcphdr { +struct Tcphdr +{ #define TCP_EHSIZE 14 uchar d[6]; /* Ethernet destination */ uchar s[6]; /* Ethernet source */ @@ -96,11 +145,12 @@ struct Tcphdr { /* Options segment */ uchar tcpopt[2]; uchar tcpmss[2]; - }; +}; -struct Timer { +struct Timer +{ Timer *next; Timer *prev; int state; @@ -108,9 +158,10 @@ struct Timer { int count; void (*func)(void*); void *arg; - }; +}; -struct Tcpctl { +struct Tcpctl +{ QLock; uchar state; /* Connection state */ uchar type; /* Listening or active connection */ @@ -166,7 +217,8 @@ struct Tcpctl { int mdev; /* Mean deviation of round trip */ }; -struct Tcp { +struct Tcp +{ Port source; Port dest; int seq; @@ -175,18 +227,20 @@ struct Tcp { ushort wnd; ushort up; ushort mss; - }; +}; -struct Reseq { +struct Reseq +{ Reseq *next; Tcp seg; Block *bp; ushort length; char tos; - }; +}; /* An ip interface used for UDP/TCP/ARP/ICMP */ -struct Ipconv { +struct Ipconv +{ QLock; /* Ref count lock */ int ref; Qinfo *stproto; /* Stream protocol for this device */ @@ -207,7 +261,10 @@ struct Ipconv { int backlog; /* Maximum number of waiting connections */ int curlog; /* Number of waiting connections */ int contype; - Tcpctl tcpctl; /* Tcp control block */ + union { + Tcpctl tcpctl; /* Tcp control block */ + Ilcb ilctl; /* Il control block */ + }; }; #define MAX_TIME 100000000 /* Forever */ @@ -255,7 +312,8 @@ struct Ipconv { #define read_timer(t) ((t)->count) #define run_timer(t) ((t)->state == TIMER_RUN) -enum { +enum +{ CLOSED = 0, LISTEN, SYN_SENT, @@ -267,12 +325,13 @@ enum { CLOSING, LAST_ACK, TIME_WAIT - }; +}; /* * Ip interface structure. We have one for each active protocol driver */ -struct Ipifc { +struct Ipifc +{ QLock; int ref; uchar protocol; /* Ip header protocol number */ @@ -285,21 +344,24 @@ struct Ipifc { Lock; }; -struct Fragq { +struct Fragq +{ QLock; Block *blist; Fragq *next; Ipaddr src; Ipaddr dst; ushort id; - }; +}; -struct Ipfrag { +struct Ipfrag +{ ushort foff; ushort flen; - }; +}; -struct Arpcache { +struct Arpcache +{ uchar status; /* Entry status */ uchar type; /* Entry type */ Ipaddr ip; /* Host byte order */ @@ -311,6 +373,7 @@ struct Arpcache { Arpcache *frwd; Arpcache *prev; }; + #define ARP_FREE 0 #define ARP_OK 1 #define ARP_ASKED 2 @@ -341,10 +404,12 @@ struct Arpcache { #define IP_MAX 8192 /* Maximum Internet packet size */ #define UDP_MAX (IP_MAX-ETHER_IPHDR) /* Maximum UDP datagram size */ #define UDP_DATMAX (UDP_MAX-UDP_HDRSIZE) /* Maximum amount of udp data */ +#define IL_DATMAX (IP_MAX-IL_HDRSIZE) /* Maximum IL data in one ip packet */ /* Protocol numbers */ #define IP_UDPPROTO 17 #define IP_TCPPROTO 6 +#define IP_ILPROTO 190 /* I have no idea */ /* Protocol port numbers */ #define PORTALLOC 5000 /* First automatic allocated port */ @@ -440,3 +505,4 @@ extern Rendez tcpflowr; extern Qinfo tcpinfo; extern Qinfo ipinfo; extern Qinfo udpinfo; +extern Qinfo ilinfo; diff --git a/port/stil.c b/port/stil.c new file mode 100644 index 0000000000000000000000000000000000000000..cf367999bd7dee3a8f8da7e72ec0bcf53fec7e27 --- /dev/null +++ b/port/stil.c @@ -0,0 +1,92 @@ +/* + * stil - Internet link protocol + */ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "errno.h" +#include "arp.h" +#include "ipdat.h" + +#define DPRINT if(pip)print + +void ilrcvmsg(Ipconv *, Block *); + +void +ilopen(Queue *q, Stream *s) +{ + Ipconv *ipc; + + ipc = &ipconv[s->dev][s->id]; + ipc->ipinterface = newipifc(IP_ILPROTO, ilrcvmsg, ipconv[s->dev], + 1500, 512, ETHER_HDR, "IL"); + + qlock(ipc); + ipc->ref++; + qunlock(ipc); + ipc->readq = RD(q); + RD(q)->ptr = (void *)ipc; + WR(q)->next->ptr = (void *)ipc->ipinterface; + WR(q)->ptr = (void *)ipc; +} + +void +ilclose(Queue *q) +{ +} + +void +iloput(Queue *q, Block *bp) +{ + Ipconv *ipc; + Ilhdr *ih; + int dlen; + + /* Prepend udp header to packet and pass on to ip layer */ + ipc = (Ipconv *)(q->ptr); + if(ipc->psrc == 0) + error(Enoport); + + if(bp->type != M_DATA) { + freeb(bp); + error(Ebadctl); + } + + /* Only allow atomic Il writes to form datagrams */ + if(!(bp->flags & S_DELIM)) { + freeb(bp); + error(Emsgsize); + } + + dlen = blen(bp); + if(dlen > IL_DATMAX) { + freeb(bp); + error(Emsgsize); + } + + /* Make space to fit il & ip & ethernet header */ + bp = padb(bp, IL_EHSIZE+IL_HDRSIZE); + + ih = (Ilhdr *)(bp->rptr); + + hnputs(ih->illen, dlen+IL_EHSIZE+IL_HDRSIZE); + hnputs(ih->ilsrc, ipc->psrc); + hnputs(ih->ildst, ipc->pdst); + ih->iltype = Ildata; + ih->ilspec = 0; + hnputl(ih->ilid, ipc->ilctl.sent++); + hnputl(ih->ilack, ipc->ilctl.recvd); + ih->ilsum[0] = 0; + ih->ilsum[1] = 0; + + PUTNEXT(q, bp); +} + + +void +iliput(Queue *q, Block *bp) +{ +} diff --git a/port/stream.c b/port/stream.c index 8381bc5d249a1e9bfa0177a557f7f04ac09621cc..c90bda25537401e01cd0b31757ec2273b5bfbf7c 100644 --- a/port/stream.c +++ b/port/stream.c @@ -94,6 +94,9 @@ streaminit(void) void newqinfo(Qinfo *qi) { + if(qi->next) + panic("newqinfo: already configured"); + qi->next = lds; lds = qi; if(qi->reset)