Advertisement
Guest User

Untitled

a guest
Apr 19th, 2015
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.69 KB | None | 0 0
  1. /* * Strobe (c) 1995 Julian Assange (proff@suburbia.net), * All rights reserved. * Port Scanner * $ cc strobe.c -o strobe */ #define VERSION "1.03" #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/time.h> #include <ctype.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/socket.h> #ifdef _AIX # include <sys/select.h> #endif #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <string.h> #include <errno.h> #if defined(solaris) || defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__GCC__) # define fvoid void #else # define fvoid extern int optind; extern char *optarg; #endif #define bool char #ifndef INADDR_NONE # define INADDR_NONE ((unsigned long)-1) #endif #define port_t (unsigned short) /* * the below should be set via the Makefile, but if not... */ #ifndef ETC_SERVICES # define ETC_SERVICES "/etc/services" #endif #ifndef STROBE_SERVICES # define STROBE_SERVICES "strobe.services" #endif #ifndef LIB_STROBE_SERVICES # define LIB_STROBE_SERVICES "/usr/local/lib/strobe.services" #endif int a_timeout = 20; char *a_output = NULL; char *a_services = "strobe.services"; char *a_input = NULL; /* char *a_prescan = NULL; */ int a_start = 1; int a_end = 65535; int a_sock_max = 64; int a_abort = 0; int a_bindport = 0; char *a_bindaddr= NULL; struct in_addr bindaddr; bool f_linear = 0; bool f_verbose = 0; bool f_verbose_stats = 0; bool f_fast = 0; bool f_stats = 0; bool f_quiet = 0; bool f_delete_dupes = 0; bool f_minimise = 0; bool f_dontgetpeername = 0; int connects = 0; int hosts_done = 0; int attempts_done = 0; int attempts_outstanding = 0; struct timeval time_start; fd_set set_sel; fd_set set_sel_r; fd_set set_sel_w; int host_n; int Argc; char **Argv; FILE *fh_input; #define HO_ACTIVE 1 #define HO_ABORT 2 #define HO_COMPLETING 4 struct hosts_s { char *name; struct in_addr in_addr; int port; int portlist_ent; struct timeval time_used; struct timeval time_start; int attempts; int attempts_done; int attempts_highest_done; int connects; time_t notice_abort; int status; }; struct hosts_s ho_initial; struct hosts_s *hosts; #define HT_SOCKET 1 #define HT_CONNECTING 2 struct htuple_s { char *name; struct in_addr in_addr; int port; int sfd; int status; struct timeval sock_start; int timeout; struct hosts_s *host; }; struct htuple_s ht_initial; struct htuple_s *attempt; struct port_desc_s { int port; char *name; char *portname; struct port_desc_s *next; struct port_desc_s *next_port; }; struct port_desc_s **port_descs; int *portlist = NULL; int portlist_n = 0; char * Srealloc (ptr, len) char *ptr; int len; { char *p; int retries = 10; while (!(p = ptr? realloc (ptr, len): malloc(len))) { if (!--retries) { perror("malloc"); exit(1); } if (!f_quiet) fprintf(stderr, "Smalloc: couldn't allocate %d bytes...sleeping\n", len); sleep (2); } return p; } char * Smalloc (len) int len; { return Srealloc (NULL, len); } fvoid sock_block (sfd) int sfd; { int flags; flags = (~O_NONBLOCK) & fcntl (sfd, F_GETFL); fcntl (sfd, F_SETFL, flags); } fvoid sock_unblock (sfd) int sfd; { int flags; flags = O_NONBLOCK | fcntl (sfd, F_GETFL); fcntl (sfd, F_SETFL, flags); } int timeval_subtract (result, x, y) /* from gnu c-lib info.texi */ struct timeval *result, *x, *y; { /* Perform the carry for the later subtraction by updating y. */ if (x->tv_usec < y->tv_usec) { int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; y->tv_usec -= 1000000 * nsec; y->tv_sec += nsec; } if (x->tv_usec - y->tv_usec > 1000000) { int nsec = (y->tv_usec - x->tv_usec) / 1000000; y->tv_usec += 1000000 * nsec; y->tv_sec -= nsec; } /* Compute the time remaining to wait. `tv_usec' is certainly positive. */ result->tv_sec = x->tv_sec - y->tv_sec; result->tv_usec = x->tv_usec - y->tv_usec; /* Return 1 if result is negative. */ return x->tv_sec < y->tv_sec; } fvoid attempt_clear (h) struct htuple_s *h; { if (h->status & HT_SOCKET) { struct timeval tv1, tv2; gettimeofday(&tv1, NULL); timeval_subtract(&tv2, &tv1, &(h->sock_start)); h->host->time_used.tv_sec+=tv2.tv_sec; if ((h->host->time_used.tv_usec+=tv2.tv_usec) >= 1000000) { h->host->time_used.tv_usec -= 1000000; h->host->time_used.tv_sec++; } attempts_done++; h->host->attempts_done++; if (h->port > h->host->attempts_highest_done) h->host->attempts_highest_done=h->port; sock_unblock (h->sfd); /* shutdown (h->sfd, 2); */ close (h->sfd); if (FD_ISSET(h->sfd, &set_sel)) { FD_CLR (h->sfd, &set_sel); attempts_outstanding--; } } *h = ht_initial; } fvoid clear_all () { int n; for (n = 0; n < a_sock_max; n++) attempt_clear (&attempt[n]); } fvoid attempt_init () { int n; for (n = 0; n < a_sock_max; n++) attempt[n] = ht_initial; } fvoid hosts_init () { int n; for (n = 0; n < a_sock_max; n++) hosts[n] = ho_initial; } fvoid fdsets_init () { FD_ZERO(&set_sel_r); /* yes, we have to do this, despite the later */ FD_ZERO(&set_sel_w); /* assisgnments */ FD_ZERO(&set_sel); } int sc_connect (h) struct htuple_s *h; { struct sockaddr_in sa_in; int sopts1 = 1; struct linger slinger; if ((h->sfd = socket (PF_INET, SOCK_STREAM, 0)) == -1) return 0; memset(&sa_in, 0, sizeof(sa_in)); h->status |= HT_SOCKET; gettimeofday(&(h->sock_start), NULL); sock_unblock (h->sfd); setsockopt (h->sfd, SOL_SOCKET, SO_REUSEADDR, (char *) &sopts1, sizeof (sopts1)); setsockopt (h->sfd, SOL_SOCKET, SO_OOBINLINE, (char *) &sopts1, sizeof (sopts1)); slinger.l_onoff = 0; /* off */ setsockopt (h->sfd, SOL_SOCKET, SO_LINGER, (char *) &slinger, sizeof (slinger)); sa_in.sin_family = AF_INET; if (a_bindport) sa_in.sin_port = a_bindport; if (a_bindaddr) sa_in.sin_addr = bindaddr; if (a_bindaddr || a_bindport) if (bind (h->sfd, (struct sockaddr *)&sa_in, sizeof(sa_in)) == -1) { fprintf(stderr, "couldn't bind %s : %d ", a_bindaddr? a_bindaddr: "0.0.0.0", ntohs(a_bindport)); perror(""); if (errno == EACCES) exit(1); return 0; } sa_in.sin_addr = h->in_addr; sa_in.sin_port = htons (h->port); if (connect (h->sfd, (struct sockaddr *) &sa_in, sizeof (sa_in)) == -1) { switch (errno) { case EINPROGRESS: case EWOULDBLOCK: break; case ETIMEDOUT: case ECONNREFUSED: case EADDRNOTAVAIL: if (f_verbose) { fprintf(stderr, "%s:%d ", h->name, h->port); perror(""); } h->host->attempts++; attempt_clear (h); return 1; default: if (!f_quiet) { fprintf(stderr, "%s:%d ", h->name, h->port); perror (""); } attempt_clear (h); return 0; } } h->host->attempts++; h->status |= HT_CONNECTING; sock_block (h->sfd); FD_SET(h->sfd, &set_sel); attempts_outstanding++; return 1; } int gatherer_tcp (h) struct htuple_s *h; { struct port_desc_s *pd; if (f_minimise) printf ("%s\t%d\n", h->name, h->port); else { if ((pd = port_descs[h->port])) { printf ("%-30s %-16s %5d/tcp %s\n", h->name, pd->portname, h->port, pd->name); while (!f_delete_dupes && !f_minimise && (pd=pd->next)) printf ("#%-29s %-16s %5d/tcp %s\n", h->name, pd->portname, h->port, pd->name); } else printf ("%-30s %-16s %5d/tcp unassigned\n", h->name, "unknown", h->port); } h->host->connects++; connects++; attempt_clear (h); return 1; } bool gather () { struct timeval timeout; struct htuple_s *h; int n; int selected; time_t tim; if (!attempts_outstanding) return 1; set_sel_r=set_sel_w=set_sel; timeout.tv_sec = 0; timeout.tv_usec = 250000; /* 1/4 of a second */ selected = select (FD_SETSIZE, &set_sel_r, &set_sel_w, 0, &timeout); /* Look for timeouts */ tim = time (NULL); for ( n = 0 ; n < a_sock_max; n++ ) { h = &attempt[n]; if ((h->status & HT_SOCKET) && ((h->sock_start.tv_sec + h->timeout) < tim)) attempt_clear (h); } switch (selected) { case -1: perror ("select"); return 0; case 0: return 1; } for (n = 0; selected && (n < a_sock_max); n++) { h = &attempt[n]; if (h->status & HT_CONNECTING) { if (FD_ISSET (h->sfd, &set_sel_r) || FD_ISSET (h->sfd, &set_sel_w)) { struct sockaddr_in in; int len = sizeof (in); selected--; /* select() lies occasionaly */ if (!f_dontgetpeername) /* but solaris2.3 crashes occasionally ;-| */ { if (getpeername (h->sfd, (struct sockaddr *) &in, &len) == 0) gatherer_tcp (h); else attempt_clear (h); } else gatherer_tcp (h); } } } return 1; } bool add_attempt (add) struct htuple_s *add; { struct htuple_s *h; static time_t oldtime; static int n; for (;;) { for (; n < a_sock_max; n++) { h = &attempt[n]; if (!h->status) goto foundfree; } n = 0; gather (); continue; foundfree: *h = *add; if (!sc_connect (h)) { gather (); continue; } if ((oldtime + 1) < time (NULL)) { oldtime = time (NULL); gather (); } break; } return 1; } int scatter (host, timeout) struct hosts_s *host; int timeout; { static struct htuple_s add; add = ht_initial; add.host = host; add.name = host->name; add.in_addr = host->in_addr; add.port = host->port; add.timeout = timeout; if (f_verbose) fprintf (stderr, "attempting port=%d host=%s\n", add.port, add.name); add_attempt (&add); return 1; } fvoid wait_end (t) int t; { time_t st; st = time (NULL); while ((st + t) > time (NULL)) { gather (); if (attempts_outstanding<1) break; } } struct in_addr resolve (name) char *name; { static struct in_addr in; unsigned long l; struct hostent *ent; if ((l = inet_addr (name)) != INADDR_NONE) { in.s_addr = l; return in; } if (!(ent = gethostbyname (name))) { perror (name); in.s_addr = INADDR_NONE; return in; } return *(struct in_addr *) ent->h_addr; } char * next_host () { static char lbuf[512]; hosts_done++; if (a_input) { int n; reread: if (!fgets (lbuf, sizeof (lbuf), fh_input)) { fclose (fh_input); a_input = NULL; return next_host(); } if (strchr("# \t\n\r", lbuf[0])) goto reread; n = strcspn (lbuf, " \t\n\r"); if (n) lbuf[n] = '\0'; return lbuf; } if ( host_n >= Argc ) return NULL; return Argv[host_n++]; } bool host_init (h, name, nocheck) struct hosts_s *h; char *name; bool nocheck; { int n; *h=ho_initial; h->in_addr = resolve (name); if (h->in_addr.s_addr == INADDR_NONE) return 0; if (!nocheck) for (n=0; n<a_sock_max; n++) { if (hosts[n].name && hosts[n].in_addr.s_addr==h->in_addr.s_addr) { if (!f_quiet) fprintf(stderr, "ip duplication: %s == %s (last host ignored)\n", hosts[n].name, name); return 0; } } h->name = (char *) Smalloc (strlen (name) + 1); strcpy (h->name, name); h->port = a_start; h->status = HO_ACTIVE; gettimeofday(&(h->time_start), NULL); return 1; } fvoid host_clear (h) struct hosts_s *h; { if (h->name) { free (h->name); } *h=ho_initial; } fvoid host_stats (h) struct hosts_s *h; { struct timeval tv, tv2; float t, st; gettimeofday(&tv, NULL); timeval_subtract(&tv2, &tv, &(h->time_start)); t = tv2.tv_sec+(float)tv2.tv_usec/1000000.0; st = h->time_used.tv_sec+(float)h->time_used.tv_usec/1000000.0; fprintf(stderr, "stats: host = %s trys = %d cons = %d time = %.2fs trys/s = %.2f trys/ss = %.2f\n", h->name, h->attempts_done, h->connects, t, h->attempts_done/t, h->attempts_done/st); } fvoid final_stats() { struct timeval tv, tv2; float t; gettimeofday(&tv, NULL); timeval_subtract(&tv2, &tv, &(time_start)); t = tv2.tv_sec+(float)tv2.tv_usec/1000000.0; fprintf(stderr, "stats: hosts = %d trys = %d cons = %d time = %.2fs trys/s = %.2f\n", hosts_done, attempts_done, connects, t, attempts_done/t); } bool skip_host(h) struct hosts_s *h; { if (a_abort && !h->connects && (h->attempts_highest_done >= a_abort)) /* async pain */ { if (h->status & HO_ABORT) { if ((time(NULL)-h->notice_abort)>a_timeout) { if (f_verbose) fprintf(stderr, "skipping: %s (no connects in %d attempts)\n", h->name, h->attempts_done); return 1; } } else { h->notice_abort=time(NULL); h->status|=HO_ABORT; } } return 0; } int next_port (h) struct hosts_s *h; { int n; for (n = h->port; ++n <= a_end;) { if (!f_fast) return n; if (++h->portlist_ent>portlist_n) return -1; return (portlist[h->portlist_ent-1]); } return -1; } fvoid scan_ports_linear () { struct hosts_s host; char *name; while ((name = next_host ())) { if (!host_init(&host, name, 1)) continue; for (;;) { scatter (&host, a_timeout); if (skip_host(&host)) break; if ((host.port = next_port(&host))==-1) break; } wait_end (a_timeout); if (f_verbose_stats) host_stats (&host); clear_all (); host_clear(&host); } }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement