void cg_http_packet_sethost(CgHttpPacket *httpPkt, const char *addr, int port) { char *host; size_t hostMaxLen; cg_log_debug_l4("Entering...\n"); if (addr == NULL) return; hostMaxLen = cg_strlen(addr) + CG_NET_IPV6_ADDRSTRING_MAXSIZE + CG_STRING_INTEGER_BUFLEN; host = malloc(sizeof(char) * hostMaxLen); if (host == NULL) /* Memory allocation failure */ return; #if defined(HAVE_SNPRINTF) if (0 < port && port != CG_HTTP_DEFAULT_PORT) { if (cg_net_isipv6address(addr) == TRUE) snprintf(host, hostMaxLen, "[%s]:%d", addr, port); else snprintf(host, hostMaxLen, "%s:%d", addr, port); } else { if (cg_net_isipv6address(addr) == TRUE) snprintf(host, hostMaxLen, "[%s]", addr); else snprintf(host, hostMaxLen, "%s", addr); } #else if (0 < port && port != CG_HTTP_DEFAULT_PORT) { if (cg_net_isipv6address(addr) == TRUE) sprintf(host, "[%s]:%d", addr, port); else sprintf(host, "%s:%d", addr, port); } else { if (cg_net_isipv6address(addr) == TRUE) sprintf(host, "[%s]", addr); else sprintf(host, "%s", addr); } #endif cg_http_packet_setheadervalue(httpPkt, CG_HTTP_HOST, host); free(host); cg_log_debug_l4("Leaving...\n"); }
char *cg_net_getmodifierhosturl(char *host, int port, char *uri, char *buf, int bufSize, char *begin, char *end) { BOOL isIPv6Host; cg_log_debug_l4("Entering...\n"); isIPv6Host = cg_net_isipv6address(host); #if defined(HAVE_SNPRINTF) snprintf(buf, bufSize, #else sprintf(buf, #endif "%shttp://%s%s%s:%d%s%s", begin, ((isIPv6Host == TRUE) ? "[" : ""), host, ((isIPv6Host == TRUE) ? "]" : ""), port, uri, end); return buf; cg_log_debug_l4("Leaving...\n"); }
BOOL cg_net_isuseaddress(char *addr) { cg_log_debug_l4("Entering...\n"); if (CG_NET_USE_ONLY_IPV6_ADDR == TRUE) { if (cg_net_isipv6address(addr) == FALSE) return FALSE; } if (CG_NET_USE_ONLY_IPV4_ADDR == TRUE) { if (cg_net_isipv6address(addr) == TRUE) return FALSE; } return TRUE; cg_log_debug_l4("Leaving...\n"); }
char *cg_upnp_ssdp_gethostaddress(char *ifAddr) { char *ssdpAddr = CG_UPNP_SSDP_ADDRESS; cg_log_debug_l4("Entering...\n"); if (cg_net_isipv6address(ifAddr) == TRUE) ssdpAddr = cg_upnp_ssdp_getipv6address(); return ssdpAddr; cg_log_debug_l4("Leaving...\n"); }
int cg_net_getipv6scopeid(const char *addr) { size_t addrLen; ssize_t perIdx; char scopeIDBuf[8+1]; cg_log_debug_l4("Entering...\n"); if (cg_net_isipv6address(addr) == FALSE) return 0; addrLen = cg_strlen(addr); perIdx = cg_strchr(addr, "%", 1); if (perIdx < 0) return 0; cg_strncpy(scopeIDBuf, (addr+perIdx+1), sizeof(scopeIDBuf)-1); scopeIDBuf[sizeof(scopeIDBuf)-1] = '\0'; cg_log_debug_l4("Leaving...\n"); return atoi(scopeIDBuf); }
BOOL cg_upnp_ssdp_server_open(CgUpnpSSDPServer *server, char *bindAddr) { const char *ssdpAddr = CG_UPNP_SSDP_ADDRESS; cg_log_debug_l4("Entering...\n"); if (cg_upnp_ssdp_server_isopened(server) == TRUE) return FALSE; if (cg_net_isipv6address(bindAddr) == TRUE) ssdpAddr = cg_upnp_ssdp_getipv6address(); server->httpmuSock = cg_upnp_httpmu_socket_new(); if (cg_upnp_httpmu_socket_bind(server->httpmuSock, ssdpAddr, CG_UPNP_SSDP_PORT, bindAddr) == FALSE) { cg_upnp_httpmu_socket_delete(server->httpmuSock); server->httpmuSock = NULL; return FALSE; } cg_log_debug_l4("Leaving...\n"); return TRUE; }
BOOL cg_socket_joingroup(CgSocket *sock, char *mcastAddr, char *ifAddr) { struct addrinfo hints; struct addrinfo *mcastAddrInfo, *ifAddrInfo; /**** for IPv6 ****/ struct ipv6_mreq ipv6mr; struct sockaddr_in6 toaddr6, ifaddr6; int scopeID; /**** for IPv4 ****/ struct ip_mreq ipmr; struct sockaddr_in toaddr, ifaddr; BOOL joinSuccess; int sockOptRetCode; cg_log_debug_l4("Entering...\n"); memset(&hints, 0, sizeof(hints)); hints.ai_flags= AI_NUMERICHOST | AI_PASSIVE; if (getaddrinfo(mcastAddr, NULL, &hints, &mcastAddrInfo) != 0) return FALSE; if (getaddrinfo(ifAddr, NULL, &hints, &ifAddrInfo) != 0) { freeaddrinfo(mcastAddrInfo); return FALSE; } joinSuccess = TRUE; if (cg_net_isipv6address(mcastAddr) == TRUE) { memcpy(&toaddr6, mcastAddrInfo->ai_addr, sizeof(struct sockaddr_in6)); memcpy(&ifaddr6, ifAddrInfo->ai_addr, sizeof(struct sockaddr_in6)); ipv6mr.ipv6mr_multiaddr = toaddr6.sin6_addr; scopeID = cg_net_getipv6scopeid(ifAddr); ipv6mr.ipv6mr_interface = scopeID /*if_nametoindex*/; sockOptRetCode = setsockopt(sock->id, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *)&scopeID, sizeof(scopeID)); if (sockOptRetCode != 0) joinSuccess = FALSE; sockOptRetCode = setsockopt(sock->id, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&ipv6mr, sizeof(ipv6mr)); if (sockOptRetCode != 0) joinSuccess = FALSE; } else { memcpy(&toaddr, mcastAddrInfo->ai_addr, sizeof(struct sockaddr_in)); memcpy(&ifaddr, ifAddrInfo->ai_addr, sizeof(struct sockaddr_in)); memcpy(&ipmr.imr_multiaddr.s_addr, &toaddr.sin_addr, sizeof(struct in_addr)); memcpy(&ipmr.imr_interface.s_addr, &ifaddr.sin_addr, sizeof(struct in_addr)); sockOptRetCode = setsockopt(sock->id, IPPROTO_IP, IP_MULTICAST_IF, (char *)&ipmr.imr_interface.s_addr, sizeof(struct in_addr)); if (sockOptRetCode != 0) joinSuccess = FALSE; sockOptRetCode = setsockopt(sock->id, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&ipmr, sizeof(ipmr)); if (sockOptRetCode != 0) joinSuccess = FALSE; } freeaddrinfo(mcastAddrInfo); freeaddrinfo(ifAddrInfo); cg_log_debug_l4("Leaving...\n"); return joinSuccess; }
void cg_upnp_device_ssdpmessagereceived(CgUpnpDevice *dev, CgUpnpSSDPPacket *ssdpPkt, int filter) { BOOL isRootDev; const char *ssdpST; const char *devUDN, *devType; char ssdpMsg[CG_UPNP_SSDP_HEADER_LINE_MAXSIZE]; char deviceUSN[CG_UPNP_SSDP_HEADER_LINE_MAXSIZE]; #if defined WINCE size_t n; #else int n; #endif CgUpnpService *service; CgUpnpDevice *childDev; const char *ssdpMXString; int ssdpMX; const char *ssdpTargetAddr; cg_log_debug_l4("Entering...\n"); ssdpMXString = cg_http_headerlist_getvalue(ssdpPkt->headerList, CG_HTTP_MX); ssdpST = cg_upnp_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 (cg_strstr(cg_string_getvalue(ssdpPkt->dgmPkt->data), CG_HTTP_MSEARCH) < 0) return; /**** check for * and return if not found ****/ if (cg_strstr(cg_string_getvalue(ssdpPkt->dgmPkt->data), "*") < 0) return; /**** check HTTP version and return if not found ****/ if (cg_strstr(cg_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 = cg_upnp_ssdp_packet_gethost(ssdpPkt); if (cg_strcmp(ssdpTargetAddr, CG_UPNP_SSDP_MULTICAST_ADDRESS) != 0 && !cg_net_isipv6address(ssdpTargetAddr) ) return; /**************************************** * check MAN header, return if incorrect ***************************************/ if (cg_upnp_ssdp_packet_isdiscover(ssdpPkt) == FALSE) return; /**************************************** * check MX header, return if incorrect ***************************************/ if (ssdpMXString == NULL || cg_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 (cg_strlen(ssdpST) <= 0) return; /* Check if we have received this search recently * and ignore duplicates. */ //if ( filter_duplicate_m_search(ssdpPkt) ) // return; ssdpMX = cg_upnp_ssdp_packet_getmx(ssdpPkt); cg_log_debug("Sleeping for a while... (MX:%d)\n", ssdpMX); cg_waitrandom((ssdpMX*1000)/4); } isRootDev = cg_upnp_device_isrootdevice(dev); if (cg_upnp_st_isalldevice(ssdpST) == TRUE) { /* for root device only */ if (isRootDev == TRUE) { cg_upnp_device_getnotifydevicent(dev, ssdpMsg, sizeof(ssdpMsg)); cg_upnp_device_getnotifydeviceusn(dev, deviceUSN, sizeof(deviceUSN)); cg_upnp_device_postsearchresponse(dev, ssdpPkt, ssdpMsg, deviceUSN); } /* for all devices send */ /* device type : device version */ cg_upnp_device_getnotifydevicetypent(dev, ssdpMsg, sizeof(ssdpMsg)); cg_upnp_device_getnotifydevicetypeusn(dev, deviceUSN, sizeof(deviceUSN)); cg_upnp_device_postsearchresponse(dev, ssdpPkt, ssdpMsg, deviceUSN); /* device UUID */ cg_upnp_device_postsearchresponse(dev, ssdpPkt, cg_upnp_device_getudn(dev), cg_upnp_device_getudn(dev)); } else if (cg_upnp_st_isrootdevice(ssdpST) == TRUE) { if (isRootDev == TRUE) { cg_upnp_device_getnotifydeviceusn(dev, deviceUSN, sizeof(deviceUSN)); cg_upnp_device_postsearchresponse(dev, ssdpPkt, CG_UPNP_ST_ROOT_DEVICE, deviceUSN); } } else if (cg_upnp_st_isuuiddevice(ssdpST) == TRUE) { devUDN = cg_upnp_device_getudn(dev); if (cg_streq(ssdpST, devUDN) == TRUE) cg_upnp_device_postsearchresponse(dev, ssdpPkt, devUDN, devUDN); } else if (cg_upnp_st_isurn(ssdpST) == TRUE) { devType = cg_upnp_device_getdevicetype(dev); if (cg_streq(ssdpST, devType) == TRUE) { cg_upnp_device_getnotifydevicetypeusn(dev, deviceUSN, sizeof(deviceUSN)); cg_upnp_device_postsearchresponse(dev, ssdpPkt, devType, deviceUSN); } } for (service=cg_upnp_device_getservices(dev); service != NULL; service = cg_upnp_service_next(service)) cg_upnp_service_ssdpmessagereceived(service, ssdpPkt); for (childDev = cg_upnp_device_getdevices(dev); childDev != NULL; childDev = cg_upnp_device_next(childDev)) cg_upnp_device_ssdpmessagereceived(childDev, ssdpPkt, FALSE); cg_log_debug_l4("Leaving...\n"); }