xref: /plan9-contrib/sys/src/9/ip/eipconvtest.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1*7dd7cddfSDavid du Colombier #include <u.h>
2*7dd7cddfSDavid du Colombier #include <libc.h>
3*7dd7cddfSDavid du Colombier 
4*7dd7cddfSDavid du Colombier enum
5*7dd7cddfSDavid du Colombier {
6*7dd7cddfSDavid du Colombier 	Isprefix= 16,
7*7dd7cddfSDavid du Colombier };
8*7dd7cddfSDavid du Colombier 
9*7dd7cddfSDavid du Colombier uchar prefixvals[256] =
10*7dd7cddfSDavid du Colombier {
11*7dd7cddfSDavid du Colombier [0x00] 0 | Isprefix,
12*7dd7cddfSDavid du Colombier [0x80] 1 | Isprefix,
13*7dd7cddfSDavid du Colombier [0xC0] 2 | Isprefix,
14*7dd7cddfSDavid du Colombier [0xE0] 3 | Isprefix,
15*7dd7cddfSDavid du Colombier [0xF0] 4 | Isprefix,
16*7dd7cddfSDavid du Colombier [0xF8] 5 | Isprefix,
17*7dd7cddfSDavid du Colombier [0xFC] 6 | Isprefix,
18*7dd7cddfSDavid du Colombier [0xFE] 7 | Isprefix,
19*7dd7cddfSDavid du Colombier [0xFF] 8 | Isprefix,
20*7dd7cddfSDavid du Colombier };
21*7dd7cddfSDavid du Colombier 
22*7dd7cddfSDavid du Colombier uchar v4prefix[16] = {
23*7dd7cddfSDavid du Colombier 	0, 0, 0, 0,
24*7dd7cddfSDavid du Colombier 	0, 0, 0, 0,
25*7dd7cddfSDavid du Colombier 	0, 0, 0xff, 0xff,
26*7dd7cddfSDavid du Colombier 	0, 0, 0, 0
27*7dd7cddfSDavid du Colombier };
28*7dd7cddfSDavid du Colombier 
29*7dd7cddfSDavid du Colombier void
hnputl(void * p,ulong v)30*7dd7cddfSDavid du Colombier hnputl(void *p, ulong v)
31*7dd7cddfSDavid du Colombier {
32*7dd7cddfSDavid du Colombier 	uchar *a;
33*7dd7cddfSDavid du Colombier 
34*7dd7cddfSDavid du Colombier 	a = p;
35*7dd7cddfSDavid du Colombier 	a[0] = v>>24;
36*7dd7cddfSDavid du Colombier 	a[1] = v>>16;
37*7dd7cddfSDavid du Colombier 	a[2] = v>>8;
38*7dd7cddfSDavid du Colombier 	a[3] = v;
39*7dd7cddfSDavid du Colombier }
40*7dd7cddfSDavid du Colombier 
41*7dd7cddfSDavid du Colombier int
eipconv(va_list * arg,Fconv * f)42*7dd7cddfSDavid du Colombier eipconv(va_list *arg, Fconv *f)
43*7dd7cddfSDavid du Colombier {
44*7dd7cddfSDavid du Colombier 	char buf[8*5];
45*7dd7cddfSDavid du Colombier 	static char *efmt = "%.2lux%.2lux%.2lux%.2lux%.2lux%.2lux";
46*7dd7cddfSDavid du Colombier 	static char *ifmt = "%d.%d.%d.%d";
47*7dd7cddfSDavid du Colombier 	uchar *p, ip[16];
48*7dd7cddfSDavid du Colombier 	ulong *lp;
49*7dd7cddfSDavid du Colombier 	ushort s;
50*7dd7cddfSDavid du Colombier 	int i, j, n, eln, eli;
51*7dd7cddfSDavid du Colombier 
52*7dd7cddfSDavid du Colombier 	switch(f->chr) {
53*7dd7cddfSDavid du Colombier 	case 'E':		/* Ethernet address */
54*7dd7cddfSDavid du Colombier 		p = va_arg(*arg, uchar*);
55*7dd7cddfSDavid du Colombier 		sprint(buf, efmt, p[0], p[1], p[2], p[3], p[4], p[5]);
56*7dd7cddfSDavid du Colombier 		break;
57*7dd7cddfSDavid du Colombier 	case 'I':		/* Ip address */
58*7dd7cddfSDavid du Colombier 		p = va_arg(*arg, uchar*);
59*7dd7cddfSDavid du Colombier common:
60*7dd7cddfSDavid du Colombier 		if(memcmp(p, v4prefix, 12) == 0)
61*7dd7cddfSDavid du Colombier 			sprint(buf, ifmt, p[12], p[13], p[14], p[15]);
62*7dd7cddfSDavid du Colombier 		else {
63*7dd7cddfSDavid du Colombier 			/* find longest elision */
64*7dd7cddfSDavid du Colombier 			eln = eli = -1;
65*7dd7cddfSDavid du Colombier 			for(i = 0; i < 16; i += 2){
66*7dd7cddfSDavid du Colombier 				for(j = i; j < 16; j += 2)
67*7dd7cddfSDavid du Colombier 					if(p[j] != 0 || p[j+1] != 0)
68*7dd7cddfSDavid du Colombier 						break;
69*7dd7cddfSDavid du Colombier 				if(j > i && j - i > eln){
70*7dd7cddfSDavid du Colombier 					eli = i;
71*7dd7cddfSDavid du Colombier 					eln = j - i;
72*7dd7cddfSDavid du Colombier 				}
73*7dd7cddfSDavid du Colombier 			}
74*7dd7cddfSDavid du Colombier 
75*7dd7cddfSDavid du Colombier 			/* print with possible elision */
76*7dd7cddfSDavid du Colombier 			n = 0;
77*7dd7cddfSDavid du Colombier 			for(i = 0; i < 16; i += 2){
78*7dd7cddfSDavid du Colombier 				if(i == eli){
79*7dd7cddfSDavid du Colombier 					n += sprint(buf+n, "::");
80*7dd7cddfSDavid du Colombier 					i += eln;
81*7dd7cddfSDavid du Colombier 					if(i >= 16)
82*7dd7cddfSDavid du Colombier 						break;
83*7dd7cddfSDavid du Colombier 				} else if(i != 0)
84*7dd7cddfSDavid du Colombier 					n += sprint(buf+n, ":");
85*7dd7cddfSDavid du Colombier 				s = (p[i]<<8) + p[i+1];
86*7dd7cddfSDavid du Colombier 				n += sprint(buf+n, "%ux", s);
87*7dd7cddfSDavid du Colombier 			}
88*7dd7cddfSDavid du Colombier 		}
89*7dd7cddfSDavid du Colombier 		break;
90*7dd7cddfSDavid du Colombier 	case 'i':		/* v6 address as 4 longs */
91*7dd7cddfSDavid du Colombier 		lp = va_arg(*arg, ulong*);
92*7dd7cddfSDavid du Colombier 		for(i = 0; i < 4; i++)
93*7dd7cddfSDavid du Colombier 			hnputl(ip+4*i, *lp++);
94*7dd7cddfSDavid du Colombier 		p = ip;
95*7dd7cddfSDavid du Colombier 		goto common;
96*7dd7cddfSDavid du Colombier 	case 'V':		/* v4 ip address */
97*7dd7cddfSDavid du Colombier 		p = va_arg(*arg, uchar*);
98*7dd7cddfSDavid du Colombier 		sprint(buf, ifmt, p[0], p[1], p[2], p[3]);
99*7dd7cddfSDavid du Colombier 		break;
100*7dd7cddfSDavid du Colombier 	case 'M':		/* ip mask */
101*7dd7cddfSDavid du Colombier 		p = va_arg(*arg, uchar*);
102*7dd7cddfSDavid du Colombier 
103*7dd7cddfSDavid du Colombier 		/* look for a prefix mask */
104*7dd7cddfSDavid du Colombier 		for(i = 0; i < 16; i++)
105*7dd7cddfSDavid du Colombier 			if(p[i] != 0xff)
106*7dd7cddfSDavid du Colombier 				break;
107*7dd7cddfSDavid du Colombier 		if(i < 16){
108*7dd7cddfSDavid du Colombier 			if((prefixvals[p[i]] & Isprefix) == 0)
109*7dd7cddfSDavid du Colombier 				goto common;
110*7dd7cddfSDavid du Colombier 			for(j = i+1; j < 16; j++)
111*7dd7cddfSDavid du Colombier 				if(p[j] != 0)
112*7dd7cddfSDavid du Colombier 					goto common;
113*7dd7cddfSDavid du Colombier 			n = 8*i + (prefixvals[p[i]] & ~Isprefix);
114*7dd7cddfSDavid du Colombier 		} else
115*7dd7cddfSDavid du Colombier 			n = 8*16;
116*7dd7cddfSDavid du Colombier 
117*7dd7cddfSDavid du Colombier 		/* got one, use /xx format */
118*7dd7cddfSDavid du Colombier 		sprint(buf, "/%d", n);
119*7dd7cddfSDavid du Colombier 		break;
120*7dd7cddfSDavid du Colombier 	default:
121*7dd7cddfSDavid du Colombier 		strcpy(buf, "(eipconv)");
122*7dd7cddfSDavid du Colombier 	}
123*7dd7cddfSDavid du Colombier 	strconv(buf, f);
124*7dd7cddfSDavid du Colombier 	return sizeof(uchar*);
125*7dd7cddfSDavid du Colombier }
126*7dd7cddfSDavid du Colombier 
127*7dd7cddfSDavid du Colombier uchar testvec[11][16] =
128*7dd7cddfSDavid du Colombier {
129*7dd7cddfSDavid du Colombier  { 0,0,0,0, 0,0,0,0, 0,0,0xff,0xff, 1,3,4,5, },
130*7dd7cddfSDavid du Colombier  { 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, },
131*7dd7cddfSDavid du Colombier  { 0xff,0xff,0x80,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, },
132*7dd7cddfSDavid du Colombier  { 0xff,0xff,0xff,0xc0, 0,0,0,0, 0,0,0,0, 0,0,0,0, },
133*7dd7cddfSDavid du Colombier  { 0xff,0xff,0xff,0xff, 0xe0,0,0,0, 0,0,0,0, 0,0,0,0, },
134*7dd7cddfSDavid du Colombier  { 0xff,0xff,0xff,0xff, 0xff,0xf0,0,0, 0,0,0,0, 0,0,0,0, },
135*7dd7cddfSDavid du Colombier  { 0xff,0xff,0xff,0xff, 0xff,0xff,0xf8,0, 0,0,0,0, 0,0,0,0, },
136*7dd7cddfSDavid du Colombier  { 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, },
137*7dd7cddfSDavid du Colombier  { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, },
138*7dd7cddfSDavid du Colombier  { 0,0,0,0, 0,0x11,0,0, 0,0,0,0, 0,0,0,0, },
139*7dd7cddfSDavid du Colombier  { 0,0,0,0x11, 0,0,0,0, 0,0,0,0, 0,0,0,0x12, },
140*7dd7cddfSDavid du Colombier };
141*7dd7cddfSDavid du Colombier 
142*7dd7cddfSDavid du Colombier void
main(void)143*7dd7cddfSDavid du Colombier main(void)
144*7dd7cddfSDavid du Colombier {
145*7dd7cddfSDavid du Colombier 	int i;
146*7dd7cddfSDavid du Colombier 
147*7dd7cddfSDavid du Colombier 	fmtinstall('I', eipconv);
148*7dd7cddfSDavid du Colombier 	fmtinstall('M', eipconv);
149*7dd7cddfSDavid du Colombier 	for(i = 0; i < 11; i++)
150*7dd7cddfSDavid du Colombier 		print("%I\n%M\n", testvec[i], testvec[i]);
151*7dd7cddfSDavid du Colombier 	exits(0);
152*7dd7cddfSDavid du Colombier }
153