## 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); .