M port/devip.c => port/devip.c +15 -6
@@ 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]);
M port/ipdat.h => port/ipdat.h +87 -21
@@ 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;
A port/stil.c => port/stil.c +92 -0
@@ 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)
+{
+}
M port/stream.c => port/stream.c +3 -0
@@ 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)