--------------------- PatchSet 1317 Date: 2005/04/25 13:48:56 Author: rmartinez Branch: squid3-ipv6 Tag: (none) Log: Adding new IPv6 support routines Members: lib/safe_inet_addr.c:1.1.30.4->1.1.30.5 Index: squid3/lib/safe_inet_addr.c =================================================================== RCS file: /cvsroot/squid-sf//squid3/lib/safe_inet_addr.c,v retrieving revision 1.1.30.4 retrieving revision 1.1.30.5 diff -u -r1.1.30.4 -r1.1.30.5 --- squid3/lib/safe_inet_addr.c 19 Apr 2005 10:57:54 -0000 1.1.30.4 +++ squid3/lib/safe_inet_addr.c 25 Apr 2005 13:48:56 -0000 1.1.30.5 @@ -1,6 +1,6 @@ /* - * $Id: safe_inet_addr.c,v 1.1.30.4 2005/04/19 10:57:54 rmartinez Exp $ + * $Id: safe_inet_addr.c,v 1.1.30.5 2005/04/25 13:48:56 rmartinez Exp $ */ #include "config.h" @@ -29,22 +29,14 @@ #endif #include "snprintf.h" - -#if ENABLE_IPV6 -#include -#include -#endif +#include "string.h" int -<<<<<<< safe_inet_addr.c -safe_inet4_addr(const char *buf, struct in_addr *addr) -======= -safe_inet_addr(const char *buf, struct IN_ADDR *addr) ->>>>>>> 1.4 +safe_inet_addr(const char *buf, struct in_addr *addr) { static char addrbuf[32]; int a1 = 0, a2 = 0, a3 = 0, a4 = 0; - struct IN_ADDR A; + struct in_addr A; char x; #if defined(_SQUID_HPUX_) /* @@ -74,211 +66,49 @@ return 1; } -#if ENABLE_IPV6 -#else -int -safe_inet_addr(const char *buf, struct in_addr *addr) +#ifdef INET6 +int safe_inet_sockaddr(const char *buf, struct sockaddr_storage *addr) { - return safe_inet4_addr(buf,addr); -} -#endif + struct in6_addr inaddr6; + struct in_addr inaddr4; -int -is_numeric_ip_address(const char *hostname) -{ -#if ENABLE_IPV6 - struct addrinfo * res = NULL; - struct addrinfo hints = {ai_flags: AI_NUMERICHOST, ai_family: PF_UNSPEC, ai_socktype: 0, ai_protocol: 0, ai_addrlen: 0, ai_addr: NULL, ai_canonname: NULL, ai_next: NULL }; - int error = getaddrinfo(hostname,NULL,&hints,&res); - - if (res!=NULL) { - freeaddrinfo(res); + if (inet_pton(AF_INET6, buf, &inaddr6) != 0) { + struct sockaddr_in6 *saddr6p = (struct sockaddr_in6 *)addr; + saddr6p->sin6_family = AF_INET6; + saddr6p->sin6_addr = inaddr6; + return 1; + } else if (inet_aton(buf,&inaddr4) != 0) { + struct sockaddr_in *saddr4p = (struct sockaddr_in *)addr; + saddr4p->sin_family = AF_INET; + saddr4p->sin_addr = inaddr4; + return 1; } - - // FIXME: error could indicate another error than just "no numeric ip address" - return error==0; - -#else - struct in_addr ip4_address; - - return safe_inet4_addr(hostname,&ip4_address); -#endif + return 0; } -#if ENABLE_IPV6 - -// CAUTION: This function is not reentrant, because both in the IPv4 and IPv6 case, it uses a static buffer for the result - static char sockaddr_host_address_to_address_string_namebuf[NI_MAXHOST]; -/** - @return a static name string buffer or NULL (which should not happen) -*/ -char * -sockaddr_host_address_to_address_string(struct sockaddr_storage * sockaddr) +int +safe_inet6_addr(const char *buf, struct in6_addr *addr) { - char * name; - - // Implemented as recommended by http://ftp.gnu.org/savannah/files/ffss/doc/ipv6-app-port.html, inet_ntoa - if (sockaddr_storage_is_ipv4(sockaddr)) { - name = inet_ntoa(sockaddr_storage_to_in4_addr(sockaddr)); - } else { - int error = getnameinfo((struct sockaddr *) sockaddr,sockaddr_storage_len(sockaddr), - sockaddr_host_address_to_address_string_namebuf,sizeof(sockaddr_host_address_to_address_string_namebuf), - NULL,0, - NI_NUMERICHOST); - - if (error) { - name = NULL; - } else { - name = sockaddr_host_address_to_address_string_namebuf; - } - } - - return name; -} - -// CAUTION: This function is not reentrant, because both in the IPv4 and IPv6 case, it uses a static buffer for the result - static char inet6_network_byte_order_to_address_string_namebuf[NI_MAXHOST]; + static char addrbuf[128]; + /* try IPv4 dotted quad first */ + if (safe_inet_addr(buf, (struct in_addr *)addr) == 1) { + /* we need to convert to IPv6 mapped IPv4 address */ + xmemcpy(addrbuf, "::FFFF:", 7); + xmemcpy(&addrbuf[7], buf, strlen(buf) + 1); + return inet_pton(AF_INET6, addrbuf, addr); + } -/** - @return a static name string buffer or NULL (which should not happen) -*/ -char * -inet6_network_byte_order_to_address_string(struct inaddr_storage * addr6) -{ - char * name; - - // Implemented as recommended by http://ftp.gnu.org/savannah/files/ffss/doc/ipv6-app-port.html, inet_ntoa - if (inaddr_storage_is_ipv4(addr6)) { - name = inet_ntoa(inaddr_storage_to_in4_addr(&addr6)); - } else { - int error = getnameinfo(inaddr_storage_to_sockaddr(&addr6),inaddr_storage_to_sockaddr_len(&addr6), - inet6_network_byte_order_to_address_string_namebuf,sizeof(inet6_network_byte_order_to_address_string_namebuf), - NULL,0, - NI_NUMERICHOST); - - if (error) { - name = NULL; - } else { - name = inet6_network_byte_order_to_address_string_namebuf; - } - } - - return name; + /* else try IPv6 */ + return inet_pton(AF_INET6, buf, addr); } -/** - @return a static name string buffer - @throws - failed assertion on error (which should not happen) -*/ -char * -sockaddr_host_address_to_address_string_force(struct sockaddr_storage * sockaddr) -{ - char * name = sockaddr_host_address_to_address_string(sockaddr); - - assert(name); - - return name; -} -/** - @return a static name string buffer - @throws - failed assertion on error (which should not happen) -*/ -char * -inet6_network_byte_order_to_address_string_force(struct inaddr_storage * addr6) -{ - char * name = inet6_network_byte_order_to_address_string(addr6); - - assert(name); - - return name; -} -/* - Simple host compare - - fancy host compare does also compare IPv6-mapped IPv4 adresses with IPv4-adresses - - @return - 0 if both adresses match - !=0 if they do not match -*/ -int -sockaddr_host_simple_compare(struct sockaddr_storage * ss0,struct sockaddr_storage * ss1) +const char * inet6_ntoa(const struct in6_addr in) { - if ((ss0->ss_family==AF_INET)&&(ss1->ss_family==AF_INET)) { -// return ((struct sockaddr_in *) ss0)->sin_addr!=((struct sockaddr_in *) ss1)->sin_addr; - return memcmp(&((struct sockaddr_in *) ss0)->sin_addr,&((struct sockaddr_in *) ss1)->sin_addr,sizeof(struct in_addr)); - - } else if ((ss0->ss_family==AF_INET6)&&(ss1->ss_family==AF_INET6)) { - return - memcmp(&((struct sockaddr_in6 *) ss0)->sin6_addr,&((struct sockaddr_in6 *) ss1)->sin6_addr,sizeof(struct in6_addr)) || - (((struct sockaddr_in6 *) ss0)->sin6_scope_id!=((struct sockaddr_in6 *) ss1)->sin6_scope_id); // That's difficult with the scope_id, because adresses with "the default scope" do not match. - } else { - // This should not happen -#if HAVE_SOCKADDR_STORAGE_LEN // Note that for certain platforms, struct sockaddr_storage.ss_len does not exist. - return memcmp(ss0,ss1,MIN(MIN(ss0->ss_len,ss1->ss_len),sizeof(struct sockaddr_storage))); // CAUTIOn: Not every implementation of struct sockaddr_storage has a sockaddr_storage.ss_len field -#else - return memcmp(ss0,ss1,sizeof(struct sockaddr_storage)); // CAUTIOn: Not every implementation of struct sockaddr_storage has a sockaddr_storage.ss_len field -#endif - } -} - -void -copy_sockaddr_host(struct sockaddr_storage * from,struct sockaddr_storage * to) { - memset(to,0,sizeof(struct sockaddr_storage)); - if (from->ss_family==AF_INET) { -#if HAVE_SOCKADDR_STORAGE_LEN // Note that for certain platforms, struct sockaddr_storage.ss_len does not exist. - to->ss_len = sizeof(struct sockaddr_in); /* CAUTION: not every sockaddr_in implementation has sockaddr_in.sin_len */ -#endif - to->ss_family = (from)->ss_family; - ((struct sockaddr_in *) to)->sin_addr = ((struct sockaddr_in *) from)->sin_addr; - } else if ((from)->ss_family==AF_INET6) { -#if HAVE_SOCKADDR_STORAGE_LEN // Note that for certain platforms, struct sockaddr_storage.ss_len does not exist. - to->ss_len = sizeof(struct sockaddr_in6); /* CAUTION: not every sockaddr_in6 implementation has sockaddr_in6.sin6_len */ -#endif - to->ss_family = (from)->ss_family; - ((struct sockaddr_in6 *) to)->sin6_addr = ((struct sockaddr_in6 *) from)->sin6_addr; - ((struct sockaddr_in6 *) to)->sin6_scope_id = ((struct sockaddr_in6 *) from)->sin6_scope_id; - } else { /* FIXME: huh, this should not happen */ - *to = *from; - } -} + static char buff[INET6_ADDRSTRLEN]; -/** - Copies the IP-address-part of an sockaddr_storage to an inaddr_storage - - What exactly is the IP-address-part? The port is not the IP-address part. But what about flow label and scope id? - As flow labels belong to flows, I -*/ -void -sockaddr_storage_to_inaddr_storage(struct sockaddr_storage * from,struct inaddr_storage * to) { - copy_sockaddr_host(from,&to->embedded); - /* - memset(to,0,sizeof(struct inaddr_storage)); - if ((from)->ss_family==AF_INET) { -#if HAVE_SOCKADDR_STORAGE_LEN // Note that for certain platforms, struct sockaddr_storage.ss_len does not exist. - (to)->embedded.ss_len = sizeof(struct sockaddr_in); // CAUTION: not every sockaddr_in implementation has sockaddr_in.sin_len -#endif - (to)->embedded.ss_family = (from)->ss_family; - memcpy(&((struct sockaddr_in) (to->embedded)).sin_addr,&((struct sockaddr_in *) (from))->sin_addr,sizeof(struct in_addr)); -// ((struct sockaddr_in) (to->embedded)).sin_zero = ((struct sockaddr_in *) (from))->sin_zero; - } else if ((from)->ss_family==AF_INET6) { -#if HAVE_SOCKADDR_STORAGE_LEN // Note that for certain platforms, struct sockaddr_storage.ss_len does not exist. - (to)->embedded.ss_len = sizeof(struct sockaddr_in6); // CAUTION: not every sockaddr_in6 implementation has sockaddr_in6.sin6_len -#endif - (to)->embedded.ss_family = (from)->ss_family; -// ((struct sockaddr6_in) (to->embedded)).sin6_port = 0; -// ((struct sockaddr6_in) (to->embedded)).sin6_flowinfo = 0; - ((struct sockaddr6_in) (to->embedded)).sin6_addr = ((struct sockaddr6_in *) (from))->sin6_addr; - ((struct sockaddr6_in) (to->embedded)).sin6_scopeid = ((struct sockaddr6_in *) (from))->sin6_scopeid; - } else { // FIXME: huh, this should not happen - (to)->embedded = *from; - } - */ + return inet_ntop(AF_INET6, &in, buff, INET6_ADDRSTRLEN); } - #endif