Updates to Tomato RAF including NGINX && PHP
[tomato.git] / release / src / router / miniupnpd / getifaddr.c
bloba6b15540e94edcfcd8844f3973f0815b716e9345
1 /* $Id: getifaddr.c,v 1.15 2012/03/05 20:36:16 nanard Exp $ */
2 /* MiniUPnP project
3 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4 * (c) 2006-2011 Thomas Bernard
5 * This software is subject to the conditions detailed
6 * in the LICENCE file provided within the distribution */
8 #include <stdio.h>
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 <netinet/in.h>
17 #include <arpa/inet.h>
18 #if defined(sun)
19 #include <sys/sockio.h>
20 #endif
22 #include "config.h"
23 #include "getifaddr.h"
24 #if defined(USE_GETIFADDRS) || defined(ENABLE_IPV6)
25 #include <ifaddrs.h>
26 #endif
28 int
29 getifaddr(const char * ifname, char * buf, int len)
31 #ifndef USE_GETIFADDRS
32 /* use ioctl SIOCGIFADDR. Works only for ip v4 */
33 /* SIOCGIFADDR struct ifreq * */
34 int s;
35 struct ifreq ifr;
36 int ifrlen;
37 struct sockaddr_in * addr;
38 ifrlen = sizeof(ifr);
40 if(!ifname || ifname[0]=='\0')
41 return -1;
42 s = socket(PF_INET, SOCK_DGRAM, 0);
43 if(s < 0)
45 syslog(LOG_ERR, "socket(PF_INET, SOCK_DGRAM): %m");
46 return -1;
48 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
49 if(ioctl(s, SIOCGIFADDR, &ifr, &ifrlen) < 0)
51 syslog(LOG_ERR, "ioctl(s, SIOCGIFADDR, ...): %m");
52 close(s);
53 return -1;
55 addr = (struct sockaddr_in *)&ifr.ifr_addr;
56 if(!inet_ntop(AF_INET, &addr->sin_addr, buf, len))
58 syslog(LOG_ERR, "inet_ntop(): %m");
59 close(s);
60 return -1;
62 close(s);
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;
68 if(!ifname || ifname[0]=='\0')
69 return -1;
70 if(getifaddrs(&ifap)<0)
72 syslog(LOG_ERR, "getifaddrs: %m");
73 return -1;
75 for(ife = ifap; ife; ife = ife->ifa_next)
77 /* skip other interfaces if one was specified */
78 if(ifname && (0 != strcmp(ifname, ife->ifa_name)))
79 continue;
80 if(ife->ifa_addr == NULL)
81 continue;
82 switch(ife->ifa_addr->sa_family)
84 case AF_INET:
85 inet_ntop(ife->ifa_addr->sa_family,
86 &((struct sockaddr_in *)ife->ifa_addr)->sin_addr,
87 buf, len);
88 break;
90 case AF_INET6:
91 inet_ntop(ife->ifa_addr->sa_family,
92 &((struct sockaddr_in6 *)ife->ifa_addr)->sin6_addr,
93 buf, len);
97 freeifaddrs(ifap);
98 #endif
99 return 0;
102 #ifdef ENABLE_IPV6
104 find_ipv6_addr(const char * ifname,
105 char * dst, int n)
107 struct ifaddrs * ifap;
108 struct ifaddrs * ife;
109 const struct sockaddr_in6 * addr;
110 char buf[64];
111 int r = 0;
113 if(!dst)
114 return -1;
116 if(getifaddrs(&ifap)<0)
118 syslog(LOG_ERR, "getifaddrs: %m");
119 return -1;
121 for(ife = ifap; ife; ife = ife->ifa_next)
123 /* skip other interfaces if one was specified */
124 if(ifname && (0 != strcmp(ifname, ife->ifa_name)))
125 continue;
126 if(ife->ifa_addr == NULL)
127 continue;
128 if(ife->ifa_addr == NULL)
129 continue;
130 if(ife->ifa_addr->sa_family == AF_INET6)
132 addr = (const struct sockaddr_in6 *)ife->ifa_addr;
133 if(!IN6_IS_ADDR_LOOPBACK(&addr->sin6_addr)
134 && !IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr))
136 inet_ntop(ife->ifa_addr->sa_family,
137 &addr->sin6_addr,
138 buf, sizeof(buf));
139 /* add brackets */
140 snprintf(dst, n, "[%s]", buf);
141 r = 1;
145 freeifaddrs(ifap);
146 return r;
148 #endif