|
Lines 558-569
Link Here
|
| 558 |
prefix_t |
558 |
prefix_t |
| 559 |
*prefix_pton(const char *string, long len, const char **errmsg) |
559 |
*prefix_pton(const char *string, long len, const char **errmsg) |
| 560 |
{ |
560 |
{ |
|
|
561 |
unsigned char buf[sizeof(struct in6_addr)]; |
| 561 |
char save[256], *cp, *ep; |
562 |
char save[256], *cp, *ep; |
| 562 |
struct addrinfo hints, *ai; |
|
|
| 563 |
void *addr; |
563 |
void *addr; |
| 564 |
prefix_t *ret; |
564 |
prefix_t *ret; |
| 565 |
size_t slen; |
565 |
size_t slen; |
| 566 |
int r; |
566 |
int domain = AF_INET; |
| 567 |
|
567 |
|
| 568 |
ret = NULL; |
568 |
ret = NULL; |
| 569 |
|
569 |
|
|
Lines 587-612
Link Here
|
| 587 |
} |
587 |
} |
| 588 |
/* More checks below */ |
588 |
/* More checks below */ |
| 589 |
} |
589 |
} |
| 590 |
memset(&hints, '\0', sizeof(hints)); |
|
|
| 591 |
hints.ai_flags = AI_NUMERICHOST; |
| 592 |
|
590 |
|
| 593 |
if ((r = getaddrinfo(save, NULL, &hints, &ai)) != 0) { |
591 |
if (strchr(save,':')) |
| 594 |
snprintf(save, sizeof(save), "getaddrinfo: %s:", |
592 |
domain = AF_INET6; |
| 595 |
gai_strerror(r)); |
593 |
|
| 596 |
*errmsg = save; |
594 |
switch (inet_pton(domain, save, buf)) { |
| 597 |
return NULL; |
595 |
case 1: break; |
| 598 |
} |
596 |
case 0: |
| 599 |
if (ai == NULL || ai->ai_addr == NULL) { |
597 |
*errmsg = "the address is not in presentation format"; |
| 600 |
*errmsg = "getaddrinfo returned no result"; |
598 |
return NULL; |
| 601 |
goto out; |
599 |
case -1: |
|
|
600 |
*errmsg = "the address family is not supported"; |
| 601 |
return NULL; |
| 602 |
default: |
| 603 |
*errmsg = "unknown error"; |
| 604 |
return NULL; |
| 602 |
} |
605 |
} |
| 603 |
switch (ai->ai_addr->sa_family) { |
606 |
*errmsg = "invalid prefix length"; |
|
|
607 |
switch (domain) { |
| 604 |
case AF_INET: |
608 |
case AF_INET: |
| 605 |
if (len == -1) |
609 |
if (len == -1) |
| 606 |
len = 32; |
610 |
len = 32; |
| 607 |
else if (len < 0 || len > 32) |
611 |
else if (len < 0 || len > 32) |
| 608 |
goto out; |
612 |
goto out; |
| 609 |
addr = &((struct sockaddr_in *) ai->ai_addr)->sin_addr; |
613 |
addr = &((struct in_addr *) buf)->s_addr; |
| 610 |
sanitise_mask(addr, len, 32); |
614 |
sanitise_mask(addr, len, 32); |
| 611 |
break; |
615 |
break; |
| 612 |
case AF_INET6: |
616 |
case AF_INET6: |
|
Lines 614-631
Link Here
|
| 614 |
len = 128; |
618 |
len = 128; |
| 615 |
else if (len < 0 || len > 128) |
619 |
else if (len < 0 || len > 128) |
| 616 |
goto out; |
620 |
goto out; |
| 617 |
addr = &((struct sockaddr_in6 *) ai->ai_addr)->sin6_addr; |
621 |
addr = &((struct in6_addr *) buf)->s6_addr; |
| 618 |
sanitise_mask(addr, len, 128); |
622 |
sanitise_mask(addr, len, 128); |
| 619 |
break; |
623 |
break; |
| 620 |
default: |
624 |
default: |
| 621 |
goto out; |
625 |
goto out; |
| 622 |
} |
626 |
} |
| 623 |
|
627 |
|
| 624 |
ret = New_Prefix2(ai->ai_addr->sa_family, addr, len, NULL); |
628 |
ret = New_Prefix2(domain, addr, len, NULL); |
| 625 |
if (ret == NULL) |
629 |
if (ret == NULL) |
| 626 |
*errmsg = "New_Prefix2 failed"; |
630 |
*errmsg = "New_Prefix2 failed"; |
| 627 |
out: |
631 |
out: |
| 628 |
freeaddrinfo(ai); |
|
|
| 629 |
return (ret); |
632 |
return (ret); |
| 630 |
} |
633 |
} |
| 631 |
|
634 |
|