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"); }
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"); }
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); }