Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/ip/ipaux.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname ip/ipaux.c 1997/0327
## diff -e /dev/null /n/emeliedump/1997/0327/sys/src/brazil/ip/ipaux.c
0a
#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"../port/error.h"
#include	"kernel.h"
#include	"ip.h"

static	short	endian	= 1;
static	byte*	aendian	= (byte*)&endian;
#define	LITTLE	*aendian

ushort
ptclbsum(byte *addr, int len)
{
	ulong losum, hisum, mdsum, x;
	ulong t1, t2;

	losum = 0;
	hisum = 0;
	mdsum = 0;

	x = 0;
	if((ulong)addr & 1) {
		if(len) {
			hisum += addr[0];
			len--;
			addr++;
		}
		x = 1;
	}
	while(len >= 16) {
		t1 = *(ushort*)(addr+0);
		t2 = *(ushort*)(addr+2);	mdsum += t1;
		t1 = *(ushort*)(addr+4);	mdsum += t2;
		t2 = *(ushort*)(addr+6);	mdsum += t1;
		t1 = *(ushort*)(addr+8);	mdsum += t2;
		t2 = *(ushort*)(addr+10);	mdsum += t1;
		t1 = *(ushort*)(addr+12);	mdsum += t2;
		t2 = *(ushort*)(addr+14);	mdsum += t1;
		mdsum += t2;
		len -= 16;
		addr += 16;
	}
	while(len >= 2) {
		mdsum += *(ushort*)addr;
		len -= 2;
		addr += 2;
	}
	if(x) {
		if(len)
			losum += addr[0];
		if(LITTLE)
			losum += mdsum;
		else
			hisum += mdsum;
	} else {
		if(len)
			hisum += addr[0];
		if(LITTLE)
			hisum += mdsum;
		else
			losum += mdsum;
	}

	losum += hisum >> 8;
	losum += (hisum & 0xff) << 8;
	while(hisum = losum>>16)
		losum = hisum + (losum & 0xffff);

	return losum & 0xffff;
}

ushort
ptclcsum(Block *bp, int offset, int len)
{
	byte *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;
}

Ipaddr
defmask(Ipaddr ip)
{
	switch(ip>>30){
	default:
		return 0xff000000;
	case 2:
		return 0xffff0000;
	case 3:
		return 0xffffff00;
	}
}

int
myetheraddr(uchar *to, char *dev)
{
	int n, fd;
	char buf[256], *ptr;

	/* Make one exist */
	if(*dev == '/' || *dev == '#')
		sprint(buf, "%s/clone", dev);
	else
		sprint(buf, "/net/%s/clone", dev);

	fd = kopen(buf, ORDWR);
	if(fd >= 0)
		kclose(fd);

	if(*dev == '/' || *dev == '#')
		sprint(buf, "%s/0/stats", dev);
	else
		sprint(buf, "/net/%s/0/stats", dev);
	fd = kopen(buf, OREAD);
	if(fd < 0)
		return -1;

	n = kread(fd, buf, sizeof(buf)-1);
	kclose(fd);
	if(n <= 0)
		return -1;
	buf[n] = 0;

	ptr = strstr(buf, "addr: ");
	if(!ptr)
		return -1;
	ptr += 6;

	parseether(to, ptr);
	return 0;
}

int
eipconv(va_list *arg, Fconv *f)
{
	char buf[64];
	static char *efmt = "%.2lux%.2lux%.2lux%.2lux%.2lux%.2lux";
	static char *ifmt = "%d.%d.%d.%d";
	uchar *p, ip[4];

	switch(f->chr) {
	case 'E':		/* Ethernet address */
		p = va_arg(*arg, uchar*);
		sprint(buf, efmt, p[0], p[1], p[2], p[3], p[4], p[5]);
		break;
	case 'I':		/* Ip address */
		p = va_arg(*arg, uchar*);
		sprint(buf, ifmt, p[0], p[1], p[2], p[3]);
		break;
	case 'i':
		hnputl(ip, va_arg(*arg, ulong));
		sprint(buf, ifmt, ip[0], ip[1], ip[2], ip[3]);
		break;
	default:
		strcpy(buf, "(eipconv)");
	}
	strconv(buf, f);
	return sizeof(uchar*);
}

#define CLASS(p) ((*(uchar*)(p))>>6)

ulong
parseip(char *to, char *from)
{
	int i;
	char *p;

	p = from;
	memset(to, 0, 4);
	for(i = 0; i < 4 && *p; i++){
		to[i] = strtoul(p, &p, 0);
		if(*p == '.')
			p++;
	}
	switch(CLASS(to)){
	case 0:	/* class A - 1 byte 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 byte net */
		if(i == 3){
			to[3] = to[2];
			to[2] = 0;
		}
		break;
	}
	return nhgetl((uchar*)to);
}
.
## diffname ip/ipaux.c 1997/0423
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/ip/ipaux.c /n/emeliedump/1997/0423/sys/src/brazil/ip/ipaux.c
246c
	return nhgetl(to);
.
215c
parseip(uchar *to, char *from)
.
## diffname ip/ipaux.c 1997/0926
## diff -e /n/emeliedump/1997/0423/sys/src/brazil/ip/ipaux.c /n/emeliedump/1997/0926/sys/src/brazil/ip/ipaux.c
10,74d
## diffname ip/ipaux.c 1998/0306
## diff -e /n/emeliedump/1997/0926/sys/src/brazil/ip/ipaux.c /n/emeliedump/1998/0306/sys/src/brazil/ip/ipaux.c
181c
	return p;
}

int
isv4(uchar *ip)
{
	return memcmp(ip, v4prefix, IPv4off) == 0;
}

void
v4tov6(uchar *v6, uchar *v4)
{
	memmove(v6, v4prefix, IPv4off);
	memmove(v6 + IPv4off, v4, IPv4addrlen);
}

int
v6tov4(uchar *v4, uchar *v6)
{
	if(memcmp(v6, v4prefix, IPv4off) != 0)
		return -1;
	memmove(v4, v6 + IPv4off, IPv4addrlen);
	return 0;
}

ulong
parseip(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 += 2;
		} 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
 */
ulong
parseipmask(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;
}

void
maskip(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)
{
	return classmask[ip[IPv4off]>>6];
}

/*
 *  parse a command written to a device
 */
Cmdbuf*
parsecmd(char *p, int n)
{
	Cmdbuf *cb;

	cb = smalloc(sizeof(*cb));
	
	if(n > sizeof(cb->buf)-1)
		n = sizeof(cb->buf)-1;
	memmove(cb->buf, p, n);
	cb->buf[n] = '\0';
	cb->nf = parsefields(cb->buf, cb->f, nelem(cb->f), " ");
	return cb;
}

/*
 *  parse a hex mac address 
 */
int
parsemac(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)
			return -1;
		nip[0] = *p++;
		if(*p == 0)
			return -1;
		nip[1] = *p++;
		nip[2] = 0;
		to[i] = strtoul(nip, 0, 16);
		if(*p == ':')
			p++;
	}
	return 0;
.
174c
	case 2:	/* class B - 2 uchar net */
.
163c
	case 0:	/* class A - 1 uchar net */
.
156d
149,150c
static char*
v4parseip(uchar *to, char *from)
.
136,138c
	case 'M':		/* ip mask */
		p = va_arg(*arg, 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 */
		sprint(buf, "/%d", n);
.
133a
common:
		if(memcmp(p, v4prefix, 12) == 0)
			sprint(buf, ifmt, p[12], p[13], p[14], p[15]);
		else {
			/* 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);
			}
		}
		break;
	case 'i':		/* v6 address as 4 longs */
		lp = va_arg(*arg, ulong*);
		for(i = 0; i < 4; i++)
			hnputl(ip+4*i, *lp++);
		p = ip;
		goto common;
	case 'V':		/* v4 ip address */
		p = va_arg(*arg, uchar*);
.
125c
	uchar *p, ip[16];
	ulong *lp;
	ushort s;
	int i, j, n, eln, eli;
.
122c
	char buf[8*5];
.
86,118d
83,84c
[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,
};
.
80,81c
uchar prefixvals[256] =
.
70,78c
	Isprefix= 16,
};
.
67,68c
enum
.
13c
	uchar *addr;
.
9a
/*
 *  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
};


.
## diffname ip/ipaux.c 1998/0313
## diff -e /n/emeliedump/1998/0306/sys/src/brazil/ip/ipaux.c /n/emeliedump/1998/0313/sys/src/brazil/ip/ipaux.c
374a
	if(n > 0 && cb->buf[n-1] == '\n')
		n--;
.
## diffname ip/ipaux.c 1998/0320
## diff -e /n/emeliedump/1998/0313/sys/src/brazil/ip/ipaux.c /n/emeliedump/1998/0320/sys/src/brazil/ip/ipaux.c
283c
			i += 4;
			break;
.
## diffname ip/ipaux.c 1998/0328
## diff -e /n/emeliedump/1998/0320/sys/src/brazil/ip/ipaux.c /n/emeliedump/1998/0328/sys/src/brazil/ip/ipaux.c
213c
extern char*
.
## diffname ip/ipaux.c 1998/0630
## diff -e /n/emeliedump/1998/0328/sys/src/brazil/ip/ipaux.c /n/emeliedump/1998/0630/sys/src/brazil/ip/ipaux.c
407c
	return i;
.
396,402c
		if(p[0] == '\0' || p[1] == '\0')
			break;

		nip[0] = p[0];
		nip[1] = p[1];
		nip[2] = '\0';
		p += 2;

.
384c
 *  parse a hex mac address
.
## diffname ip/ipaux.c 1999/0316
## diff -e /n/emeliedump/1998/0630/sys/src/brazil/ip/ipaux.c /n/emeliedump/1999/0316/sys/src/brazil/ip/ipaux.c
364,383d
## diffname ip/ipaux.c 1999/0523
## diff -e /n/emeliedump/1999/0316/sys/src/brazil/ip/ipaux.c /n/emeliedump/1999/0523/sys/src/brazil/ip/ipaux.c
264a
	}
.
263c
	if(memcmp(v6, v4prefix, IPv4off) != 0){
		memset(v4, 0, 4);
.
## diffname ip/ipaux.c 1999/1109
## diff -e /n/emeliedump/1999/0523/sys/src/brazil/ip/ipaux.c /n/emeliedump/1999/1109/sys/src/9/ip/ipaux.c
112c
static uchar prefixvals[256] =
.
## diffname ip/ipaux.c 2000/1111
## diff -e /n/emeliedump/1999/1109/sys/src/9/ip/ipaux.c /n/emeliedump/2000/1111/sys/src/9/ip/ipaux.c
7d
## diffname ip/ipaux.c 2001/0127
## diff -e /n/emeliedump/2000/1111/sys/src/9/ip/ipaux.c /n/emeliedump/2001/0127/sys/src/9/ip/ipaux.c
255,256c
	v6[0] = *(ulong)v4prefix;
	v6[1] = *(ulong)(v4prefix+4);
	v6[2] = *(ulong)(v4prefix+8);
	v6[3] = *(ulong)v4;
.
## diffname ip/ipaux.c 2001/0128
## diff -e /n/emeliedump/2001/0127/sys/src/9/ip/ipaux.c /n/emeliedump/2001/0128/sys/src/9/ip/ipaux.c
255,258c
//	memmove(v6, v4prefix, IPv4off);
//	memmove(v6 + IPv4off, v4, IPv4addrlen);
	*(ulong*)v6 = *(ulong*)v4prefix;
	*(ulong*)(v6+4) = *(ulong*)(v4prefix+4);
	*(ulong*)(v6+8) = *(ulong*)(v4prefix+8);
	*(ulong*)(v6+12) = *(ulong*)v4;
.
## diffname ip/ipaux.c 2001/0301
## diff -e /n/emeliedump/2001/0128/sys/src/9/ip/ipaux.c /n/emeliedump/2001/0301/sys/src/9/ip/ipaux.c
393a
}

/*
 *  hashing tcp, udp, ... connections
 */
ulong
iphash(uchar *sa, ushort sp, uchar *da, ushort dp)
{
	return ((sa[IPaddrlen-1]<<24) ^ (sp << 16) ^ (da[IPaddrlen-1]<<8) ^ dp ) % Nhash;
}

void
iphtadd(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);
}

void
iphtrem(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;
.
255,260c
	if((((ulong)v6) & 0x3) != 0 || (((ulong)v4) & 0x3) != 0){
		memmove(v6, v4prefix, IPv4off);
		memmove(v6 + IPv4off, v4, IPv4addrlen);
	} else {
		*(ulong*)v6 = *(ulong*)v4prefix;
		*(ulong*)(v6+4) = *(ulong*)(v4prefix+4);
		*(ulong*)(v6+8) = *(ulong*)(v4prefix+8);
		*(ulong*)(v6+12) = *(ulong*)v4;
	}
.
251a
/* 
 *  since we call v4tov6 so often (per packet in), avoiding the memmove's is
 *  useful.  However, we need to check allignment for processors
 *  without unalligned moves.
 */
.
## diffname ip/ipaux.c 2001/0302
## diff -e /n/emeliedump/2001/0301/sys/src/9/ip/ipaux.c /n/emeliedump/2001/0302/sys/src/9/ip/ipaux.c
436a

.
278,279d
274c
	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 {
.
260,268c
	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];
.
252,255c

/*
 *  the following routines are unrolled with no memset's to speed
 *  up the usual case
.
## diffname ip/ipaux.c 2002/0217
## diff -e /n/emeliedump/2001/0302/sys/src/9/ip/ipaux.c /n/emeliedump/2002/0217/sys/src/9/ip/ipaux.c
206,207c
	return fmtit(f, "(eipfmt)");
.
201,204c
		return fmtit(f, "/%d", n);

.
184c
		p = va_arg(f->args, uchar*);
.
180,182c
		p = va_arg(f->args, uchar*);
		return fmtit(f, ifmt, p[0], p[1], p[2], p[3]);

.
178a

.
174c
		lp = va_arg(f->args, ulong*);
.
172c

		/* 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);

.
158,169c
		/* 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;
.
144,156c
			return fmtit(f, ifmt, p[12], p[13], p[14], p[15]);
.
141c
		p = va_arg(f->args, uchar*);
.
137,139c
		p = va_arg(f->args, uchar*);
		return fmtit(f, efmt, p[0], p[1], p[2], p[3], p[4], p[5]);

.
135c
	switch(f->r) {
.
127c
	char buf[5*8];
.
125c
eipfmt(Fmt *f)
.
## diffname ip/ipaux.c 2002/0218
## diff -e /n/emeliedump/2002/0217/sys/src/9/ip/ipaux.c /n/emeliedump/2002/0218/sys/src/9/ip/ipaux.c
205c
	return fmtprint(f, "(eipfmt)");
.
202c
		return fmtprint(f, "/%d", n);
.
182c
		return fmtprint(f, ifmt, p[0], p[1], p[2], p[3]);
.
144c
			return fmtprint(f, ifmt, p[12], p[13], p[14], p[15]);
.
138c
		return fmtprint(f, efmt, p[0], p[1], p[2], p[3], p[4], p[5]);
.
## diffname ip/ipaux.c 2002/0221
## diff -e /n/emeliedump/2002/0218/sys/src/9/ip/ipaux.c /n/emeliedump/2002/0221/sys/src/9/ip/ipaux.c
205c
	return fmtstrcpy(f, "(eipfmt)");
.
202,203c
		snprint(buf, sizeof buf, "/%d", n);
		return fmtstrcpy(f, buf);
.
182c
		snprint(buf, sizeof buf, ifmt, p[0], p[1], p[2], p[3]);
		return fmtstrcpy(f, buf);
.
143,144c
		if(memcmp(p, v4prefix, 12) == 0){
			snprint(buf, sizeof buf, ifmt, p[12], p[13], p[14], p[15]);
			return fmtstrcpy(f, buf);
		}
.
138c
		snprint(buf, sizeof buf, efmt, p[0], p[1], p[2], p[3], p[4], p[5]);
		return fmtstrcpy(f, buf);
.
## diffname ip/ipaux.c 2002/0507
## diff -e /n/emeliedump/2002/0221/sys/src/9/ip/ipaux.c /n/emeliedump/2002/0507/sys/src/9/ip/ipaux.c
399a

void
ipv62smcast(uchar *smcast, uchar *a)
{
	assert(IPaddrlen == 16);
	memmove(smcast, v6solicitednode, IPaddrlen);
	smcast[13] = a[13];
	smcast[14] = a[14];
	smcast[15] = a[15];
}

.
398c
	if(isv4(ip))
		return classmask[ip[IPv4off]>>6];
	else {
		if(ipcmp(ip, v6loopback) == 0)
			return IPallbits;
		else if(memcmp(ip, v6linklocal, v6linklocalprefix) == 0)
			return v6linklocalmask;
		else if(memcmp(ip, v6sitelocal, v6sitelocalprefix) == 0)
			return v6sitelocalmask;
		else if(memcmp(ip, v6solicitednode, v6solicitednodeprefix) == 0)
			return v6solicitednodemask;
		else if(memcmp(ip, v6multicast, v6multicastprefix) == 0)
			return v6multicastmask;
		return IPallbits;
	}
.
233c
		} else if(i == 2){
.
209c
	return fmtprint(f, "(eipfmt)");
.
206,207c
		return fmtprint(f, "/%d", n);

.
185,186c
		return fmtprint(f, ifmt, p[0], p[1], p[2], p[3]);
.
144,147c
		if(memcmp(p, v4prefix, 12) == 0)
			return fmtprint(f, ifmt, p[12], p[13], p[14], p[15]);
.
138,139c
		return fmtprint(f, efmt, p[0], p[1], p[2], p[3], p[4], p[5]);
.
48a
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 v6linklocalprefix = 8;
uchar 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 v6sitelocalprefix = 6;
uchar 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 v6multicastprefix = 1;
uchar 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 v6allnodesprefix = 2;
uchar 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 v6allnodesLprefix = 2;
uchar 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 v6solicitednodeprefix = 13;




.
35a

.
7a
#include  "ipv6.h"
.
## diffname ip/ipaux.c 2003/0404
## diff -e /n/emeliedump/2002/0507/sys/src/9/ip/ipaux.c /n/emeliedump/2003/0404/sys/src/9/ip/ipaux.c
352c
	return fmtstrcpy(f, "(eipfmt)");
.
349,350c
		snprint(buf, sizeof buf, "/%d", n);
		return fmtstrcpy(f, buf);
.
329c
		snprint(buf, sizeof buf, ifmt, p[0], p[1], p[2], p[3]);
		return fmtstrcpy(f, buf);
.
290,291c
		if(memcmp(p, v4prefix, 12) == 0){
			snprint(buf, sizeof buf, ifmt, p[12], p[13], p[14], p[15]);
			return fmtstrcpy(f, buf);
		}
.
285c
		snprint(buf, sizeof buf, efmt, p[0], p[1], p[2], p[3], p[4], p[5]);
		return fmtstrcpy(f, buf);
.

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.