Esempio n. 1
0
/* Open and configure the socket listening for 
 * SSDP udp packets sent on 239.255.255.250 port 1900 */
int
OpenAndConfSSDPReceiveSocket()
{
	int s;
	int i;
	int j = 1;
	struct sockaddr_in sockname;
	
	if( (s = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
	{
		syslog(LOG_ERR, "socket(udp): %m");
		return -1;
	}	
	
	memset(&sockname, 0, sizeof(struct sockaddr_in));
    sockname.sin_family = AF_INET;
    sockname.sin_port = htons(SSDP_PORT);
	/* NOTE : it seems it doesnt work when binding on the specific address */
    /*sockname.sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);*/
    sockname.sin_addr.s_addr = htonl(INADDR_ANY);
    /*sockname.sin_addr.s_addr = inet_addr(ifaddr);*/

	if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &j, sizeof(j)) < 0)
	{
		syslog(LOG_WARNING, "setsockopt(udp, SO_REUSEADDR): %m");
	}


    if(bind(s, (struct sockaddr *)&sockname, sizeof(struct sockaddr_in)) < 0)
	{
		syslog(LOG_ERR, "bind(udp): %m");
		close(s);
		return -1;
    }

	i = n_lan_addr;
	while(i>0)
	{
		i--;
		if(AddMulticastMembership(s, lan_addr[i].addr.s_addr) < 0)
		{
			syslog(LOG_WARNING,
			       "Failed to add multicast membership for address %s", 
			       lan_addr[i].str );
		}
	}

	return s;
}
Esempio n. 2
0
void
renew_mcast_membership(struct lan_addr_s *iface)
{
	if (DropMulticastMembership(sssdp, iface) < 0)
	{
		DPRINTF(E_DEBUG, L_SSDP, "Failed to drop multicast membership for address %s\n",
			iface->str);
	}

	if (AddMulticastMembership(sssdp, iface) < 0)
	{
		DPRINTF(E_ERROR, L_SSDP, "Failed to add multicast membership for address %s\n",
			iface->str);
	}
}
Esempio n. 3
0
/* Open and configure the socket listening for 
 * SSDP udp packets sent on 239.255.255.250 port 1900 */
int
OpenAndConfSSDPReceiveSocket(void)
{
	int s;
	int i = 1;
	struct sockaddr_in sockname;
	
	s = socket(PF_INET, SOCK_DGRAM, 0);
	if (s < 0)
	{
		DPRINTF(E_ERROR, L_SSDP, "socket(udp): %s\n", strerror(errno));
		return -1;
	}	

	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0)
		DPRINTF(E_WARN, L_SSDP, "setsockopt(udp, SO_REUSEADDR): %s\n", strerror(errno));
	
	memset(&sockname, 0, sizeof(struct sockaddr_in));
	sockname.sin_family = AF_INET;
	sockname.sin_port = htons(SSDP_PORT);
	/* NOTE : it seems it doesnt work when binding on the specific address */
	sockname.sin_addr.s_addr = htonl(INADDR_ANY);

	if (bind(s, (struct sockaddr *)&sockname, sizeof(struct sockaddr_in)) < 0)
	{
		DPRINTF(E_ERROR, L_SSDP, "bind(udp): %s\n", strerror(errno));
		close(s);
		return -1;
	}

	i = n_lan_addr;
	while (i > 0)
	{
		i--;
		if (AddMulticastMembership(s, lan_addr[i].addr.s_addr) < 0)
		{
			DPRINTF(E_WARN, L_SSDP,
			       "Failed to add multicast membership for address %s\n", 
			       lan_addr[i].str );
		}
	}

	return s;
}
Esempio n. 4
0
/* Open and configure the socket listening for
 * SSDP udp packets sent on 239.255.255.250 port 1900
 * SSDP v6 udp packets sent on FF02::C, or FF05::C, port 1900 */
int
OpenAndConfSSDPReceiveSocket(int ipv6)
{
	int s;
	struct sockaddr_storage sockname;
	socklen_t sockname_len;
	struct lan_addr_s * lan_addr;
	int j = 1;

	if( (s = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0)) < 0)
	{
		syslog(LOG_ERR, "%s: socket(udp): %m",
		       "OpenAndConfSSDPReceiveSocket");
		return -1;
	}

	memset(&sockname, 0, sizeof(struct sockaddr_storage));
	if(ipv6) {
		struct sockaddr_in6 * saddr = (struct sockaddr_in6 *)&sockname;
		saddr->sin6_family = AF_INET6;
		saddr->sin6_port = htons(SSDP_PORT);
		saddr->sin6_addr = in6addr_any;
		sockname_len = sizeof(struct sockaddr_in6);
	} else {
		struct sockaddr_in * saddr = (struct sockaddr_in *)&sockname;
		saddr->sin_family = AF_INET;
		saddr->sin_port = htons(SSDP_PORT);
		/* NOTE : it seems it doesnt work when binding on the specific address */
		/*saddr->sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);*/
		saddr->sin_addr.s_addr = htonl(INADDR_ANY);
		/*saddr->sin_addr.s_addr = inet_addr(ifaddr);*/
		sockname_len = sizeof(struct sockaddr_in);
	}

	if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &j, sizeof(j)) < 0)
	{
		syslog(LOG_WARNING, "setsockopt(udp, SO_REUSEADDR): %m");
	}

	if(!set_non_blocking(s))
	{
		syslog(LOG_WARNING, "%s: set_non_blocking(): %m",
		       "OpenAndConfSSDPReceiveSocket");
	}

	if(bind(s, (struct sockaddr *)&sockname, sockname_len) < 0)
	{
		syslog(LOG_ERR, "%s: bind(udp%s): %m",
		       "OpenAndConfSSDPReceiveSocket", ipv6 ? "6" : "");
		close(s);
		return -1;
	}

#ifdef ENABLE_IPV6
	if(ipv6)
	{
		AddMulticastMembershipIPv6(s);
	}
	else
#endif
	{
		for(lan_addr = lan_addrs.lh_first; lan_addr != NULL; lan_addr = lan_addr->list.le_next)
		{
			if(AddMulticastMembership(s, lan_addr->addr.s_addr) < 0)
			{
				syslog(LOG_WARNING,
				       "Failed to add multicast membership for interface %s",
				       lan_addr->str ? lan_addr->str : "NULL");
			}
		}
	}

	return s;
}
Esempio n. 5
0
/* disabled at the moment */
int
ProcessInterfaceUp(struct ifinfomsg *ifi)
{
	struct lan_iface_s * lan_iface;
	struct lan_iface_s * lan_iface2;
	struct lan_addr_s * lan_addr;
	char ifname[IFNAMSIZ];
	char ifstraddr[16];
	struct in_addr ifaddr;

	/* check if we already have this iface */
	for(lan_iface = lan_ifaces.lh_first; lan_iface != NULL; lan_iface = lan_iface->list.le_next)
		if (lan_iface->iface.index == ifi->ifi_index)
			break;

	if (lan_iface != NULL)
		return 0;

	if (if_indextoname(ifi->ifi_index, ifname) == NULL)
	{
		syslog(LOG_ERR, "if_indextoname(%d, ifname) failed", ifi->ifi_index);
		return -1;
	}

	if (getifaddr(ifname, ifstraddr, 16) < 0)
	{
		syslog(LOG_DEBUG, "getifaddr(%s, ifaddr, 16) failed", ifname);
		return 1;
	}

	if (inet_pton(AF_INET, ifstraddr, &ifaddr) != 1)
	{
		syslog(LOG_ERR, "inet_pton(AF_INET, \"%s\", &ifaddr) failed", ifstraddr);
		return -1;
	}

	/* check if this new interface has address which we need to listen to */
	for(lan_addr = lan_addrs.lh_first; lan_addr != NULL; lan_addr = lan_addr->list.le_next)
	{
		if (lan_addr->addr.s_addr != ifaddr.s_addr)
			continue;

		syslog(LOG_INFO, "Interface up: %s (%s)", ifname, ifstraddr);

		/* adding new lan_iface entry */
		lan_iface = (struct lan_iface_s *) malloc(sizeof(struct lan_iface_s));
		if (lan_iface == NULL)
		{
			syslog(LOG_ERR, "malloc(sizeof(struct lan_iface_s): %m");
			continue;
		}

		lan_iface->lan_addr = lan_addr;
		strncpy(lan_iface->iface.name, ifname, IFNAMSIZ);
		lan_iface->iface.index = ifi->ifi_index;
		lan_iface->iface.addr = ifaddr;
		lan_iface->snotify = -1;
#ifdef ENABLE_NATPMP
		lan_iface->snatpmp = -1;
#endif

		LIST_INSERT_HEAD(&lan_ifaces, lan_iface, list);

		/* adding multicast membership for SSDP */
		if(AddMulticastMembership(sudp, ifaddr.s_addr, ifi->ifi_index) < 0)
			syslog(LOG_WARNING, "Failed to add multicast membership for interface %s (%s)", ifname, ifstraddr);
		else
			syslog(LOG_INFO, "Multicast membership added for %s (%s)", ifname, ifstraddr);

		/* create SSDP notify socket */
		if (OpenAndConfSSDPNotifySocket(lan_iface) < 0)
			syslog(LOG_WARNING, "Failed to open SSDP notify socket for interface %s (%s)", ifname, ifstraddr);

#ifdef ENABLE_NATPMP
		/* create NAT-PMP socket */
		for(lan_iface2 = lan_ifaces.lh_first; lan_iface2 != NULL; lan_iface2 = lan_iface2->list.le_next)
			if (lan_iface2->lan_addr->addr.s_addr == lan_iface->lan_addr->addr.s_addr &&
			    lan_iface2->snatpmp >= 0)
				lan_iface->snatpmp = lan_iface2->snatpmp;

		if (lan_iface->snatpmp < 0)
		{
			lan_iface->snatpmp = OpenAndConfNATPMPSocket(ifaddr.s_addr);
			if (lan_iface->snatpmp < 0)
				syslog(LOG_ERR, "OpenAndConfNATPMPSocket(ifaddr.s_addr) failed for %s (%s)", ifname, ifstraddr);
			else
				syslog(LOG_INFO, "Listening for NAT-PMP connection on %s:%d", ifstraddr, NATPMP_PORT);
		}
#endif
	}

	return 0;
}
Esempio n. 6
0
/* open the UDP socket used to send SSDP notifications to
 * the multicast group reserved for them */
int
OpenAndConfSSDPNotifySocket(struct lan_addr_s *iface)
{
	int s;
	unsigned char loopchar = 0;
	/* no need
	int bcast = 1;
	*/
	uint8_t ttl = 2; /* UDA v1.1 says :
		The TTL for the IP packet SHOULD default to 2 and
		SHOULD be configurable. */
	struct in_addr mc_if;
	struct sockaddr_in sockname;
	
	s = socket(PF_INET, SOCK_DGRAM, 0);
	if (s < 0)
	{
		DPRINTF(E_ERROR, L_SSDP, "socket(udp_notify): %s\n", strerror(errno));
		return -1;
	}

	mc_if.s_addr = iface->addr.s_addr;

	if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopchar, sizeof(loopchar)) < 0)
	{
		DPRINTF(E_ERROR, L_SSDP, "setsockopt(udp_notify, IP_MULTICAST_LOOP): %s\n", strerror(errno));
		close(s);
		return -1;
	}

	if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (char *)&mc_if, sizeof(mc_if)) < 0)
	{
		DPRINTF(E_ERROR, L_SSDP, "setsockopt(udp_notify, IP_MULTICAST_IF): %s\n", strerror(errno));
		close(s);
		return -1;
	}

	setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));

	/* no need
	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof(bcast)) < 0)
	{
		DPRINTF(E_ERROR, L_SSDP, "setsockopt(udp_notify, SO_BROADCAST): %s\n", strerror(errno));
		close(s);
		return -1;
	}
	*/

	memset(&sockname, 0, sizeof(struct sockaddr_in));
	sockname.sin_family = AF_INET;
	sockname.sin_addr.s_addr = iface->addr.s_addr;

	if (bind(s, (struct sockaddr *)&sockname, sizeof(struct sockaddr_in)) < 0)
	{
		DPRINTF(E_ERROR, L_SSDP, "bind(udp_notify): %s\n", strerror(errno));
		close(s);
		return -1;
	}

	if (DropMulticastMembership(sssdp, iface) < 0)
	{
		DPRINTF(E_DEBUG, L_SSDP, "Failed to drop multicast membership for address %s\n",
			iface->str);
	}

	if (AddMulticastMembership(sssdp, iface) < 0)
	{
		DPRINTF(E_WARN, L_SSDP, "Failed to add multicast membership for address %s\n", 
			iface->str);
	}

	return s;
}