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_pton.c,v 1.7 1999/10/13 16:39:28 vixie Exp $";
20: #endif
21:
22: #include <sys/param.h>
23: #include <sys/types.h>
24: #include <sys/socket.h>
25: #include <netinet/in.h>
26: #include <arpa/inet.h>
27: #include <arpa/nameser.h>
28: #include <ctype.h>
29: #include <string.h>
30: #include <errno.h>
31:
32:
33:
34:
35:
36:
37: static int inet_pton4 (const char *src, u_char *dst) internal_function;
38: static int inet_pton6 (const char *src, u_char *dst) internal_function;
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51: int
52: inet_pton(af, src, dst)
53: int af;
54: const char *src;
55: void *dst;
56: {
57: switch (af) {
58: case AF_INET:
59: return (inet_pton4(src, dst));
60: case AF_INET6:
61: return (inet_pton6(src, dst));
62: default:
63: __set_errno (EAFNOSUPPORT);
64: return (-1);
65: }
66:
67: }
68: libc_hidden_def (inet_pton)
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81: static int
82: internal_function
83: inet_pton4(src, dst)
84: const char *src;
85: u_char *dst;
86: {
87: int saw_digit, octets, ch;
88: u_char tmp[NS_INADDRSZ], *tp;
89:
90: saw_digit = 0;
91: octets = 0;
92: *(tp = tmp) = 0;
93: while ((ch = *src++) != '\0') {
94:
95: if (ch >= '0' && ch <= '9') {
96: u_int new = *tp * 10 + (ch - '0');
97:
98: if (saw_digit && *tp == 0)
99: return (0);
100: if (new > 255)
101: return (0);
102: *tp = new;
103: if (! saw_digit) {
104: if (++octets > 4)
105: return (0);
106: saw_digit = 1;
107: }
108: } else if (ch == '.' && saw_digit) {
109: if (octets == 4)
110: return (0);
111: *++tp = 0;
112: saw_digit = 0;
113: } else
114: return (0);
115: }
116: if (octets < 4)
117: return (0);
118: memcpy(dst, tmp, NS_INADDRSZ);
119: return (1);
120: }
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135: static int
136: internal_function
137: inet_pton6(src, dst)
138: const char *src;
139: u_char *dst;
140: {
141: static const char xdigits[] = "0123456789abcdef";
142: u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
143: const char *curtok;
144: int ch, saw_xdigit;
145: u_int val;
146:
147: tp = memset(tmp, '\0', NS_IN6ADDRSZ);
148: endp = tp + NS_IN6ADDRSZ;
149: colonp = NULL;
150:
151: if (*src == ':')
152: if (*++src != ':')
153: return (0);
154: curtok = src;
155: saw_xdigit = 0;
156: val = 0;
157: while ((ch = tolower (*src++)) != '\0') {
158: const char *pch;
159:
160: pch = strchr(xdigits, ch);
161: if (pch != NULL) {
162: val <<= 4;
163: val |= (pch - xdigits);
164: if (val > 0xffff)
165: return (0);
166: saw_xdigit = 1;
167: continue;
168: }
169: if (ch == ':') {
170: curtok = src;
171: if (!saw_xdigit) {
172: if (colonp)
173: return (0);
174: colonp = tp;
175: continue;
176: } else if (*src == '\0') {
177: return (0);
178: }
179: if (tp + NS_INT16SZ > endp)
180: return (0);
181: *tp++ = (u_char) (val >> 8) & 0xff;
182: *tp++ = (u_char) val & 0xff;
183: saw_xdigit = 0;
184: val = 0;
185: continue;
186: }
187: if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
188: inet_pton4(curtok, tp) > 0) {
189: tp += NS_INADDRSZ;
190: saw_xdigit = 0;
191: break;
192: }
193: return (0);
194: }
195: if (saw_xdigit) {
196: if (tp + NS_INT16SZ > endp)
197: return (0);
198: *tp++ = (u_char) (val >> 8) & 0xff;
199: *tp++ = (u_char) val & 0xff;
200: }
201: if (colonp != NULL) {
202:
203:
204:
205:
206: const int n = tp - colonp;
207: int i;
208:
209: if (tp == endp)
210: return (0);
211: for (i = 1; i <= n; i++) {
212: endp[- i] = colonp[n - i];
213: colonp[n - i] = 0;
214: }
215: tp = endp;
216: }
217: if (tp != endp)
218: return (0);
219: memcpy(dst, tmp, NS_IN6ADDRSZ);
220: return (1);
221: }