| #include <u.h> |
| #include <libc.h> |
| #include <ip.h> |
| |
| char* |
| v4parseip(uchar *to, char *from) |
| { |
| int i; |
| char *p; |
| |
| p = from; |
| for(i = 0; i < 4 && *p; i++){ |
| to[i] = strtoul(p, &p, 0); |
| if(*p == '.') |
| p++; |
| } |
| switch(CLASS(to)){ |
| case 0: /* class A - 1 uchar 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 uchar net */ |
| if(i == 3){ |
| to[3] = to[2]; |
| to[2] = 0; |
| } |
| break; |
| } |
| return p; |
| } |
| |
| 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 += 4; |
| break; |
| } |
| 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; |
| } |
| |
| /* |
| * parse a v4 ip address/mask in cidr format |
| */ |
| char* |
| v4parsecidr(uchar *addr, uchar *mask, char *from) |
| { |
| int i; |
| char *p; |
| uchar *a; |
| |
| p = v4parseip(addr, from); |
| |
| if(*p == '/'){ |
| /* as a number of prefix bits */ |
| i = strtoul(p+1, &p, 0); |
| if(i > 32) |
| i = 32; |
| memset(mask, 0, IPv4addrlen); |
| for(a = mask; i >= 8; i -= 8) |
| *a++ = 0xff; |
| if(i > 0) |
| *a = ~((1<<(8-i))-1); |
| } else |
| memcpy(mask, defmask(addr), IPv4addrlen); |
| return p; |
| } |