File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / miniupnpd / upnputils.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 00:32:35 2013 UTC (11 years, 5 months ago) by misho
Branches: miniupnpd, elwix, MAIN
CVS tags: v1_8p0, v1_8, HEAD
1.8

    1: /* $Id: upnputils.c,v 1.1.1.2 2013/07/22 00:32:35 misho Exp $ */
    2: /* MiniUPnP project
    3:  * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
    4:  * (c) 2006-2013 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: 
   23: #include "upnputils.h"
   24: #include "upnpglobalvars.h"
   25: #ifdef ENABLE_IPV6
   26: #include "getroute.h"
   27: #endif
   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
   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
   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: 
   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: }
  158: 

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