parseip.c (2129B)
1 #include <u.h> 2 #include <libc.h> 3 #include <ip.h> 4 5 char* 6 v4parseip(uchar *to, char *from) 7 { 8 int i; 9 char *p; 10 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 } 38 39 ulong 40 parseip(uchar *to, char *from) 41 { 42 int i, elipsis = 0, v4 = 1; 43 ulong x; 44 char *p, *op; 45 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 } 76 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; 87 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); 106 } 107 return x; 108 } 109 110 /* 111 * parse a v4 ip address/mask in cidr format 112 */ 113 char* 114 v4parsecidr(uchar *addr, uchar *mask, char *from) 115 { 116 int i; 117 char *p; 118 uchar *a; 119 120 p = v4parseip(addr, from); 121 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; 135 }