~kris/9p

9hist

07f3dd072d551a5840a1e365c20c93690fdda7f6 — David du Colombier 34 years ago 30fe961
Plan 9 from Bell Labs 1991-10-12
4 files changed, 197 insertions(+), 27 deletions(-)

M port/devip.c
M port/ipdat.h
A port/stil.c
M port/stream.c
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)