#include #include #include #include #include #include #include #include #include #include #define WCBS 0x1000 #define WCEL 0x0400 #define MYPORT 8088 typedef uint32_t in_addr_t; in_addr_t get_ip_by_name(char *hostname) { struct hostent *he; if((he=gethostbyname(hostname))==NULL) { herror(hostname); return -1; } else return *(in_addr_t *)he->h_addr; } void fill_sa_in(struct sockaddr_in *sai, in_addr_t addr,unsigned short port) { sai->sin_family=AF_INET; sai->sin_port=htons(port); sai->sin_addr.s_addr=addr; memset(sai->sin_zero,0,sizeof(sai->sin_zero)); } struct sockaddr_in www_in,me_in; int www_init(char *hostname, char *portname) { int c,port; in_addr_t ip; if((ip=get_ip_by_name(hostname))==-1) return -1; if(portname==NULL || sscanf(portname,"%u%n",&port,&c)!=1 || portname[c]!=0) port=80; fill_sa_in(&www_in,ip,port); return 0; } int www_client(int rs) { int i,sk,rl,wr; char *es,*s1,*s2,*cp,buf[WCBS]; /* read, log, and check request */ for(rl=0; (i=read(rs,buf+WCEL+rl,sizeof(buf)-WCEL-rl))>0; ) if((rl+=i)>4) { cp=buf+WCEL+rl; if(*--cp!='\n') continue; if((i=*--cp)=='\r') i=*--cp; if(i=='\n') break; } write(1,buf+WCEL,rl); if(rl<=0 || rl>=sizeof(buf)-WCEL) goto brq; buf[WCEL+rl]=0; if((s2=strchr(buf+WCEL,'\n'))==NULL || (s1=strchr(buf+WCEL,'/'))==NULL || (cp=strchr(s1+1,' '))==NULL || cp>s2 || (s2=strchr(s1+1,'/'))==NULL || s2>cp) goto brq; *s2=0; if((cp=strchr(s2,':'))!=NULL) *cp++=0; if(www_init(s1+1,cp)<0) goto brq; if(cp!=NULL) *--cp=':'; for(i=0; i0;) { if(wr>0) { for(i=0; wr!=0 && isin_addr.s_addr)[0], ((byte *)&in->sin_addr.s_addr)[1], ((byte *)&in->sin_addr.s_addr)[2], ((byte *)&in->sin_addr.s_addr)[3], ntohs(in->sin_port)); write(1, buf, strlen(buf)); } int www_server() { int s,c,l; char *es; struct sockaddr_in rem_in; if((s=socket(AF_INET,SOCK_STREAM,0))==-1) { es="www_socket"; goto err; } if(bind(s, (struct sockaddr *)&me_in, sizeof(me_in))==-1) { es="www_bind"; goto err; } if(listen(s,5)==-1) { es="www_listen"; goto err; } next: l=sizeof(rem_in); c=accept(s, (struct sockaddr *)&rem_in, &l); if(c==-1) perror("www_accept"); else { show_ip_and_port(&rem_in); www_client(c); } goto next; err: perror(es); return -1; } char usage[]= "Usage: %s port\n" "redirects HTTP from the specified port\n"; int main(int ac, char **av /**/) { int myport,vfy; if(ac==1 || sscanf(av[1],"%u%n",&myport,&vfy)!=1 || av[1][vfy]!=0) { fprintf(stderr,usage,av[0]); return -1; } fill_sa_in(&me_in,htonl(INADDR_ANY),myport); www_server(); dup2(2,1); show_ip_and_port(&me_in); return -1; }