1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2009 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * Phong Vo <kpv@research.att.com> * 20 * * 21 ***********************************************************************/ 22 #pragma prototyped 23 24 #include <ast.h> 25 #include <ctype.h> 26 27 /* 28 * convert string to 4 byte local byte order ip address 29 * with optional prefix bits 30 * pointer to first unused char placed in *e, even on error 31 * return 0:ok <0:error 32 * 33 * valid addresses match the egrep RE: 34 * 35 * [0-9]{1,3}(\.[0-9]{1,3})*|0[xX][0-9a-fA-Z]+ 36 * 37 * valid bits/masks match the egrep RE: 38 * 39 * (/([0-9]+|[0-9]{1,3}(\.[0-9]{1,3})*))? 40 * 41 * if pbits!=0 and no bits/mask specified then trailing 0's in addr 42 * are used to compute the mask 43 */ 44 45 int 46 strtoip4(register const char* s, char** e, uint32_t* paddr, unsigned char* pbits) 47 { 48 register int c; 49 register unsigned int n; 50 register uint32_t addr; 51 register int part; 52 register unsigned char bits; 53 uint32_t z; 54 int old; 55 int r; 56 const char* b; 57 58 r = -1; 59 while (isspace(*s)) 60 s++; 61 b = s; 62 addr = 0; 63 bits = 0; 64 part = 0; 65 do 66 { 67 n = 0; 68 while ((c = *s++) >= '0' && c <= '9') 69 n = n * 10 + (c - '0'); 70 if ((c == 'x' || c == 'X') && !part) 71 { 72 addr = n; 73 for (;;) 74 { 75 if ((c = *s++) >= '0' && c <= '9') 76 c -= '0'; 77 else if (c >= 'a' && c <= 'f') 78 c -= 'a' - 10; 79 else if (c >= 'A' && c <= 'F') 80 c -= 'F' - 10; 81 else 82 break; 83 addr = addr * 16 + c; 84 } 85 part = 4; 86 break; 87 } 88 if (n > 0xff) 89 goto done; 90 addr = (addr << 8) | n; 91 part++; 92 } while (c == '.'); 93 if ((s - b) == 1 && c != '/' || part > 4) 94 goto done; 95 if (old = part < 4) 96 while (part++ < 4) 97 addr <<= 8; 98 if (pbits) 99 { 100 if (c == '/') 101 { 102 part = 0; 103 z = 0; 104 for (;;) 105 { 106 n = 0; 107 while ((c = *s++) >= '0' && c <= '9') 108 n = n * 10 + (c - '0'); 109 z = (z << 8) | n; 110 part++; 111 if (c != '.') 112 break; 113 old = 1; 114 } 115 if (part > 4) 116 goto done; 117 if (z <= 32 && (!old || part < 2)) 118 bits = z; 119 else if (z) 120 { 121 if (part == 4 && (z & 0x8000001) == 1) 122 z = ~z; 123 while (!(z & 1)) 124 z >>= 1; 125 while (z & 1) 126 { 127 z >>= 1; 128 bits++; 129 } 130 } 131 } 132 else if ((z = (addr >> 24)) < 128) 133 bits = 8; 134 else if (z < 192) 135 bits = 16; 136 else 137 bits = 24; 138 if (*pbits = bits) 139 addr &= ~((((uint32_t)1)<<(32-bits))-1); 140 else 141 addr = 0; 142 } 143 if (paddr) 144 *paddr = addr; 145 r = 0; 146 done: 147 if (e) 148 *e = (char*)(s - 1); 149 return r; 150 } 151