eipconvtest.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) 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 }