sockaddr.c (302408) | sockaddr.c (362181) |
---|---|
1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 --- 11 unchanged lines hidden (view full) --- 20#include "apr_lib.h" 21#include "apr_strings.h" 22#include "apr_private.h" 23 24#if APR_HAVE_STDLIB_H 25#include <stdlib.h> 26#endif 27 | 1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 --- 11 unchanged lines hidden (view full) --- 20#include "apr_lib.h" 21#include "apr_strings.h" 22#include "apr_private.h" 23 24#if APR_HAVE_STDLIB_H 25#include <stdlib.h> 26#endif 27 |
28#ifdef HAVE_NET_IF_H 29#include <net/if.h> 30#endif 31 32#if defined(HAVE_IF_INDEXTONAME) && defined(_MSC_VER) 33#include "arch/win32/apr_arch_misc.h" 34#endif 35 |
|
28#define APR_WANT_STRFUNC 29#include "apr_want.h" 30 31struct apr_ipsubnet_t { 32 int family; 33#if APR_HAVE_IPV6 34 apr_uint32_t sub[4]; /* big enough for IPv4 and IPv6 addresses */ 35 apr_uint32_t mask[4]; --- 84 unchanged lines hidden (view full) --- 120 && buflen > strlen("::ffff:")) { 121 /* This is an IPv4-mapped IPv6 address; drop the leading 122 * part of the address string so we're left with the familiar 123 * IPv4 format. 124 */ 125 memmove(buf, buf + strlen("::ffff:"), 126 strlen(buf + strlen("::ffff:"))+1); 127 } | 36#define APR_WANT_STRFUNC 37#include "apr_want.h" 38 39struct apr_ipsubnet_t { 40 int family; 41#if APR_HAVE_IPV6 42 apr_uint32_t sub[4]; /* big enough for IPv4 and IPv6 addresses */ 43 apr_uint32_t mask[4]; --- 84 unchanged lines hidden (view full) --- 128 && buflen > strlen("::ffff:")) { 129 /* This is an IPv4-mapped IPv6 address; drop the leading 130 * part of the address string so we're left with the familiar 131 * IPv4 format. 132 */ 133 memmove(buf, buf + strlen("::ffff:"), 134 strlen(buf + strlen("::ffff:"))+1); 135 } |
128#endif | 136 |
129 /* ensure NUL termination if the buffer is too short */ 130 buf[buflen-1] = '\0'; | 137 /* ensure NUL termination if the buffer is too short */ 138 buf[buflen-1] = '\0'; |
139 140#ifdef HAVE_IF_INDEXTONAME 141 /* Append scope name for link-local addresses. */ 142 if (sockaddr->family == AF_INET6 143 && IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)sockaddr->ipaddr_ptr)) { 144 char scbuf[IF_NAMESIZE], *p = buf + strlen(buf); 145 146 if (if_indextoname(sockaddr->sa.sin6.sin6_scope_id, scbuf) == scbuf) { 147 /* Space check, need room for buf + '%' + scope + '\0'. 148 * Assert: buflen >= strlen(buf) + strlen(scbuf) + 2 149 * Equiv: buflen >= (p-buf) + strlen(buf) + 2 150 * Thus, fail in inverse condition: */ 151 if (buflen < strlen(scbuf) + (p - buf) + 2) { 152 return APR_ENOSPC; 153 } 154 *p++ = '%'; 155 memcpy(p, scbuf, strlen(scbuf) + 1); 156 } 157 } 158#endif /* HAVE_IF_INDEXTONAME */ 159#endif /* APR_HAVE_IPV6 */ 160 |
|
131 return APR_SUCCESS; 132} 133 134APR_DECLARE(apr_status_t) apr_sockaddr_ip_get(char **addr, 135 apr_sockaddr_t *sockaddr) 136{ 137 *addr = apr_palloc(sockaddr->pool, sockaddr->addr_str_len); 138 return apr_sockaddr_ip_getbuf(*addr, sockaddr->addr_str_len, sockaddr); --- 23 unchanged lines hidden (view full) --- 162#if APR_HAVE_IPV6 163 else if (family == APR_INET6) { 164 addr->salen = sizeof(struct sockaddr_in6); 165 addr->addr_str_len = 46; 166 addr->ipaddr_ptr = &(addr->sa.sin6.sin6_addr); 167 addr->ipaddr_len = sizeof(struct in6_addr); 168 } 169#endif | 161 return APR_SUCCESS; 162} 163 164APR_DECLARE(apr_status_t) apr_sockaddr_ip_get(char **addr, 165 apr_sockaddr_t *sockaddr) 166{ 167 *addr = apr_palloc(sockaddr->pool, sockaddr->addr_str_len); 168 return apr_sockaddr_ip_getbuf(*addr, sockaddr->addr_str_len, sockaddr); --- 23 unchanged lines hidden (view full) --- 192#if APR_HAVE_IPV6 193 else if (family == APR_INET6) { 194 addr->salen = sizeof(struct sockaddr_in6); 195 addr->addr_str_len = 46; 196 addr->ipaddr_ptr = &(addr->sa.sin6.sin6_addr); 197 addr->ipaddr_len = sizeof(struct in6_addr); 198 } 199#endif |
200#if APR_HAVE_SOCKADDR_UN 201 else if (family == APR_UNIX) { 202 addr->salen = sizeof(struct sockaddr_un); 203 addr->addr_str_len = sizeof(addr->sa.unx.sun_path);; 204 addr->ipaddr_ptr = &(addr->sa.unx.sun_path); 205 addr->ipaddr_len = addr->addr_str_len; 206 } 207#endif |
|
170} 171 172APR_DECLARE(apr_status_t) apr_socket_addr_get(apr_sockaddr_t **sa, 173 apr_interface_e which, 174 apr_socket_t *sock) 175{ 176 if (which == APR_LOCAL) { 177 if (sock->local_interface_unknown || sock->local_port_unknown) { --- 86 unchanged lines hidden (view full) --- 264 /* handle scope id; this is the only context where it is allowed */ 265 scope_delim = memchr(str, '%', addrlen); 266 if (scope_delim) { 267 if (scope_delim == end_bracket - 1) { /* '%' without scope id */ 268 *port = 0; 269 return APR_EINVAL; 270 } 271 addrlen = scope_delim - str - 1; | 208} 209 210APR_DECLARE(apr_status_t) apr_socket_addr_get(apr_sockaddr_t **sa, 211 apr_interface_e which, 212 apr_socket_t *sock) 213{ 214 if (which == APR_LOCAL) { 215 if (sock->local_interface_unknown || sock->local_port_unknown) { --- 86 unchanged lines hidden (view full) --- 302 /* handle scope id; this is the only context where it is allowed */ 303 scope_delim = memchr(str, '%', addrlen); 304 if (scope_delim) { 305 if (scope_delim == end_bracket - 1) { /* '%' without scope id */ 306 *port = 0; 307 return APR_EINVAL; 308 } 309 addrlen = scope_delim - str - 1; |
272 *scope_id = apr_palloc(p, end_bracket - scope_delim); 273 memcpy(*scope_id, scope_delim + 1, end_bracket - scope_delim - 1); 274 (*scope_id)[end_bracket - scope_delim - 1] = '\0'; | 310 *scope_id = apr_pstrmemdup(p, scope_delim + 1, end_bracket - scope_delim - 1); |
275 } 276 else { 277 addrlen = addrlen - 2; /* minus 2 for '[' and ']' */ 278 } 279 | 311 } 312 else { 313 addrlen = addrlen - 2; /* minus 2 for '[' and ']' */ 314 } 315 |
280 *addr = apr_palloc(p, addrlen + 1); 281 memcpy(*addr, 282 str + 1, 283 addrlen); 284 (*addr)[addrlen] = '\0'; | 316 *addr = apr_pstrmemdup(p, str + 1, addrlen); |
285 if (apr_inet_pton(AF_INET6, *addr, &ipaddr) != 1) { 286 *addr = NULL; 287 *scope_id = NULL; 288 *port = 0; 289 return APR_EINVAL; 290 } 291 } 292 else 293#endif 294 { 295 /* XXX If '%' is not a valid char in a DNS name, we *could* check 296 * for bogus scope ids first. 297 */ | 317 if (apr_inet_pton(AF_INET6, *addr, &ipaddr) != 1) { 318 *addr = NULL; 319 *scope_id = NULL; 320 *port = 0; 321 return APR_EINVAL; 322 } 323 } 324 else 325#endif 326 { 327 /* XXX If '%' is not a valid char in a DNS name, we *could* check 328 * for bogus scope ids first. 329 */ |
298 *addr = apr_palloc(p, addrlen + 1); 299 memcpy(*addr, str, addrlen); 300 (*addr)[addrlen] = '\0'; | 330 *addr = apr_pstrmemdup(p, str, addrlen); |
301 } 302 return APR_SUCCESS; 303} 304 305#if defined(HAVE_GETADDRINFO) 306 307static apr_status_t call_resolver(apr_sockaddr_t **sa, 308 const char *hostname, apr_int32_t family, --- 308 unchanged lines hidden (view full) --- 617 return APR_EINVAL; 618 } 619#if !APR_HAVE_IPV6 620 if (flags & APR_IPV6_ADDR_OK) { 621 return APR_ENOTIMPL; 622 } 623#endif 624 } | 331 } 332 return APR_SUCCESS; 333} 334 335#if defined(HAVE_GETADDRINFO) 336 337static apr_status_t call_resolver(apr_sockaddr_t **sa, 338 const char *hostname, apr_int32_t family, --- 308 unchanged lines hidden (view full) --- 647 return APR_EINVAL; 648 } 649#if !APR_HAVE_IPV6 650 if (flags & APR_IPV6_ADDR_OK) { 651 return APR_ENOTIMPL; 652 } 653#endif 654 } |
655 if (family == APR_UNSPEC && hostname && *hostname == '/') { 656 family = APR_UNIX; 657 } 658 if (family == APR_UNIX) { 659#if APR_HAVE_SOCKADDR_UN 660 if (hostname && *hostname == '/') { 661 *sa = apr_pcalloc(p, sizeof(apr_sockaddr_t)); 662 (*sa)->pool = p; 663 apr_cpystrn((*sa)->sa.unx.sun_path, hostname, 664 sizeof((*sa)->sa.unx.sun_path)); 665 (*sa)->hostname = apr_pstrdup(p, hostname); 666 (*sa)->family = APR_UNIX; 667 (*sa)->sa.unx.sun_family = APR_UNIX; 668 (*sa)->salen = sizeof(struct sockaddr_un); 669 (*sa)->addr_str_len = sizeof((*sa)->sa.unx.sun_path); 670 (*sa)->ipaddr_ptr = &((*sa)->sa.unx.sun_path); 671 (*sa)->ipaddr_len = (*sa)->addr_str_len; 672 673 return APR_SUCCESS; 674 } 675 else 676#endif 677 { 678 *sa = NULL; 679 return APR_ENOTIMPL; 680 } 681 } |
|
625#if !APR_HAVE_IPV6 626 /* What may happen is that APR is not IPv6-enabled, but we're still 627 * going to call getaddrinfo(), so we have to tell the OS we only 628 * want IPv4 addresses back since we won't know what to do with 629 * IPv6 addresses. 630 */ 631 if (family == APR_UNSPEC) { 632 family = APR_INET; 633 } 634#endif 635 636 return find_addresses(sa, hostname, family, port, flags, p); 637} 638 | 682#if !APR_HAVE_IPV6 683 /* What may happen is that APR is not IPv6-enabled, but we're still 684 * going to call getaddrinfo(), so we have to tell the OS we only 685 * want IPv4 addresses back since we won't know what to do with 686 * IPv6 addresses. 687 */ 688 if (family == APR_UNSPEC) { 689 family = APR_INET; 690 } 691#endif 692 693 return find_addresses(sa, hostname, family, port, flags, p); 694} 695 |
696APR_DECLARE(apr_status_t) apr_sockaddr_info_copy(apr_sockaddr_t **dst, 697 const apr_sockaddr_t *src, 698 apr_pool_t *p) 699{ 700 apr_sockaddr_t *d; 701 const apr_sockaddr_t *s; 702 703 for (*dst = d = NULL, s = src; s; s = s->next) { 704 if (!d) { 705 *dst = d = apr_pmemdup(p, s, sizeof *s); 706 } 707 else { 708 d = d->next = apr_pmemdup(p, s, sizeof *s); 709 } 710 if (s->hostname) { 711 if (s == src || s->hostname != src->hostname) { 712 d->hostname = apr_pstrdup(p, s->hostname); 713 } 714 else { 715 d->hostname = (*dst)->hostname; 716 } 717 } 718 if (s->servname) { 719 if (s == src || s->servname != src->servname) { 720 d->servname = apr_pstrdup(p, s->servname); 721 } 722 else { 723 d->servname = (*dst)->servname; 724 } 725 } 726 d->pool = p; 727 apr_sockaddr_vars_set(d, s->family, s->port); 728 } 729 return APR_SUCCESS; 730} 731 |
|
639APR_DECLARE(apr_status_t) apr_getnameinfo(char **hostname, 640 apr_sockaddr_t *sockaddr, 641 apr_int32_t flags) 642{ 643#if defined(HAVE_GETNAMEINFO) 644 int rc; 645#if defined(NI_MAXHOST) 646 char tmphostname[NI_MAXHOST]; --- 22 unchanged lines hidden (view full) --- 669#ifdef SIN6_LEN 670 tmpsa.sin_len = sizeof(tmpsa); 671#endif 672 673 rc = getnameinfo((const struct sockaddr *)&tmpsa, sizeof(tmpsa), 674 tmphostname, sizeof(tmphostname), NULL, 0, 675 flags != 0 ? flags : NI_NAMEREQD); 676 } | 732APR_DECLARE(apr_status_t) apr_getnameinfo(char **hostname, 733 apr_sockaddr_t *sockaddr, 734 apr_int32_t flags) 735{ 736#if defined(HAVE_GETNAMEINFO) 737 int rc; 738#if defined(NI_MAXHOST) 739 char tmphostname[NI_MAXHOST]; --- 22 unchanged lines hidden (view full) --- 762#ifdef SIN6_LEN 763 tmpsa.sin_len = sizeof(tmpsa); 764#endif 765 766 rc = getnameinfo((const struct sockaddr *)&tmpsa, sizeof(tmpsa), 767 tmphostname, sizeof(tmphostname), NULL, 0, 768 flags != 0 ? flags : NI_NAMEREQD); 769 } |
770#if APR_HAVE_SOCKADDR_UN 771 else if (sockaddr->family == APR_UNIX) { 772 *hostname = sockaddr->hostname; 773 return APR_SUCCESS; 774 } 775#endif |
|
677 else 678#endif 679 rc = getnameinfo((const struct sockaddr *)&sockaddr->sa, sockaddr->salen, 680 tmphostname, sizeof(tmphostname), NULL, 0, 681 flags != 0 ? flags : NI_NAMEREQD); 682 if (rc != 0) { 683 *hostname = NULL; 684 --- 141 unchanged lines hidden (view full) --- 826#define V4MAPPED_EQUAL(a,b) \ 827((a)->sa.sin.sin_family == AF_INET && \ 828 (b)->sa.sin.sin_family == AF_INET6 && \ 829 IN6_IS_ADDR_V4MAPPED((struct in6_addr *)(b)->ipaddr_ptr) && \ 830 !memcmp((a)->ipaddr_ptr, \ 831 &((struct in6_addr *)(b)->ipaddr_ptr)->s6_addr[12], \ 832 (a)->ipaddr_len)) 833 | 776 else 777#endif 778 rc = getnameinfo((const struct sockaddr *)&sockaddr->sa, sockaddr->salen, 779 tmphostname, sizeof(tmphostname), NULL, 0, 780 flags != 0 ? flags : NI_NAMEREQD); 781 if (rc != 0) { 782 *hostname = NULL; 783 --- 141 unchanged lines hidden (view full) --- 925#define V4MAPPED_EQUAL(a,b) \ 926((a)->sa.sin.sin_family == AF_INET && \ 927 (b)->sa.sin.sin_family == AF_INET6 && \ 928 IN6_IS_ADDR_V4MAPPED((struct in6_addr *)(b)->ipaddr_ptr) && \ 929 !memcmp((a)->ipaddr_ptr, \ 930 &((struct in6_addr *)(b)->ipaddr_ptr)->s6_addr[12], \ 931 (a)->ipaddr_len)) 932 |
933#if APR_HAVE_IPV6 934#define SCOPE_OR_ZERO(sa_) ((sa_)->family != AF_INET6 ? 0 : \ 935 ((sa_)->sa.sin6.sin6_scope_id)) 936#else 937#define SCOPE_OR_ZERO(sa_) (0) 938#endif 939 |
|
834APR_DECLARE(int) apr_sockaddr_equal(const apr_sockaddr_t *addr1, 835 const apr_sockaddr_t *addr2) 836{ | 940APR_DECLARE(int) apr_sockaddr_equal(const apr_sockaddr_t *addr1, 941 const apr_sockaddr_t *addr2) 942{ |
837 if (addr1->ipaddr_len == addr2->ipaddr_len && 838 !memcmp(addr1->ipaddr_ptr, addr2->ipaddr_ptr, addr1->ipaddr_len)) { | 943 if (addr1->ipaddr_len == addr2->ipaddr_len 944 && !memcmp(addr1->ipaddr_ptr, addr2->ipaddr_ptr, addr1->ipaddr_len) 945 && SCOPE_OR_ZERO(addr1) == SCOPE_OR_ZERO(addr2)) { |
839 return 1; 840 } 841#if APR_HAVE_IPV6 842 if (V4MAPPED_EQUAL(addr1, addr2)) { 843 return 1; 844 } 845 if (V4MAPPED_EQUAL(addr2, addr1)) { 846 return 1; --- 133 unchanged lines hidden (view full) --- 980 return APR_EBADIP; 981 } 982 } 983 return APR_SUCCESS; 984} 985 986static int looks_like_ip(const char *ipstr) 987{ | 946 return 1; 947 } 948#if APR_HAVE_IPV6 949 if (V4MAPPED_EQUAL(addr1, addr2)) { 950 return 1; 951 } 952 if (V4MAPPED_EQUAL(addr2, addr1)) { 953 return 1; --- 133 unchanged lines hidden (view full) --- 1087 return APR_EBADIP; 1088 } 1089 } 1090 return APR_SUCCESS; 1091} 1092 1093static int looks_like_ip(const char *ipstr) 1094{ |
1095 if (strlen(ipstr) == 0) { 1096 return 0; 1097 } 1098 |
|
988 if (strchr(ipstr, ':')) { 989 /* definitely not a hostname; assume it is intended to be an IPv6 address */ 990 return 1; 991 } 992 993 /* simple IPv4 address string check */ 994 while ((*ipstr == '.') || apr_isdigit(*ipstr)) 995 ipstr++; --- 109 unchanged lines hidden (view full) --- 1105 } 1106#else 1107 if ((sa->sa.sin.sin_addr.s_addr & ipsub->mask[0]) == ipsub->sub[0]) { 1108 return 1; 1109 } 1110#endif /* APR_HAVE_IPV6 */ 1111 return 0; /* no match */ 1112} | 1099 if (strchr(ipstr, ':')) { 1100 /* definitely not a hostname; assume it is intended to be an IPv6 address */ 1101 return 1; 1102 } 1103 1104 /* simple IPv4 address string check */ 1105 while ((*ipstr == '.') || apr_isdigit(*ipstr)) 1106 ipstr++; --- 109 unchanged lines hidden (view full) --- 1216 } 1217#else 1218 if ((sa->sa.sin.sin_addr.s_addr & ipsub->mask[0]) == ipsub->sub[0]) { 1219 return 1; 1220 } 1221#endif /* APR_HAVE_IPV6 */ 1222 return 0; /* no match */ 1223} |
1224 1225APR_DECLARE(apr_status_t) apr_sockaddr_zone_set(apr_sockaddr_t *sa, 1226 const char *zone_id) 1227{ 1228#if !APR_HAVE_IPV6 || !defined(HAVE_IF_NAMETOINDEX) 1229 return APR_ENOTIMPL; 1230#else 1231 unsigned int idx; 1232 1233 if (sa->family != APR_INET6 1234 || !IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)sa->ipaddr_ptr)) { 1235 return APR_EBADIP; 1236 } 1237 1238 idx = if_nametoindex(zone_id); 1239 if (idx) { 1240 sa->sa.sin6.sin6_scope_id = idx; 1241 return APR_SUCCESS; 1242 } 1243 1244 if (errno != ENODEV) { 1245 return errno; 1246 } 1247 else { 1248 char *endptr; 1249 apr_int64_t i = apr_strtoi64(zone_id, &endptr, 10); 1250 1251 if (*endptr != '\0' || errno || i < 1 || i > APR_INT16_MAX) { 1252 return APR_EGENERAL; 1253 } 1254 1255 sa->sa.sin6.sin6_scope_id = (unsigned int) i; 1256 return APR_SUCCESS; 1257 } 1258#endif 1259} 1260 1261APR_DECLARE(apr_status_t) apr_sockaddr_zone_get(const apr_sockaddr_t *sa, 1262 const char **name, 1263 apr_uint32_t *id, 1264 apr_pool_t *p) 1265{ 1266#if !APR_HAVE_IPV6 || !defined(HAVE_IF_INDEXTONAME) 1267 return APR_ENOTIMPL; 1268#else 1269 if (sa->family != APR_INET6 || !sa->sa.sin6.sin6_scope_id) { 1270 return APR_EBADIP; 1271 } 1272 1273 if (name) { 1274 char *buf = apr_palloc(p, IF_NAMESIZE); 1275 if (if_indextoname(sa->sa.sin6.sin6_scope_id, buf) == NULL) 1276 return errno; 1277 *name = buf; 1278 } 1279 1280 if (id) *id = sa->sa.sin6.sin6_scope_id; 1281 1282 return APR_SUCCESS; 1283#endif 1284} |
|