Returns 1 for a valid IPv4 or IPv6 addr, or 0 for a bad one. */
| 467 | |
| 468 | /* Returns 1 for a valid IPv4 or IPv6 addr, or 0 for a bad one. */ |
| 469 | static int valid_ipaddr(const char *s, int allow_scope) |
| 470 | { |
| 471 | int i; |
| 472 | |
| 473 | if (strchr(s, ':') != NULL) { /* Only IPv6 has a colon. */ |
| 474 | int count, saw_double_colon = 0; |
| 475 | int ipv4_at_end = 0; |
| 476 | |
| 477 | if (*s == ':') { /* A colon at the start must be a :: */ |
| 478 | if (*++s != ':') |
| 479 | return 0; |
| 480 | saw_double_colon = 1; |
| 481 | s++; |
| 482 | } |
| 483 | |
| 484 | for (count = 0; count < 8; count++) { |
| 485 | if (!*s) |
| 486 | return saw_double_colon; |
| 487 | if (allow_scope && *s == '%') { |
| 488 | if (saw_double_colon) |
| 489 | break; |
| 490 | return 0; |
| 491 | } |
| 492 | |
| 493 | if (strchr(s, ':') == NULL && strchr(s, '.') != NULL) { |
| 494 | if ((!saw_double_colon && count != 6) || (saw_double_colon && count > 6)) |
| 495 | return 0; |
| 496 | ipv4_at_end = 1; |
| 497 | break; |
| 498 | } |
| 499 | |
| 500 | if (!isHexDigit(s++)) /* Need 1-4 hex digits */ |
| 501 | return 0; |
| 502 | if (isHexDigit(s) && isHexDigit(++s) && isHexDigit(++s) && isHexDigit(++s)) |
| 503 | return 0; |
| 504 | |
| 505 | if (*s == ':') { |
| 506 | if (!*++s) |
| 507 | return 0; |
| 508 | if (*s == ':') { |
| 509 | if (saw_double_colon) |
| 510 | return 0; |
| 511 | saw_double_colon = 1; |
| 512 | s++; |
| 513 | } |
| 514 | } |
| 515 | } |
| 516 | |
| 517 | if (!ipv4_at_end) { |
| 518 | if (allow_scope && *s == '%') |
| 519 | for (s++; isAlNum(s); s++) { } |
| 520 | return !*s && s[-1] != '%'; |
| 521 | } |
| 522 | } |
| 523 | |
| 524 | /* IPv4 */ |
| 525 | for (i = 0; i < 4; i++) { |
| 526 | long n; |
no test coverage detected