/** * @brief This function parses the received description message from IGD(Internet Gateway Device). * @return 0: success, 1: received xml parse error */ signed char parseDescription( const char* xml /**< string for parse */ ) { const char controlURL_[]="<controlURL>"; const char eventSubURL_[]="<eventSubURL>"; char *URL_start=0, *URL_end=0; if(parseHTTP(xml) != 0) return 1; // Find Control URL("/etc/linuxigd/gateconnSCPD.ctl") if((URL_start = strstr(xml, "urn:schemas-upnp-org:service:WANIPConnection:1")) == NULL) return 1; if((URL_start = strstr(URL_start, controlURL_)) == NULL) return 1; if((URL_end = strstr(URL_start, "</controlURL>")) == NULL) return 1; strncpy(controlURL, URL_start+strlen(controlURL_), URL_end-URL_start-strlen(controlURL_)); // Find Eventing Subscription URL("/etc/linuxigd/gateconnSCPD.evt") if((URL_start = strstr(xml, "urn:schemas-upnp-org:service:WANIPConnection:1")) == NULL) return 1; if((URL_start = strstr(URL_start, eventSubURL_)) == NULL) return 1; if((URL_end = strstr(URL_start, "</eventSubURL>")) == NULL) return 1; strncpy(eventSubURL, URL_start+strlen(eventSubURL_), URL_end-URL_start-strlen(eventSubURL_)); return 0; }
/** * @brief This function parses the received SSDP message from IGD(Internet Gateway Device). * @return 0: success, 1: received xml parse error */ signed char parseSSDP( const char* xml /**< string for parse */ ) { const char LOCATION_[]="LOCATION: "; char *LOCATION_start=0, *LOCATION_end=0; if(parseHTTP(xml) != 0) return 1; // Find Description URL("http://192.168.0.1:3121/etc/linuxigd/gatedesc.xml") if((LOCATION_start = strstr(xml, LOCATION_)) == NULL) return 1; if((LOCATION_end = strstr(LOCATION_start, "\r\n")) == NULL) return 1; strncpy(descURL, LOCATION_start+strlen(LOCATION_), LOCATION_end-LOCATION_start-strlen(LOCATION_)); // Find IP of IGD("http://192.168.0.1") if((LOCATION_start = strstr(descURL, "http://")) == NULL) return 1; if((LOCATION_end = strstr(LOCATION_start+7, ":")) == NULL) return 1; strncpy(descIP, LOCATION_start+7, LOCATION_end-LOCATION_start-7); // Find PORT of IGD("3121") if((LOCATION_start = LOCATION_end+1) == NULL) return 1; if((LOCATION_end = strstr(LOCATION_start, "/")) == NULL) return 1; strncpy(descPORT, LOCATION_start, LOCATION_end-LOCATION_start); // Find Description Location("/etc/linuxigd/gatedesc.xml") if((LOCATION_start = LOCATION_end) == NULL) return 1; if((LOCATION_end = LOCATION_start + strlen(LOCATION_start)) == NULL) return 1; strncpy(descLOCATION, LOCATION_start, LOCATION_end-LOCATION_start); return 0; }
/** * @brief This function parses the received add port message from IGD(Internet Gateway Device). * @return 0: success, 1: received xml parse error, other: UPnP error code */ signed short parseAddPort( const char* xml /**< string for parse */ ) { parseHTTP(xml); if(strstr(xml, "u:AddPortMappingResponse xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\"") == NULL){ return parseError(xml); } return 0; }
/** * @brief This function subscribes to the eventing message from IGD(Internet Gateway Device). * @return 0: success, -2: Invalid UPnP Step, -1: reply packet timeout */ signed char SetEventing( SOCKET sockfd /**< a socket number. */ ) { long endTime=0; uint32 ipaddr; uint16 port; // Check UPnP Step if(UPnP_Step < 2) return -2; // Make Subscription message memset(send_buffer, '\0', MAX_BUFFER); MakeSubscribe(send_buffer, PORT_UPNP_EVENTING); #ifdef UPNP_DEBUG printf("%s\r\n", send_buffer); #endif ipaddr = inet_addr((uint8*)descIP); ipaddr = swapl(ipaddr); port = ATOI(descPORT, 10); // Connect to IGD(Internet Gateway Device) if(TCPClientOpen(sockfd, PORT_UPNP, (uint8*)&ipaddr, port) == FAIL) printf("TCP Socket Error!!\r\n"); // Send Subscription Message while(GetTCPSocketStatus(sockfd) != STATUS_ESTABLISHED); TCPSend(sockfd, (void *)send_buffer, strlen(send_buffer)); // Receive Reply memset(recv_buffer, '\0', MAX_BUFFER); Delay_ms(500); endTime = my_time + 3; while (TCPRecv(sockfd, (void *)recv_buffer, MAX_BUFFER) <= 0 && my_time < endTime); // Check Receive Buffer of W5200 if(my_time >= endTime){ // Check Timeout TCPClose(sockfd); return -1; } // TCP Socket Close TCPClose(sockfd); #ifdef UPNP_DEBUG printf("\r\nReceiveData\r\n%s\r\n", recv_buffer); #endif return parseHTTP(recv_buffer); }
int main (int argc, char **argv) { /* bind exit handler */ printf("binding exit handler ...\n"); if (atexit(onexit) != 0) { perror("atexit"); exit(EXIT_FAILURE); } /* configure signal handling */ printf("binding signal handlers ...\n"); if (signal(SIGINT, sighandler) == SIG_ERR) { perror("signal(SIGINT)"); exit(EXIT_FAILURE); } if (signal(SIGQUIT, sighandler) == SIG_ERR) { perror("signal(SIGQUIT)"); exit(EXIT_FAILURE); } /* create listening socket */ printf("creating listening socket ...\n"); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(EXIT_FAILURE); } /* bind listening socket */ printf("binding listening socket ... \n"); { struct sockaddr_in address; memset(&address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_addr.s_addr = htonl (INADDR_ANY); address.sin_port = htons(DEFAULT_PORT); if (bind(sock,(const struct sockaddr*)&address, sizeof(address)) != 0) { perror("bind"); exit(EXIT_FAILURE); } } /* set listening socket to listen state */ printf("calling listen() on socket ... \n"); if (listen(sock, 0) != 0) { perror("listen"); exit(EXIT_FAILURE); } /* compile http regex */ printf("compiling http regex '%s' ... \n", http_regex); { int retval = 0; if((retval = regcomp(&preg , http_regex, REG_EXTENDED)) != 0) { char errorbuffer[128]; memset(errorbuffer, 0, sizeof(errorbuffer)); regerror(retval, &preg, errorbuffer, sizeof(errorbuffer)); fprintf(stderr, "regcomp: %s", errorbuffer); } } /* wait for new client connection */ while (running) { struct sockaddr_in address; socklen_t address_len = sizeof(address); memset(&address, 0, address_len); printf("waiting for new client connection ... \n"); sock_client = accept(sock, (struct sockaddr *)&address, &address_len); if (sock_client == -1) { perror("accept"); exit(EXIT_FAILURE); } /* new connection */ { char* addr_str = inet_ntoa(address.sin_addr); printf("new connection from %s:%d ... \n", addr_str, ntohs(address.sin_port)); } /* handle the connection */ { char buffer[65535]; ssize_t readbytes = 0; http_request_t http_req; memset(buffer, 0, sizeof(buffer)); if ((readbytes = read(sock_client, buffer, sizeof(buffer))) == -1) { perror("read"); exit(EXIT_FAILURE); } printf("read %d bytes:\n%s\n", readbytes, buffer); parseHTTP(buffer, &http_req); } /* close client connection */ if (sock_client != -1) { printf("closing client connection (%d) ... \n", sock_client); if (close(sock_client) != 0) perror("close(sock_client)"); sock_client = -1; } } exit(EXIT_SUCCESS); }
// @brief: handles webclient // @param[in]: socket - socket that client is connected on // @param[in]: ip_addr - ip address of the client void WebHostEmulator::HandleClient(SOCKET* socket, const std::string ip_addr) { #ifdef __DEBUG static int ThreadCounter = 0; const int ThreadID = ThreadCounter++; printf("Thread %i started\n", ThreadID); #endif std::queue <std::string> RecvQueue; std::string Received, overflow; while (1) { // Recieve std::string RecvBuffer; RecvBuffer.resize(8192); int iResult = recv(*socket, &RecvBuffer[0], RecvBuffer.length(), 0); if (iResult <= 0) { #ifdef __DEBUG printf("Thread %i ended\n", ThreadID); #endif closesocket(*socket); delete socket; return; } RecvBuffer.resize(iResult); if (parseHTTP (RecvBuffer, Received, overflow) != 0) { continue; } #ifdef __DEBUG printf("Received Message:-----\n%s\nEnd Received-----\n\n", Received.c_str()); #endif // Send size_t found; std::string Body, ContentLength, ContentType, Header, Response; found = Received.find("GET"); if (found == 0) { size_t start = Received.find("/"); size_t end = Received.find(" ", start); ContentType = GetReq(std::string(Received, start, end - start), Body); Header = BuildHeader(Body, 200, ContentType, true); Response = Header + Body; iResult = send(*socket, Response.c_str(), Response.size(), 0); } found = Received.find("POST"); if (found == 0) { size_t start = Received.find("/"); size_t end = Received.find(" ", start); std::string Result = PostReq( std::string(Received, start, end - start), GetBody(Received), ip_addr ); ContentType = "text/html"; // This is a temp fix. Body = BuildResult(Result, std::string("result.html")); Header = BuildHeader(Body, 200, ContentType, false); Response = Header + Body; iResult = send(*socket, Response.c_str(), Response.size(), 0); } Received.clear(); } #ifdef __DEBUG printf("Thread %i ended\n", ThreadID); #endif closesocket(*socket); delete socket; return; }