@@ 9,7 9,6 @@
#include "devtab.h"
-
enum
{
Nrprotocol = 3, /* Number of protocols supported by this driver */
@@ 605,7 604,6 @@ void
tcpstopen(Queue *q, Stream *s)
{
Ipconv *ipc;
- static int donekproc;
/* Start tcp service processes */
if(!Tcpoutput) {
@@ 719,7 717,7 @@ tcpstclose(Queue *q)
/*
- * ptcl_csum - protcol cecksum routine
+ * ptcl_csum - protcol checksum routine
*/
ushort
ptcl_csum(Block *bp, int offset, int len)
@@ 858,4 856,3 @@ ip_conn(Ipconv *ic, Port dst, Port src, Ipaddr dest, char proto)
return 0;
}
-
@@ 12,14 12,26 @@
#include "ipdat.h"
#define DPRINT if(pip)print
+int ilcksum = 1;
+Queue *Iloutput; /* Il to lance output channel */
-void ilrcvmsg(Ipconv *, Block *);
+void ilrcvmsg(Ipconv*, Block*);
+void ilackproc(void*);
void
ilopen(Queue *q, Stream *s)
{
Ipconv *ipc;
+ /* Start il service processes */
+ if(!Iloutput) {
+ Iloutput = WR(q);
+ /* This never goes away - we use this queue to send acks/rejects */
+ s->opens++;
+ s->inuse++;
+ kproc("ilack", ilackproc, 0);
+ }
+
ipc = &ipconv[s->dev][s->id];
ipc->ipinterface = newipifc(IP_ILPROTO, ilrcvmsg, ipconv[s->dev],
1500, 512, ETHER_HDR, "IL");
@@ 43,7 55,9 @@ iloput(Queue *q, Block *bp)
{
Ipconv *ipc;
Ilhdr *ih;
+ Ilcb *ic;
int dlen;
+ Block *np;
/* Prepend udp header to packet and pass on to ip layer */
ipc = (Ipconv *)(q->ptr);
@@ 71,22 85,115 @@ iloput(Queue *q, Block *bp)
bp = padb(bp, IL_EHSIZE+IL_HDRSIZE);
ih = (Ilhdr *)(bp->rptr);
+ ic = &ipc->ilctl;
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);
+ hnputl(ih->ilid, ic->sent++);
+ hnputl(ih->ilack, ic->recvd);
ih->ilsum[0] = 0;
ih->ilsum[1] = 0;
+ /* Checksum of ilheader plus data (not ip & no pseudo header) */
+ if(ilcksum)
+ hnputs(ih->ilsum, ptcl_csum(bp, IL_EHSIZE, dlen+IL_HDRSIZE));
+
+ /* Enqueue a copy on the unacked queue in case this one gets lost */
+ np = copyb(bp, blen(bp));
+ if(ic->unacked) {
+ ic->unackedtail->next = np;
+ ic->unackedtail = np;
+ }
+ else {
+ ic->unacked = np;
+ ic->unackedtail = np;
+ }
+ np->next = 0;
+
PUTNEXT(q, bp);
}
-
void
iliput(Queue *q, Block *bp)
{
+ PUTNEXT(q, bp);
+}
+
+void
+ilrcvmsg(Ipconv *ipc, Block *bp)
+{
+ Ilhdr *ih;
+
+ ih = (Ilhdr *)bp;
+
+ plen = blen(bp);
+ if(plen < IL_EHSIZE+IL_HDRSIZE)
+ goto drop;
+
+ if(ilcksum && ptcl_csum(bp, IL_EHSIZE, plen) != 0) {
+ print("il: cksum error\n");
+ goto drop;
+ }
+
+ s = ip_conn(ipc, hngets(ih->ildst), hngets(ih->ilsrc), hngetl(), IP_ILPROTO);
+ if(s == 0) {
+ ilsentctl(0, ih, Ilreset);
+ goto drop;
+ }
+
+ switch(s->state) {
+ case Closed:
+ ilsentctl(0, ih, Ilreset);
+ goto drop;
+ case Syncee:
+ case Syncer:
+ case Established:
+ case Closing:
+ }
+
+drop:
+ freeb(bp);
+}
+
+void
+ilsendctl(Ipconv *ipc, Ilhdr *inih, int type)
+{
+ Ilhdr *ih;
+ Ilcb *ic;
+ Block *bp;
+
+ bp = allocb(IL_EHSIZE+IL_HDRSIZE);
+ ih = (Ilhdr *)(bp->rptr);
+ ic = &ipc->ilctl;
+
+ hnputs(ih->illen, IL_EHSIZE+IL_HDRSIZE);
+ if(inih) {
+ hnputs(ih->ilsrc, inih->ildst);
+ hnputs(ih->ildst, inih->ilsrc);
+ hnputl(ih->ilid, inih->recvd);
+ hnputl(ih->ilack, inih->sent);
+ }
+ else {
+ hnputs(ih->ilsrc, ipc->psrc);
+ hnputs(ih->ildst, ipc->pdst);
+ hnputl(ih->ilid, ic->sent);
+ hnputl(ih->ilack, ic->recvd);
+ }
+ ih->iltype = type;
+ ih->ilspec = 0;
+ ih->ilsum[0] = 0;
+ ih->ilsum[1] = 0;
+
+ if(ilcksum)
+ hnputs(ih->ilsum, ptcl_csum(bp, IL_EHSIZE, IL_HDRSIZE));
+
+ PUTNEXT(Iloutput, bp);
+}
+
+void
+ilackproc(void *junk)
+{
}