123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- #include <u.h>
- #include <libc.h>
- #include <ip.h>
- enum
- {
- Isprefix= 16,
- };
- 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,
- };
- int
- eipfmt(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)");
- }
|