#include #include #include #include #include #include #define RCV_PORT 8642 #define SND_PORT 8080 #define SND_HOST "192.168.1.23" #define BUF_SIZE 262144 // function declarations void connection (int newsock); void retrieve(char * host, char * request, char * reply); // global variables time_t tLastUpd = (time_t) 0; void sigchld_handler(int signo) { while (waitpid(-1, NULL, WNOHANG) > 0); } // code entry point int main (int argc, char *argv[]) { struct sockaddr_in sAddr; int listensock; int newsock; int result; int pid; int val; listensock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); val = 1; result = setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); if (result < 0) { perror("proxy error - main setsockopt"); return 0; } sAddr.sin_family = AF_INET; sAddr.sin_port = htons(RCV_PORT); sAddr.sin_addr.s_addr = INADDR_ANY; result = bind(listensock, (struct sockaddr *) &sAddr, sizeof(sAddr)); if (result < 0) { perror("proxy error - main bind"); return 0; } result = listen(listensock, 10); if (result < 0) { perror("proxy error - main listen"); return 0; } signal(SIGCHLD, sigchld_handler); while (1) { newsock = accept(listensock, NULL ,NULL); if ((pid = fork()) == 0) { close (listensock); connection (newsock); exit(0); } close(newsock); } } void connection (int newsock) { FILE *fp; char req_buf[BUF_SIZE]; char rpl_buf[BUF_SIZE]; char *p; int n, nleft; memset (req_buf, 0, BUF_SIZE); p = req_buf; nleft = BUF_SIZE; while (1) { n = recv (newsock, p, nleft, 0); p += n; nleft -= n; if ((n == 0) || (nleft <= 0) || (strstr(req_buf, "\n\n") != 0) || (strstr(req_buf, "\r\n\r\n") != 0)) break; } // modify some of the http request headers if ((p = strstr(req_buf, "RCV_PORT")) != NULL) strncpy (p, "SND_PORT", 4); if ((p = strstr(req_buf, "If-Modified-Since:")) != NULL) strncpy (p, "XXXXXX", 6); if ((p = strstr(req_buf, "Accept-Encoding:")) != NULL) strncpy (p, "XXXXXX", 6); if ((p = strstr(req_buf, "Keep-Alive")) != NULL) strncpy (p, "XXXXXX", 6); if ((p = strstr(req_buf, "Connection: keep-alive")) != NULL) strncpy (p + 12, "close ", 10); if ((p = strstr(req_buf, "Connection: Keep-Alive")) != NULL) strncpy (p + 12, "Close ", 10); retrieve (SND_HOST, req_buf, rpl_buf); // modify URLs in the result before sending back while ((p = strstr(rpl_buf, "http://192.168.1.23:SND_PORT/roller/folder/")) != NULL) strncpy (p, " http://www.i-am.ws/", 39); while ((p = strstr(rpl_buf, "http://192.168.1.23:RCV_PORT/roller/folder/")) != NULL) strncpy (p, " http://www.i-am.ws/", 39); // send the page back to the client (via the DMZ) send (newsock, rpl_buf, strlen(rpl_buf), 0); close (newsock); return; } void retrieve(char * host, char * request, char * reply) { int sock; struct sockaddr_in sAddr; struct hostent *hent; unsigned int a, b, c, d; char addr[5]; char buffer[BUF_SIZE]; int n, nleft; char *p; sAddr.sin_family = AF_INET; sAddr.sin_addr.s_addr = INADDR_ANY; sAddr.sin_port = 0; sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); bind(sock, (const struct sockaddr *) &sAddr, sizeof(sAddr)); if ((hent = gethostbyname(host)) == NULL) { n = sscanf(host, "%u.%u.%u.%u", &a,&b,&c,&d); addr[0] = a; addr[1] = b; addr[2] = c; addr[3] = d; hent = gethostbyaddr(addr, 4, AF_INET); } memcpy (&sAddr.sin_addr, hent->h_addr, hent->h_length); sAddr.sin_port = htons(SND_PORT); if (connect(sock, (const struct sockaddr *) &sAddr, sizeof(sAddr)) != 0) { perror("proxy error - retrieve connect"); return; } // send the socket request n = send (sock, request, strlen(request), 0); // now get the reply (piece by piece) memset (reply, 0, BUF_SIZE); p = reply; nleft = BUF_SIZE; while (1) { n = recv (sock, p, nleft, 0); p += n; nleft -= n; if ((n == 0) || (nleft <= 0)) break; } close(sock); return; } // end of source