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