Example #1
0
const char *mupnp_ssdp_gethostaddress(const char *ifAddr)
{
	const char *ssdpAddr = MUPNP_SSDP_ADDRESS;

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

	if (mupnp_net_isipv6address(ifAddr) == TRUE)
		ssdpAddr = mupnp_ssdp_getipv6address();
	return ssdpAddr;

	mupnp_log_debug_l4("Leaving...\n");
}
Example #2
0
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");
}
Example #3
0
int mupnp_net_gethostinterfaces(mUpnpNetworkInterfaceList* netIfList)
{
#if !defined(MUPNP_USE_WIN32_GETHOSTADDRESSES) && !defined(MUPNP_USE_WIN32_GETADAPTERSINFO)
  mUpnpNetworkInterface* netIf;
  SOCKET sd;
  int nNumInterfaces;
  INTERFACE_INFO InterfaceList[20];
  unsigned long nBytesReturned, *pnBytesReturned = &nBytesReturned;
  struct sockaddr_in* pAddress;
  struct sockaddr_in* pNetmask;
  char* host;
  char* netmask;
  u_long nFlags;
  int i;

  mupnp_socket_startup();
  mupnp_net_interfacelist_clear(netIfList);

  sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
  //Theo Beisch WINSOCK2API WSASocket will return INVALID_SOCKET on error, not SOCKET_ERROR
  if (sd == INVALID_SOCKET) {
    return 0;
  }

  if (WSAIoctl(sd, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList, sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR)
    return 0;

  nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);
  for (i = 0; i < nNumInterfaces; ++i) {
    nFlags = InterfaceList[i].iiFlags;
    //if (CyberNet::HostInterface::USE_ONLY_IPV4_ADDR == false) {
    if (nFlags & IFF_LOOPBACK)
      continue;
    //}
    if (!(nFlags & IFF_UP))
      continue;
    //if (IsUseAddress(host) == false)
    //	continue;

    netIf = mupnp_net_interface_new();

    pAddress = (struct sockaddr_in*)&(InterfaceList[i].iiAddress);
    host = inet_ntoa(pAddress->sin_addr);
    mupnp_net_interface_setaddress(netIf, host);

    pNetmask = (struct sockaddr_in*)&(InterfaceList[i].iiNetmask);
    netmask = inet_ntoa(pNetmask->sin_addr);
    mupnp_net_interface_setnetmask(netIf, netmask);

    mupnp_net_interfacelist_add(netIfList, netIf);
  }

#elif defined(MUPNP_USE_WIN32_GETADAPTERSINFO)
#pragma comment(lib, "Iphlpapi.lib")

  mUpnpNetworkInterface* netIf;
  PIP_ADAPTER_INFO pAdapterInfo = NULL, pAdapter = NULL;
  ULONG ulOutBufLen;
  DWORD dwRetVal;
  DWORD nOfInterfaces;

  mupnp_socket_startup();
  mupnp_net_interfacelist_clear(netIfList);

  ulOutBufLen = sizeof(IP_ADAPTER_INFO);
  pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen);
  if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
    free(pAdapterInfo);
    pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen);
  }

  if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
    for (pAdapter = pAdapterInfo, nOfInterfaces = 0; pAdapter; pAdapter = pAdapter->Next, ++nOfInterfaces) {
      if (pAdapter->Type == MIB_IF_TYPE_LOOPBACK)
        continue;
      if (mupnp_streq(pAdapter->IpAddressList.IpAddress.String, "0.0.0.0"))
        continue;
      netIf = mupnp_net_interface_new();
      mupnp_net_interface_setaddress(netIf, pAdapter->IpAddressList.IpAddress.String);
      mupnp_net_interface_setnetmask(netIf, pAdapter->IpAddressList.IpMask.String);
      if (pAdapter->AddressLength == MUPNP_NET_MACADDR_SIZE)
        mupnp_net_interface_setmacaddress(netIf, pAdapter->Address);
      mupnp_net_interfacelist_add(netIfList, netIf);
    }
  }
  free(pAdapterInfo);

#elif defined(MUPNP_USE_WIN32_GETHOSTADDRESSES)
#pragma comment(lib, "Iphlpapi.lib")

  IP_ADAPTER_ADDRESSES *pAdapterAddresses, *ai;
  DWORD ifFlags;
  ULONG outBufLen;
  IP_ADAPTER_UNICAST_ADDRESS* uai;
  SOCKET_ADDRESS sockaddr;
  SOCKADDR* saddr;
  INT saddrlen;
  char addr[NI_MAXHOST];
  char port[NI_MAXSERV];
  int namInfoRet;
  int ifIdx;
  mUpnpNetworkInterface* netIf;

  mupnp_socket_startup();
  mupnp_net_interfacelist_clear(netIfList);

  outBufLen = 0;
  ifFlags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_FRIENDLY_NAME | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;

  GetAdaptersAddresses(AF_UNSPEC, ifFlags, NULL, NULL, &outBufLen);
  pAdapterAddresses = (IP_ADAPTER_ADDRESSES*)LocalAlloc(LMEM_ZEROINIT, outBufLen);
  GetAdaptersAddresses(AF_UNSPEC, ifFlags, NULL, pAdapterAddresses, &outBufLen);
  ai = pAdapterAddresses;
  while (ai != NULL) {
    if (ai->OperStatus != IfOperStatusUp) {
      ai = ai->Next;
      continue;
    }
    if (ai->IfType == IF_TYPE_SOFTWARE_LOOPBACK) {
      ai = ai->Next;
      continue;
    }
    if (ai->IfType == IF_TYPE_TUNNEL) {
      ai = ai->Next;
      continue;
    }
    uai = ai->FirstUnicastAddress;
    while (uai != NULL) {
      sockaddr = uai->Address;
      saddr = sockaddr.lpSockaddr;
      saddrlen = sockaddr.iSockaddrLength;
      namInfoRet = getnameinfo(saddr, saddrlen, addr, sizeof(addr), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
      if (namInfoRet == 0) {
        //if (IsUseAddress(addr) == true) {
        ifIdx = 0;
        if (mupnp_net_isipv6address(addr) == true)
          ifIdx = mupnp_net_getipv6scopeid(addr);
        netIf = mupnp_net_interface_new();
        mupnp_net_interface_setaddress(netIf, addr);
        if (ai->PhysicalAddressLength == MUPNP_NET_MACADDR_SIZE)
          mupnp_net_interface_setmacaddress(netIf, ai->PhysicalAddress);
        mupnp_net_interface_setindex(netIf, ifIdx);
        mupnp_net_interfacelist_add(netIfList, netIf);
        //}
      }
      else {
        int err = WSAGetLastError();
      }
      uai = uai->Next;
    }
    ai = ai->Next;
  }
  LocalFree(pAdapterAddresses);

#endif

  return mupnp_net_interfacelist_size(netIfList);
}