--- embedaddon/miniupnpd/upnputils.c 2012/05/29 12:55:57 1.1.1.1 +++ embedaddon/miniupnpd/upnputils.c 2013/07/22 00:32:35 1.1.1.2 @@ -1,13 +1,17 @@ -/* $Id: upnputils.c,v 1.1.1.1 2012/05/29 12:55:57 misho Exp $ */ +/* $Id: upnputils.c,v 1.1.1.2 2013/07/22 00:32:35 misho Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2011 Thomas Bernard + * (c) 2006-2013 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ #include "config.h" #include +#include +#include +#include +#include #include #include #include @@ -17,6 +21,10 @@ #endif #include "upnputils.h" +#include "upnpglobalvars.h" +#ifdef ENABLE_IPV6 +#include "getroute.h" +#endif int sockaddr_to_string(const struct sockaddr * addr, char * str, size_t size) @@ -42,6 +50,11 @@ sockaddr_to_string(const struct sockaddr * addr, char n = snprintf(str, size, "%s:%hu", buffer, port); break; #ifdef AF_LINK +#if defined(__sun) + /* solaris does not seem to have link_ntoa */ + /* #define link_ntoa _link_ntoa */ +#define link_ntoa(x) "dummy-link_ntoa" +#endif case AF_LINK: { struct sockaddr_dl * sdl = (struct sockaddr_dl *)addr; @@ -65,4 +78,81 @@ sockaddr_to_string(const struct sockaddr * addr, char } +int +set_non_blocking(int fd) +{ + int flags = fcntl(fd, F_GETFL); + if(flags < 0) + return 0; + if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) + return 0; + return 1; +} + +struct lan_addr_s * +get_lan_for_peer(const struct sockaddr * peer) +{ + struct lan_addr_s * lan_addr = NULL; + +#ifdef ENABLE_IPV6 + if(peer->sa_family == AF_INET6) + { + struct sockaddr_in6 * peer6 = (struct sockaddr_in6 *)peer; + if(IN6_IS_ADDR_V4MAPPED(&peer6->sin6_addr)) + { + struct in_addr peer_addr; + memcpy(&peer_addr, &peer6->sin6_addr.s6_addr[12], 4); + for(lan_addr = lan_addrs.lh_first; + lan_addr != NULL; + lan_addr = lan_addr->list.le_next) + { + if( (peer_addr.s_addr & lan_addr->mask.s_addr) + == (lan_addr->addr.s_addr & lan_addr->mask.s_addr)) + break; + } + } + else + { + int index = -1; + if(get_src_for_route_to(peer, NULL, NULL, &index) < 0) + return NULL; + syslog(LOG_DEBUG, "%s looking for LAN interface index=%d", + "get_lan_for_peer()", index); + for(lan_addr = lan_addrs.lh_first; + lan_addr != NULL; + lan_addr = lan_addr->list.le_next) + { + syslog(LOG_DEBUG, + "ifname=%s index=%u str=%s addr=%08x mask=%08x", + lan_addr->ifname, lan_addr->index, + lan_addr->str, + ntohl(lan_addr->addr.s_addr), + ntohl(lan_addr->mask.s_addr)); + if(index == (int)lan_addr->index) + break; + } + } + } + else if(peer->sa_family == AF_INET) + { +#endif + for(lan_addr = lan_addrs.lh_first; + lan_addr != NULL; + lan_addr = lan_addr->list.le_next) + { + if( (((const struct sockaddr_in *)peer)->sin_addr.s_addr & lan_addr->mask.s_addr) + == (lan_addr->addr.s_addr & lan_addr->mask.s_addr)) + break; + } +#ifdef ENABLE_IPV6 + } +#endif + + if(lan_addr) + syslog(LOG_DEBUG, "%s: found in LAN %s %s", + "get_lan_for_peer()", lan_addr->ifname, lan_addr->str); + else + syslog(LOG_DEBUG, "%s: not found !", "get_lan_for_peer()"); + return lan_addr; +}