| 201 } |
204 } |
| 202 |
205 |
| 203 GList * |
206 GList * |
| 204 purple_network_get_all_local_system_ips(void) |
207 purple_network_get_all_local_system_ips(void) |
| 205 { |
208 { |
| |
209 #ifdef HAVE_GETIFADDRS |
| |
210 GList *result = NULL; |
| |
211 struct ifaddrs *start, *ifa; |
| |
212 int ret; |
| |
213 |
| |
214 ret = getifaddrs(&start); |
| |
215 if (ret < 0) { |
| |
216 purple_debug_warning("network", |
| |
217 "getifaddrs() failed: %s\n", g_strerror(errno)); |
| |
218 return NULL; |
| |
219 } |
| |
220 |
| |
221 for (ifa = start; ifa; ifa = ifa->ifa_next) { |
| |
222 int family = ifa->ifa_addr ? ifa->ifa_addr->sa_family : AF_UNSPEC; |
| |
223 char host[INET6_ADDRSTRLEN]; |
| |
224 const char *tmp = NULL; |
| |
225 |
| |
226 if ((family != AF_INET && family != AF_INET6) || ifa->ifa_flags & IFF_LOOPBACK) |
| |
227 continue; |
| |
228 |
| |
229 if (family == AF_INET) |
| |
230 tmp = inet_ntop(family, &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, host, sizeof(host)); |
| |
231 else { |
| |
232 struct sockaddr_in6 *sockaddr = (struct sockaddr_in6 *)ifa->ifa_addr; |
| |
233 /* Peer-peer link-local communication is a big TODO. I am not sure |
| |
234 * how communicating link-local addresses is supposed to work, and |
| |
235 * it seems like it would require attempting the cartesian product |
| |
236 * of the local and remote interfaces to see if any match (eww). |
| |
237 */ |
| |
238 if (!IN6_IS_ADDR_LINKLOCAL(&sockaddr->sin6_addr)) |
| |
239 tmp = inet_ntop(family, &sockaddr->sin6_addr, host, sizeof(host)); |
| |
240 } |
| |
241 if (tmp != NULL) |
| |
242 result = g_list_prepend(result, g_strdup(tmp)); |
| |
243 } |
| |
244 |
| |
245 freeifaddrs(start); |
| |
246 |
| |
247 return g_list_reverse(result); |
| |
248 #else /* HAVE_GETIFADDRS */ |
| 206 GList *result = NULL; |
249 GList *result = NULL; |
| 207 int source = socket(PF_INET,SOCK_STREAM, 0); |
250 int source = socket(PF_INET,SOCK_STREAM, 0); |
| 208 char buffer[1024]; |
251 char buffer[1024]; |
| 209 char *tmp; |
252 char *tmp; |
| 210 struct ifconf ifc; |
253 struct ifconf ifc; |
| 220 char dst[INET_ADDRSTRLEN]; |
263 char dst[INET_ADDRSTRLEN]; |
| 221 |
264 |
| 222 ifr = (struct ifreq *)tmp; |
265 ifr = (struct ifreq *)tmp; |
| 223 tmp += HX_SIZE_OF_IFREQ(*ifr); |
266 tmp += HX_SIZE_OF_IFREQ(*ifr); |
| 224 |
267 |
| 225 /* TODO: handle IPv6 */ |
|
| 226 if (ifr->ifr_addr.sa_family == AF_INET) { |
268 if (ifr->ifr_addr.sa_family == AF_INET) { |
| 227 struct sockaddr_in *sinptr = (struct sockaddr_in *)&ifr->ifr_addr; |
269 struct sockaddr_in *sinptr = (struct sockaddr_in *)&ifr->ifr_addr; |
| 228 |
270 |
| 229 inet_ntop(AF_INET, &sinptr->sin_addr, dst, |
271 inet_ntop(AF_INET, &sinptr->sin_addr, dst, |
| 230 sizeof(dst)); |
272 sizeof(dst)); |