#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;} ulongparseip(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 */ulongparseipmask(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;}
#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;
}