/* * @(#)netcat.c--Copy to network port * * No rights reserved, no responsibility accepted. * ShadeTree Software, Inc. */ static char *what[]={ "@(#)netcat--Copy to network port", "@(#)STS/KBS 2apr1996", 0, }; #include #include #include #include #include #include int debugl; char *iam; extern char * optarg; /* stuff for getopt */ extern int optind, optopt; /* stuff for getopt */ void usage(void) { fprintf(stderr,"usage: %s [-d] -hhostname -pportnumber\n",iam); fprintf(stderr," -d debug messages to stderr\n"); exit(1); } int main( int ac, char *av[] ) { int s; struct sockaddr_in sin; int c; struct hostent *hp; char buf[1024]; int bufr,bufw; char *hostname; int port; int eret; char *iam; int maxfd; int osocks[FD_SETSIZE]; /* socket table */ int oc; fd_set allmask,rmask; /* select masks */ int rz,wz; /* read/write sizes */ int sc; /* select fd */ int sv; /* select() value */ iam = av[0]; hostname = (char *)0; port = -1; while(( oc = getopt(ac,av,"dh:p:")) != -1 ) { switch(oc) { case 'd': debugl++; break; case 'h': hostname = optarg; break; case 'p': port = atoi(optarg); break; case ':': case '?': default: usage(); break; } } if(optind < ac) { fprintf(stderr,"Too many arguments (%s)\n",av[optind]); usage(); } if(hostname==0 || port<0) { if(!hostname) { fprintf(stderr,"No host name\n"); } if(port < 0 || port > 65535) { fprintf(stderr,"Missing or invalid port number\n"); } usage(); } if(debugl) { fprintf(stderr,"Host: %s\n",hostname); fprintf(stderr,"Port: %d\n",port); } eret=0; setbuf(stderr,NULL); hp = gethostbyname(hostname); if(debugl) fprintf(stderr,"gethostbyname(%s)=0x%x\n",hostname,hp); if(!hp) { herror(hostname); return(2); } memcpy( (char *)&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); sin.sin_family = hp->h_addrtype; sin.sin_port = htons(port); if(debugl) fprintf(stderr," ip = %s\n",inet_ntoa(sin.sin_addr)); for(;;) { s=socket(AF_INET, SOCK_STREAM, 0); if(debugl) fprintf(stderr,"socket()=%d\n",s); if(s<0) { perror("Can't open socket"); return(2); } c=connect(s,(struct sockaddr *)&sin,sizeof(sin)); if(debugl) fprintf(stderr,"connect()=%d\n",c); if(c) { if(debugl) { sprintf(buf,"Connect to port %d on %s",port,hostname); perror(buf); } close(s); sleep(5); } else { break; } } /* * Setup select mask. * Initialize to our socket and stdin */ FD_ZERO(&allmask); FD_SET(0,&allmask); FD_SET(s,&allmask); maxfd = s; osocks[0] = s; /* stdin -> socket */ osocks[s] = 1; /* socket -> stderr */ /* * Wait for activity */ for(;;) { if(debugl) fprintf(stderr,"\n>"); /**/ memcpy(&rmask,&allmask,sizeof(allmask)); sv = select(maxfd+1,&rmask,0,0,0); if(sv<0) { perror("select"); exit(2); } /* * Check for activity */ for(sc = 0; sc <= maxfd; sc++) { if(FD_ISSET(sc,&rmask)) { FD_CLR(sc,&rmask); if(debugl) fprintf(stderr,"(s%d)",sc); /**/ rz = read(sc,buf,sizeof(buf)); if(debugl) fprintf(stderr,"(r%d)",rz); /**/ if(rz <= 0) { if(rz==0) { if(debugl) { fprintf(stderr,"EOF from %d--disconnecting\n",sc); goto close_n_exit; } eret = 0; } else { sprintf(buf,"read from socket %d--disconnecting",sc); perror(buf); eret = 2; } goto close_n_exit; } wz = write(osocks[sc],buf,rz); if (debugl) fprintf(stderr,"(s%d)(w%d)",osocks[sc],wz); /**/ if(wz <= 0) { if(wz==0) { fprintf( stderr, "EOF on write to %d--disconnecting\n", osocks[sc] ); eret = 3; } else { sprintf( buf, "write to socket %d--disconnecting", osocks[sc] ); perror(buf); eret = 2; } goto close_n_exit; } } } } close_n_exit: close(s); return(eret); }