Annotation of embedaddon/miniupnpd/getifaddr.c, revision 1.1.1.2
1.1.1.2 ! misho 1: /* $Id: getifaddr.c,v 1.11 2011/05/15 08:59:27 nanard Exp $ */
1.1 misho 2: /* MiniUPnP project
3: * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
1.1.1.2 ! misho 4: * (c) 2006-2011 Thomas Bernard
1.1 misho 5: * This software is subject to the conditions detailed
6: * in the LICENCE file provided within the distribution */
7:
1.1.1.2 ! misho 8: #include <stdio.h>
1.1 misho 9: #include <string.h>
10: #include <syslog.h>
11: #include <unistd.h>
12: #include <sys/ioctl.h>
13: #include <sys/types.h>
14: #include <sys/socket.h>
15: #include <net/if.h>
16: #include <arpa/inet.h>
17: #include <netinet/in.h>
18: #if defined(sun)
19: #include <sys/sockio.h>
20: #endif
21:
1.1.1.2 ! misho 22: #include "config.h"
1.1 misho 23: #include "getifaddr.h"
1.1.1.2 ! misho 24: #if defined(USE_GETIFADDRS) || defined(ENABLE_IPV6)
! 25: #include <ifaddrs.h>
! 26: #endif
1.1 misho 27:
28: int
29: getifaddr(const char * ifname, char * buf, int len)
30: {
1.1.1.2 ! misho 31: #ifndef USE_GETIFADDRS
! 32: /* use ioctl SIOCGIFADDR. Works only for ip v4 */
1.1 misho 33: /* SIOCGIFADDR struct ifreq * */
34: int s;
35: struct ifreq ifr;
36: int ifrlen;
37: struct sockaddr_in * addr;
38: ifrlen = sizeof(ifr);
1.1.1.2 ! misho 39:
1.1 misho 40: if(!ifname || ifname[0]=='\0')
41: return -1;
42: s = socket(PF_INET, SOCK_DGRAM, 0);
43: if(s < 0)
44: {
45: syslog(LOG_ERR, "socket(PF_INET, SOCK_DGRAM): %m");
46: return -1;
47: }
48: strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
49: if(ioctl(s, SIOCGIFADDR, &ifr, &ifrlen) < 0)
50: {
51: syslog(LOG_ERR, "ioctl(s, SIOCGIFADDR, ...): %m");
52: close(s);
53: return -1;
54: }
55: addr = (struct sockaddr_in *)&ifr.ifr_addr;
56: if(!inet_ntop(AF_INET, &addr->sin_addr, buf, len))
57: {
58: syslog(LOG_ERR, "inet_ntop(): %m");
59: close(s);
60: return -1;
61: }
62: close(s);
1.1.1.2 ! misho 63: #else /* ifndef USE_GETIFADDRS */
! 64: /* Works for all address families (both ip v4 and ip v6) */
! 65: struct ifaddrs * ifap;
! 66: struct ifaddrs * ife;
! 67:
! 68: if(!ifname || ifname[0]=='\0')
! 69: return -1;
! 70: if(getifaddrs(&ifap)<0)
! 71: {
! 72: syslog(LOG_ERR, "getifaddrs: %m");
! 73: return -1;
! 74: }
! 75: for(ife = ifap; ife; ife = ife->ifa_next)
! 76: {
! 77: /* skip other interfaces */
! 78: if(0 != strcmp(ifname, ife->ifa_name))
! 79: continue;
! 80: switch(ife->ifa_addr->sa_family)
! 81: {
! 82: case AF_INET:
! 83: inet_ntop(ife->ifa_addr->sa_family,
! 84: &((struct sockaddr_in *)ife->ifa_addr)->sin_addr,
! 85: buf, len);
! 86: break;
! 87: /*
! 88: case AF_INET6:
! 89: inet_ntop(ife->ifa_addr->sa_family,
! 90: &((struct sockaddr_in6 *)ife->ifa_addr)->sin6_addr,
! 91: buf, len);
! 92: */
! 93: }
! 94: }
! 95: freeifaddrs(ifap);
! 96: #endif
1.1 misho 97: return 0;
98: }
99:
1.1.1.2 ! misho 100: #ifdef ENABLE_IPV6
! 101: int
! 102: find_ipv6_addr(const char * ifname,
! 103: char * dst, int n)
! 104: {
! 105: struct ifaddrs * ifap;
! 106: struct ifaddrs * ife;
! 107: const struct sockaddr_in6 * addr;
! 108: char buf[64];
! 109: int r = 0;
! 110:
! 111: if(!dst)
! 112: return -1;
! 113:
! 114: if(getifaddrs(&ifap)<0)
! 115: {
! 116: syslog(LOG_ERR, "getifaddrs: %m");
! 117: return -1;
! 118: }
! 119: for(ife = ifap; ife; ife = ife->ifa_next)
! 120: {
! 121: /* skip other interfaces if one was specified */
! 122: if(ifname && (0 != strcmp(ifname, ife->ifa_name)))
! 123: continue;
! 124: if(ife->ifa_addr->sa_family == AF_INET6)
! 125: {
! 126: addr = (const struct sockaddr_in6 *)ife->ifa_addr;
! 127: if(!IN6_IS_ADDR_LOOPBACK(&addr->sin6_addr)
! 128: && !IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr))
! 129: {
! 130: inet_ntop(ife->ifa_addr->sa_family,
! 131: &addr->sin6_addr,
! 132: buf, sizeof(buf));
! 133: /* add brackets */
! 134: snprintf(dst, n, "[%s]", buf);
! 135: r = 1;
! 136: }
! 137: }
! 138: }
! 139: return r;
! 140: }
! 141: #endif
! 142:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>