5
5
* | (__| |_| | _ <| |___
6
6
* \___|\___/|_| \_\_____|
8
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
8
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
10
10
* This software is licensed as described in the file COPYING, which
11
11
* you should have received as part of this distribution. The terms
86
char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size)
86
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
87
const char *interf, char *buf, int buf_size)
88
89
struct ifaddrs *iface, *head;
90
if2ip_result_t res = IF2IP_NOT_FOUND;
91
96
if(getifaddrs(&head) >= 0) {
92
97
for(iface=head; iface != NULL; iface=iface->ifa_next) {
93
if((iface->ifa_addr != NULL) &&
94
(iface->ifa_addr->sa_family == af) &&
95
curl_strequal(iface->ifa_name, interf)) {
98
if(iface->ifa_addr != NULL) {
99
if(iface->ifa_addr->sa_family == af) {
100
if(curl_strequal(iface->ifa_name, interf)) {
98
105
#ifdef ENABLE_IPV6
100
unsigned int scopeid = 0;
101
addr = &((struct sockaddr_in6 *)iface->ifa_addr)->sin6_addr;
107
unsigned int scopeid = 0;
108
addr = &((struct sockaddr_in6 *)iface->ifa_addr)->sin6_addr;
102
109
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
103
/* Include the scope of this interface as part of the address */
104
scopeid = ((struct sockaddr_in6 *)iface->ifa_addr)->sin6_scope_id;
107
snprintf(scope, sizeof(scope), "%%%u", scopeid);
111
addr = &((struct sockaddr_in *)iface->ifa_addr)->sin_addr;
112
ip = (char *) Curl_inet_ntop(af, addr, buf, buf_size);
113
strlcat(buf, scope, buf_size);
110
/* Include the scope of this interface as part of the address */
112
((struct sockaddr_in6 *)iface->ifa_addr)->sin6_scope_id;
114
if(scopeid != remote_scope) {
115
/* We are interested only in interface addresses whose
116
scope ID matches the remote address we want to
117
connect to: global (0) for global, link-local for
118
link-local, etc... */
119
if(res == IF2IP_NOT_FOUND) res = IF2IP_AF_NOT_SUPPORTED;
123
snprintf(scope, sizeof(scope), "%%%u", scopeid);
127
addr = &((struct sockaddr_in *)iface->ifa_addr)->sin_addr;
129
ip = (char *) Curl_inet_ntop(af, addr, ipstr, sizeof(ipstr));
130
snprintf(buf, buf_size, "%s%s", ip, scope);
134
else if((res == IF2IP_NOT_FOUND) &&
135
curl_strequal(iface->ifa_name, interf)) {
136
res = IF2IP_AF_NOT_SUPPORTED;
117
140
freeifaddrs(head);
122
145
#elif defined(HAVE_IOCTL_SIOCGIFADDR)
126
149
/* This is here just to support the old interfaces */
129
char *ip = Curl_if2ip(AF_INET, interf, buf, sizeof(buf));
131
return (ip != NULL) ? TRUE : FALSE;
152
return (Curl_if2ip(AF_INET, 0, interf, buf, sizeof(buf)) ==
153
IF2IP_NOT_FOUND) ? FALSE : TRUE;
134
char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size)
156
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
157
const char *interf, char *buf, int buf_size)
136
159
struct ifreq req;
137
160
struct in_addr in;
138
161
struct sockaddr_in *s;
139
162
curl_socket_t dummy;
143
167
if(!interf || (af != AF_INET))
168
return IF2IP_NOT_FOUND;
146
170
len = strlen(interf);
147
171
if(len >= sizeof(req.ifr_name))
172
return IF2IP_NOT_FOUND;
150
174
dummy = socket(AF_INET, SOCK_STREAM, 0);
151
175
if(CURL_SOCKET_BAD == dummy)
176
return IF2IP_NOT_FOUND;
154
178
memset(&req, 0, sizeof(req));
155
179
memcpy(req.ifr_name, interf, len+1);
158
182
if(ioctl(dummy, SIOCGIFADDR, &req) < 0) {
184
/* With SIOCGIFADDR, we cannot tell the difference between an interface
185
that does not exist and an interface that has no address of the
186
correct family. Assume the interface does not exist */
187
return IF2IP_NOT_FOUND;
163
190
s = (struct sockaddr_in *)&req.ifr_addr;
164
191
memcpy(&in, &s->sin_addr, sizeof(in));
165
ip = (char *) Curl_inet_ntop(s->sin_family, &in, buf, buf_size);
192
Curl_inet_ntop(s->sin_family, &in, buf, buf_size);