plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }