コード例 #1
0
ファイル: controlpoint.c プロジェクト: jink2005/mupnpc
/**
 * Do an M-SEARCH to look for devices in the network.
 *
 * @param ctrlPoint The control point in question
 * @param target The Search Target parameter (ex. "ssdp:all")
 */
bool mupnp_controlpoint_search(mUpnpControlPoint *ctrlPoint, const char *target)
{
	mUpnpSSDPRequest *ssdpReq;
	mUpnpSSDPResponseServerList *ssdpResServerList;
	int i = 0;
	bool retval = false;
	
	mupnp_log_debug_l4("Entering...\n");

	ssdpReq = mupnp_ssdprequest_new();
	mupnp_ssdprequest_setmethod(ssdpReq, MUPNP_HTTP_MSEARCH);
	mupnp_ssdprequest_setst(ssdpReq, target);
	mupnp_ssdprequest_setmx(ssdpReq, mupnp_controlpoint_getssdpsearchmx(ctrlPoint));
	mupnp_ssdprequest_setman(ssdpReq, MUPNP_MAN_DISCOVER);
	
	mupnp_log_debug("Announcing %d times.\n", mupnp_ssdp_getannouncecount());
	mupnp_ssdprequest_print(ssdpReq);
	
	for (i = 0; i < mupnp_ssdp_getannouncecount(); i++)
	{
		ssdpResServerList = mupnp_controlpoint_getssdpresponseserverlist(ctrlPoint);
		retval = ( mupnp_ssdpresponse_serverlist_post(ssdpResServerList, ssdpReq ) || retval );
		mupnp_wait(MUPNP_CONTROLPOINT_SSDP_MIN_DELAY);
	}
	
	mupnp_ssdprequest_delete(ssdpReq);

	mupnp_log_debug_l4("Leaving...\n");

	return retval;
}
コード例 #2
0
ファイル: interface_function.c プロジェクト: Coramo/mupnp
int mupnp_net_gethostinterfaces(mUpnpNetworkInterfaceList* netIfList)
{
  mupnp_log_debug_l4("Entering...\n");

  mUpnpNetworkInterface* netIf;
  FILE* fd;
  int s;
  char buffer[256 + 1];
  char ifaddr[20 + 1];
  char* ifname;
  char* sep;

  mupnp_net_interfacelist_clear(netIfList);

  s = socket(AF_INET, SOCK_DGRAM, 0);
  if (s < 0)
    return 0;
  fd = fopen(PATH_PROC_NET_DEV, "r");
  fgets(buffer, sizeof(buffer) - 1, fd);
  fgets(buffer, sizeof(buffer) - 1, fd);
  while (!feof(fd)) {
    ifname = buffer;
    sep;
    if (fgets(buffer, sizeof(buffer) - 1, fd) == NULL)
      break;
    sep = strrchr(buffer, ':');
    if (sep)
      *sep = 0;
    while (*ifname == ' ')
      ifname++;
    struct ifreq req;
    strcpy(req.ifr_name, ifname);
    if (ioctl(s, SIOCGIFFLAGS, &req) < 0)
      continue;
    if (!(req.ifr_flags & IFF_UP))
      continue;
    if (req.ifr_flags & IFF_LOOPBACK)
      continue;
    if (ioctl(s, SIOCGIFADDR, &req) < 0)
      continue;
    strncpy(ifaddr, inet_ntoa(((struct sockaddr_in*)&req.ifr_addr)->sin_addr), sizeof(ifaddr) - 1);
    netIf = mupnp_net_interface_new();
    mupnp_net_interface_setname(netIf, ifname);
    mupnp_net_interface_setaddress(netIf, ifaddr);
    mupnp_net_interfacelist_add(netIfList, netIf);
    mupnp_log_debug("Interface name: %s, address: %s\n", ifname, ifaddr);
    //cout << ifname << ", " << ifaddr << endl;
  }
  fclose(fd);
  close(s);
  return mupnp_net_interfacelist_size(netIfList);

  mupnp_log_debug_l4("Leaving...\n");
}
コード例 #3
0
ファイル: device_ssdp_server.c プロジェクト: dwlinux/mupnpc
static int simple_string_hash(char *str, int table_size)
{
        int sum=0;

	mupnp_log_debug_l4("Entering...\n");
	
        if (str==NULL) return -1;
	
	mupnp_log_debug("Calculating hash from string |%s|, table size: %d\n", str, table_size);

	/* Sum up all the characters in the string */
	for( ; *str; str++) sum += *str;

	mupnp_log_debug_l4("Leaving...\n");

	return sum % table_size;
}
コード例 #4
0
ファイル: device_ssdp_server.c プロジェクト: dwlinux/mupnpc
void mupnp_device_ssdpmessagereceived(mUpnpDevice *dev, mUpnpSSDPPacket *ssdpPkt, int filter)
{
	BOOL isRootDev;
	const char *ssdpST;
	const char *devUDN, *devType;
	char ssdpMsg[MUPNP_SSDP_HEADER_LINE_MAXSIZE];
	char deviceUSN[MUPNP_SSDP_HEADER_LINE_MAXSIZE];
#if defined WINCE
	size_t n;
#else
	int n;
#endif
	mUpnpService *service;
	mUpnpDevice *childDev;
	const char *ssdpMXString;
	int ssdpMX;
	const char *ssdpTargetAddr;

	mupnp_log_debug_l4("Entering...\n");

	ssdpMXString = mupnp_http_headerlist_getvalue(ssdpPkt->headerList, CG_HTTP_MX);
	ssdpST = mupnp_ssdp_packet_getst(ssdpPkt);

	/* Check if this ssdp packet has already been checked + filtered */
	if (filter)
	{
		
		/****************************************
		 * Request line
		 * Check the request line for errors, this is not ideal as it currently only
		 * checks for the presence of the strings and not the order.
		 ***************************************/
		/**** check for M-SEARCH and return if not found ****/
		if (mupnp_strstr(mupnp_string_getvalue(ssdpPkt->dgmPkt->data), CG_HTTP_MSEARCH) < 0)
			return;
		/**** check for * and return if not found ****/
		if (mupnp_strstr(mupnp_string_getvalue(ssdpPkt->dgmPkt->data), "*") < 0)
			return;
		/**** check HTTP version and return if not found ****/
		if (mupnp_strstr(mupnp_string_getvalue(ssdpPkt->dgmPkt->data),  CG_HTTP_VER11) < 0)
			return;

		/****************************************
		 * check HOST header, should always be 239.255.255.250:1900, return if incorrect
		 ***************************************/
		ssdpTargetAddr = mupnp_ssdp_packet_gethost(ssdpPkt);
		if (mupnp_strcmp(ssdpTargetAddr, MUPNP_SSDP_MULTICAST_ADDRESS) != 0 && !mupnp_net_isipv6address(ssdpTargetAddr) )
			return;

		/****************************************
		 * check MAN header, return if incorrect
		 ***************************************/
		if (mupnp_ssdp_packet_isdiscover(ssdpPkt) == FALSE)
			return;

		/****************************************
		 * check MX header, return if incorrect
		 ***************************************/
		if (ssdpMXString == NULL || mupnp_strlen(ssdpMXString)==0)
			/* return if the MX value does not exist or is empty */
			return;
		/* check if MX value is not an integer */
		for (n=0; n<strlen(ssdpMXString); n++) {
			if (isdigit(ssdpMXString[n]) == 0)
				/* MX value contains a non-digit so is invalid */
				return;
		}

		/****************************************
		 * check ST header and if empty return
		 ***************************************/
		if (mupnp_strlen(ssdpST) <= 0)
			return;

		/* Check if we have received this search recently
		 * and ignore duplicates. */
		if ( filter_duplicate_m_search(ssdpPkt) )
			return;

		ssdpMX = mupnp_ssdp_packet_getmx(ssdpPkt);
		mupnp_log_debug("Sleeping for a while... (MX:%d)\n", ssdpMX);
		mupnp_waitrandom((ssdpMX*1000)/4);
	}

	isRootDev = mupnp_device_isrootdevice(dev);
	
	if (mupnp_st_isalldevice(ssdpST) == TRUE) {
		/* for root device only */
		if (isRootDev == TRUE) {
			mupnp_device_getnotifydevicent(dev, ssdpMsg, sizeof(ssdpMsg));
			mupnp_device_getnotifydeviceusn(dev, deviceUSN, sizeof(deviceUSN));
			mupnp_device_postsearchresponse(dev, ssdpPkt, ssdpMsg, deviceUSN);
		}
		/* for all devices send */
		/* device type : device version */
		mupnp_device_getnotifydevicetypent(dev, ssdpMsg, sizeof(ssdpMsg));
		mupnp_device_getnotifydevicetypeusn(dev, deviceUSN, sizeof(deviceUSN));
		mupnp_device_postsearchresponse(dev, ssdpPkt, ssdpMsg, deviceUSN);
		/* device UUID */
		mupnp_device_postsearchresponse(dev, ssdpPkt, mupnp_device_getudn(dev), mupnp_device_getudn(dev));
	}
	else if (mupnp_st_isrootdevice(ssdpST)  == TRUE) {
		if (isRootDev == TRUE) {
			mupnp_device_getnotifydeviceusn(dev, deviceUSN, sizeof(deviceUSN));
			mupnp_device_postsearchresponse(dev, ssdpPkt, MUPNP_ST_ROOT_DEVICE, deviceUSN);
		}
	}
	else if (mupnp_st_isuuiddevice(ssdpST)  == TRUE) {
		devUDN = mupnp_device_getudn(dev);
		if (mupnp_streq(ssdpST, devUDN) == TRUE)
			mupnp_device_postsearchresponse(dev, ssdpPkt, devUDN, devUDN);
	}
	else if (mupnp_st_isurn(ssdpST)  == TRUE) {
		devType = mupnp_device_getdevicetype(dev);
		if (mupnp_streq(ssdpST, devType) == TRUE) {
			mupnp_device_getnotifydevicetypeusn(dev, deviceUSN, sizeof(deviceUSN));
			mupnp_device_postsearchresponse(dev, ssdpPkt, devType, deviceUSN);
		}
	}

	for (service=mupnp_device_getservices(dev); service != NULL; service = mupnp_service_next(service))
		mupnp_service_ssdpmessagereceived(service, ssdpPkt);

	for (childDev = mupnp_device_getdevices(dev); childDev != NULL; childDev = mupnp_device_next(childDev))
		mupnp_device_ssdpmessagereceived(childDev, ssdpPkt, FALSE);
	

	mupnp_log_debug_l4("Leaving...\n");
}
コード例 #5
0
ファイル: device_ssdp_server.c プロジェクト: dwlinux/mupnpc
static int filter_duplicate_m_search(mUpnpSSDPPacket *ssdpPkt)
{
	mUpnpTime *timestamps = ssdpPkt->timestamps;
	size_t s_length;
	int loc;
  const char *st;
	char *id_string, *r_address, port[6];
	mUpnpTime curr_time;

	mupnp_log_debug_l4("Entering...\n");
	
	/* Initializing hash table to zero */
	if (!ssdpPkt->initialized) {
		ssdpPkt->initialized = 1;
		memset(timestamps, '\0', MUPNP_SSDP_FILTER_TABLE_SIZE * sizeof( mUpnpTime ));
	}

	r_address = mupnp_string_getvalue(ssdpPkt->dgmPkt->remoteAddress);
	st = mupnp_ssdp_packet_getst(ssdpPkt);
	sprintf(port, "%d", ssdpPkt->dgmPkt->remotePort); 

	/* Catenating remote address string with ssdp ST header field. */
	s_length = strlen( r_address ) + strlen( st ) + strlen( port );
	id_string = (char *)malloc( s_length + 1 );

	if ( NULL == id_string )
	{
		mupnp_log_debug_s("Memory allocation problem!\n");
		return FALSE;
	}

	memset(id_string, '\0', s_length + 1);

	mupnp_strcat(id_string, r_address );
	mupnp_strcat(id_string, port);
	mupnp_strcat(id_string, st );
	
	loc = simple_string_hash(id_string, MUPNP_SSDP_FILTER_TABLE_SIZE);

	mupnp_log_debug("Calculated hash: %d\n", loc);

	free(id_string);

	curr_time = mupnp_getcurrentsystemtime();

	if ( 0 == timestamps[loc] ) {
		timestamps[loc] = curr_time;
		mupnp_log_debug("First packet... Updating hash table.\n");
		return FALSE;
	}	
	else if ( ( curr_time - timestamps[loc] ) < MUPNP_DEVICE_M_SEARCH_FILTER_INTERVAL ) {
		mupnp_log_debug("Filtering packet!\n");
		timestamps[loc] = curr_time;
		return TRUE;
	}
	else {
		timestamps[loc] = curr_time;
		mupnp_log_debug("Old timestamp found, just updating it.\n");
		return FALSE;
	}
	
	mupnp_log_debug_l4("Leaving...\n");
}
コード例 #6
0
ファイル: interface_function.c プロジェクト: Coramo/mupnp
int mupnp_net_gethostinterfaces(mUpnpNetworkInterfaceList* netIfList)
{
  mUpnpNetworkInterface* netIf;
  struct ifaddrs* ifaddr;
  char addr[NI_MAXHOST + 1];
  char netmask[NI_MAXHOST + 1];
  char* ifname;
  struct ifaddrs* i;
#if defined(HAVE_SOCKADDR_DL)
  struct sockaddr_dl* dladdr;
#elif defined(HAVE_SIOCGIFHWADDR)
  int sock;
  struct ifreq ifr;
#endif

  mupnp_log_debug_l4("Entering...\n");

  mupnp_net_interfacelist_clear(netIfList);

  if (getifaddrs(&ifaddr) != 0) {
    mupnp_log_debug("No addresses for interfaces!\n");
    return 0;
  }

  for (i = ifaddr; i != NULL; i = i->ifa_next) {

    // Thanks for Ricardo Rivldo (04/10/12)
    //  - for some reason, vmware and virtualbox \"virtual\" interfaces does not return ifa_addr
    if (i->ifa_addr == NULL || i->ifa_netmask == NULL)
      continue;

    // Thanks for Tobias.Gansen (01/15/06)
    if (i->ifa_addr->sa_family != AF_INET)
      continue;
    if (!(i->ifa_flags & IFF_UP))
      continue;
    if (i->ifa_flags & IFF_LOOPBACK)
      continue;

    if (getnameinfo(i->ifa_addr, sizeof(struct sockaddr), addr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) != 0)
      continue;

    if (getnameinfo(i->ifa_netmask, sizeof(struct sockaddr), netmask, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) != 0)
      continue;

    ifname = i->ifa_name;
    mupnp_log_debug("Interface name: %s, address: %s\n", ifname, addr);
    netIf = mupnp_net_interface_new();
    mupnp_net_interface_setname(netIf, ifname);
    mupnp_net_interface_setaddress(netIf, addr);
    mupnp_net_interface_setnetmask(netIf, netmask);
#if defined(HAVE_SOCKADDR_DL)
    dladdr = (struct sockaddr_dl*)(i->ifa_addr);
    mupnp_net_interface_setmacaddress(netIf, LLADDR(dladdr));
#elif defined(HAVE_SIOCGIFHWADDR)
    sock = socket(AF_INET, SOCK_DGRAM, 0);
    strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);
    ifr.ifr_addr.sa_family = AF_INET;
    ioctl(sock, SIOCGIFHWADDR, &ifr);
    mupnp_net_interface_setmacaddress(netIf, ifr.ifr_hwaddr.sa_data);
    close(sock);
#endif
    mupnp_net_interfacelist_add(netIfList, netIf);
  }
  freeifaddrs(ifaddr);

  mupnp_log_debug_l4("Leaving...\n");

  return mupnp_net_interfacelist_size(netIfList);
}
コード例 #7
0
BOOL mupnp_http_persistentconnection_put(char *host, int port, void *data)
{
       mUpnpHttpPersistentConnection *new_node = NULL, *node = NULL;

	mupnp_log_debug_l4("Entering...\n");

       /* If we dont have cache, then just exit */
       if (cache == NULL) {
	       mupnp_log_debug("(put) No cache! Persistent connections not initialized?\n");
	       return FALSE;
       }

       /* Check if we already have this one cached */
       for (node = (mUpnpHttpPersistentConnection*)mupnp_list_gets((mUpnpList*)cache);
            node != NULL;
            node = (mUpnpHttpPersistentConnection*)mupnp_list_next((mUpnpList*)node))
       {
               if (mupnp_strcmp(mupnp_string_getvalue(node->host), host) == 0 &&
                   node->port == port)
               {
                       /* If also data is the same, then update just
                          timestamp */
                       if (node->cacheData == data)
                       {
                               node->timestamp = mupnp_getcurrentsystemtime();
                               return TRUE;
                       }

		      mupnp_log_debug_s("Found cached persistent connection for %s:%d\n",
			      mupnp_string_getvalue(node->host), node->port);
                       new_node = node;
                       mupnp_list_remove((mUpnpList*)new_node);
                       break;
               }
       }

       /* We didn't find it */
       if (new_node == NULL)
       {
               /* Check if we have already too many cached things */
               if (mupnp_list_size((mUpnpList*)cache) >= CG_HTTP_PERSISTENT_CACHE_SIZE)
               {
                       /* Take last node (not refreshed for a long time) */
                       new_node = (mUpnpHttpPersistentConnection *)mupnp_list_next((mUpnpList *)cache);
                       mupnp_list_remove((mUpnpList*)new_node);
                       mupnp_http_persistentconnection_delete(new_node);
                       new_node = NULL;

		      mupnp_log_debug_s("Max persistent HTTP connection cache reached.\n");
               }

               if (new_node == NULL)
               {
                       if (data == NULL) return TRUE;

                       new_node = mupnp_http_persistentconnection_new();
                       if (new_node == NULL) return FALSE;

		      mupnp_log_debug_s("Adding persistent HTTP Connection %s:%d to cache\n",
			       host, port);
		      mupnp_log_debug_s("Persistent connections: %d\n", mupnp_list_size((mUpnpList*)cache));
               }
       }

       if (data != NULL)
       {
               /* Set appropriate values for the node */
               mupnp_string_setvalue(new_node->host, host);
               new_node->port = port;
               new_node->cacheData = data;
               new_node->timestamp = mupnp_getcurrentsystemtime();

               mupnp_list_add((mUpnpList*)cache, (mUpnpList*)new_node);
       } else {
               /* remove and delete node */
               mupnp_http_persistentconnection_delete(new_node);
       }

       return TRUE;

	mupnp_log_debug_l4("Leaving...\n");
}
コード例 #8
0
void *mupnp_http_persistentconnection_get(char *host, int port)
{
       mUpnpHttpPersistentConnection *node;
       mUpnpTime sys_time = mupnp_getcurrentsystemtime();
       BOOL iterate;

mupnp_log_debug_l4("Entering...\n");

       /* If we dont have cache, then just exit */
       if (cache == NULL) { 
	       mupnp_log_debug("(get) No cache! Persistent connections not initialized?\n");
	       return NULL;
	}

       /* Clear all expired nodes */
       do {
               iterate = FALSE;
               for (node = (mUpnpHttpPersistentConnection*)mupnp_list_gets((mUpnpList*)cache);
                    node != NULL;
                    node = (mUpnpHttpPersistentConnection*)mupnp_list_next((mUpnpList*)node))
               {
                       if (sys_time > node->timestamp + CG_HTTP_PERSISTENT_TIMEOUT_PERIOD)
                       {
			      mupnp_log_debug_s("Timeout for persistent HTTP Connection to %s:%d "
				       "(timestamp: %d)\n",
				      mupnp_string_getvalue(node->host), node->port,
				      node->timestamp);
                               mupnp_list_remove((mUpnpList*)node);
                               mupnp_http_persistentconnection_delete(node);
                               iterate = TRUE;
                               break;
                       }
               }
       } while (iterate);

       /* Get persistent node */
       for (node = (mUpnpHttpPersistentConnection*)mupnp_list_gets((mUpnpList*)cache);
            node != NULL;
            node = (mUpnpHttpPersistentConnection*)mupnp_list_next((mUpnpList*)node))
       {
               if (mupnp_strcmp(mupnp_string_getvalue(node->host), host) == 0 &&
                   node->port == port)
               {
                       /* Node was required, remove and add again to refresh
                          cache */
                       mupnp_list_remove((mUpnpList*)node);
                       mupnp_list_add((mUpnpList*)cache, (mUpnpList*)node);

                       node->timestamp = mupnp_getcurrentsystemtime();

		      mupnp_log_debug_s("Persistent HTTP Connection cache HIT for %s:%d\n",
			       host, port);

                       return node->cacheData;
               }
       }

      mupnp_log_debug_s("Persistent HTTP Connection cache MISS for %s:%d\n",
	      host, port);

       return NULL;

	mupnp_log_debug_l4("Leaving...\n");
}