Article 13042 of alt.sources:
Path: nntpd.lkg.dec.com!lead.zk3.dec.com!crl.dec.com!crl.dec.com!caen!msunews!agate!howland.reston.ans.net!newsfeed.internetmci.com!news.cfa.org!chi-news.cic.net!nntp.coast.net!harbinger.cc.monash.edu.au!news.rmit.EDU.AU!goanna.cs.rmit.EDU.AU!core.apana.org.au!suburbia.net!proff
From: proff@suburbia.net (Julian Assange)
Newsgroups: alt.sources
Subject: strobe v1.03 optimized tcp port surveyor shar 01/03
Date: 28 Nov 1995 13:25:05 GMT
Organization: Australian Public Access Network Association
Lines: 1820
Message-ID: <49f2jh$c7e@core.apana.org.au>
NNTP-Posting-Host: suburbia.apana.org.au
X-Newsreader: TIN [version 1.2 PL2]


#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1995-11-29 00:24 EST by <proff@suburbia>.
# Source directory was `/mnt/hdc2/home/p/proff/c/strobe'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This is part 1 of a multipart archive.                                   
# Do not concatenate these parts, unpack them in order with `/bin/sh'.     
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#  20518 -rw-r--r-- strobe.c
#   7100 -rw-r--r-- strobe.1
#   1409 -rw-r--r-- Makefile
#    375 -rw-r--r-- INSTALL
#      5 -rw-r--r-- VERSION
#    636 -rw-r--r-- HISTORY
#    890 -rw-r--r-- COPYRIGHT
#   9432 -rw-r--r-- POST
#  10025 -rw-r--r-- strobe.man
#  60558 -rw-r--r-- strobe.services
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  echo 'WARNING: not restoring timestamps.  Consider getting and'
  echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
if test -r _sharseq.tmp; then
  echo 'Must unpack archives in sequence!'
  echo Please unpack part `cat _sharseq.tmp` next
  exit 1
fi
# ============= strobe.c ==============
if test -f 'strobe.c' && test X"$1" != X"-c"; then
  echo 'x - skipping strobe.c (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting strobe.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'strobe.c' &&
/*
X * Strobe (c) 1995 Julian Assange (proff@suburbia.net),
X * All rights reserved.
X *
X * $ cc strobe.c -o strobe
X */
X
#define VERSION "1.03"
X
#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>
X
#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
X
#ifndef INADDR_NONE
#  define INADDR_NONE ((unsigned long)-1)
#endif
X
#define port_t (unsigned short)
X
/*
X * the below should be set via the Makefile, but if not...
X */
X
#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
X
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;
X
int connects = 0;
int hosts_done = 0;
int attempts_done = 0;
int attempts_outstanding = 0;
struct timeval time_start;
X
fd_set set_sel;
fd_set set_sel_r;
fd_set set_sel_w;
X
int host_n;
int Argc;
char **Argv;
X
FILE *fh_input;
X
#define HO_ACTIVE 1
#define HO_ABORT 2
#define HO_COMPLETING 4
X
struct hosts_s
{
X    char *name;
X    struct in_addr in_addr;
X    int port;
X    int portlist_ent;
X    struct timeval time_used;
X    struct timeval time_start;
X    int attempts;
X    int attempts_done;
X    int attempts_highest_done;
X    int connects;
X    time_t notice_abort;
X    int status;
};
struct hosts_s ho_initial;
struct hosts_s *hosts;
X
#define HT_SOCKET 1
#define HT_CONNECTING 2
X
struct htuple_s
{
X    char *name;
X    struct in_addr in_addr;
X    int port;
X    int sfd;
X    int status;
X    struct timeval sock_start;
X    int timeout;
X    struct hosts_s *host;
};
X
struct htuple_s ht_initial;
struct htuple_s *attempt;
X
struct port_desc_s
{
X    int port;
X    char *name;
X    char *portname;
X    struct port_desc_s *next;
X    struct port_desc_s *next_port;
};
X
struct port_desc_s **port_descs;
X
int *portlist = NULL;
int portlist_n = 0;
X
char *
Srealloc (ptr, len)
X  char *ptr;
X  int len;
{
X    char *p;
X    int retries = 10;
X    while (!(p = ptr? realloc (ptr, len): malloc(len)))
X    {
X        if (!--retries)
X        {
X		perror("malloc");
X		exit(1);
X	}
X	if (!f_quiet)
X	   fprintf(stderr, "Smalloc: couldn't allocate %d bytes...sleeping\n", len);
X	sleep (2);
X    }
X    return p;
}
X
char *
Smalloc (len)
X  int len;
{
X   return Srealloc (NULL, len);
}
X
fvoid
sock_block (sfd)
X  int sfd;
{
X    int flags;
X    flags = (~O_NONBLOCK) & fcntl (sfd, F_GETFL);
X    fcntl (sfd, F_SETFL, flags);
}
X
fvoid
sock_unblock (sfd)
X  int sfd;
{
X    int flags;
X    flags = O_NONBLOCK | fcntl (sfd, F_GETFL);
X    fcntl (sfd, F_SETFL, flags);
}
X
int
timeval_subtract (result, x, y) /* from gnu c-lib info.texi */
X  struct timeval *result, *x, *y;
{
/* Perform the carry for the later subtraction by updating y. */
if (x->tv_usec < y->tv_usec) {
X int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
X y->tv_usec -= 1000000 * nsec;
X y->tv_sec += nsec;
}
if (x->tv_usec - y->tv_usec > 1000000) {
X int nsec = (y->tv_usec - x->tv_usec) / 1000000;
X y->tv_usec += 1000000 * nsec;
X y->tv_sec -= nsec;
}
X
/* Compute the time remaining to wait.
X  `tv_usec' is certainly positive. */
result->tv_sec = x->tv_sec - y->tv_sec;
result->tv_usec = x->tv_usec - y->tv_usec;
X
/* Return 1 if result is negative. */
return x->tv_sec < y->tv_sec;
}
X
fvoid
attempt_clear (h)
X  struct htuple_s *h;
{
X    if (h->status & HT_SOCKET)
X    {
X	struct timeval tv1, tv2;
X	gettimeofday(&tv1, NULL);
X	timeval_subtract(&tv2, &tv1, &(h->sock_start));
X	h->host->time_used.tv_sec+=tv2.tv_sec;
X	if ((h->host->time_used.tv_usec+=tv2.tv_usec) >= 1000000)
X	{
X	    h->host->time_used.tv_usec -= 1000000;
X	    h->host->time_used.tv_sec++;
X	}
X        attempts_done++;
X	h->host->attempts_done++;
X	if (h->port > h->host->attempts_highest_done)
X	    h->host->attempts_highest_done=h->port;
X	sock_unblock (h->sfd);
/*	shutdown (h->sfd, 2); */
X	close (h->sfd);
X        if (FD_ISSET(h->sfd, &set_sel))
X	{
X	     FD_CLR (h->sfd, &set_sel);
X	     attempts_outstanding--;
X	}
X    }
X    *h = ht_initial;
}
X
fvoid
clear_all ()
{
X    int n;
X    for (n = 0; n < a_sock_max; n++)
X	attempt_clear (&attempt[n]);
}
X
fvoid
attempt_init ()
{
X    int n;
X    for (n = 0; n < a_sock_max; n++)
X	attempt[n] = ht_initial;
}
X
fvoid
hosts_init ()
{
X    int n;
X    for (n = 0; n < a_sock_max; n++)
X	hosts[n] = ho_initial;
}
X
fvoid
fdsets_init ()
{
X    FD_ZERO(&set_sel_r); /* yes, we have to do this, despite the later */
X    FD_ZERO(&set_sel_w); /* assisgnments */
X    FD_ZERO(&set_sel);
}
X
int
sc_connect (h)
X  struct htuple_s *h;
{
X    struct sockaddr_in sa_in;
X    int sopts1 = 1;
X    struct linger slinger;
X    if ((h->sfd = socket (PF_INET, SOCK_STREAM, 0)) == -1)
X	return 0;
X    memset(&sa_in, 0, sizeof(sa_in));
X    h->status |= HT_SOCKET;
X    gettimeofday(&(h->sock_start), NULL);
X    sock_unblock (h->sfd);
X    setsockopt (h->sfd, SOL_SOCKET, SO_REUSEADDR, (char *) &sopts1, sizeof (sopts1));
X    setsockopt (h->sfd, SOL_SOCKET, SO_OOBINLINE, (char *) &sopts1, sizeof (sopts1));
X    slinger.l_onoff = 0;	/* off */
X    setsockopt (h->sfd, SOL_SOCKET, SO_LINGER, (char *) &slinger, sizeof (slinger));
X    sa_in.sin_family = AF_INET;
X    if (a_bindport)
X        sa_in.sin_port = a_bindport;
X    if (a_bindaddr)
X        sa_in.sin_addr = bindaddr;
X    if (a_bindaddr || a_bindport)
X        if (bind (h->sfd, (struct sockaddr *)&sa_in, sizeof(sa_in)) == -1)
X        {
X		fprintf(stderr, "couldn't bind %s : %d  ", a_bindaddr? a_bindaddr: "0.0.0.0", ntohs(a_bindport));
X		perror("");
X		if (errno == EACCES)
X			exit(1);
X		return 0;
X	}
X    sa_in.sin_addr = h->in_addr;
X    sa_in.sin_port = htons (h->port);
X
X    if (connect (h->sfd, (struct sockaddr *) &sa_in, sizeof (sa_in)) == -1)
X    {
X	switch (errno)
X	{
X	case EINPROGRESS:
X	case EWOULDBLOCK:
X	    break;
X	case ETIMEDOUT:
X	case ECONNREFUSED:
X	case EADDRNOTAVAIL:
X	    if (f_verbose)
X	    {
X		fprintf(stderr, "%s:%d ", h->name, h->port);
X		perror("");
X	    }
X	    h->host->attempts++;
X	    attempt_clear (h);
X	    return 1;
X	default:
X	    if (!f_quiet)
X	    {
X	    	fprintf(stderr, "%s:%d ", h->name, h->port);
X	    	perror ("");
X	    }
X	    attempt_clear (h);
X	    return 0;
X	}
X    }
X    h->host->attempts++;
X    h->status |= HT_CONNECTING;
X    sock_block (h->sfd);
X    FD_SET(h->sfd, &set_sel);
X    attempts_outstanding++;
X    return 1;
}
X
int
gatherer_tcp (h)
X  struct htuple_s *h;
{
X    struct port_desc_s *pd;
X    if (f_minimise)
X	printf ("%s\t%d\n", h->name, h->port);
X    else
X    {
X    	if ((pd = port_descs[h->port]))
X        {
X    	    	printf ("%-30s %-16s %5d/tcp %s\n", h->name, pd->portname, h->port, pd->name);
X	    while (!f_delete_dupes && !f_minimise && (pd=pd->next))
X	        printf ("#%-29s %-16s %5d/tcp %s\n", h->name, pd->portname, h->port, pd->name);
X    	}
X    	else
X	    printf ("%-30s %-16s %5d/tcp unassigned\n", h->name, "unknown", h->port);
X    }
X    h->host->connects++;
X    connects++;
X    attempt_clear (h);
X    return 1;
}
X
bool
gather ()
{
X    struct timeval timeout;
X    struct htuple_s *h;
X    int n;
X    int selected;
X    time_t tim;
X
X    if (!attempts_outstanding) return 1;
X    set_sel_r=set_sel_w=set_sel;
X    timeout.tv_sec = 0;
X    timeout.tv_usec = 250000; /* 1/4 of a second */
X
X    selected = select (FD_SETSIZE, &set_sel_r, &set_sel_w, 0, &timeout);
X    /* Look for timeouts */
X
X    tim = time (NULL);
X    for ( n = 0 ; n < a_sock_max; n++ )
X    {
X      h = &attempt[n];
X      if ((h->status & HT_SOCKET) &&
X	  ((h->sock_start.tv_sec + h->timeout) < tim))
X 	attempt_clear (h);
X    }
X
X    switch (selected)
X    {
X    case -1:
X	perror ("select");
X	return 0;
X    case 0:
X	return 1;
X    }
X    for (n = 0; selected && (n < a_sock_max); n++)
X    {
X	h = &attempt[n];
X	if (h->status & HT_CONNECTING)
X	{
X	    if (FD_ISSET (h->sfd, &set_sel_r) || FD_ISSET (h->sfd, &set_sel_w))
X	    {
X		struct sockaddr_in in;
X		int len = sizeof (in);
X		selected--;
X		/* select() lies occasionaly
X                 */
X		if (!f_dontgetpeername) /* but solaris2.3 crashes occasionally ;-| */
X		{
X			if (getpeername (h->sfd, (struct sockaddr *) &in, &len) == 0)
X		    	    gatherer_tcp (h);
X			else
X		    	    attempt_clear (h);
X		}
X		else
X		    	gatherer_tcp (h);
X	    }
X	}
X    }
X    return 1;
}
X
bool
add_attempt (add)
X  struct htuple_s *add;
{
X    struct htuple_s *h;
X    static time_t oldtime;
X    static int n;
X    for (;;)
X    {
X	for (; n < a_sock_max; n++)
X	{
X	    h = &attempt[n];
X	    if (!h->status)
X		goto foundfree;
X	}
X	n = 0;
X	gather ();
X	continue;
X      foundfree:
X	*h = *add;
X	if (!sc_connect (h))
X	{
X	    gather ();
X	    continue;
X	}
X	if ((oldtime + 1) < time (NULL))
X	{
X	    oldtime = time (NULL);
X	    gather ();
X	}
X	break;
X    }
X    return 1;
}
X
int
scatter (host, timeout)
X  struct hosts_s *host;
X  int timeout;
{
X    static struct htuple_s add;
X    add = ht_initial;
X    add.host = host;
X    add.name = host->name;
X    add.in_addr = host->in_addr;
X    add.port = host->port;
X    add.timeout = timeout;
X    if (f_verbose)
X	fprintf (stderr, "attempting port=%d host=%s\n", add.port, add.name);
X    add_attempt (&add);
X    return 1;
}
X
fvoid
wait_end (t)
X  int t;
{
X    time_t st;
X    st = time (NULL);
X    while ((st + t) > time (NULL))
X    {
X	gather ();
X	if (attempts_outstanding<1) break;
X    }
}
X
struct in_addr
resolve (name)
X  char *name;
{
X    static struct in_addr in;
X    unsigned long l;
X    struct hostent *ent;
X    if ((l = inet_addr (name)) != INADDR_NONE)
X    {
X	in.s_addr = l;
X	return in;
X    }
X    if (!(ent = gethostbyname (name)))
X    {
X	perror (name);
X	in.s_addr = INADDR_NONE;
X	return in;
X    }
X    return *(struct in_addr *) ent->h_addr;
}
X
char *
next_host ()
{
X    static char lbuf[512];
X    hosts_done++;
X    if (a_input)
X    {
X	int n;
reread:
X	if (!fgets (lbuf, sizeof (lbuf), fh_input))
X	{
X	    fclose (fh_input);
X            a_input = NULL;
X	    return next_host();
X	}
X	if (strchr("# \t\n\r", lbuf[0])) goto reread;
X	n = strcspn (lbuf, " \t\n\r");
X	if (n)
X	    lbuf[n] = '\0';
X	return lbuf;
X    }
X    if ( host_n >= Argc )
X      return NULL;
X
X    return Argv[host_n++];
}
X
bool
host_init (h, name, nocheck)
X  struct hosts_s *h;
X  char *name;
X  bool nocheck;
{
X    int n;
X    *h=ho_initial;
X    h->in_addr = resolve (name);
X    if (h->in_addr.s_addr == INADDR_NONE)
X	return 0;
X    if (!nocheck)
X        for (n=0; n<a_sock_max; n++)
X   	{ 
X	    if (hosts[n].name && hosts[n].in_addr.s_addr==h->in_addr.s_addr)
X	    {
X		if (!f_quiet)
X		    fprintf(stderr, "ip duplication: %s == %s (last host ignored)\n",
X		        hosts[n].name, name);
X		return 0;
X	    }
X        }
X    h->name = (char *) Smalloc (strlen (name) + 1);
X    strcpy (h->name, name);
X    h->port = a_start;
X    h->status = HO_ACTIVE;
X    gettimeofday(&(h->time_start), NULL);
X    return 1;
}
X
fvoid
host_clear (h)
X  struct hosts_s *h;
{
X    if (h->name)
X    {
X    	free (h->name);
X    }
X    *h=ho_initial;
}
X
fvoid
host_stats (h)
X  struct hosts_s *h;
{
X    struct timeval tv, tv2;
X    float t, st;
X    gettimeofday(&tv, NULL);
X    timeval_subtract(&tv2, &tv, &(h->time_start));
X    t = tv2.tv_sec+(float)tv2.tv_usec/1000000.0;
X    st = h->time_used.tv_sec+(float)h->time_used.tv_usec/1000000.0;
X    fprintf(stderr, "stats: host = %s trys = %d cons = %d time = %.2fs trys/s = %.2f trys/ss = %.2f\n",
X	h->name, h->attempts_done, h->connects, t, h->attempts_done/t, h->attempts_done/st);
}
X
fvoid
final_stats()
{
X    struct timeval tv, tv2;
X    float t;
X    gettimeofday(&tv, NULL);
X    timeval_subtract(&tv2, &tv, &(time_start));
X    t = tv2.tv_sec+(float)tv2.tv_usec/1000000.0;
X    fprintf(stderr, "stats: hosts = %d trys = %d cons = %d time = %.2fs trys/s = %.2f\n",
X	hosts_done, attempts_done, connects, t, attempts_done/t);
}
X
bool skip_host(h)
X  struct hosts_s *h;
{
X    if (a_abort && !h->connects && (h->attempts_highest_done >= a_abort)) /* async pain */
X    {
X	if (h->status & HO_ABORT)
X	{
X	    if ((time(NULL)-h->notice_abort)>a_timeout)
X	    {
X		if (f_verbose)
X		    fprintf(stderr, "skipping: %s (no connects in %d attempts)\n",
X			h->name, h->attempts_done);
X		return 1;
X	    }
X	} else 
X        {
X		h->notice_abort=time(NULL);
X		h->status|=HO_ABORT;
X	}
X    }
X    return 0;
}
X
int
next_port (h)
struct hosts_s *h;
{
X    int n;
X    for (n = h->port; ++n <= a_end;)
X    {
X    	if (!f_fast) return n;
X	if (++h->portlist_ent>portlist_n) return -1;
X        return (portlist[h->portlist_ent-1]);
X    }
X    return -1;
}
X
fvoid
scan_ports_linear ()
{
X    struct hosts_s host;
X    char *name;
X    while ((name = next_host ()))
X    {
X	if (!host_init(&host, name, 1)) continue;
X	for (;;)
X	{
X	    scatter (&host, a_timeout);
X	    if (skip_host(&host)) break;
X	    if ((host.port = next_port(&host))==-1)
X		break;
X	}
X	wait_end (a_timeout);
X	if (f_verbose_stats)
X	    host_stats (&host);
X	clear_all ();
X	host_clear(&host);
X    }
}
X
/* Huristics:
X *  o  fast connections have priority == maximise bandwidth i.e 
X *     a port in the hand is worth two in the bush
X *
X *  o  newer hosts have priority == lower ports checked more quickly
X *
X *  o  all hosts eventually get equal "socket time" == despite
X *     priorities let no one host hog the sockets permanently
X *
X *  o  when host usage times are equal (typically on or shortly after
X *     initial startup) distribute hosts<->sockets evenly rather than
X *     play a game of chaotic bifurcatic ping-pong
X */
X          
fvoid
scan_ports_paralell ()
{
X    int n;
X    struct timeval smallest_val;
X    int smallest_cnt;
X    char *name;
X    struct hosts_s *h, *smallest = &hosts[0];
X    while (smallest)
X    {
X	smallest_val.tv_sec=0xfffffff;
X	smallest_val.tv_usec=0;
X	for (n = 0, smallest_cnt = 0xfffffff, smallest = NULL; n < a_sock_max; n++)
X	{
X	    h = &hosts[n];
X
X	    if (((h->status & HO_COMPLETING) &&
X                 (h->attempts_done == h->attempts)) ||
X                skip_host(h))
X	    {
X		if (f_verbose_stats) host_stats (h);
X		host_clear (h);
X	    }
X
X	    if (!h->name && ((name = next_host ())))
X		if (!host_init (h, name, 0))
X		{
X		    host_clear (h);
X		    continue;
X		}
X
X	    if (h->name)
X	    {
X		if (((h->time_used.tv_sec < smallest_val.tv_sec) ||
X		     ((h->time_used.tv_sec == smallest_val.tv_sec) &&
X		      (h->time_used.tv_usec <= smallest_val.tv_usec))) &&
X		    (((h->time_used.tv_sec != smallest_val.tv_sec) &&
X		      (h->time_used.tv_usec != smallest_val.tv_usec)) ||
X		     (h->attempts < smallest_cnt)))
X	        {
X	  	    smallest_cnt = h->attempts;
X		    smallest_val = h->time_used;
X		    smallest = h;
X		 }
X	    }
X	}
X
X	if (smallest)
X	{
X	    if (!(smallest->status & HO_COMPLETING))
X	    {
X		scatter (smallest, a_timeout);
X		if ((smallest->port=next_port(smallest))==-1)
X	            smallest->status|=HO_COMPLETING;
X	    }
X	    else
X		gather();
X	}
X    }
}
X
fvoid
loaddescs ()
{
X    FILE *fh;
X    char lbuf[1024];
X    char desc[256];
X    char portname[17];
X    unsigned int port;
X    char *fn;
X    char prot[4];
X    prot[3]='\0';
X    if (!(fh = fopen ((fn=a_services), "r")) &&
X        !(fh = fopen ((fn=LIB_STROBE_SERVICES), "r")) &&
X        !(fh = fopen ((fn=ETC_SERVICES), "r")))
X    {
X	perror (fn);
X	exit (1);
X    }
X    port_descs=(struct port_desc_s **) Smalloc(sizeof(struct port_descs_s *) * 65536);
X    memset(port_descs, 0, 65536);
X    while (fgets (lbuf, sizeof (lbuf), fh))
X    {
X	char *p;
X	struct port_desc_s *pd, *pdp;
X	if (strchr("*# \t\n", lbuf[0])) continue;
X	if (!(p = strchr (lbuf, '/'))) continue;
X	*p = ' ';
X	desc[0]='\0';
X	if (sscanf (lbuf, "%16s %u %3s %255[^\r\n]", portname, &port, prot, desc) <3 || strcmp (prot, "tcp") || (port > 65535))
X	    continue;
X	pd = port_descs[port];
X	if (!pd)
X	{
X	    portlist = (int *)Srealloc((char *)portlist, ++portlist_n*sizeof(int));
X	    portlist[portlist_n-1]=port;
X	}
X	if (!f_minimise)
X	{
X	    pdp = (struct port_desc_s *) Smalloc (sizeof (*pd) + strlen (desc) + 1 + strlen (portname) + 1);
X	    if (pd)
X	    {
X	        for (; pd->next; pd = pd->next);
X	        pd->next = pdp;
X	        pd = pd->next;
X	    } else 
X	    {
X	        pd = pdp;
X	        port_descs[port] = pd;
X	    } 
X	    pd->next = NULL;
X	    pd->name = (char *) (pd) + sizeof (*pd);
X	    pd->portname = pd->name + strlen(desc)+1;
X	    strcpy (pd->name, desc);
X	    strcpy (pd->portname, portname);
X	} else
X	    port_descs[port] = (struct port_desc_s *)-1;
X    }
X    if (f_minimise) 
X        free (port_descs);
}
X
fvoid
usage ()
{
X    fprintf (stderr, "\
usage: %8s [options]\n\
\t\t[-v(erbose)]\n\
\t\t[-V(erbose_stats]\n\
\t\t[-m(inimise)]\n\
\t\t[-d(elete_dupes)]\n\
\t\t[-g(etpeername_disable)]\n\
\t\t[-s(tatistics)]\n\
\t\t[-q(uiet)]\n\
\t\t[-o output_file]\n\
\t\t[-b begin_port_n]\n\
\t\t[-e end_port_n]\n\
\t\t[-p single_port_n]\n\
\t\t[-P bind_port_n]\n\
\t\t[-A bind_addr_n]\n\
\t\t[-t timeout_n]\n\
\t\t[-n num_sockets_n]\n\
\t\t[-S services_file]\n\
\t\t[-i hosts_input_file]\n\
\t\t[-l(inear)]\n\
\t\t[-f(ast)]\n\
\t\t[-a abort_after_port_n]\n\
\t\t[-M(ail_author)]\n\
\t\t[host1 [...host_n]]\n", Argv[0]);
X    exit (1);
}
int
main (argc, argv)
X  int argc;
X  char **argv;
{
X    int c;
X    Argc = argc;
X    Argv = argv;
X
X    while ((c = getopt (argc, argv, "o:dvVmgb:e:p:P:a:A:t:n:S:i:lfsqM")) != -1)
X	switch (c)
X	{
X	case 'o':
X	    a_output = optarg;
X	    break;
X	case 'd':
X	    f_delete_dupes=1;
X	    break;
X	case 'v':
X	    f_verbose = 1;
X	    break;
X	case 'V':
X	    f_verbose_stats = 1;
X	    break;
X	case 'm':
X	    f_minimise = 1;
X	    break;
X	case 'g':
X	    f_dontgetpeername = 1;
X	    break;
X	case 'b':
X	    a_start = atoi (optarg);
X	    break;
X	case 'e':
X	    a_end = atoi (optarg);
X	    break;
X	case 'P':
X	    a_bindport = htons (atoi (optarg));
X	    break;
X	case 'A':
X	    a_bindaddr = optarg;
X	    bindaddr = resolve (a_bindaddr);
X	    if (bindaddr.s_addr == INADDR_NONE)
X	    {
X	    	perror(a_bindaddr);
X		exit(1);
X	    }
X            break;
X	case 'p':
X	    a_start = a_end = atoi (optarg);
X	    break;
X	case 'a':
X	    a_abort = atoi (optarg);
X	    break;
X	case 't':
X	    a_timeout = atoi (optarg);
X	    break;
X	case 'n':
X	    a_sock_max = atoi (optarg);
X	    break;
X	case 'S':
X	    a_services = optarg;
X	    break;
X	case 'i':
X	    a_input = optarg;
X	    break;
X	case 'l':
X	    f_linear = 1;
X	    break;
X	case 'f':
X	    f_fast = 1;
X	    break;
X	case 's':
X	    f_stats = 1;
X	    break;
X        case 'q':
X	    f_quiet = 1;
X	    break;
X	case 'M':
X	    fprintf(stderr, "Enter mail to author below. End with ^D or .\n");
X	    system("mail strobe@suburbia.net");
X	    break;
X	case '?':
X	default:
X	    fprintf (stderr, "unknown option %s\n", argv[optind-1]);
X	    usage ();
X	    /* NOT_REACHED */
X	}
X    host_n = optind;
X
X    if (!f_quiet)
X        fprintf (stderr, "strobe %s (c) 1995 Julian Assange (proff@suburbia.net).\n", VERSION);
X    if (a_input)
X    {
X        if ( ! strcmp("-",a_input) ) { /* Use stdin as input file */
X	    fh_input = stdin;
X	  }
X	else {
X	  if (!(fh_input = fopen (a_input, "r")))
X	    {
X	      perror (a_input);
X	      exit (1);
X	    }
X	}
X    } else
X    {
X      switch ( argc - host_n ) { /* Number of hosts found on command line */
X      case 0:
X	fh_input = stdin;
X	a_input = "stdin"; /* Needed in "next_host()" */
X	break;
X      case 1:
X	f_linear = 1;
X	break;
X      }
X    }
X
X    if ((fh_input==stdin) && !f_quiet)
X      fprintf (stderr, "Reading host names from stdin...\n");
X
X    if (a_output)
X    {
X        int fd;
X        if ((fd=open(a_output, O_WRONLY|O_CREAT|O_TRUNC, 0666))==-1)
X	{
X		perror(a_output);
X		exit(1);
X	}
X	dup2(fd, 1);
X    }
X    attempt = (struct htuple_s *) Smalloc (a_sock_max * sizeof (struct htuple_s));
X    attempt_init();
X    if (!f_linear)
X    {
X    	hosts = (struct hosts_s *) Smalloc (a_sock_max * sizeof (struct hosts_s));
X    	hosts_init();
X    }
X    if (!f_minimise || f_fast)
X    	loaddescs ();
X    fdsets_init();
X    gettimeofday(&time_start, NULL);
X    f_linear ? scan_ports_linear ():
X 	       scan_ports_paralell ();
X    if (f_stats || f_verbose_stats)
X	final_stats();
X    exit (0);
}
SHAR_EOF
  $shar_touch -am 1127193795 'strobe.c' &&
  chmod 0644 'strobe.c' ||
  echo 'restore of strobe.c failed'
  shar_count="`wc -c < 'strobe.c'`"
  test 20518 -eq "$shar_count" ||
    echo "strobe.c: original size 20518, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= strobe.1 ==============
if test -f 'strobe.1' && test X"$1" != X"-c"; then
  echo 'x - skipping strobe.1 (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting strobe.1 (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'strobe.1' &&
X.\" "%W% %G%"
X.TH STROBE\ 1.03 1
X.SH NAME
strobe \- Super optimized TCP port surveyor
X.SH SYNOPSIS
X.B strobe
[ -vVmdbepPAtnSilfsaM ] [host1 ... [hostn]]
X.SH DESCRIPTION
X.I strobe
is a network/security tool that locates and describes all listening tcp ports on a
(remote) host or on many hosts in a bandwidth utilisation maximising, and
process resource minimizing manner. 
X.PP
X.I strobe
approximates a parallel finite state machine internally. In non-linear multi-host
mode it attempts to apportion bandwidth and sockets amoung the hosts very efficiently.
This can reap appreciable gains in speed for multiple distinct hosts/routes. 
X.PP
On a machine with a reasonable number of sockets,
X.I strobe
is fast enough to port scan entire Internet sub domains. It is even possible to survey
an entire small country in a reasonable time from a fast machine on the network backbone,
provided the machine in question uses dynamic socket allocation or has had its static
socket allocation increased very appreciably (check your kernel options). In this
very limited application
X.I strobe
is said to be faster than
X.B ISS2.1
(a high quality commercial security scanner by cklaus@iss.net and friends) or
X.BR PingWare 
(also comercial).
X.SH OPTIONS
X.TP
X.B \-v
Verbose output.
X.TP
X.B \-V
Verbose statistical output.
X.TP
X.B \-m
Minimise output. Only print hostname, port tuples. Implies 
X.BR \-d .
Useful for automated output parsing.
X.TP
X.B \-d
Delete duplicate entries for port descriptions. i.e use only the first definition.
X.TP
X.B \-g
Disable usage of
X.BR getpeername (2).
On
X.B solaris
2.3 machines this causes a core dump, for reasons unknown. This behavior is fixed with
X.B solaris
2.4. Under Linux, HP and perhaps other unix implimentations, false tcp connection positives
may occurr when this option is activated.
X.TP
X.B \-s
Statistical information describing the average of all hosts surveyed is sent to
stderr on completion.
X.TP
X.B \-q
Quiet mode. Don't print non-fatal errors or the (c) message.
X.TP
X.B \-d
Display only the first description in the port services entry file (Cf.
X.BR \-B ).
X.TP
X.B \-o file
Direct output (but not any messages which can be affected by
X.BR \-q )
to file.
X.TP
X.B \-b number
Beginning (starting) port number.
X.TP
X.B \-e number
Ending port number.
X.TP
X.B \-p number
Port number if you intend to scan a single port.
X.TP
X.B \-P number
Local port to bind outgoing connection requests to.
(you will normally need super-user privileges to bind ports smaller than 1024)
X.TP
X.B \-A address
Interface address to send outgoing connection requests from for multi-homed machines.
X.TP
X.B \-t number
Time after which a connection attempt to a completely unresponsive host/port is
aborted.
X.TP
X.B \-n number
Use this number of sockets in parallel (defaults to 64). 
X.I strobe
attempts to figure out if
X.B number
is greater than the quantity of available sockets at any point in time -- and
if so, only use the amount found. On some UNIX implimentations such as Solaris,
this appears not to work correctly and you may find yourself with unusual errors
such as
X.B NO ROUTE TO HOST
when you hit the socket ceiling. Remember that 
X.I strobe
probably isn't the only process on the system desiring a socket or two. Having
X.I strobe
pilfer all the spare sockets away from 
X.BR inetd (8)
and other daemons and clients isn't such a crash hot idea, unless you want
to stop all new incoming and outgoing connections.
X.TP
X.B \-S file
Change the default port services description file to
X.BR file .
Note that if 
X.B \-S
is not specified port services are loaded from one of
X.BR strobe.services ,
X.BR /usr/local/lib/strobe.services ,
or
X.BR /etc/services .
X.TP
X.B \-i file
Obtain hostnames to strobe from 
X.B file
rather than from the command line. Note that only the first white-space
seperated word in each line of
X.B file
is used, so one can feed in files such as
X.BR /etc/hosts .
If filename is 
X.B '-'
, stdin will be used.
X.TP
X.B \-l
Probe hosts linearly (sequentually) rather than in parallel. The actual
ports on each host are still checked in a parallel manner (with a parallelism
of
X.B \-n
(defaults to 64)).
X.TP
X.B \-f
Fast mode, probe only the tcp ports detailed in the port services file (see
X.BR \-S ).
X.TP
X.B \-a number
Abort and skip to the next host after ports upto to
X.B number
have been probed and still no connections have occurred. Due to the parallel
nature of the probing, reply packets for n+m may return before those relating
to n. What this means is that ports >
X.B number
may be probed. If
X.I strobe
see's a connection on any one of these higher ports before its negated all
possibility of a service listening on ports <=
X.B number
then despite the fact that all ports up to and including
X.B number
may turn out to be connectionless,
X.I strobe
will `abort the abort'. This is considered optimal, if unusual behavior.
X.TP
X.B \-M
Mail a bug report, or tcp/udp port description to the current source maintainer.
X.SH EXAMPLES
X.PP
strobe -n 120 -a 80 -i /etc/hosts -s -f -V -S services -o out
X.PP
X.I strobe
all entries in
X.B /etc/hosts
(identical ip addresses are skipped automagically)
using 120 sockets in parallel, but only check the individual tcp ports mentioned
in
X.BR services .
If we have probed up to port 80 on a host
and have still not yet evidenced a connection, then skip that host. Display speed/time
statistics for each host and for the totality of hosts to stderr. Place the regular
output in
X.BR out .
X.PP
ypcat hosts | strobe -p 80 -t 2 -A 203.4.184.1 -P 53
X.PP
X.I strobe
all hosts in your hosts YP/NIS-table for WWW-servers. Use a timeout of two seconds.
Set the source address to the 203.4.184.1 interface. Make all connection requests
appear to come from port 53 (DNS).
X.PP
X.SH BUGS
X.I Strobe
performs no other security functions (yet) and does not verify route blocking against
UDP or TCP handshake sequence guessing one-way IP spoofing attacks. 
X.SH AUTHOR
X.PP
X.I Julian Assange 
X.PP
X.RS
X.nf
EMAIL:
X	strobe@suburbia.net
X	proff@suburbia.net
X.fi
X.RE
X.SH OFFICAL DISTRIBUTION
X.PP
ftp://suburbia.net:/pub/strobe.tgz
X.SH COPYRIGHT
X
Copyright (c) Julian Assange 1995, All rights reserved.
X
This software maybe distributed only freely, in full and without modification.
It may not be bundled with any sort of hardware or software if a fee is
charged for that hardware or software directly or indirectly, in whole or in
part. If you would like to include this software in such a distribution
then please contact the author to negotiate reasonable (possibly free) terms.
X
The author shall not under any circumstances accept any liability for this software,
for its use, misuse, or any failings it may have. Your on your own.
X
The author reserves the right to alter the aformentioned conditions from time
to time as he sees appropriate. The author's most recent copyright notice and
conditions for this software always supersede any issued previously.
X
Use and or distribution of this software implies acceptance of the above.
X
X.BR So\ there .
X.PP
X.SH SEE ALSO
X.BR nslookup (1),
X.BR host (1),
X.BR dig (1),
X.BR socket (2),
X.BR bind (2),
X.BR connect (2),
X.BR iss (1).
SHAR_EOF
  $shar_touch -am 1127200995 'strobe.1' &&
  chmod 0644 'strobe.1' ||
  echo 'restore of strobe.1 failed'
  shar_count="`wc -c < 'strobe.1'`"
  test 7100 -eq "$shar_count" ||
    echo "strobe.1: original size 7100, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= Makefile ==============
if test -f 'Makefile' && test X"$1" != X"-c"; then
  echo 'x - skipping Makefile (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting Makefile (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
# Strobe (c) 1995 Julian Assange, All rights reserved.
# (proff@suburbia.apana.org.au || proff@four.net || proff@gnu.ai.mit.edu)
X
# Modify the below to suit your filesystem
X
INSTALLDIR=/usr/local/bin
LIBDIR=/usr/local/lib
MANDIR=/usr/local/man/man1
X
#CC=cc
CC=gcc
X
#FLAGS=-O -nointl		# SCO
FLAGS= -O
X
#LIBS= -lnsl -lsocket		# SYSVR4 / SOLARIS
#LIBS= -lsocket -lmalloc -lc_s	# SCO
LIBS=
X
ETC_SERVICES=/etc/services
X
# Don't change anything from this point on.
X
OBJS=strobe.o
BIN=strobe
MAN=strobe.1
DATA=strobe.services
EXTRA=Makefile INSTALL VERSION HISTORY COPYRIGHT POST strobe.man
X
DEFS=-DLIB_STROBE_SERVICES='"$(LIBDIR)/$(DATA)"'\
X     -DSTROBE_SERVICES='"$(DATA)"'\
X     -DETC_SERVICES='"$(ETC_SERVICES)"'
X
CFLAGS=$(FLAGS) $(DEFS)
X
$(BIN): $(OBJS)
X	$(CC) $(CFLAGS) -o $(BIN) $(OBJS) $(LIBS)
$(OBJS):
$(DATA):
$(MAN):
$(INSTALLDIR)/$(BIN): $(BIN)
X	-rm -f $(INSTALLDIR)/$(BIN)
X	install -m 755 -s $(BIN) $(INSTALLDIR)/$(BIN)
$(LIBDIR)/$(DATA): $(DATA)
X	-rm -f $(LIBDIR)/$(DATA)
X	install -m 644 $(DATA) $(LIBDIR)/$(DATA)
$(MANDIR)/$(MAN): $(MAN)
X	-rm -f $(MANDIR)/$(MAN)
X	install -m 644 $(MAN) $(MANDIR)/$(MAN)
install: $(INSTALLDIR)/$(BIN) $(LIBDIR)/$(DATA) $(MANDIR)/$(MAN)
strobe.man : $(MAN)
X	 nroff -man -Tascii $(MAN) > strobe.man
tar:
X	(cd .. ; tar -zcf strobe.tgz strobe)
shar:
X	shar -L 50 -o strobe.shar *.c *.1 $(EXTRA) $(DATA)
clean:
X	rm -f $(BIN) *.o *.bak *.\~ errlist *.shar.* *.tgz *.swp core
SHAR_EOF
  $shar_touch -am 1127203995 'Makefile' &&
  chmod 0644 'Makefile' ||
  echo 'restore of Makefile failed'
  shar_count="`wc -c < 'Makefile'`"
  test 1409 -eq "$shar_count" ||
    echo "Makefile: original size 1409, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= INSTALL ==============
if test -f 'INSTALL' && test X"$1" != X"-c"; then
  echo 'x - skipping INSTALL (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting INSTALL (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'INSTALL' &&
(1) Edit the Makefile to suit your system -- follow the descriptions
X    therein
(2) type "make install"
(3) test with "./strobe localhost"
(4) read the man page
X
(5) if you find any staticly assigned tcp ports that it doesn't know about, then
X    send me a description so I can add it to the strobe.services database.
X
Happy strobing!
X
-Julian Assange  (proff@suburbia.net)
SHAR_EOF
  $shar_touch -am 1127182895 'INSTALL' &&
  chmod 0644 'INSTALL' ||
  echo 'restore of INSTALL failed'
  shar_count="`wc -c < 'INSTALL'`"
  test 375 -eq "$shar_count" ||
    echo "INSTALL: original size 375, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= VERSION ==============
if test -f 'VERSION' && test X"$1" != X"-c"; then
  echo 'x - skipping VERSION (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting VERSION (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'VERSION' &&
1.03
SHAR_EOF
  $shar_touch -am 1127195995 'VERSION' &&
  chmod 0644 'VERSION' ||
  echo 'restore of VERSION failed'
  shar_count="`wc -c < 'VERSION'`"
  test 5 -eq "$shar_count" ||
    echo "VERSION: original size 5, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= HISTORY ==============
if test -f 'HISTORY' && test X"$1" != X"-c"; then
  echo 'x - skipping HISTORY (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting HISTORY (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'HISTORY' &&
95-11-24 : 1.03 : bug fixes mainly relating to timeouts. new single port flag,
X                  bind port flag, bind address flag, read hostnames from stdin
95-03-09 : 1.02 : compat fix. remalloc(NULL, length) broke under versions of sunos,
X                  causing Srealloc() to hang. <select.h> included for IRIX FD_*
95-03-07 : 1.01 : bug fix. 'b' missing from getopt()
95-03-07 : 1.00 : many trivial changes, some bug fixes.
95-02-28 : 0.93 : char c; -> int c; in main() as char c caused problems with
X                  getopt() on systems such as IRIX which had unsigned char by default.
95-02-27 : 0.92 : Intial public release.
SHAR_EOF
  $shar_touch -am 1127193995 'HISTORY' &&
  chmod 0644 'HISTORY' ||
  echo 'restore of HISTORY failed'
  shar_count="`wc -c < 'HISTORY'`"
  test 636 -eq "$shar_count" ||
    echo "HISTORY: original size 636, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= COPYRIGHT ==============
if test -f 'COPYRIGHT' && test X"$1" != X"-c"; then
  echo 'x - skipping COPYRIGHT (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting COPYRIGHT (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'COPYRIGHT' &&
Copyright (c) Julian Assange 1995, All rights reserved.
X
This software maybe distributed only freely, in full and without modification.
It may not be bundled with any sort of hardware or software if a fee is
charged for that hardware or software directly or indirectly, in whole or in
part. If you would like to include this software in such a distribution
then please contact the author to negotiate reasonable (possibly free) terms.
X
The author shall not under any circumstances accept any liability for this software,
for its use, misuse, or any failings it may have. Your on your own.
X
The author reserves the right to alter the aformentioned conditions from time
to time as he sees appropriate. The author's most recent copyright notice and
conditions for this software always supersede any issued previously.
X
Use and or distribution of this software implies acceptance of the above.
SHAR_EOF
  $shar_touch -am 1127183195 'COPYRIGHT' &&
  chmod 0644 'COPYRIGHT' ||
  echo 'restore of COPYRIGHT failed'
  shar_count="`wc -c < 'COPYRIGHT'`"
  test 890 -eq "$shar_count" ||
    echo "COPYRIGHT: original size 890, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= POST ==============
if test -f 'POST' && test X"$1" != X"-c"; then
  echo 'x - skipping POST (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting POST (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'POST' &&
This is strobe1.03 an small update to strobe1.02.
X
I (proff@suburbia.net) have moved on to other projects of this type (e.g
GoSH) and was not intending to release another version of strobe.
However this month a few people (most notably edturka@statt.ericsson.se)
sent in some important bug fixes (ugh) and some minor new features. When I
applied their patches, I broke my vows about not working on strobe any
more and hacked in a just a few more options that really should have
been there in the first place.
X
strobe is available from ftp://suburbia.net/pub/strobe.tgz
X
-Proff
X
+----------------------------------+-----------------------------------------+
|Julian Assange                    | "if you think the United  States has    |
|FAX: +61-3-9819-9066              |  has stood still, who built the largest |
|EMAIL: proff@suburbia.net         |  shopping centre in the world?" - Nixon |
+----------------------------------+-----------------------------------------+
X
X
STROBE 1.03(1)                                     STROBE 1.03(1)
X
X
NAME
X       strobe - Super optimized TCP port surveyor
X
SYNOPSIS
X       strobe [ -vVmdbepPAtnSilfsaM ] [host1 ... [hostn]]
X
DESCRIPTION
X       strobe   is  a  network/security  tool  that  locates  and
X       describes all listening tcp ports on a (remote) host or on
X       many hosts in a bandwidth utilisation maximising, and pro-
X       cess resource minimizing manner.
X
X       strobe approximates a parallel finite state machine inter-
X       nally. In non-linear multi-host mode it attempts to appor-
X       tion bandwidth and sockets amoung  the  hosts  very  effi-
X       ciently.   This  can  reap  appreciable gains in speed for
X       multiple distinct hosts/routes.
X
X       On a machine with a reasonable number of  sockets,  strobe
X       is  fast  enough to port scan entire Internet sub domains.
X       It is even possible to survey an entire small country in a
X       reasonable  time  from a fast machine on the network back-
X       bone, provided the machine in question uses dynamic socket
X       allocation   or  has  had  its  static  socket  allocation
X       increased very appreciably (check your kernel options). In
X       this  very limited application strobe is said to be faster
X       than ISS2.1 (a high quality commercial security scanner by
X       cklaus@iss.net  and friends) or PingWare (also comercial).
X
OPTIONS
X       -v     Verbose output.
X
X       -V     Verbose statistical output.
X
X       -m     Minimise output. Only print hostname, port  tuples.
X              Implies -d.  Useful for automated output parsing.
X
X       -d     Delete duplicate entries for port descriptions. i.e
X              use only the first definition.
X
X       -g     Disable usage of getpeername(2).   On  solaris  2.3
X              machines  this  causes  a  core  dump,  for reasons
X              unknown. This behavior is fixed with  solaris  2.4.
X              Under  Linux, HP and perhaps other unix implimenta-
X              tions, false tcp connection  positives  may  occurr
X              when this option is activated.
X
X       -s     Statistical  information  describing the average of
X              all hosts surveyed is sent to stderr on completion.
X
X       -q     Quiet mode. Don't print non-fatal errors or the (c)
X              message.
X
X       -d     Display only the  first  description  in  the  port
X              services entry file (Cf.  -B).
X
X       -o file
X              Direct  output  (but  not any messages which can be
X              affected by -q) to file.
X
X       -b number
X              Beginning (starting) port number.
X
X       -e number
X              Ending port number.
X
X       -p number
X              Port number if you intend to scan a single port.
X
X       -P number
X              Local port to bind outgoing connection requests to.
X              (you  will  normally  need super-user privileges to
X              bind ports smaller than 1024)
X
X       -A address
X              Interface  address  to  send  outgoing   connection
X              requests from for multi-homed machines.
X
X       -t number
X              Time  after  which  a  connection attempt to a com-
X              pletely unresponsive host/port is aborted.
X
X       -n number
X              Use this number of sockets in parallel (defaults to
X              64).   strobe  attempts  to figure out if number is
X              greater than the quantity of available  sockets  at
X              any point in time -- and if so, only use the amount
X              found.  On  some  UNIX  implimentations   such   as
X              Solaris, this appears not to work correctly and you
X              may find yourself with unusual errors  such  as  NO
X              ROUTE  TO  HOST  when  you  hit the socket ceiling.
X              Remember that strobe probably isn't the  only  pro-
X              cess on the system desiring a socket or two. Having
X              strobe pilfer  all  the  spare  sockets  away  from
X              inetd(8) and other daemons and clients isn't such a
X              crash hot idea, unless you want  to  stop  all  new
X              incoming and outgoing connections.
X
X       -S file
X              Change  the  default port services description file
X              to file.  Note that if -S  is  not  specified  port
X              services  are  loaded  from one of strobe.services,
X              /usr/local/lib/strobe.services, or /etc/services.
X
X       -i file
X              Obtain hostnames to strobe from  file  rather  than
X              from  the  command  line.  Note that only the first
X              white-space seperated word in each line of file  is
X              used,  so one can feed in files such as /etc/hosts.
X              If filename is '-' , stdin will be used.
X
X       -l     Probe hosts linearly (sequentually) rather than  in
X              parallel.  The  actual ports on each host are still
X              checked in a parallel manner (with a parallelism of
X              -n (defaults to 64)).
X
X       -f     Fast mode, probe only the tcp ports detailed in the
X              port services file (see -S).
X
X       -a number
X              Abort and skip to the next host after ports upto to
X              number  have  been  probed and still no connections
X              have occurred. Due to the parallel  nature  of  the
X              probing,  reply  packets  for n+m may return before
X              those relating to n. What this means is that  ports
X              >  number  may be probed. If strobe see's a connec-
X              tion on any one of these higher  ports  before  its
X              negated  all  possibility of a service listening on
X              ports <= number then  despite  the  fact  that  all
X              ports up to and including number may turn out to be
X              connectionless, strobe will `abort the abort'. This
X              is considered optimal, if unusual behavior.
X
X       -M     Mail  a  bug report, or tcp/udp port description to
X              the current source maintainer.
X
EXAMPLES
X       strobe -n 120 -a 80 -i /etc/hosts -s -f -V -S services  -o
X       out
X
X       strobe  all  entries in /etc/hosts (identical ip addresses
X       are skipped automagically) using 120 sockets in  parallel,
X       but  only check the individual tcp ports mentioned in ser-
X       vices.  If we have probed up to port 80 on a host and have
X       still not yet evidenced a connection, then skip that host.
X       Display speed/time statistics for each host  and  for  the
X       totality  of  hosts to stderr. Place the regular output in
X       out.
X
X       ypcat hosts | strobe -p 80 -t 2 -A 203.4.184.1 -P 53
X
X       strobe all hosts  in  your  hosts  YP/NIS-table  for  WWW-
X       servers.  Use  a  timeout  of two seconds.  Set the source
X       address to the 203.4.184.1 interface. Make all  connection
X       requests appear to come from port 53 (DNS).
X
BUGS
X       Strobe performs no other security functions (yet) and does
X       not verify route blocking against  UDP  or  TCP  handshake
X       sequence guessing one-way IP spoofing attacks.
X
AUTHOR
X       Julian Assange
X
X              EMAIL:
X                   strobe@suburbia.net
X                   proff@suburbia.net
X
OFFICAL DISTRIBUTION
X       ftp://suburbia.net:/pub/strobe.tgz
X
COPYRIGHT
X       Copyright (c) Julian Assange 1995, All rights reserved.
X
X       This  software  maybe distributed only freely, in full and
X       without modification.  It may not be bundled with any sort
X       of hardware or software if a fee is charged for that hard-
X       ware or software directly or indirectly, in  whole  or  in
X       part. If you would like to include this software in such a
X       distribution then please contact the author  to  negotiate
X       reasonable (possibly free) terms.
X
X       The  author  shall  not under any circumstances accept any
X       liability for this software, for its use, misuse,  or  any
X       failings it may have. Your on your own.
X
X       The  author  reserves the right to alter the aformentioned
X       conditions from time to time as he sees  appropriate.  The
X       author's  most  recent copyright notice and conditions for
X       this software always supersede any issued previously.
X
X       Use and or distribution of this  software  implies  accep-
X       tance of the above.
X
X       So there.
X
X
SEE ALSO
X       nslookup(1),  host(1),  dig(1),  socket(2),  bind(2), con-
X       nect(2), iss(1).
SHAR_EOF
  $shar_touch -am 1127203895 'POST' &&
  chmod 0644 'POST' ||
  echo 'restore of POST failed'
  shar_count="`wc -c < 'POST'`"
  test 9432 -eq "$shar_count" ||
    echo "POST: original size 9432, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= strobe.man ==============
if test -f 'strobe.man' && test X"$1" != X"-c"; then
  echo 'x - skipping strobe.man (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting strobe.man (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'strobe.man' &&
X
X
X
STROBE 1.03(1)                                     STROBE 1.03(1)
X
X
NAME
X       strobe - Super optimized TCP port surveyor
X
SYNOPSIS
X       strobe [ -vVmdbepPAtnSilfsaM ] [host1 ... [hostn]]
X
DESCRIPTION
X       strobe   is  a  network/security  tool  that  locates  and
X       describes all listening tcp ports on a (remote) host or on
X       many hosts in a bandwidth utilisation maximising, and pro-
X       cess resource minimizing manner.
X
X       strobe approximates a parallel finite state machine inter-
X       nally. In non-linear multi-host mode it attempts to appor-
X       tion bandwidth and sockets amoung  the  hosts  very  effi-
X       ciently.   This  can  reap  appreciable gains in speed for
X       multiple distinct hosts/routes.
X
X       On a machine with a reasonable number of  sockets,  strobe
X       is  fast  enough to port scan entire Internet sub domains.
X       It is even possible to survey an entire small country in a
X       reasonable  time  from a fast machine on the network back-
X       bone, provided the machine in question uses dynamic socket
X       allocation   or  has  had  its  static  socket  allocation
X       increased very appreciably (check your kernel options). In
X       this  very limited application strobe is said to be faster
X       than ISS2.1 (a high quality commercial security scanner by
X       cklaus@iss.net  and friends) or PingWare (also comercial).
X
OPTIONS
X       -v     Verbose output.
X
X       -V     Verbose statistical output.
X
X       -m     Minimise output. Only print hostname, port  tuples.
X              Implies -d.  Useful for automated output parsing.
X
X       -d     Delete duplicate entries for port descriptions. i.e
X              use only the first definition.
X
X       -g     Disable usage of getpeername(2).   On  solaris  2.3
X              machines  this  causes  a  core  dump,  for reasons
X              unknown. This behavior is fixed with  solaris  2.4.
X              Under  Linux, HP and perhaps other unix implimenta-
X              tions, false tcp connection  positives  may  occurr
X              when this option is activated.
X
X       -s     Statistical  information  describing the average of
X              all hosts surveyed is sent to stderr on completion.
X
X       -q     Quiet mode. Don't print non-fatal errors or the (c)
X              message.
X
X       -d     Display only the  first  description  in  the  port
X
X
X
X                                                                1
X
X
X
X
X
STROBE 1.03(1)                                     STROBE 1.03(1)
X
X
X              services entry file (Cf.  -B).
X
X       -o file
X              Direct  output  (but  not any messages which can be
X              affected by -q) to file.
SHAR_EOF
  : || echo 'restore of strobe.man failed'
fi
echo 'End of archive part 1'
echo 'File strobe.man is continued in part 2'
echo 2 > _sharseq.tmp
exit 0


