Fixed the --interface option to work with IPv6 connections on glibc

systems supporting getifaddrs(). Also fixed a problem where an IPv6
address could be chosen instead of an IPv4 one for --interface when it
involved a name lookup.
This commit is contained in:
Dan Fandrich 2008-10-09 19:23:50 +00:00
parent 5ecff1e4c3
commit fad3288d20
7 changed files with 132 additions and 63 deletions

View file

@ -42,6 +42,60 @@
!defined(__AMIGA__) && !defined(__minix) && !defined(__SYMBIAN32__) && \
!defined(__WATCOMC__)
#if defined(HAVE_GETIFADDRS)
/*
* glibc provides getifaddrs() to provide a list of all interfaces and their
* addresses.
*/
#include <ifaddrs.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include "inet_ntop.h"
#include "strequal.h"
char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
{
struct ifaddrs *iface, *head;
char *ip=NULL;
if (getifaddrs(&head) >= 0) {
for (iface=head; iface != NULL; iface=iface->ifa_next) {
if ((iface->ifa_addr->sa_family == af) &&
curl_strequal(iface->ifa_name, interface)) {
void *addr;
char scope[12]="";
if (af == AF_INET6) {
unsigned int scopeid;
addr = &((struct sockaddr_in6 *)iface->ifa_addr)->sin6_addr;
/* Include the scope of this interface as part of the address */
scopeid = ((struct sockaddr_in6 *)iface->ifa_addr)->sin6_scope_id;
if (scopeid)
snprintf(scope, sizeof(scope), "%%%u", scopeid);
} else
addr = &((struct sockaddr_in *)iface->ifa_addr)->sin_addr;
ip = (char *) Curl_inet_ntop(af, addr, buf, buf_size);
Curl_strlcat(buf, scope, buf_size);
break;
}
}
freeifaddrs(head);
}
return ip;
}
#else
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
@ -83,12 +137,12 @@
#define SYS_ERROR -1
char *Curl_if2ip(const char *interface, char *buf, int buf_size)
char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
{
int dummy;
char *ip=NULL;
if(!interface)
if(!interface || (af != AF_INET))
return NULL;
dummy = socket(AF_INET, SOCK_STREAM, 0);
@ -124,11 +178,13 @@ char *Curl_if2ip(const char *interface, char *buf, int buf_size)
}
return ip;
}
#endif
/* -- end of if2ip() -- */
#else
char *Curl_if2ip(const char *interf, char *buf, int buf_size)
char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size)
{
(void) af;
(void) interf;
(void) buf;
(void) buf_size;