1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18: #if defined(LIBC_SCCS) && !defined(lint)
19: static const char rcsid[] = "$BINDId: inet_net_pton.c,v 1.11 1999/01/08 19:23:44 vixie Exp $";
20: #endif
21:
22: #include <sys/types.h>
23: #include <sys/socket.h>
24: #include <netinet/in.h>
25: #include <arpa/inet.h>
26:
27: #include <assert.h>
28: #include <ctype.h>
29: #include <errno.h>
30: #include <stdio.h>
31: #include <string.h>
32: #include <stdlib.h>
33:
34: #ifdef SPRINTF_CHAR
35: # define SPRINTF(x) strlen(sprintfx)
36: #else
37: # define SPRINTF(x) ((size_t)sprintf x)
38: #endif
39:
40: static int inet_net_pton_ipv4 (const char *src, u_char *dst,
41: size_t size) __THROW;
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56: int
57: inet_net_pton(af, src, dst, size)
58: int af;
59: const char *src;
60: void *dst;
61: size_t size;
62: {
63: switch (af) {
64: case AF_INET:
65: return (inet_net_pton_ipv4(src, dst, size));
66: default:
67: __set_errno (EAFNOSUPPORT);
68: return (-1);
69: }
70: }
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88: static int
89: inet_net_pton_ipv4(src, dst, size)
90: const char *src;
91: u_char *dst;
92: size_t size;
93: {
94: static const char xdigits[] = "0123456789abcdef";
95: int n, ch, tmp, dirty, bits;
96: const u_char *odst = dst;
97:
98: ch = *src++;
99: if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
100: && isascii(src[1]) && isxdigit(src[1])) {
101:
102: if (size <= 0)
103: goto emsgsize;
104: dirty = 0;
105: tmp = 0;
106: src++;
107: while (isxdigit((ch = *src++))) {
108: ch = _tolower(ch);
109: n = (const char *) __rawmemchr(xdigits, ch) - xdigits;
110: assert(n >= 0 && n <= 15);
111: if (dirty == 0)
112: tmp = n;
113: else
114: tmp = (tmp << 4) | n;
115: if (++dirty == 2) {
116: if (size-- <= 0)
117: goto emsgsize;
118: *dst++ = (u_char) tmp;
119: dirty = 0;
120: }
121: }
122: if (dirty) {
123: if (size-- <= 0)
124: goto emsgsize;
125: *dst++ = (u_char) (tmp << 4);
126: }
127: } else if (isascii(ch) && isdigit(ch)) {
128:
129: for (;;) {
130: tmp = 0;
131: do {
132: n = ((const char *) __rawmemchr(xdigits, ch)
133: - xdigits);
134: assert(n >= 0 && n <= 9);
135: tmp *= 10;
136: tmp += n;
137: if (tmp > 255)
138: goto enoent;
139: } while (isascii((ch = *src++)) && isdigit(ch));
140: if (size-- <= 0)
141: goto emsgsize;
142: *dst++ = (u_char) tmp;
143: if (ch == '\0' || ch == '/')
144: break;
145: if (ch != '.')
146: goto enoent;
147: ch = *src++;
148: if (!isascii(ch) || !isdigit(ch))
149: goto enoent;
150: }
151: } else
152: goto enoent;
153:
154: bits = -1;
155: if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
156:
157: ch = *src++;
158: bits = 0;
159: do {
160: n = (const char *) __rawmemchr(xdigits, ch) - xdigits;
161: assert(n >= 0 && n <= 9);
162: bits *= 10;
163: bits += n;
164: } while (isascii((ch = *src++)) && isdigit(ch));
165: if (ch != '\0')
166: goto enoent;
167: if (bits > 32)
168: goto emsgsize;
169: }
170:
171:
172: if (ch != '\0')
173: goto enoent;
174:
175:
176: if (dst == odst)
177: goto enoent;
178:
179: if (bits == -1) {
180: if (*odst >= 240)
181: bits = 32;
182: else if (*odst >= 224)
183: bits = 4;
184: else if (*odst >= 192)
185: bits = 24;
186: else if (*odst >= 128)
187: bits = 16;
188: else
189: bits = 8;
190:
191: if (bits >= 8 && bits < ((dst - odst) * 8))
192: bits = (dst - odst) * 8;
193: }
194:
195: while (bits > ((dst - odst) * 8)) {
196: if (size-- <= 0)
197: goto emsgsize;
198: *dst++ = '\0';
199: }
200: return (bits);
201:
202: enoent:
203: __set_errno (ENOENT);
204: return (-1);
205:
206: emsgsize:
207: __set_errno (EMSGSIZE);
208: return (-1);
209: }