Annotation of embedaddon/miniupnpd/getifaddr.c, revision 1.1.1.3

1.1.1.3 ! misho       1: /* $Id: getifaddr.c,v 1.15 2012/03/05 20:36:16 nanard Exp $ */
1.1       misho       2: /* MiniUPnP project
                      3:  * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
1.1.1.3 ! 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 <netinet/in.h>
1.1.1.3 ! misho      17: #include <arpa/inet.h>
1.1       misho      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:        {
1.1.1.3 ! misho      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)
1.1.1.2   misho      81:                        continue;
                     82:                switch(ife->ifa_addr->sa_family)
                     83:                {
                     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;
                     89: /*
                     90:                case AF_INET6:
                     91:                        inet_ntop(ife->ifa_addr->sa_family,
                     92:                                  &((struct sockaddr_in6 *)ife->ifa_addr)->sin6_addr,
                     93:                                  buf, len);
                     94: */
                     95:                }
                     96:        }
                     97:        freeifaddrs(ifap);
                     98: #endif
1.1       misho      99:        return 0;
                    100: }
                    101: 
1.1.1.2   misho     102: #ifdef ENABLE_IPV6
                    103: int
                    104: find_ipv6_addr(const char * ifname,
                    105:                char * dst, int n)
                    106: {
                    107:        struct ifaddrs * ifap;
                    108:        struct ifaddrs * ife;
                    109:        const struct sockaddr_in6 * addr;
                    110:        char buf[64];
                    111:        int r = 0;
                    112: 
                    113:        if(!dst)
                    114:                return -1;
                    115: 
                    116:        if(getifaddrs(&ifap)<0)
                    117:        {
                    118:                syslog(LOG_ERR, "getifaddrs: %m");
                    119:                return -1;
                    120:        }
                    121:        for(ife = ifap; ife; ife = ife->ifa_next)
                    122:        {
                    123:                /* skip other interfaces if one was specified */
                    124:                if(ifname && (0 != strcmp(ifname, ife->ifa_name)))
                    125:                        continue;
1.1.1.3 ! misho     126:                if(ife->ifa_addr == NULL)
        !           127:                        continue;
1.1.1.2   misho     128:                if(ife->ifa_addr->sa_family == AF_INET6)
                    129:                {
                    130:                        addr = (const struct sockaddr_in6 *)ife->ifa_addr;
                    131:                        if(!IN6_IS_ADDR_LOOPBACK(&addr->sin6_addr)
                    132:                           && !IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr))
                    133:                        {
                    134:                                inet_ntop(ife->ifa_addr->sa_family,
                    135:                                          &addr->sin6_addr,
                    136:                                          buf, sizeof(buf));
                    137:                                /* add brackets */
                    138:                                snprintf(dst, n, "[%s]", buf);
                    139:                                r = 1;
                    140:                        }
                    141:                }
                    142:        }
1.1.1.3 ! misho     143:        freeifaddrs(ifap);
1.1.1.2   misho     144:        return r;
                    145: }
                    146: #endif
                    147: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>