Annotation of embedaddon/miniupnpd/upnputils.c, revision 1.1.1.2

1.1.1.2 ! misho       1: /* $Id: upnputils.c,v 1.6 2013/02/06 10:50:04 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-2013 Thomas Bernard
1.1       misho       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>
1.1.1.2 ! misho      11: #include <string.h>
        !            12: #include <syslog.h>
        !            13: #include <unistd.h>
        !            14: #include <fcntl.h>
1.1       misho      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: 
                     23: #include "upnputils.h"
1.1.1.2 ! misho      24: #include "upnpglobalvars.h"
        !            25: #ifdef ENABLE_IPV6
        !            26: #include "getroute.h"
        !            27: #endif
1.1       misho      28: 
                     29: int
                     30: sockaddr_to_string(const struct sockaddr * addr, char * str, size_t size)
                     31: {
                     32:        char buffer[64];
                     33:        unsigned short port = 0;
                     34:        int n = -1;
                     35: 
                     36:        switch(addr->sa_family)
                     37:        {
                     38:        case AF_INET6:
                     39:                inet_ntop(addr->sa_family,
                     40:                          &((struct sockaddr_in6 *)addr)->sin6_addr,
                     41:                          buffer, sizeof(buffer));
                     42:                port = ntohs(((struct sockaddr_in6 *)addr)->sin6_port);
                     43:                n = snprintf(str, size, "[%s]:%hu", buffer, port);
                     44:                break;
                     45:        case AF_INET:
                     46:                inet_ntop(addr->sa_family,
                     47:                          &((struct sockaddr_in *)addr)->sin_addr,
                     48:                          buffer, sizeof(buffer));
                     49:                port = ntohs(((struct sockaddr_in *)addr)->sin_port);
                     50:                n = snprintf(str, size, "%s:%hu", buffer, port);
                     51:                break;
                     52: #ifdef AF_LINK
1.1.1.2 ! misho      53: #if defined(__sun)
        !            54:                /* solaris does not seem to have link_ntoa */
        !            55:                /* #define link_ntoa _link_ntoa */
        !            56: #define link_ntoa(x) "dummy-link_ntoa"
        !            57: #endif
1.1       misho      58:        case AF_LINK:
                     59:                {
                     60:                        struct sockaddr_dl * sdl = (struct sockaddr_dl *)addr;
                     61:                        n = snprintf(str, size, "index=%hu type=%d %s",
                     62:                                     sdl->sdl_index, sdl->sdl_type,
                     63:                                     link_ntoa(sdl));
                     64:                }
                     65:                break;
                     66: #endif
                     67:        default:
                     68:                n = snprintf(str, size, "unknown address family %d", addr->sa_family);
                     69: #if 0
                     70:                n = snprintf(str, size, "unknown address family %d "
                     71:                             "%02x %02x %02x %02x %02x %02x %02x %02x",
                     72:                             addr->sa_family,
                     73:                             addr->sa_data[0], addr->sa_data[1], (unsigned)addr->sa_data[2], addr->sa_data[3],
                     74:                             addr->sa_data[4], addr->sa_data[5], (unsigned)addr->sa_data[6], addr->sa_data[7]);
                     75: #endif
                     76:        }
                     77:        return n;
                     78: }
                     79: 
                     80: 
1.1.1.2 ! misho      81: int
        !            82: set_non_blocking(int fd)
        !            83: {
        !            84:        int flags = fcntl(fd, F_GETFL);
        !            85:        if(flags < 0)
        !            86:                return 0;
        !            87:        if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0)
        !            88:                return 0;
        !            89:        return 1;
        !            90: }
        !            91: 
        !            92: struct lan_addr_s *
        !            93: get_lan_for_peer(const struct sockaddr * peer)
        !            94: {
        !            95:        struct lan_addr_s * lan_addr = NULL;
        !            96: 
        !            97: #ifdef ENABLE_IPV6
        !            98:        if(peer->sa_family == AF_INET6)
        !            99:        {
        !           100:                struct sockaddr_in6 * peer6 = (struct sockaddr_in6 *)peer;
        !           101:                if(IN6_IS_ADDR_V4MAPPED(&peer6->sin6_addr))
        !           102:                {
        !           103:                        struct in_addr peer_addr;
        !           104:                        memcpy(&peer_addr, &peer6->sin6_addr.s6_addr[12], 4);
        !           105:                        for(lan_addr = lan_addrs.lh_first;
        !           106:                            lan_addr != NULL;
        !           107:                            lan_addr = lan_addr->list.le_next)
        !           108:                        {
        !           109:                                if( (peer_addr.s_addr & lan_addr->mask.s_addr)
        !           110:                                   == (lan_addr->addr.s_addr & lan_addr->mask.s_addr))
        !           111:                                        break;
        !           112:                        }
        !           113:                }
        !           114:                else
        !           115:                {
        !           116:                        int index = -1;
        !           117:                        if(get_src_for_route_to(peer, NULL, NULL, &index) < 0)
        !           118:                                return NULL;
        !           119:                        syslog(LOG_DEBUG, "%s looking for LAN interface index=%d",
        !           120:                               "get_lan_for_peer()", index);
        !           121:                        for(lan_addr = lan_addrs.lh_first;
        !           122:                            lan_addr != NULL;
        !           123:                            lan_addr = lan_addr->list.le_next)
        !           124:                        {
        !           125:                                syslog(LOG_DEBUG,
        !           126:                                       "ifname=%s index=%u str=%s addr=%08x mask=%08x",
        !           127:                                       lan_addr->ifname, lan_addr->index,
        !           128:                                       lan_addr->str,
        !           129:                                       ntohl(lan_addr->addr.s_addr),
        !           130:                                       ntohl(lan_addr->mask.s_addr));
        !           131:                                if(index == (int)lan_addr->index)
        !           132:                                        break;
        !           133:                        }
        !           134:                }
        !           135:        }
        !           136:        else if(peer->sa_family == AF_INET)
        !           137:        {
        !           138: #endif
        !           139:                for(lan_addr = lan_addrs.lh_first;
        !           140:                    lan_addr != NULL;
        !           141:                    lan_addr = lan_addr->list.le_next)
        !           142:                {
        !           143:                        if( (((const struct sockaddr_in *)peer)->sin_addr.s_addr & lan_addr->mask.s_addr)
        !           144:                           == (lan_addr->addr.s_addr & lan_addr->mask.s_addr))
        !           145:                                break;
        !           146:                }
        !           147: #ifdef ENABLE_IPV6
        !           148:        }
        !           149: #endif
        !           150: 
        !           151:        if(lan_addr)
        !           152:                syslog(LOG_DEBUG, "%s: found in LAN %s %s",
        !           153:                       "get_lan_for_peer()", lan_addr->ifname, lan_addr->str);
        !           154:        else
        !           155:                syslog(LOG_DEBUG, "%s: not found !", "get_lan_for_peer()");
        !           156:        return lan_addr;
        !           157: }
1.1       misho     158: 

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