diff options
author | George Hazan <ghazan@miranda.im> | 2017-12-06 21:44:09 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2017-12-06 21:44:17 +0300 |
commit | 4b6980f68d25901133519bc1ad1c5376819a3876 (patch) | |
tree | 0d919622bfc2659f34a7bed303fefb99ecab052a /libs/libcurl/src/if2ip.c | |
parent | 0112d2767268037cf63e44c4464cf9eed237d06d (diff) |
libcurl: update to 7.57
Diffstat (limited to 'libs/libcurl/src/if2ip.c')
-rw-r--r-- | libs/libcurl/src/if2ip.c | 116 |
1 files changed, 86 insertions, 30 deletions
diff --git a/libs/libcurl/src/if2ip.c b/libs/libcurl/src/if2ip.c index 05ae7d6f87..ce38ea117b 100644 --- a/libs/libcurl/src/if2ip.c +++ b/libs/libcurl/src/if2ip.c @@ -5,11 +5,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. + * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -51,18 +51,49 @@ #endif #include "inet_ntop.h" -#include "strequal.h" +#include "strcase.h" #include "if2ip.h" - -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" #include "curl_memory.h" -/* The last #include file should be: */ #include "memdebug.h" /* ------------------------------------------------------------------ */ +/* Return the scope of the given address. */ +unsigned int Curl_ipv6_scope(const struct sockaddr *sa) +{ +#ifndef ENABLE_IPV6 + (void) sa; +#else + if(sa->sa_family == AF_INET6) { + const struct sockaddr_in6 * sa6 = (const struct sockaddr_in6 *)(void *) sa; + const unsigned char *b = sa6->sin6_addr.s6_addr; + unsigned short w = (unsigned short) ((b[0] << 8) | b[1]); + + if((b[0] & 0xFE) == 0xFC) /* Handle ULAs */ + return IPV6_SCOPE_UNIQUELOCAL; + switch(w & 0xFFC0) { + case 0xFE80: + return IPV6_SCOPE_LINKLOCAL; + case 0xFEC0: + return IPV6_SCOPE_SITELOCAL; + case 0x0000: + w = b[1] | b[2] | b[3] | b[4] | b[5] | b[6] | b[7] | b[8] | b[9] | + b[10] | b[11] | b[12] | b[13] | b[14]; + if(w || b[15] != 0x01) + break; + return IPV6_SCOPE_NODELOCAL; + default: + break; + } + } +#endif + + return IPV6_SCOPE_GLOBAL; +} + + #if defined(HAVE_GETIFADDRS) bool Curl_if_is_interface_name(const char *interf) @@ -72,8 +103,8 @@ bool Curl_if_is_interface_name(const char *interf) struct ifaddrs *iface, *head; if(getifaddrs(&head) >= 0) { - for(iface=head; iface != NULL; iface=iface->ifa_next) { - if(curl_strequal(iface->ifa_name, interf)) { + for(iface = head; iface != NULL; iface = iface->ifa_next) { + if(strcasecompare(iface->ifa_name, interf)) { result = TRUE; break; } @@ -84,7 +115,8 @@ bool Curl_if_is_interface_name(const char *interf) } if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, - const char *interf, char *buf, int buf_size) + unsigned int remote_scope_id, const char *interf, + char *buf, int buf_size) { struct ifaddrs *iface, *head; if2ip_result_t res = IF2IP_NOT_FOUND; @@ -93,38 +125,56 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, (void) remote_scope; #endif +#if !defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) || \ + !defined(ENABLE_IPV6) + (void) remote_scope_id; +#endif + if(getifaddrs(&head) >= 0) { - for(iface=head; iface != NULL; iface=iface->ifa_next) { + for(iface = head; iface != NULL; iface = iface->ifa_next) { if(iface->ifa_addr != NULL) { if(iface->ifa_addr->sa_family == af) { - if(curl_strequal(iface->ifa_name, interf)) { + if(strcasecompare(iface->ifa_name, interf)) { void *addr; char *ip; - char scope[12]=""; + char scope[12] = ""; char ipstr[64]; #ifdef ENABLE_IPV6 if(af == AF_INET6) { unsigned int scopeid = 0; - addr = &((struct sockaddr_in6 *)iface->ifa_addr)->sin6_addr; -#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID - /* Include the scope of this interface as part of the address */ - scopeid = - ((struct sockaddr_in6 *)iface->ifa_addr)->sin6_scope_id; -#endif - if(scopeid != remote_scope) { + unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr); + + if(ifscope != remote_scope) { /* We are interested only in interface addresses whose - scope ID matches the remote address we want to - connect to: global (0) for global, link-local for + scope matches the remote address we want to + connect to: global for global, link-local for link-local, etc... */ if(res == IF2IP_NOT_FOUND) res = IF2IP_AF_NOT_SUPPORTED; continue; } + + addr = + &((struct sockaddr_in6 *)(void *)iface->ifa_addr)->sin6_addr; +#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID + /* Include the scope of this interface as part of the address */ + scopeid = ((struct sockaddr_in6 *)(void *)iface->ifa_addr) + ->sin6_scope_id; + + /* If given, scope id should match. */ + if(remote_scope_id && scopeid != remote_scope_id) { + if(res == IF2IP_NOT_FOUND) + res = IF2IP_AF_NOT_SUPPORTED; + + continue; + } +#endif if(scopeid) snprintf(scope, sizeof(scope), "%%%u", scopeid); } else #endif - addr = &((struct sockaddr_in *)iface->ifa_addr)->sin_addr; + addr = + &((struct sockaddr_in *)(void *)iface->ifa_addr)->sin_addr; res = IF2IP_FOUND; ip = (char *) Curl_inet_ntop(af, addr, ipstr, sizeof(ipstr)); snprintf(buf, buf_size, "%s%s", ip, scope); @@ -132,13 +182,15 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, } } else if((res == IF2IP_NOT_FOUND) && - curl_strequal(iface->ifa_name, interf)) { + strcasecompare(iface->ifa_name, interf)) { res = IF2IP_AF_NOT_SUPPORTED; } } } + freeifaddrs(head); } + return res; } @@ -149,12 +201,13 @@ bool Curl_if_is_interface_name(const char *interf) /* This is here just to support the old interfaces */ char buf[256]; - return (Curl_if2ip(AF_INET, 0, interf, buf, sizeof(buf)) == + return (Curl_if2ip(AF_INET, 0 /* unused */, 0, interf, buf, sizeof(buf)) == IF2IP_NOT_FOUND) ? FALSE : TRUE; } if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, - const char *interf, char *buf, int buf_size) + unsigned int remote_scope_id, const char *interf, + char *buf, int buf_size) { struct ifreq req; struct in_addr in; @@ -163,6 +216,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, size_t len; (void)remote_scope; + (void)remote_scope_id; if(!interf || (af != AF_INET)) return IF2IP_NOT_FOUND; @@ -176,7 +230,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, return IF2IP_NOT_FOUND; memset(&req, 0, sizeof(req)); - memcpy(req.ifr_name, interf, len+1); + memcpy(req.ifr_name, interf, len + 1); req.ifr_addr.sa_family = AF_INET; if(ioctl(dummy, SIOCGIFADDR, &req) < 0) { @@ -187,7 +241,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, return IF2IP_NOT_FOUND; } - s = (struct sockaddr_in *)&req.ifr_addr; + s = (struct sockaddr_in *)(void *)&req.ifr_addr; memcpy(&in, &s->sin_addr, sizeof(in)); Curl_inet_ntop(s->sin_family, &in, buf, buf_size); @@ -205,10 +259,12 @@ bool Curl_if_is_interface_name(const char *interf) } if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, - const char *interf, char *buf, int buf_size) + unsigned int remote_scope_id, const char *interf, + char *buf, int buf_size) { (void) af; (void) remote_scope; + (void) remote_scope_id; (void) interf; (void) buf; (void) buf_size; |