vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

eipconvtest.c (3135B)


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