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>