plan 9 kernel history: overview | file list | diff list

1998/0306/ip/gre.c (diff list | history)

1997/0531/sys/src/9/ip/gre.c:23,421998/0306/sys/src/9/ip/gre.c:23,42 (short | long | prev | next)
1997/0327    
typedef struct GREhdr 
{ 
	/* ip header */ 
	byte	vihl;		/* Version and header length */ 
	byte	tos;		/* Type of service */ 
	byte	len[2];		/* packet length (including headers) */ 
	byte	id[2];		/* Identification */ 
	byte	frag[2];	/* Fragment information */ 
	byte	Unused;	 
	byte	proto;		/* Protocol */ 
	byte	cksum[2];	/* checksum */ 
	byte	src[4];		/* Ip source */ 
	byte	dst[4];		/* Ip destination */ 
1998/0306    
	uchar	vihl;		/* Version and header length */ 
	uchar	tos;		/* Type of service */ 
	uchar	len[2];		/* packet length (including headers) */ 
	uchar	id[2];		/* Identification */ 
	uchar	frag[2];	/* Fragment information */ 
	uchar	Unused;	 
	uchar	proto;		/* Protocol */ 
	uchar	cksum[2];	/* checksum */ 
	uchar	src[4];		/* Ip source */ 
	uchar	dst[4];		/* Ip destination */ 
1997/0327    
 
	/* gre header */ 
	byte	flags[2]; 
	byte	eproto[2];	/* encapsulation protocol */ 
1998/0306    
	uchar	flags[2]; 
	uchar	eproto[2];	/* encapsulation protocol */ 
1997/0327    
} GREhdr; 
 
	Proto	gre; 
1997/0531/sys/src/9/ip/gre.c:56,621998/0306/sys/src/9/ip/gre.c:56,62
1997/0327    
 
	/* make sure noone's already connected to this other sys */ 
	p = c->p; 
	lock(p); 
1998/0306    
	qlock(p); 
1997/0327    
	ecp = &p->conv[p->nc]; 
	for(cp = p->conv; cp < ecp; cp++){ 
		tc = *cp; 
1997/0531/sys/src/9/ip/gre.c:66,771998/0306/sys/src/9/ip/gre.c:66,77
1997/0327    
			continue; 
		if(tc->rport == c->rport && tc->raddr == c->raddr){ 
			err = "already connected to that addr/proto"; 
			c->rport = 0; 
			c->raddr = 0; 
1998/0306    
			ipmove(c->laddr, IPnoaddr); 
			ipmove(c->raddr, IPnoaddr); 
1997/0327    
			break; 
		} 
	} 
	unlock(p); 
1998/0306    
	qunlock(p); 
1997/0327    
 
1997/0403    
	if(err != nil) 
		return err; 
1997/0531/sys/src/9/ip/gre.c:81,911998/0306/sys/src/9/ip/gre.c:81,90
1997/0327    
} 
 
static int 
grestate(char **msg, Conv *c) 
1998/0306    
grestate(Conv *c, char *state, int n) 
1997/0327    
{ 
	USED(c); 
	*msg = "Datagram"; 
	return 1; 
1998/0306    
	return snprint(state, n, "%s", "Datagram"); 
1997/0327    
} 
 
static void 
1997/0531/sys/src/9/ip/gre.c:107,1141998/0306/sys/src/9/ip/gre.c:106,113
1997/0327    
	qclose(c->rq); 
	qclose(c->wq); 
	qclose(c->eq); 
	c->laddr = 0; 
	c->raddr = 0; 
1998/0306    
	ipmove(c->laddr, IPnoaddr); 
	ipmove(c->raddr, IPnoaddr); 
1997/0327    
	c->lport = 0; 
	c->rport = 0; 
 
1997/0531/sys/src/9/ip/gre.c:122,1281998/0306/sys/src/9/ip/gre.c:121,127
1997/0327    
{ 
	GREhdr *ghp; 
1997/0524    
	Block *bp; 
1997/0530    
	ulong raddr, laddr; 
1998/0306    
	uchar laddr[IPaddrlen], raddr[IPaddrlen]; 
1997/0327    
 
	USED(l); 
 
1997/0531/sys/src/9/ip/gre.c:142,1571998/0306/sys/src/9/ip/gre.c:141,157
1997/0327    
 
	ghp = (GREhdr *)(bp->rp); 
 
1997/0531    
	raddr = nhgetl(ghp->dst); 
	laddr = nhgetl(ghp->src); 
1997/0530    
	if(raddr == 0) 
		raddr = c->raddr; 
1997/0531    
	if(laddr == 0 || Mediaforme(ghp->src) <= 0) 
1997/0530    
		laddr = c->laddr; 
1998/0306    
	v4tov6(raddr, ghp->dst); 
	if(ipcmp(raddr, v4prefix) == 0) 
		memmove(ghp->dst, c->raddr + IPv4off, IPv4addrlen); 
	v4tov6(laddr, ghp->src); 
	if(ipcmp(laddr, v4prefix) == 0){ 
		if(ipcmp(c->laddr, IPnoaddr) == 0) 
			findlocalip(c->laddr, raddr); /* pick interface closest to dest */ 
		memmove(ghp->src, c->laddr + IPv4off, IPv4addrlen); 
	} 
1997/0530    
 
1997/0327    
	ghp->proto = IP_GREPROTO; 
1997/0530    
	hnputl(ghp->dst, raddr); 
	hnputl(ghp->src, laddr); 
1997/0327    
	hnputs(ghp->eproto, c->rport); 
1997/0522    
	ghp->frag[0] = 0; 
	ghp->frag[1] = 0; 
1997/0531/sys/src/9/ip/gre.c:160,1781998/0306/sys/src/9/ip/gre.c:160,177
1997/0327    
} 
 
static void 
1997/0423    
greiput(Media *m, Block *bp) 
1998/0306    
greiput(uchar*, Block *bp) 
1997/0327    
{ 
	int len; 
	GREhdr *ghp; 
	Ipaddr addr; 
	Conv *c, **p; 
	ushort eproto; 
1998/0306    
	uchar raddr[IPaddrlen]; 
1997/0327    
 
1997/0423    
	USED(m); 
1997/0327    
	ghp = (GREhdr*)(bp->rp); 
 
1998/0306    
	v4tov6(raddr, ghp->src); 
1997/0327    
	eproto = nhgets(ghp->eproto); 
	addr = nhgetl(ghp->src); 
 
	/* Look for a conversation structure for this port and address */ 
	c = nil; 
1997/0531/sys/src/9/ip/gre.c:180,1861998/0306/sys/src/9/ip/gre.c:179,185
1997/0327    
		c = *p; 
		if(c->inuse == 0) 
			continue; 
		if(c->raddr == addr && c->rport == eproto) 
1998/0306    
		if(c->rport == eproto && ipcmp(c->raddr, raddr) == 0) 
1997/0327    
			break; 
	} 
 
1997/0531/sys/src/9/ip/gre.c:216,2211998/0306/sys/src/9/ip/gre.c:215,228
1997/0327    
	} 
} 
 
1998/0306    
int 
grestats(char *buf, int len) 
{ 
	return snprint(buf, len, 
		"gre: csum %d hlen %d len %d order %d rexmit %d\n", 
		gre.csumerr, gre.hlenerr, gre.lenerr, gre.order, gre.rexmit); 
} 
 
1997/0327    
void 
greinit(Fs *fs) 
{ 
1997/0531/sys/src/9/ip/gre.c:229,2341998/0306/sys/src/9/ip/gre.c:236,242
1997/0327    
	gre.rcv = greiput; 
	gre.ctl = nil; 
	gre.advise = nil; 
1998/0306    
	gre.stats = grestats; 
1997/0327    
	gre.ipproto = IP_GREPROTO; 
	gre.nc = 64; 
	gre.ptclsize = 0; 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)