Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
5 char*
6 v4parseip(uchar *to, char *from)
7 {
8 int i;
9 char *p;
11 p = from;
12 for(i = 0; i < 4 && *p; i++){
13 to[i] = strtoul(p, &p, 0);
14 if(*p == '.')
15 p++;
16 }
17 switch(CLASS(to)){
18 case 0: /* class A - 1 uchar net */
19 case 1:
20 if(i == 3){
21 to[3] = to[2];
22 to[2] = to[1];
23 to[1] = 0;
24 } else if (i == 2){
25 to[3] = to[1];
26 to[1] = 0;
27 }
28 break;
29 case 2: /* class B - 2 uchar net */
30 if(i == 3){
31 to[3] = to[2];
32 to[2] = 0;
33 }
34 break;
35 }
36 return p;
37 }
39 ulong
40 parseip(uchar *to, char *from)
41 {
42 int i, elipsis = 0, v4 = 1;
43 ulong x;
44 char *p, *op;
46 memset(to, 0, IPaddrlen);
47 p = from;
48 for(i = 0; i < 16 && *p; i+=2){
49 op = p;
50 x = strtoul(p, &p, 16);
51 if(*p == '.' || (*p == 0 && i == 0)){
52 p = v4parseip(to+i, op);
53 i += 4;
54 break;
55 }
56 to[i] = x>>8;
57 to[i+1] = x;
58 if(*p == ':'){
59 v4 = 0;
60 if(*++p == ':'){
61 elipsis = i+2;
62 p++;
63 }
64 }
65 }
66 if(i < 16){
67 memmove(&to[elipsis+16-i], &to[elipsis], i-elipsis);
68 memset(&to[elipsis], 0, 16-i);
69 }
70 if(v4){
71 to[10] = to[11] = 0xff;
72 return nhgetl(to+12);
73 } else
74 return 6;
75 }
77 /*
78 * hack to allow ip v4 masks to be entered in the old
79 * style
80 */
81 ulong
82 parseipmask(uchar *to, char *from)
83 {
84 ulong x;
85 int i;
86 uchar *p;
88 if(*from == '/'){
89 /* as a number of prefix bits */
90 i = atoi(from+1);
91 if(i < 0)
92 i = 0;
93 if(i > 128)
94 i = 128;
95 memset(to, 0, IPaddrlen);
96 for(p = to; i >= 8; i -= 8)
97 *p++ = 0xff;
98 if(i > 0)
99 *p = ~((1<<(8-i))-1);
100 x = nhgetl(to+IPv4off);
101 } else {
102 /* as a straight bit mask */
103 x = parseip(to, from);
104 if(memcmp(to, v4prefix, IPv4off) == 0)
105 memset(to, 0xff, IPv4off);
107 return x;
110 /*
111 * parse a v4 ip address/mask in cidr format
112 */
113 char*
114 v4parsecidr(uchar *addr, uchar *mask, char *from)
116 int i;
117 char *p;
118 uchar *a;
120 p = v4parseip(addr, from);
122 if(*p == '/'){
123 /* as a number of prefix bits */
124 i = strtoul(p+1, &p, 0);
125 if(i > 32)
126 i = 32;
127 memset(mask, 0, IPv4addrlen);
128 for(a = mask; i >= 8; i -= 8)
129 *a++ = 0xff;
130 if(i > 0)
131 *a = ~((1<<(8-i))-1);
132 } else
133 memcpy(mask, defmask(addr), IPv4addrlen);
134 return p;