⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipaux.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include	"u.h"#include	"../port/lib.h"#include	"mem.h"#include	"dat.h"#include	"fns.h"#include	"../port/error.h"#include	"ip.h"#include  "ipv6.h"/* *  well known IP addresses */uchar IPv4bcast[IPaddrlen] = {	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0xff, 0xff,	0xff, 0xff, 0xff, 0xff};uchar IPv4allsys[IPaddrlen] = {	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0xff, 0xff,	0xe0, 0, 0, 0x01};uchar IPv4allrouter[IPaddrlen] = {	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0xff, 0xff,	0xe0, 0, 0, 0x02};uchar IPallbits[IPaddrlen] = {	0xff, 0xff, 0xff, 0xff,	0xff, 0xff, 0xff, 0xff,	0xff, 0xff, 0xff, 0xff,	0xff, 0xff, 0xff, 0xff};uchar IPnoaddr[IPaddrlen];/* *  prefix of all v4 addresses */uchar v4prefix[IPaddrlen] = {	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0xff, 0xff,	0, 0, 0, 0};char *v6hdrtypes[Maxhdrtype] ={	[HBH]		"HopbyHop",	[ICMP]		"ICMP",	[IGMP]		"IGMP",	[GGP]		"GGP",	[IPINIP]		"IP",	[ST]		"ST",	[TCP]		"TCP",	[UDP]		"UDP",	[ISO_TP4]	"ISO_TP4",	[RH]		"Routinghdr",	[FH]		"Fraghdr",	[IDRP]		"IDRP",	[RSVP]		"RSVP",	[AH]		"Authhdr",	[ESP]		"ESP",	[ICMPv6]	"ICMPv6",	[NNH]		"Nonexthdr",	[ISO_IP]	"ISO_IP",	[IGRP]		"IGRP",	[OSPF]		"OSPF",};/* *  well known IPv6 addresses */uchar v6Unspecified[IPaddrlen] = {	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0};uchar v6loopback[IPaddrlen] = {	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0x01};uchar v6linklocal[IPaddrlen] = {	0xfe, 0x80, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0};uchar v6linklocalmask[IPaddrlen] = {	0xff, 0xff, 0xff, 0xff,	0xff, 0xff, 0xff, 0xff,	0, 0, 0, 0,	0, 0, 0, 0};int v6llpreflen = 8;	// link-local prefix lengthuchar v6sitelocal[IPaddrlen] = {	0xfe, 0xc0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0};uchar v6sitelocalmask[IPaddrlen] = {	0xff, 0xff, 0xff, 0xff,	0xff, 0xff, 0xff, 0xff,	0, 0, 0, 0,	0, 0, 0, 0};int v6slpreflen = 6;	// site-local prefix lengthuchar v6glunicast[IPaddrlen] = {	0x08, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0};uchar v6multicast[IPaddrlen] = {	0xff, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0};uchar v6multicastmask[IPaddrlen] = {	0xff, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0};int v6mcpreflen = 1;	// multicast prefix lengthuchar v6allnodesN[IPaddrlen] = {	0xff, 0x01, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0x01};uchar v6allnodesNmask[IPaddrlen] = {	0xff, 0xff, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0};int v6aNpreflen = 2;	// all nodes (N) prefixuchar v6allnodesL[IPaddrlen] = {	0xff, 0x02, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0x01};uchar v6allnodesLmask[IPaddrlen] = {	0xff, 0xff, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0};int v6aLpreflen = 2;	// all nodes (L) prefixuchar v6allroutersN[IPaddrlen] = {	0xff, 0x01, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0x02};uchar v6allroutersL[IPaddrlen] = {	0xff, 0x02, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0x02};uchar v6allroutersS[IPaddrlen] = {	0xff, 0x05, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0x02};uchar v6solicitednode[IPaddrlen] = {	0xff, 0x02, 0, 0,	0, 0, 0, 0,	0, 0, 0, 0x01,	0xff, 0, 0, 0};uchar v6solicitednodemask[IPaddrlen] = {	0xff, 0xff, 0xff, 0xff,	0xff, 0xff, 0xff, 0xff,	0xff, 0xff, 0xff, 0xff,	0xff, 0x0, 0x0, 0x0};int v6snpreflen = 13;ushortptclcsum(Block *bp, int offset, int len){	uchar *addr;	ulong losum, hisum;	ushort csum;	int odd, blocklen, x;	/* Correct to front of data area */	while(bp != nil && offset && offset >= BLEN(bp)) {		offset -= BLEN(bp);		bp = bp->next;	}	if(bp == nil)		return 0;	addr = bp->rp + offset;	blocklen = BLEN(bp) - offset;	if(bp->next == nil) {		if(blocklen < len)			len = blocklen;		return ~ptclbsum(addr, len) & 0xffff;	}	losum = 0;	hisum = 0;	odd = 0;	while(len) {		x = blocklen;		if(len < x)			x = len;		csum = ptclbsum(addr, x);		if(odd)			hisum += csum;		else			losum += csum;		odd = (odd+x) & 1;		len -= x;		bp = bp->next;		if(bp == nil)			break;		blocklen = BLEN(bp);		addr = bp->rp;	}	losum += hisum>>8;	losum += (hisum&0xff)<<8;	while((csum = losum>>16) != 0)		losum = csum + (losum & 0xffff);	return ~losum & 0xffff;}enum{	Isprefix= 16,};static uchar prefixvals[256] ={[0x00] 0 | Isprefix,[0x80] 1 | Isprefix,[0xC0] 2 | Isprefix,[0xE0] 3 | Isprefix,[0xF0] 4 | Isprefix,[0xF8] 5 | Isprefix,[0xFC] 6 | Isprefix,[0xFE] 7 | Isprefix,[0xFF] 8 | Isprefix,};inteipfmt(Fmt *f){	char buf[5*8];	static char *efmt = "%.2lux%.2lux%.2lux%.2lux%.2lux%.2lux";	static char *ifmt = "%d.%d.%d.%d";	uchar *p, ip[16];	ulong *lp;	ushort s;	int i, j, n, eln, eli;	switch(f->r) {	case 'E':		/* Ethernet address */		p = va_arg(f->args, uchar*);		snprint(buf, sizeof buf, efmt, p[0], p[1], p[2], p[3], p[4], p[5]);		return fmtstrcpy(f, buf);	case 'I':		/* Ip address */		p = va_arg(f->args, uchar*);common:		if(memcmp(p, v4prefix, 12) == 0){			snprint(buf, sizeof buf, ifmt, p[12], p[13], p[14], p[15]);			return fmtstrcpy(f, buf);		}		/* find longest elision */		eln = eli = -1;		for(i = 0; i < 16; i += 2){			for(j = i; j < 16; j += 2)				if(p[j] != 0 || p[j+1] != 0)					break;			if(j > i && j - i > eln){				eli = i;				eln = j - i;			}		}		/* print with possible elision */		n = 0;		for(i = 0; i < 16; i += 2){			if(i == eli){				n += sprint(buf+n, "::");				i += eln;				if(i >= 16)					break;			} else if(i != 0)				n += sprint(buf+n, ":");			s = (p[i]<<8) + p[i+1];			n += sprint(buf+n, "%ux", s);		}		return fmtstrcpy(f, buf);	case 'i':		/* v6 address as 4 longs */		lp = va_arg(f->args, ulong*);		for(i = 0; i < 4; i++)			hnputl(ip+4*i, *lp++);		p = ip;		goto common;	case 'V':		/* v4 ip address */		p = va_arg(f->args, uchar*);		snprint(buf, sizeof buf, ifmt, p[0], p[1], p[2], p[3]);		return fmtstrcpy(f, buf);	case 'M':		/* ip mask */		p = va_arg(f->args, uchar*);		/* look for a prefix mask */		for(i = 0; i < 16; i++)			if(p[i] != 0xff)				break;		if(i < 16){			if((prefixvals[p[i]] & Isprefix) == 0)				goto common;			for(j = i+1; j < 16; j++)				if(p[j] != 0)					goto common;			n = 8*i + (prefixvals[p[i]] & ~Isprefix);		} else			n = 8*16;		/* got one, use /xx format */		snprint(buf, sizeof buf, "/%d", n);		return fmtstrcpy(f, buf);	}	return fmtstrcpy(f, "(eipfmt)");}#define CLASS(p) ((*(uchar*)(p))>>6)extern char*v4parseip(uchar *to, char *from){	int i;	char *p;	p = from;	for(i = 0; i < 4 && *p; i++){		to[i] = strtoul(p, &p, 0);		if(*p == '.')			p++;	}	switch(CLASS(to)){	case 0:	/* class A - 1 uchar net */	case 1:		if(i == 3){			to[3] = to[2];			to[2] = to[1];			to[1] = 0;		} else if(i == 2){			to[3] = to[1];			to[1] = 0;		}		break;	case 2:	/* class B - 2 uchar net */		if(i == 3){			to[3] = to[2];			to[2] = 0;		}		break;	}	return p;}intisv4(uchar *ip){	return memcmp(ip, v4prefix, IPv4off) == 0;}/* *  the following routines are unrolled with no memset's to speed *  up the usual case */voidv4tov6(uchar *v6, uchar *v4){	v6[0] = 0;	v6[1] = 0;	v6[2] = 0;	v6[3] = 0;	v6[4] = 0;	v6[5] = 0;	v6[6] = 0;	v6[7] = 0;	v6[8] = 0;	v6[9] = 0;	v6[10] = 0xff;	v6[11] = 0xff;	v6[12] = v4[0];	v6[13] = v4[1];	v6[14] = v4[2];	v6[15] = v4[3];}intv6tov4(uchar *v4, uchar *v6){	if(v6[0] == 0	&& v6[1] == 0	&& v6[2] == 0	&& v6[3] == 0	&& v6[4] == 0	&& v6[5] == 0	&& v6[6] == 0	&& v6[7] == 0	&& v6[8] == 0	&& v6[9] == 0	&& v6[10] == 0xff	&& v6[11] == 0xff)	{		v4[0] = v6[12];		v4[1] = v6[13];		v4[2] = v6[14];		v4[3] = v6[15];		return 0;	} else {		memset(v4, 0, 4);		return -1;	}}ulongparseip(uchar *to, char *from){	int i, elipsis = 0, v4 = 1;	ulong x;	char *p, *op;	memset(to, 0, IPaddrlen);	p = from;	for(i = 0; i < 16 && *p; i+=2){		op = p;		x = strtoul(p, &p, 16);		if(*p == '.' || (*p == 0 && i == 0)){			p = v4parseip(to+i, op);			i += 4;			break;		} else {			to[i] = x>>8;			to[i+1] = x;		}		if(*p == ':'){			v4 = 0;			if(*++p == ':'){				elipsis = i+2;				p++;			}		}	}	if(i < 16){		memmove(&to[elipsis+16-i], &to[elipsis], i-elipsis);		memset(&to[elipsis], 0, 16-i);	}	if(v4){		to[10] = to[11] = 0xff;		return nhgetl(to+12);	} else		return 6;}/* *  hack to allow ip v4 masks to be entered in the old *  style */ulongparseipmask(uchar *to, char *from){	ulong x;	int i;	uchar *p;	if(*from == '/'){		/* as a number of prefix bits */		i = atoi(from+1);		if(i < 0)			i = 0;		if(i > 128)			i = 128;		memset(to, 0, IPaddrlen);		for(p = to; i >= 8; i -= 8)			*p++ = 0xff;		if(i > 0)			*p = ~((1<<(8-i))-1);		x = nhgetl(to+IPv4off);	} else {		/* as a straight bit mask */		x = parseip(to, from);		if(memcmp(to, v4prefix, IPv4off) == 0)			memset(to, 0xff, IPv4off);	}	return x;}voidmaskip(uchar *from, uchar *mask, uchar *to){	int i;	for(i = 0; i < IPaddrlen; i++)		to[i] = from[i] & mask[i];}uchar classmask[4][16] = {	0xff,0xff,0xff,0xff,  0xff,0xff,0xff,0xff,  0xff,0xff,0xff,0xff,  0xff,0x00,0x00,0x00,	0xff,0xff,0xff,0xff,  0xff,0xff,0xff,0xff,  0xff,0xff,0xff,0xff,  0xff,0x00,0x00,0x00,	0xff,0xff,0xff,0xff,  0xff,0xff,0xff,0xff,  0xff,0xff,0xff,0xff,  0xff,0xff,0x00,0x00,	0xff,0xff,0xff,0xff,  0xff,0xff,0xff,0xff,  0xff,0xff,0xff,0xff,  0xff,0xff,0xff,0x00,};uchar*defmask(uchar *ip){	if(isv4(ip))		return classmask[ip[IPv4off]>>6];	else {		if(ipcmp(ip, v6loopback) == 0)			return IPallbits;		else if(memcmp(ip, v6linklocal, v6llpreflen) == 0)			return v6linklocalmask;		else if(memcmp(ip, v6sitelocal, v6slpreflen) == 0)			return v6sitelocalmask;		else if(memcmp(ip, v6solicitednode, v6snpreflen) == 0)			return v6solicitednodemask;		else if(memcmp(ip, v6multicast, v6mcpreflen) == 0)			return v6multicastmask;		return IPallbits;	}}voidipv62smcast(uchar *smcast, uchar *a){	assert(IPaddrlen == 16);	memmove(smcast, v6solicitednode, IPaddrlen);	smcast[13] = a[13];	smcast[14] = a[14];	smcast[15] = a[15];}/* *  parse a hex mac address */intparsemac(uchar *to, char *from, int len){	char nip[4];	char *p;	int i;	p = from;	memset(to, 0, len);	for(i = 0; i < len; i++){		if(p[0] == '\0' || p[1] == '\0')			break;		nip[0] = p[0];		nip[1] = p[1];		nip[2] = '\0';		p += 2;		to[i] = strtoul(nip, 0, 16);		if(*p == ':')			p++;	}	return i;}/* *  hashing tcp, udp, ... connections */ulongiphash(uchar *sa, ushort sp, uchar *da, ushort dp){	return ((sa[IPaddrlen-1]<<24) ^ (sp << 16) ^ (da[IPaddrlen-1]<<8) ^ dp ) % Nhash;}voidiphtadd(Ipht *ht, Conv *c){	ulong hv;	Iphash *h;	hv = iphash(c->raddr, c->rport, c->laddr, c->lport);	h = smalloc(sizeof(*h));	if(ipcmp(c->raddr, IPnoaddr) != 0)		h->match = IPmatchexact;	else {		if(ipcmp(c->laddr, IPnoaddr) != 0){			if(c->lport == 0)				h->match = IPmatchaddr;			else				h->match = IPmatchpa;		} else {			if(c->lport == 0)				h->match = IPmatchany;			else				h->match = IPmatchport;		}	}	h->c = c;	lock(ht);	h->next = ht->tab[hv];	ht->tab[hv] = h;	unlock(ht);}voidiphtrem(Ipht *ht, Conv *c){	ulong hv;	Iphash **l, *h;	hv = iphash(c->raddr, c->rport, c->laddr, c->lport);	lock(ht);	for(l = &ht->tab[hv]; (*l) != nil; l = &(*l)->next)		if((*l)->c == c){			h = *l;			(*l) = h->next;			free(h);			break;		}	unlock(ht);}/* look for a matching conversation with the following precedence *	connected && raddr,rport,laddr,lport *	announced && laddr,lport *	announced && *,lport *	announced && laddr,* *	announced && *,* */Conv*iphtlook(Ipht *ht, uchar *sa, ushort sp, uchar *da, ushort dp){	ulong hv;	Iphash *h;	Conv *c;	/* exact 4 pair match (connection) */	hv = iphash(sa, sp, da, dp);	lock(ht);	for(h = ht->tab[hv]; h != nil; h = h->next){		if(h->match != IPmatchexact)			continue;		c = h->c;		if(sp == c->rport && dp == c->lport		&& ipcmp(sa, c->raddr) == 0 && ipcmp(da, c->laddr) == 0){			unlock(ht);			return c;		}	}		/* match local address and port */	hv = iphash(IPnoaddr, 0, da, dp);	for(h = ht->tab[hv]; h != nil; h = h->next){		if(h->match != IPmatchpa)			continue;		c = h->c;		if(dp == c->lport && ipcmp(da, c->laddr) == 0){			unlock(ht);			return c;		}	}		/* match just port */	hv = iphash(IPnoaddr, 0, IPnoaddr, dp);	for(h = ht->tab[hv]; h != nil; h = h->next){		if(h->match != IPmatchport)			continue;		c = h->c;		if(dp == c->lport){			unlock(ht);			return c;		}	}		/* match local address */	hv = iphash(IPnoaddr, 0, da, 0);	for(h = ht->tab[hv]; h != nil; h = h->next){		if(h->match != IPmatchaddr)			continue;		c = h->c;		if(ipcmp(da, c->laddr) == 0){			unlock(ht);			return c;		}	}		/* look for something that matches anything */	hv = iphash(IPnoaddr, 0, IPnoaddr, 0);	for(h = ht->tab[hv]; h != nil; h = h->next){		if(h->match != IPmatchany)			continue;		c = h->c;		unlock(ht);		return c;	}	unlock(ht);	return nil;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -