Example #1
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);
	}
}
Example #2
0
int
ProcessInterfaceDown(struct ifinfomsg *ifi)
{
	struct lan_iface_s * lan_iface;
	struct lan_iface_s * lan_iface2;

	/* check if we 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;

	/* one of our interfaces is going down, clean up */
	syslog(LOG_INFO, "Interface down: %s", lan_iface->iface.name);

	/* remove multicast membership for SSDP */
	if(DropMulticastMembership(sudp, lan_iface->lan_addr->addr.s_addr, lan_iface->iface.index) < 0)
		syslog(LOG_WARNING, "Failed to drop multicast membership for interface %s (%s)", lan_iface->iface.name, lan_iface->lan_addr->str);
	else
		syslog(LOG_INFO, "Multicast membership dropped for %s (%s)", lan_iface->iface.name, lan_iface->lan_addr->str);

	/* closing SSDP notify socket */
	close(lan_iface->snotify);

#ifdef ENABLE_NATPMP
	/* closing NAT-PMP socket if it's not used anymore */
	for(lan_iface2 = lan_ifaces.lh_first; lan_iface2 != NULL; lan_iface2 = lan_iface2->list.le_next)
		if (lan_iface2 != lan_iface && lan_iface2->snatpmp == lan_iface->snatpmp)
			break;

	if (lan_iface2 == NULL)
		close(lan_iface->snatpmp);
#endif

	/* del corresponding lan_iface entry */
	LIST_REMOVE(lan_iface, list);
	free(lan_iface);

	return 0;
}
Example #3
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;
}