Пример #1
0
int main(int argc, char * * argv) {
	signal(SIGPIPE, SIG_IGN);

	char addrStr[INET_ADDRSTRLEN];
	in_addr_t addr = GetIfAddrIPv4("eth0");
	inet_ntop(AF_INET, &addr, addrStr, INET_ADDRSTRLEN);
	printf("Using address %s\n", addrStr);

	char * uuid = "uuid:ABBB6631-67A4-4BA1-8E6A-C073FAE13FC1";
	char location[2048];
	snprintf(location, sizeof(location), "http://%s/upnp.xml?uuid=%s", addrStr, uuid);

	sendSspd("/var/run/minissdpd.sock", uuid, location, "upnp-beacon/1.0");
	sendNotify(INADDR_ANY, uuid, location, "upnp-beacon/1.0");

	return 0;
}
Пример #2
0
/**
 * Add the multicast membership for SSDP on the interface
 * @param s	the socket
 * @param ifaddr	the IPv4 address or interface name
 * @param ipv6	IPv6 or IPv4
 * return -1 on error, 0 on success */
int
AddDropMulticastMembership(int s, const char * ifaddr, int ipv6, int drop)
{
	struct ip_mreq imr;	/* Ip multicast membership */
#ifdef ENABLE_IPV6
	struct ipv6_mreq mr;
	unsigned int ifindex;
#endif

#ifdef ENABLE_IPV6
	if(ipv6)
	{
		ifindex = if_nametoindex(ifaddr);
		memset(&mr, 0, sizeof(mr));
		inet_pton(AF_INET6, LL_SSDP_MCAST_ADDR, &mr.ipv6mr_multiaddr);
		mr.ipv6mr_interface = ifindex;
		if(setsockopt(s, IPPROTO_IPV6, drop ? IPV6_LEAVE_GROUP : IPV6_JOIN_GROUP,
		   &mr, sizeof(struct ipv6_mreq)) < 0)
		{
			syslog(LOG_ERR, "setsockopt(udp, %s)(%s): %m",
			       drop ? "IPV6_LEAVE_GROUP" : "IPV6_JOIN_GROUP",
			       ifaddr);
			return -1;
		}
		inet_pton(AF_INET6, SL_SSDP_MCAST_ADDR, &mr.ipv6mr_multiaddr);
		if(setsockopt(s, IPPROTO_IPV6, drop ? IPV6_LEAVE_GROUP : IPV6_JOIN_GROUP,
		   &mr, sizeof(struct ipv6_mreq)) < 0)
		{
			syslog(LOG_ERR, "setsockopt(udp, %s)(%s): %m",
			       drop ? "IPV6_LEAVE_GROUP" : "IPV6_JOIN_GROUP",
			       ifaddr);
			return -1;
		}
	}
	else
	{
#endif
	    /* setting up imr structure */
	    imr.imr_multiaddr.s_addr = inet_addr(SSDP_MCAST_ADDR);
	    /*imr.imr_interface.s_addr = htonl(INADDR_ANY);*/
	    /*imr.imr_interface.s_addr = inet_addr(ifaddr);*/
		imr.imr_interface.s_addr = GetIfAddrIPv4(ifaddr);
		if(imr.imr_interface.s_addr == INADDR_NONE)
		{
			syslog(LOG_ERR, "no IPv4 address for interface %s",
			       ifaddr);
			return -1;
		}
		
		if (setsockopt(s, IPPROTO_IP, drop ? IP_DROP_MEMBERSHIP : IP_ADD_MEMBERSHIP,
		    (void *)&imr, sizeof(struct ip_mreq)) < 0)
		{
	        syslog(LOG_ERR, "setsockopt(udp, %s)(%s): %m",
			       drop ? "IP_DROP_MEMBERSHIP" : "IP_ADD_MEMBERSHIP",
			       ifaddr);
			return -1;
	    }
#ifdef ENABLE_IPV6
	}
#endif

	return 0;
}
Пример #3
0
int
OpenAndConfSSDPReceiveSocket(int ipv6)
{
	int s;
	int opt = 1;
#ifdef ENABLE_IPV6
	struct sockaddr_storage sockname;
#else /* ENABLE_IPV6 */
	struct sockaddr_in sockname;
#endif /* ENABLE_IPV6 */
	socklen_t sockname_len;
	struct lan_addr_s * lan_addr;

#ifndef ENABLE_IPV6
	if(ipv6) {
		syslog(LOG_ERR, "%s: please compile with ENABLE_IPV6 to allow ipv6=1", __func__);
		return -1;
	}
#endif /* ENABLE_IPV6 */

#ifdef ENABLE_IPV6
	if( (s = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0)) < 0)
#else /* ENABLE_IPV6 */
	if( (s = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
#endif /* ENABLE_IPV6 */
	{
		syslog(LOG_ERR, "socket(udp): %m");
		return -1;
	}

	if(!set_non_blocking(s)) {
		syslog(LOG_WARNING, "Failed to set SSDP socket non blocking : %m");
	}

#ifdef ENABLE_IPV6
	memset(&sockname, 0, sizeof(struct sockaddr_storage));
	if(ipv6)
	{
#ifdef IPV6_V6ONLY
		if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
		              (char *)&opt, sizeof(opt)) < 0)
		{
			syslog(LOG_WARNING, "setsockopt(IPV6_V6ONLY): %m");
		}
#endif /* IPV6_V6ONLY */
		struct sockaddr_in6 * sa = (struct sockaddr_in6 *)&sockname;
		sa->sin6_family = AF_INET6;
		sa->sin6_port = htons(SSDP_PORT);
		sa->sin6_addr = in6addr_any;
		sockname_len = sizeof(struct sockaddr_in6);
	}
	else
	{
		struct sockaddr_in * sa = (struct sockaddr_in *)&sockname;
		sa->sin_family = AF_INET;
		sa->sin_port = htons(SSDP_PORT);
#ifdef SSDP_LISTEN_ON_SPECIFIC_ADDR
		if(n_listen_addr == 1)
		{
			sa->sin_addr.s_addr = GetIfAddrIPv4(listen_addr[0]);
			if(sa->sin_addr.s_addr == INADDR_NONE)
			{
				syslog(LOG_ERR, "no IPv4 address for interface %s",
				       listen_addr[0]);
				close(s);
				return -1;
			}
		}
		else
#endif /* SSDP_LISTEN_ON_SPECIFIC_ADDR */
			sa->sin_addr.s_addr = htonl(INADDR_ANY);
		sockname_len = sizeof(struct sockaddr_in);
	}
#else /* ENABLE_IPV6 */
	memset(&sockname, 0, sizeof(struct sockaddr_in));
    sockname.sin_family = AF_INET;
    sockname.sin_port = htons(SSDP_PORT);
#ifdef SSDP_LISTEN_ON_SPECIFIC_ADDR
	if(n_listen_addr == 1)
	{
		sockname.sin_addr.s_addr = GetIfAddrIPv4(listen_addr[0]);
		if(sockname.sin_addr.s_addr == INADDR_NONE)
		{
			syslog(LOG_ERR, "no IPv4 address for interface %s",
			       listen_addr[0]);
			close(s);
			return -1;
		}
	}
	else
#endif /* SSDP_LISTEN_ON_SPECIFIC_ADDR */
	    sockname.sin_addr.s_addr = htonl(INADDR_ANY);
	sockname_len = sizeof(struct sockaddr_in);
#endif /* ENABLE_IPV6 */

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

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

	for(lan_addr = lan_addrs.lh_first; lan_addr != NULL; lan_addr = lan_addr->list.le_next)
	{
		if(AddDropMulticastMembership(s, lan_addr, ipv6, 0) < 0)
		{
			syslog(LOG_WARNING, "Failed to add IPv%d multicast membership for interface %s.",
			       ipv6 ? 6 : 4,
			       lan_addr->ifname);
		}
	}

	return s;
}