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

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

1998/0217/sys/src/9/ip/ip.c:18,381998/0306/sys/src/9/ip/ip.c:18,38 (short | long | prev | next)
1997/0327    
	IP_HLEN		= 0x05,		/* Header length in characters */ 
	IP_DF		= 0x4000,	/* Don't fragment */ 
	IP_MF		= 0x2000,	/* More fragments */ 
1998/0217    
	IP_MAX		= (64*1024),	/* Maximum Internet packet size */ 
1998/0306    
	IP_MAX		= (32*1024),	/* Maximum Internet packet size */ 
1997/0327    
}; 
 
struct Iphdr 
{ 
	byte	vihl;		/* Version and header length */ 
	byte	tos;		/* Type of service */ 
	byte	length[2];	/* packet length */ 
	byte	id[2];		/* Identification */ 
	byte	frag[2];	/* Fragment information */ 
	byte	ttl;		/* Time to live */ 
	byte	proto;		/* Protocol */ 
	byte	cksum[2];	/* Header 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	length[2];	/* packet length */ 
	uchar	id[2];		/* Identification */ 
	uchar	frag[2];	/* Fragment information */ 
	uchar	ttl;		/* Time to live */ 
	uchar	proto;		/* Protocol */ 
	uchar	cksum[2];	/* Header checksum */ 
	uchar	src[4];		/* Ip source */ 
	uchar	dst[4];		/* Ip destination */ 
1997/0327    
}; 
 
struct Fragment 
1998/0217/sys/src/9/ip/ip.c:39,461998/0306/sys/src/9/ip/ip.c:39,46
1997/0327    
{ 
	Block*	blist; 
	Fragment* next; 
	Ipaddr 	src; 
	Ipaddr 	dst; 
1998/0306    
	ulong 	src; 
	ulong 	dst; 
1997/0327    
	ushort	id; 
	ulong 	age; 
}; 
1998/0217/sys/src/9/ip/ip.c:57,641998/0306/sys/src/9/ip/ip.c:57,64
1997/0327    
ulong		Id; 
int		iprouting;	/* true if we route like a gateway */ 
ulong		ipcsumerr; 
ulong		ipin, ippin;		/* bytes, packets in */ 
ulong		ipout, ippout;		/* bytes, packets out */ 
1998/0306    
ulong		ipin, ippin;		/* uchars, packets in */ 
ulong		ipout, ippout;		/* uchars, packets out */ 
1997/0327    
 
#define BLKIP(xp)	((Iphdr*)((xp)->rp)) 
/* 
1998/0217/sys/src/9/ip/ip.c:73,791998/0306/sys/src/9/ip/ip.c:73,79
1997/0916    
	ulong	droppedfrag; 
} stats; 
 
1997/0327    
ushort		ipcsum(byte*); 
1998/0306    
ushort		ipcsum(uchar*); 
1997/0327    
Block*		ipreassemble(int, Block*, Iphdr*); 
1997/0529    
void		ipfragfree(Fragment*); 
1997/0327    
Fragment*	ipfragallo(void); 
1998/0217/sys/src/9/ip/ip.c:81,971998/0306/sys/src/9/ip/ip.c:81,98
1997/0327    
void 
ipoput(Block *bp, int gating, int ttl) 
{ 
	Media *m; 
	byte gate[4]; 
1998/0306    
	Ipifc *ifc; 
	uchar *gate; 
1997/0327    
	ushort fragoff; 
	Block *xp, *nb; 
	Iphdr *eh, *feh; 
	int lid, len, seglen, chunk, dlen, blklen, offset, medialen; 
1998/0306    
	Route *r; 
1997/0327    
 
	/* Fill out the ip header */ 
	eh = (Iphdr *)(bp->rp); 
 
	/* Number of bytes in data and ip header to write */ 
1998/0306    
	/* Number of uchars in data and ip header to write */ 
1997/0327    
	len = blocklen(bp); 
	ipout += len; 
	ippout++; 
1998/0217/sys/src/9/ip/ip.c:104,1331998/0306/sys/src/9/ip/ip.c:105,134
1997/0327    
		if(chunk < len) 
			len = chunk; 
	} 
	if(len >= IP_MAX) { 
		netlog(Logip, "exceeded ip max size %I\n", eh->dst); 
1998/0306    
	if(len >= IP_MAX){ 
		netlog(Logip, "exceeded ip max size %V\n", eh->dst); 
1997/0327    
		goto raise; 
	} 
 
1997/0423    
	if(isbmcast(eh->dst)){ 
		m = Mediaroute(eh->src, nil); 
1997/0815    
		memmove(gate, eh->dst, IPaddrlen); 
1997/0423    
	} else 
		m = Mediaroute(eh->dst, gate); 
1997/0327    
	if(m == nil){ 
1998/0306    
	r = v4lookup(eh->dst); 
	if(r == nil){ 
1997/0916    
		stats.noroute++; 
1997/0327    
		netlog(Logip, "no interface %I\n", eh->dst); 
1998/0306    
		netlog(Logip, "no interface %V\n", eh->dst); 
1997/0327    
		goto raise; 
	} 
                 
1998/0306    
	if(r->type & (Rifc|Runi|Rbcast|Rmulti)) 
		gate = eh->dst; 
	else 
		gate = r->v4.gate; 
1997/0327    
	if(!gating){ 
		eh->vihl = IP_VER|IP_HLEN; 
		eh->tos = 0; 
		eh->ttl = ttl; 
	} 
1998/0306    
	ifc = r->ifc; 
1997/0327    
 
	/* If we dont need to fragment just send it */ 
	medialen = m->maxmtu-m->hsize; 
1998/0306    
	medialen = ifc->m->maxmtu - ifc->m->hsize; 
1997/0327    
	if(len <= medialen) { 
		if(!gating) 
			hnputs(eh->id, Id++); 
1998/0217/sys/src/9/ip/ip.c:138,1551998/0306/sys/src/9/ip/ip.c:139,157
1997/0327    
		eh->cksum[1] = 0; 
		hnputs(eh->cksum, ipcsum(&eh->vihl)); 
 
		Mediawrite(m, bp, gate); 
1998/0306    
/*print("ipoput %V->%V via %V\n", eh->src, eh->dst, gate);*/ 
		ifc->m->bwrite(ifc, bp, V4, gate); 
1997/0327    
		return; 
	} 
 
	if(eh->frag[0] & (IP_DF>>8)){ 
1997/0522    
		netlog(Logip, "%I: eh->frag[0] & (IP_DF>>8)\n", eh->dst); 
1998/0306    
		netlog(Logip, "%V: eh->frag[0] & (IP_DF>>8)\n", eh->dst); 
1997/0327    
		goto raise; 
	} 
 
	seglen = (medialen - IPHDR) & ~7; 
	if(seglen < 8){ 
		netlog(Logip, "%I seglen < 8\n", eh->dst); 
1998/0306    
		netlog(Logip, "%V seglen < 8\n", eh->dst); 
1997/0327    
		goto raise; 
	} 
 
1998/0217/sys/src/9/ip/ip.c:206,2121998/0306/sys/src/9/ip/ip.c:208,214
1997/0327    
		feh->cksum[0] = 0; 
		feh->cksum[1] = 0; 
		hnputs(feh->cksum, ipcsum(&feh->vihl)); 
		Mediawrite(m, nb, gate); 
1998/0306    
		ifc->m->bwrite(ifc, nb, V4, gate); 
1997/0327    
	} 
 
raise: 
1998/0217/sys/src/9/ip/ip.c:218,2241998/0306/sys/src/9/ip/ip.c:220,226
1997/0327    
{ 
	Fragment *fq, *eq; 
 
1997/1104    
	fragfree = malloc(sizeof(Fragment) * size); 
1998/0306    
	fragfree = (Fragment*)malloc(sizeof(Fragment) * size); 
1997/0327    
	if(fragfree == nil) 
		panic("initfrag"); 
 
1998/0217/sys/src/9/ip/ip.c:234,2451998/0306/sys/src/9/ip/ip.c:236,248
1997/0806    
//#define DBG(x)	if((logmask & Logipmsg) && (iponly == 0 || x == iponly))netlog 
 
1997/0327    
void 
1997/0423    
ipiput(Media *m, Block *bp) 
1998/0306    
ipiput(uchar *ia, Block *bp) 
1997/0327    
{ 
	Iphdr *h; 
	Proto *p; 
	ushort frag; 
	int notforme; 
1998/0306    
	uchar v6dst[IPaddrlen]; 
1997/0327    
 
1997/0806    
//	h = (Iphdr *)(bp->rp); 
//	DBG(nhgetl(h->src))(Logipmsg, "ipiput %I %I len %d proto %d\n", h->src, h->dst, BLEN(bp), h->proto); 
1998/0217/sys/src/9/ip/ip.c:252,2651998/0306/sys/src/9/ip/ip.c:255,261
1997/0327    
	} 
	h = (Iphdr *)(bp->rp); 
 
	/* Look to see if its for me before we waste time checksumming it */ 
	notforme = Mediaforme(h->dst) == 0; 
	if(notforme && !iprouting) { 
		netlog(Logip, "ip: pkt not for me\n"); 
		freeblist(bp); 
		return; 
	} 
                 
1998/0306    
	/* dump anything that whose header doesn't checksum */ 
1997/0327    
	if(ipcsum(&h->vihl)) { 
		ipcsumerr++; 
		netlog(Logip, "ip: checksum error %I\n", h->src); 
1998/0217/sys/src/9/ip/ip.c:267,2721998/0306/sys/src/9/ip/ip.c:263,283
1997/0327    
		return; 
	} 
 
1998/0306    
	/* route */ 
	v4tov6(v6dst, h->dst); 
	notforme = ipforme(v6dst) == 0; 
	if(notforme) { 
		if(iprouting) { 
			/* gate */ 
			if(h->ttl <= 1) 
				freeblist(bp); 
			else 
				ipoput(bp, 1, h->ttl - 1); 
		} else 
			useriprouter(ia, bp); 
		return; 
	} 
 
1997/0327    
	/* Check header length and version */ 
	if(h->vihl != (IP_VER|IP_HLEN)) { 
		netlog(Logip, "ip: %I bad hivl %ux\n", h->src, h->vihl); 
1998/0217/sys/src/9/ip/ip.c:287,3061998/0306/sys/src/9/ip/ip.c:298,306
1997/0327    
	ipin += blocklen(bp); 
	ippin++; 
 
	if(iprouting) { 
		/* gate */ 
		if(notforme){ 
			if(h->ttl == 0) 
				freeblist(bp); 
			else 
				ipoput(bp, 1, h->ttl - 1); 
			return; 
		} 
	} 
                 
	p = Fsrcvpcol(&fs, h->proto); 
	if(p != nil && p->rcv != nil) 
1997/0423    
		(*p->rcv)(m, bp); 
1998/0306    
		(*p->rcv)(ia, bp); 
1997/0327    
	else if(ipextprotoiput != nil) 
		ipextprotoiput(bp); 
	else 
1998/0217/sys/src/9/ip/ip.c:325,3311998/0306/sys/src/9/ip/ip.c:325,331
1997/0327    
	int fend; 
	ushort id; 
	Fragment *f, *fnext; 
	Ipaddr src, dst; 
1998/0306    
	ulong src, dst; 
1997/0327    
	Block *bl, **l, *last, *prev; 
	int ovlap, len, fragsize, pktposn; 
 
1998/0217/sys/src/9/ip/ip.c:532,5381998/0306/sys/src/9/ip/ip.c:532,538
1997/0327    
} 
 
ushort 
ipcsum(byte *addr) 
1998/0306    
ipcsum(uchar *addr) 
1997/0327    
{ 
	int len; 
	ulong sum; 


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