00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "plibc_private.h"
00043
00044 #ifndef HAVE_INET_PTON
00045
00046 #if HAVE_ARPA_NAMESER_H
00047 #include <arpa/nameser.h>
00048 #endif
00049
00050
00051
00052
00053 #if HAVE_WINSOCK_H
00054 #include <winsock2.h>
00055 #include <errno.h>
00056 #include <stdio.h>
00057 #endif
00058
00059 #ifndef EAFNOSUPPORT
00060 #define EAFNOSUPPORT WSAEAFNOSUPPORT
00061 #endif
00062
00063 #ifndef IN6ADDRSZ
00064 #define IN6ADDRSZ 16
00065 #endif
00066
00067 #ifndef INT16SZ
00068 #define INT16SZ 2
00069 #endif
00070
00071
00072
00073
00074 #ifndef INADDRSZ
00075 #define INADDRSZ 4
00076 #endif
00077
00078
00079
00080
00081
00082
00083 int inet_pton4(const char *src, u_char *dst, int pton);
00084 #if USE_IPV6
00085 int inet_pton6(const char *src, u_char *dst);
00086 #endif
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 int inet_pton(int af, const char *src, void *dst)
00100 {
00101
00102 switch (af) {
00103 case AF_INET:
00104 return (inet_pton4(src, dst, 1));
00105 #if USE_IPV6
00106 case AF_INET6:
00107 return (inet_pton6(src, dst));
00108 #endif
00109 default:
00110 errno = EAFNOSUPPORT;
00111 return (-1);
00112 }
00113
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 int inet_pton4(const char *src, u_char *dst, int pton)
00128 {
00129 u_int val;
00130 u_int digit;
00131 int base, n;
00132 unsigned char c;
00133 u_int parts[4];
00134 register u_int *pp = parts;
00135
00136 c = *src;
00137 for (;;) {
00138
00139
00140
00141
00142
00143 if (!isdigit(c))
00144 return (0);
00145 val = 0; base = 10;
00146 if (c == '0') {
00147 c = *++src;
00148 if (c == 'x' || c == 'X')
00149 base = 16, c = *++src;
00150 else if (isdigit(c) && c != '9')
00151 base = 8;
00152 }
00153
00154 if (pton && base != 10)
00155 return (0);
00156 for (;;) {
00157 if (isdigit(c)) {
00158 digit = c - '0';
00159 if (digit >= base)
00160 break;
00161 val = (val * base) + digit;
00162 c = *++src;
00163 } else if (base == 16 && isxdigit(c)) {
00164 digit = c + 10 - (islower(c) ? 'a' : 'A');
00165 if (digit >= 16)
00166 break;
00167 val = (val << 4) | digit;
00168 c = *++src;
00169 } else
00170 break;
00171 }
00172 if (c == '.') {
00173
00174
00175
00176
00177
00178
00179
00180 if (pp >= parts + 3)
00181 return (0);
00182 *pp++ = val;
00183 c = *++src;
00184 } else
00185 break;
00186 }
00187
00188
00189
00190 if (c != '\0' && !isspace(c))
00191 return (0);
00192
00193
00194
00195
00196 n = pp - parts + 1;
00197
00198 if (pton && n != 4)
00199 return (0);
00200 switch (n) {
00201
00202 case 0:
00203 return (0);
00204
00205 case 1:
00206 break;
00207
00208 case 2:
00209 if (parts[0] > 0xff || val > 0xffffff)
00210 return (0);
00211 val |= parts[0] << 24;
00212 break;
00213
00214 case 3:
00215 if ((parts[0] | parts[1]) > 0xff || val > 0xffff)
00216 return (0);
00217 val |= (parts[0] << 24) | (parts[1] << 16);
00218 break;
00219
00220 case 4:
00221 if ((parts[0] | parts[1] | parts[2] | val) > 0xff)
00222 return (0);
00223 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
00224 break;
00225 }
00226 if (dst) {
00227 val = htonl(val);
00228 memcpy(dst, &val, INADDRSZ);
00229 }
00230 return (1);
00231 }
00232
00233 #if USE_IPV6
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 int inet_pton6(const char *src, u_char *dst)
00248 {
00249 static const char xdigits_l[] = "0123456789abcdef",
00250 xdigits_u[] = "0123456789ABCDEF";
00251 u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
00252 const char *xdigits, *curtok;
00253 int ch, saw_xdigit;
00254 u_int val;
00255
00256 memset((tp = tmp), '\0', IN6ADDRSZ);
00257 endp = tp + IN6ADDRSZ;
00258 colonp = NULL;
00259
00260 if (*src == ':')
00261 if (*++src != ':')
00262 return (0);
00263 curtok = src;
00264 saw_xdigit = 0;
00265 val = 0;
00266 while ((ch = *src++) != '\0') {
00267 const char *pch;
00268
00269 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
00270 pch = strchr((xdigits = xdigits_u), ch);
00271 if (pch != NULL) {
00272 val <<= 4;
00273 val |= (pch - xdigits);
00274 if (val > 0xffff)
00275 return (0);
00276 saw_xdigit = 1;
00277 continue;
00278 }
00279 if (ch == ':') {
00280 curtok = src;
00281 if (!saw_xdigit) {
00282 if (colonp)
00283 return (0);
00284 colonp = tp;
00285 continue;
00286 } else if (*src == '\0')
00287 return (0);
00288 if (tp + INT16SZ > endp)
00289 return (0);
00290 *tp++ = (u_char) (val >> 8) & 0xff;
00291 *tp++ = (u_char) val & 0xff;
00292 saw_xdigit = 0;
00293 val = 0;
00294 continue;
00295 }
00296 if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
00297 inet_pton4(curtok, tp, 1) > 0) {
00298 tp += INADDRSZ;
00299 saw_xdigit = 0;
00300 break;
00301 }
00302 return (0);
00303 }
00304 if (saw_xdigit) {
00305 if (tp + INT16SZ > endp)
00306 return (0);
00307 *tp++ = (u_char) (val >> 8) & 0xff;
00308 *tp++ = (u_char) val & 0xff;
00309 }
00310 if (colonp != NULL) {
00311
00312
00313
00314
00315 const int n = tp - colonp;
00316 int i;
00317
00318 if (tp == endp)
00319 return (0);
00320 for (i = 1; i <= n; i++) {
00321 endp[- i] = colonp[n - i];
00322 colonp[n - i] = 0;
00323 }
00324 tp = endp;
00325 }
00326 if (tp != endp)
00327 return (0);
00328 memcpy(dst, tmp, IN6ADDRSZ);
00329 return (1);
00330 }
00331 #endif
00332
00333 #endif