Annotation of embedaddon/miniupnpd/minissdpd/upnputils.c, revision 1.1

1.1     ! misho       1: /* $Id: upnputils.c,v 1.2 2014/11/28 16:20:58 nanard Exp $ */
        !             2: /* MiniUPnP project
        !             3:  * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
        !             4:  * (c) 2006-2019 Thomas Bernard
        !             5:  * This software is subject to the conditions detailed
        !             6:  * in the LICENCE file provided within the distribution */
        !             7: 
        !             8: #include "config.h"
        !             9: 
        !            10: #include <stdio.h>
        !            11: #include <string.h>
        !            12: #include <syslog.h>
        !            13: #include <unistd.h>
        !            14: #include <fcntl.h>
        !            15: #include <sys/types.h>
        !            16: #include <sys/socket.h>
        !            17: #include <netinet/in.h>
        !            18: #include <arpa/inet.h>
        !            19: #ifdef AF_LINK
        !            20: #include <net/if_dl.h>
        !            21: #endif
        !            22: #include <time.h>
        !            23: #include <sys/time.h>
        !            24: 
        !            25: #include "upnputils.h"
        !            26: #include "getroute.h"
        !            27: #include "minissdpdtypes.h"
        !            28: 
        !            29: extern struct lan_addr_list lan_addrs;
        !            30: 
        !            31: int
        !            32: sockaddr_to_string(const struct sockaddr * addr, char * str, size_t size)
        !            33: {
        !            34:        char buffer[64];
        !            35:        unsigned short port = 0;
        !            36:        int n = -1;
        !            37: 
        !            38:        switch(addr->sa_family)
        !            39:        {
        !            40:        case AF_INET6:
        !            41:                inet_ntop(addr->sa_family,
        !            42:                          &((struct sockaddr_in6 *)addr)->sin6_addr,
        !            43:                          buffer, sizeof(buffer));
        !            44:                port = ntohs(((struct sockaddr_in6 *)addr)->sin6_port);
        !            45:                n = snprintf(str, size, "[%s]:%hu", buffer, port);
        !            46:                break;
        !            47:        case AF_INET:
        !            48:                inet_ntop(addr->sa_family,
        !            49:                          &((struct sockaddr_in *)addr)->sin_addr,
        !            50:                          buffer, sizeof(buffer));
        !            51:                port = ntohs(((struct sockaddr_in *)addr)->sin_port);
        !            52:                n = snprintf(str, size, "%s:%hu", buffer, port);
        !            53:                break;
        !            54: #ifdef AF_LINK
        !            55: #if defined(__sun)
        !            56:                /* solaris does not seem to have link_ntoa */
        !            57:                /* #define link_ntoa _link_ntoa */
        !            58: #define link_ntoa(x) "dummy-link_ntoa"
        !            59: #endif
        !            60:        case AF_LINK:
        !            61:                {
        !            62:                        struct sockaddr_dl * sdl = (struct sockaddr_dl *)addr;
        !            63:                        n = snprintf(str, size, "index=%hu type=%d %s",
        !            64:                                     sdl->sdl_index, sdl->sdl_type,
        !            65:                                     link_ntoa(sdl));
        !            66:                }
        !            67:                break;
        !            68: #endif
        !            69:        default:
        !            70:                n = snprintf(str, size, "unknown address family %d", addr->sa_family);
        !            71: #if 0
        !            72:                n = snprintf(str, size, "unknown address family %d "
        !            73:                             "%02x %02x %02x %02x %02x %02x %02x %02x",
        !            74:                             addr->sa_family,
        !            75:                             addr->sa_data[0], addr->sa_data[1], (unsigned)addr->sa_data[2], addr->sa_data[3],
        !            76:                             addr->sa_data[4], addr->sa_data[5], (unsigned)addr->sa_data[6], addr->sa_data[7]);
        !            77: #endif
        !            78:        }
        !            79:        return n;
        !            80: }
        !            81: 
        !            82: 
        !            83: int
        !            84: set_non_blocking(int fd)
        !            85: {
        !            86:        int flags = fcntl(fd, F_GETFL);
        !            87:        if(flags < 0)
        !            88:                return 0;
        !            89:        if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0)
        !            90:                return 0;
        !            91:        return 1;
        !            92: }
        !            93: 
        !            94: struct lan_addr_s *
        !            95: get_lan_for_peer(const struct sockaddr * peer)
        !            96: {
        !            97:        struct lan_addr_s * lan_addr = NULL;
        !            98: #ifdef DEBUG
        !            99:        char dbg_str[64];
        !           100: #endif /* DEBUG */
        !           101: 
        !           102: #ifdef ENABLE_IPV6
        !           103:        if(peer->sa_family == AF_INET6)
        !           104:        {
        !           105:                struct sockaddr_in6 * peer6 = (struct sockaddr_in6 *)peer;
        !           106:                if(IN6_IS_ADDR_V4MAPPED(&peer6->sin6_addr))
        !           107:                {
        !           108:                        struct in_addr peer_addr;
        !           109:                        memcpy(&peer_addr, &peer6->sin6_addr.s6_addr[12], 4);
        !           110:                        for(lan_addr = lan_addrs.lh_first;
        !           111:                            lan_addr != NULL;
        !           112:                            lan_addr = lan_addr->list.le_next)
        !           113:                        {
        !           114:                                if( (peer_addr.s_addr & lan_addr->mask.s_addr)
        !           115:                                   == (lan_addr->addr.s_addr & lan_addr->mask.s_addr))
        !           116:                                        break;
        !           117:                        }
        !           118:                }
        !           119:                else
        !           120:                {
        !           121:                        int index = -1;
        !           122:                        if(peer6->sin6_scope_id > 0)
        !           123:                                index = (int)peer6->sin6_scope_id;
        !           124:                        else
        !           125:                        {
        !           126:                                if(get_src_for_route_to(peer, NULL, NULL, &index) < 0)
        !           127:                                        return NULL;
        !           128:                        }
        !           129:                        syslog(LOG_DEBUG, "%s looking for LAN interface index=%d",
        !           130:                               "get_lan_for_peer()", index);
        !           131:                        for(lan_addr = lan_addrs.lh_first;
        !           132:                            lan_addr != NULL;
        !           133:                            lan_addr = lan_addr->list.le_next)
        !           134:                        {
        !           135:                                syslog(LOG_DEBUG,
        !           136:                                       "ifname=%s index=%u str=%s addr=%08x mask=%08x",
        !           137:                                       lan_addr->ifname, lan_addr->index,
        !           138:                                       lan_addr->str,
        !           139:                                       ntohl(lan_addr->addr.s_addr),
        !           140:                                       ntohl(lan_addr->mask.s_addr));
        !           141:                                if(index == (int)lan_addr->index)
        !           142:                                        break;
        !           143:                        }
        !           144:                }
        !           145:        }
        !           146:        else if(peer->sa_family == AF_INET)
        !           147:        {
        !           148: #endif /* ENABLE_IPV6 */
        !           149:                for(lan_addr = lan_addrs.lh_first;
        !           150:                    lan_addr != NULL;
        !           151:                    lan_addr = lan_addr->list.le_next)
        !           152:                {
        !           153:                        if( (((const struct sockaddr_in *)peer)->sin_addr.s_addr & lan_addr->mask.s_addr)
        !           154:                           == (lan_addr->addr.s_addr & lan_addr->mask.s_addr))
        !           155:                                break;
        !           156:                }
        !           157: #ifdef ENABLE_IPV6
        !           158:        }
        !           159: #endif /* ENABLE_IPV6 */
        !           160: 
        !           161: #ifdef DEBUG
        !           162:        sockaddr_to_string(peer, dbg_str, sizeof(dbg_str));
        !           163:        if(lan_addr) {
        !           164:                syslog(LOG_DEBUG, "%s: %s found in LAN %s %s",
        !           165:                       "get_lan_for_peer()", dbg_str,
        !           166:                       lan_addr->ifname, lan_addr->str);
        !           167:        } else {
        !           168:                syslog(LOG_DEBUG, "%s: %s not found !", "get_lan_for_peer()",
        !           169:                       dbg_str);
        !           170:        }
        !           171: #endif /* DEBUG */
        !           172:        return lan_addr;
        !           173: }
        !           174: 
        !           175: #if defined(CLOCK_MONOTONIC_FAST)
        !           176: #define UPNP_CLOCKID CLOCK_MONOTONIC_FAST
        !           177: #elif defined(CLOCK_MONOTONIC)
        !           178: #define UPNP_CLOCKID CLOCK_MONOTONIC
        !           179: #endif
        !           180: 
        !           181: int upnp_gettimeofday(struct timeval * tv)
        !           182: {
        !           183: #if defined(CLOCK_MONOTONIC_FAST) || defined(CLOCK_MONOTONIC)
        !           184:        struct timespec ts;
        !           185:        int ret_code = clock_gettime(UPNP_CLOCKID, &ts);
        !           186:        if (ret_code == 0)
        !           187:        {
        !           188:                tv->tv_sec = ts.tv_sec;
        !           189:                tv->tv_usec = ts.tv_nsec / 1000;
        !           190:        }
        !           191:        return ret_code;
        !           192: #else
        !           193:        return gettimeofday(tv, NULL);
        !           194: #endif
        !           195: }

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