00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "stdinc.h"
00046 #include "irc_res.h"
00047
00048 #ifdef NO_IN6ADDR_ANY
00049
00050 const struct in6_addr in6addr_any =
00051 { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } };
00052 #endif
00053
00054 #ifdef NO_INET_ATON
00055
00056
00057
00058
00059
00060
00061
00062 int
00063 inet_aton(const char *cp, struct in_addr * addr)
00064 {
00065 unsigned int val;
00066 int base,
00067 n;
00068 char c;
00069 unsigned int parts[4];
00070 unsigned int *pp = parts;
00071
00072 for (;;)
00073 {
00074
00075
00076
00077
00078 val = 0;
00079 base = 10;
00080 if (*cp == '0')
00081 {
00082 if (*++cp == 'x' || *cp == 'X')
00083 base = 16, cp++;
00084 else
00085 base = 8;
00086 }
00087 while ((c = *cp) != '\0')
00088 {
00089 if (isdigit((unsigned char) c))
00090 {
00091 val = (val * base) + (c - '0');
00092 cp++;
00093 continue;
00094 }
00095 if (base == 16 && isxdigit((unsigned char) c))
00096 {
00097 val = (val << 4) +
00098 (c + 10 - (islower((unsigned char) c) ? 'a' : 'A'));
00099 cp++;
00100 continue;
00101 }
00102 break;
00103 }
00104 if (*cp == '.')
00105 {
00106
00107
00108
00109
00110 if (pp >= parts + 3 || val > 0xff)
00111 return 0;
00112 *pp++ = val, cp++;
00113 }
00114 else
00115 break;
00116 }
00117
00118
00119
00120
00121 while (*cp)
00122 if (!isspace((unsigned char) *cp++))
00123 return 0;
00124
00125
00126
00127
00128 n = pp - parts + 1;
00129 switch (n)
00130 {
00131
00132 case 1:
00133 break;
00134
00135 case 2:
00136 if (val > 0xffffff)
00137 return 0;
00138 val |= parts[0] << 24;
00139 break;
00140
00141 case 3:
00142 if (val > 0xffff)
00143 return 0;
00144 val |= (parts[0] << 24) | (parts[1] << 16);
00145 break;
00146
00147 case 4:
00148 if (val > 0xff)
00149 return 0;
00150 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
00151 break;
00152 }
00153 if (addr)
00154 addr->s_addr = htonl(val);
00155 return 1;
00156 }
00157
00158 #endif
00159
00160 #ifdef NO_INET_NTOP
00161 static const char *inet_ntop4(const unsigned char *src, char *dst,
00162 size_t size);
00163
00164 #ifdef IPV6
00165 static const char *inet_ntop6(const unsigned char *src, char *dst,
00166 size_t size);
00167 #endif
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 const char *
00178 inet_ntop(int af, const void *src, char *dst, size_t size)
00179 {
00180 switch (af) {
00181 case AF_INET:
00182 return (inet_ntop4(src, dst, size));
00183 #ifdef IPV6
00184 case AF_INET6:
00185 return (inet_ntop6(src, dst, size));
00186 #endif
00187 default:
00188 errno = EAFNOSUPPORT;
00189 return (NULL);
00190 }
00191
00192 }
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 static const char *
00206 inet_ntop4(const unsigned char *src, char *dst, size_t size)
00207 {
00208 static const char *fmt = "%u.%u.%u.%u";
00209 char tmp[sizeof "255.255.255.255"];
00210
00211 if ((size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size)
00212 {
00213 errno = ENOSPC;
00214 return (NULL);
00215 }
00216 strcpy(dst, tmp);
00217
00218 return (dst);
00219 }
00220
00221
00222
00223
00224
00225
00226
00227 #ifdef IPV6
00228 static const char *
00229 inet_ntop6(const unsigned char *src, char *dst, size_t size)
00230 {
00231
00232
00233
00234
00235
00236
00237
00238 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
00239 struct { int base, len; } best, cur;
00240 unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
00241 int i;
00242
00243
00244
00245
00246
00247
00248 memset(words, '\0', sizeof words);
00249 for (i = 0; i < NS_IN6ADDRSZ; i++)
00250 words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
00251 best.base = -1;
00252 cur.base = -1;
00253 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
00254 if (words[i] == 0) {
00255 if (cur.base == -1)
00256 cur.base = i, cur.len = 1;
00257 else
00258 cur.len++;
00259 } else {
00260 if (cur.base != -1) {
00261 if (best.base == -1 || cur.len > best.len)
00262 best = cur;
00263 cur.base = -1;
00264 }
00265 }
00266 }
00267 if (cur.base != -1) {
00268 if (best.base == -1 || cur.len > best.len)
00269 best = cur;
00270 }
00271 if (best.base != -1 && best.len < 2)
00272 best.base = -1;
00273
00274
00275
00276
00277 tp = tmp;
00278 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
00279
00280 if (best.base != -1 && i >= best.base &&
00281 i < (best.base + best.len)) {
00282 if (i == best.base)
00283 *tp++ = ':';
00284 continue;
00285 }
00286
00287 if (i != 0)
00288 *tp++ = ':';
00289
00290 if (i == 6 && best.base == 0 &&
00291 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
00292 if (!inet_ntop4(src+12, tp,
00293 sizeof tmp - (tp - tmp)))
00294 return (NULL);
00295 tp += strlen(tp);
00296 break;
00297 }
00298 tp += sprintf(tp, "%x", words[i]);
00299 }
00300
00301 if (best.base != -1 && (best.base + best.len) ==
00302 (NS_IN6ADDRSZ / NS_INT16SZ))
00303 *tp++ = ':';
00304 *tp++ = '\0';
00305
00306
00307
00308
00309 if ((size_t)(tp - tmp) > size) {
00310 errno = ENOSPC;
00311 return (NULL);
00312 }
00313 strcpy(dst, tmp);
00314 return (dst);
00315 }
00316 #endif
00317
00318 #endif
00319
00320 #ifdef NO_INET_PTON
00321
00322 static int inet_pton4(const char *src, unsigned char *dst);
00323 #ifdef IPV6
00324 static int inet_pton6(const char *src, unsigned char *dst);
00325 #endif
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 int
00339 inet_pton(int af,
00340 const char *src,
00341 void *dst)
00342 {
00343 switch (af) {
00344 case AF_INET:
00345 return (inet_pton4(src, dst));
00346 #ifdef IPV6
00347 case AF_INET6:
00348 return (inet_pton6(src, dst));
00349 #endif
00350 default:
00351 errno = EAFNOSUPPORT;
00352 return (-1);
00353 }
00354
00355 }
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 static int
00368 inet_pton4(src, dst)
00369 const char *src;
00370 unsigned char *dst;
00371 {
00372 static const char digits[] = "0123456789";
00373 int saw_digit, octets, ch;
00374 unsigned char tmp[NS_INADDRSZ], *tp;
00375
00376 saw_digit = 0;
00377 octets = 0;
00378 *(tp = tmp) = 0;
00379 while ((ch = *src++) != '\0') {
00380 const char *pch;
00381
00382 if ((pch = strchr(digits, ch)) != NULL) {
00383 unsigned int new = *tp * 10 + (pch - digits);
00384
00385 if (new > 255)
00386 return (0);
00387 *tp = new;
00388 if (! saw_digit) {
00389 if (++octets > 4)
00390 return (0);
00391 saw_digit = 1;
00392 }
00393 } else if (ch == '.' && saw_digit) {
00394 if (octets == 4)
00395 return (0);
00396 *++tp = 0;
00397 saw_digit = 0;
00398 } else
00399 return (0);
00400 }
00401 if (octets < 4)
00402 return (0);
00403 memcpy(dst, tmp, NS_INADDRSZ);
00404 return (1);
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 #ifdef IPV6
00421 static int
00422 inet_pton6(src, dst)
00423 const char *src;
00424 unsigned char *dst;
00425 {
00426 static const char xdigits_l[] = "0123456789abcdef",
00427 xdigits_u[] = "0123456789ABCDEF";
00428 unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
00429 const char *xdigits, *curtok;
00430 int ch, saw_xdigit;
00431 unsigned int val;
00432
00433 memset((tp = tmp), '\0', NS_IN6ADDRSZ);
00434 endp = tp + NS_IN6ADDRSZ;
00435 colonp = NULL;
00436
00437 if (*src == ':')
00438 if (*++src != ':')
00439 return (0);
00440 curtok = src;
00441 saw_xdigit = 0;
00442 val = 0;
00443 while ((ch = *src++) != '\0') {
00444 const char *pch;
00445
00446 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
00447 pch = strchr((xdigits = xdigits_u), ch);
00448 if (pch != NULL) {
00449 val <<= 4;
00450 val |= (pch - xdigits);
00451 if (val > 0xffff)
00452 return (0);
00453 saw_xdigit = 1;
00454 continue;
00455 }
00456 if (ch == ':') {
00457 curtok = src;
00458 if (!saw_xdigit) {
00459 if (colonp)
00460 return (0);
00461 colonp = tp;
00462 continue;
00463 }
00464 if (tp + NS_INT16SZ > endp)
00465 return (0);
00466 *tp++ = (unsigned char) (val >> 8) & 0xff;
00467 *tp++ = (unsigned char) val & 0xff;
00468 saw_xdigit = 0;
00469 val = 0;
00470 continue;
00471 }
00472 if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
00473 inet_pton4(curtok, tp) > 0) {
00474 tp += NS_INADDRSZ;
00475 saw_xdigit = 0;
00476 break;
00477 }
00478 return (0);
00479 }
00480 if (saw_xdigit) {
00481 if (tp + NS_INT16SZ > endp)
00482 return (0);
00483 *tp++ = (unsigned char) (val >> 8) & 0xff;
00484 *tp++ = (unsigned char) val & 0xff;
00485 }
00486 if (colonp != NULL) {
00487
00488
00489
00490
00491 const int n = tp - colonp;
00492 int i;
00493
00494 for (i = 1; i <= n; i++) {
00495 endp[- i] = colonp[n - i];
00496 colonp[n - i] = 0;
00497 }
00498 tp = endp;
00499 }
00500 if (tp != endp)
00501 return (0);
00502 memcpy(dst, tmp, NS_IN6ADDRSZ);
00503 return (1);
00504 }
00505 #endif
00506
00507 #endif