Changeset eecccf1
- Timestamp:
- 2006-05-25T23:08:15Z (19 years ago)
- Branches:
- master
- Children:
- 1cda4f3
- Parents:
- 1705ec3
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
win32.c
r1705ec3 reecccf1 315 315 g_free(lpszStrings[1]); 316 316 } 317 318 void log_link(int level, int output) { /* FIXME */ } 319 320 #ifndef NS_INADDRSZ 321 #define NS_INADDRSZ 4 322 #endif 323 #ifndef NS_IN6ADDRSZ 324 #define NS_IN6ADDRSZ 16 325 #endif 326 #ifndef NS_INT16SZ 327 #define NS_INT16SZ 2 328 #endif 329 330 static const char *inet_ntop4(const guchar *src, char *dst, size_t size); 331 static const char *inet_ntop6(const guchar *src, char *dst, size_t size); 332 333 /* char * 334 * inet_ntop(af, src, dst, size) 335 * convert a network format address to presentation format. 336 * return: 337 * pointer to presentation format address (`dst'), or NULL (see errno). 338 * author: 339 * Paul Vixie, 1996. 340 */ 341 const char * 342 inet_ntop(af, src, dst, size) 343 int af; 344 const void *src; 345 char *dst; 346 size_t size; 347 { 348 switch (af) { 349 case AF_INET: 350 return (inet_ntop4(src, dst, size)); 351 case AF_INET6: 352 return (inet_ntop6(src, dst, size)); 353 default: 354 errno = WSAEAFNOSUPPORT; 355 return (NULL); 356 } 357 /* NOTREACHED */ 358 } 359 360 /* const char * 361 * inet_ntop4(src, dst, size) 362 * format an IPv4 address 363 * return: 364 * `dst' (as a const) 365 * notes: 366 * (1) uses no statics 367 * (2) takes a u_char* not an in_addr as input 368 * author: 369 * Paul Vixie, 1996. 370 */ 371 static const char * 372 inet_ntop4(src, dst, size) 373 const u_char *src; 374 char *dst; 375 size_t size; 376 { 377 static const char fmt[] = "%u.%u.%u.%u"; 378 char tmp[sizeof "255.255.255.255"]; 379 int nprinted; 380 381 nprinted = g_snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); 382 if (nprinted < 0) 383 return (NULL); /* we assume "errno" was set by "g_snprintf()" */ 384 if ((size_t)nprinted > size) { 385 errno = ENOSPC; 386 return (NULL); 387 } 388 strcpy(dst, tmp); 389 return (dst); 390 } 391 392 /* const char * 393 * inet_ntop6(src, dst, size) 394 * convert IPv6 binary address into presentation (printable) format 395 * author: 396 * Paul Vixie, 1996. 397 */ 398 static const char * 399 inet_ntop6(src, dst, size) 400 const u_char *src; 401 char *dst; 402 size_t size; 403 { 404 /* 405 * Note that int32_t and int16_t need only be "at least" large enough 406 * to contain a value of the specified size. On some systems, like 407 * Crays, there is no such thing as an integer variable with 16 bits. 408 * Keep this in mind if you think this function should have been coded 409 * to use pointer overlays. All the world's not a VAX. 410 */ 411 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; 412 struct { int base, len; } best, cur; 413 guint words[NS_IN6ADDRSZ / NS_INT16SZ]; 414 int i; 415 416 /* 417 * Preprocess: 418 * Copy the input (bytewise) array into a wordwise array. 419 * Find the longest run of 0x00's in src[] for :: shorthanding. 420 */ 421 memset(words, '\0', sizeof words); 422 for (i = 0; i < NS_IN6ADDRSZ; i++) 423 words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); 424 best.base = -1; 425 cur.base = -1; 426 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { 427 if (words[i] == 0) { 428 if (cur.base == -1) 429 cur.base = i, cur.len = 1; 430 else 431 cur.len++; 432 } else { 433 if (cur.base != -1) { 434 if (best.base == -1 || cur.len > best.len) 435 best = cur; 436 cur.base = -1; 437 } 438 } 439 } 440 if (cur.base != -1) { 441 if (best.base == -1 || cur.len > best.len) 442 best = cur; 443 } 444 if (best.base != -1 && best.len < 2) 445 best.base = -1; 446 447 /* 448 * Format the result. 449 */ 450 tp = tmp; 451 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { 452 /* Are we inside the best run of 0x00's? */ 453 if (best.base != -1 && i >= best.base && 454 i < (best.base + best.len)) { 455 if (i == best.base) 456 *tp++ = ':'; 457 continue; 458 } 459 /* Are we following an initial run of 0x00s or any real hex? */ 460 if (i != 0) 461 *tp++ = ':'; 462 /* Is this address an encapsulated IPv4? */ 463 if (i == 6 && best.base == 0 && 464 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { 465 if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) 466 return (NULL); 467 tp += strlen(tp); 468 break; 469 } 470 tp += g_snprintf(tp, sizeof tmp - (tp - tmp), "%x", words[i]); 471 } 472 /* Was it a trailing run of 0x00's? */ 473 if (best.base != -1 && (best.base + best.len) == 474 (NS_IN6ADDRSZ / NS_INT16SZ)) 475 *tp++ = ':'; 476 *tp++ = '\0'; 477 478 /* 479 * Check for overflow, copy, and we're done. 480 */ 481 if ((size_t)(tp - tmp) > size) { 482 errno = ENOSPC; 483 return (NULL); 484 } 485 strcpy(dst, tmp); 486 return (dst); 487 } 488 489 #ifdef AF_INET 490 static int inet_pton4(const char *src, u_char *dst); 491 #endif 492 #ifdef AF_INET6 493 static int inet_pton6(const char *src, u_char *dst); 494 #endif 495 496 /* int 497 * inet_pton(af, src, dst) 498 * convert from presentation format (which usually means ASCII printable) 499 * to network format (which is usually some kind of binary format). 500 * return: 501 * 1 if the address was valid for the specified address family 502 * 0 if the address wasn't valid (`dst' is untouched in this case) 503 * -1 if some other error occurred (`dst' is untouched in this case, too) 504 * author: 505 * Paul Vixie, 1996. 506 */ 507 int 508 inet_pton(af, src, dst) 509 int af; 510 const char *src; 511 void *dst; 512 { 513 switch (af) { 514 #ifdef AF_INET 515 case AF_INET: 516 return (inet_pton4(src, dst)); 517 #endif 518 #ifdef AF_INET6 519 case AF_INET6: 520 return (inet_pton6(src, dst)); 521 #endif 522 default: 523 errno = WSAEAFNOSUPPORT; 524 return (-1); 525 } 526 /* NOTREACHED */ 527 } 528 529 #ifdef AF_INET 530 /* int 531 * inet_pton4(src, dst) 532 * like inet_aton() but without all the hexadecimal and shorthand. 533 * return: 534 * 1 if `src' is a valid dotted quad, else 0. 535 * notice: 536 * does not touch `dst' unless it's returning 1. 537 * author: 538 * Paul Vixie, 1996. 539 */ 540 static int 541 inet_pton4(src, dst) 542 const char *src; 543 u_char *dst; 544 { 545 static const char digits[] = "0123456789"; 546 int saw_digit, octets, ch; 547 u_char tmp[NS_INADDRSZ], *tp; 548 549 saw_digit = 0; 550 octets = 0; 551 *(tp = tmp) = 0; 552 while ((ch = *src++) != '\0') { 553 const char *pch; 554 555 if ((pch = strchr(digits, ch)) != NULL) { 556 u_int new = *tp * 10 + (pch - digits); 557 558 if (new > 255) 559 return (0); 560 *tp = new; 561 if (! saw_digit) { 562 if (++octets > 4) 563 return (0); 564 saw_digit = 1; 565 } 566 } else if (ch == '.' && saw_digit) { 567 if (octets == 4) 568 return (0); 569 *++tp = 0; 570 saw_digit = 0; 571 } else 572 return (0); 573 } 574 if (octets < 4) 575 return (0); 576 memcpy(dst, tmp, NS_INADDRSZ); 577 return (1); 578 } 579 #endif 580 581 #ifdef AF_INET6 582 /* int 583 * inet_pton6(src, dst) 584 * convert presentation level address to network order binary form. 585 * return: 586 * 1 if `src' is a valid [RFC1884 2.2] address, else 0. 587 * notice: 588 * (1) does not touch `dst' unless it's returning 1. 589 * (2) :: in a full address is silently ignored. 590 * credit: 591 * inspired by Mark Andrews. 592 * author: 593 * Paul Vixie, 1996. 594 */ 595 static int 596 inet_pton6(src, dst) 597 const char *src; 598 u_char *dst; 599 { 600 static const char xdigits_l[] = "0123456789abcdef", 601 xdigits_u[] = "0123456789ABCDEF"; 602 u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; 603 const char *xdigits, *curtok; 604 int ch, saw_xdigit; 605 u_int val; 606 607 memset((tp = tmp), '\0', NS_IN6ADDRSZ); 608 endp = tp + NS_IN6ADDRSZ; 609 colonp = NULL; 610 /* Leading :: requires some special handling. */ 611 if (*src == ':') 612 if (*++src != ':') 613 return (0); 614 curtok = src; 615 saw_xdigit = 0; 616 val = 0; 617 while ((ch = *src++) != '\0') { 618 const char *pch; 619 620 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) 621 pch = strchr((xdigits = xdigits_u), ch); 622 if (pch != NULL) { 623 val <<= 4; 624 val |= (pch - xdigits); 625 if (val > 0xffff) 626 return (0); 627 saw_xdigit = 1; 628 continue; 629 } 630 if (ch == ':') { 631 curtok = src; 632 if (!saw_xdigit) { 633 if (colonp) 634 return (0); 635 colonp = tp; 636 continue; 637 } else if (*src == '\0') { 638 return (0); 639 } 640 if (tp + NS_INT16SZ > endp) 641 return (0); 642 *tp++ = (u_char) (val >> 8) & 0xff; 643 *tp++ = (u_char) val & 0xff; 644 saw_xdigit = 0; 645 val = 0; 646 continue; 647 } 648 if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && 649 inet_pton4(curtok, tp) > 0) { 650 tp += NS_INADDRSZ; 651 saw_xdigit = 0; 652 break; /* '\0' was seen by inet_pton4(). */ 653 } 654 return (0); 655 } 656 if (saw_xdigit) { 657 if (tp + NS_INT16SZ > endp) 658 return (0); 659 *tp++ = (u_char) (val >> 8) & 0xff; 660 *tp++ = (u_char) val & 0xff; 661 } 662 if (colonp != NULL) { 663 /* 664 * Since some memmove()'s erroneously fail to handle 665 * overlapping regions, we'll do the shift by hand. 666 */ 667 const int n = tp - colonp; 668 int i; 669 670 if (tp == endp) 671 return (0); 672 for (i = 1; i <= n; i++) { 673 endp[- i] = colonp[n - i]; 674 colonp[n - i] = 0; 675 } 676 tp = endp; 677 } 678 if (tp != endp) 679 return (0); 680 memcpy(dst, tmp, NS_IN6ADDRSZ); 681 return (1); 682 } 683 #endif
Note: See TracChangeset
for help on using the changeset viewer.