On Thursday 14 June 2007 23:27:04 Denis Vlasenko wrote:
> On Thursday 14 June 2007 16:12, Tito wrote:
> > > It's good that you added these comments,
> > > but explanation is not clear enough (at least for me).
> > > 
> > > Care to improve?
> > > --
> > > vda
> > > 
> > 
> > Here a new version of the patch with improved comments. Enjoy! ;-D
> > 
> > PS: fixed also a stupid typo in my_gettimeofday
> > if (!gettimeofday(&now, NULL)) ==> if (gettimeofday(&now, NULL))
> 
>                 s = xsocket(lsap->sa.sa_family, SOCK_STREAM, 0);
>                 ndelay_on(s);
>                 t1 = my_gettimeofday();
>                 connect(s, &lsap->sa, lsap->len);
> 
> Ok, here it can be successful, or can fail. You don't even look at return 
> value.
> It is useless or what?
> 
> These questions need to be explained in order to have understandable code.
> 
> Ok. I did a small experiment, added a few debug prints,
> and changed it to start scanning from port 79.
> 
> # ./busybox pscan -p 80 195.66.192.167 2>2
> Scanning 195.66.192.167 ports 1 to 80
>  Port   Proto   State   Service
>    80   tcp     open    www
> 78 stealth, 1 closed, 1 open ports
> 
> logfile:
> 
> pscan: connect 45us: Operation now in progress
> pscan: write:-1 4us
> pscan: write:-1 2us
> <15759 more write errors snipped>
> pscan: connect 31us: Operation now in progress
> pscan: write:-1 2us
> <~140000 more write errors snipped>
> pscan: write:1 18us
> 
> I don't like write() flood, with accompanying horde of gettimeofday calls.
> 
> Maybe this? (please see attched).
> --
> vda
> 

Looks good to me, added some of the TODOs and changed all the time to msec.
Please check if i fully understood your code. Sorry no time for a patch right 
now,
sending the file I've changed. If needed patch will follow tomorrow. ;-)

Ciao,
Tito
PS: change usage.h to

#define pscan_trivial_usage \
       "[-p MIN_PORT][-P MAX_PORT][-t MIN_RTT][-T TIMEOUT] HOST"
#define pscan_full_usage \
       " Scan a host's ports printing all open ports." \
       "\n\nOptions:\n" \
       "        -p      scan from this port (default 1)\n" \
       "        -P      scan up to this port (default 1024)\n" \
       "        -t      minimum roundtrip time in msec (default 1000)"\
       "        -T      timeout in msecs (default 5000)"
/*
 * Pscan is a mini port scanner implementation for busybox
 *
 * Copyright 2007 Tito Ragusa <[EMAIL PROTECTED]>
 *
 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
 */

#include "libbb.h"

 /* debugging */
#ifdef DEBUG
#define DMSG(...) bb_error_msg(__VA_ARGS__)
#define DERR(...) bb_perror_msg(__VA_ARGS__)
#else
#define DMSG(...) ((void)0)
#define DERR(...) ((void)0)
#endif

/* return time in msec */
static unsigned long my_gettimeofday(void)
{
	struct timeval now;
	
	if (gettimeofday(&now, NULL))
		return 0;
	return (now.tv_sec * 1000 + now.tv_usec / 1000);
}

static const char *my_getservbyport(int port)
{
	struct servent *server;

	server = getservbyport(htons(port), NULL);
	if (server)
		return server->s_name;
	return "unknown";
}

int pscan_main( int argc, char **argv);
int pscan_main( int argc, char **argv)
{
	const char *opt_max_port = "1024";          /* default max port */
	const char *opt_min_port = "1";             /* default min port */
	const char *opt_max_timeout = "5000";       /* arbitrary default max timeout for roundtrip: 5000 mseconds */
	const char *opt_min_timeout = "1000";       /* arbitrary default max timeout for roundtrip: 1000 mseconds */
	unsigned port;
	unsigned max_port;
	unsigned closed_ports = 0;
	unsigned open_ports = 0;
	long unsigned timeout;                           /* in us */
	long unsigned min_timeout;                       /* in us */
	long unsigned rtt;                               /* in us */
	long unsigned start;                             /* in us */
	int s;
	len_and_sockaddr *lsap;

	opt_complementary = "-1";
	getopt32(argc, argv, "p:P:t:T:", &opt_min_port, &opt_max_port, &opt_max_timeout, &opt_min_timeout);

	max_port =  xatou_range(opt_max_port, 1, 65535);
	port =  xatou_range(opt_min_port, 1, 65535);
	rtt = timeout = xatou_range(opt_max_timeout, 1, ULONG_MAX);
	min_timeout = xatou_range(opt_min_timeout, 1, ULONG_MAX);
	argv += optind;
	lsap = xhost2sockaddr(*argv, port);

	printf("Scanning %s ports 1 to %d\n Port\tProto\tState\tService\n", *argv, max_port);

	for (; port <= max_port; port++) {
		DMSG("rtt %lu", rtt);

		/* The SOCK_STREAM socket type is implemented on the TCP/IP protocol. */
		set_nport(lsap, htons(port));
		s = xsocket(lsap->sa.sa_family, SOCK_STREAM, 0);

		/* We need unblocking socket so we don't need to wait for ETIMEOUT. */
		/* Nonblocking connect typically "fails" with errno == EINPROGRESS */
		ndelay_on(s);
		DMSG("connect to port %u", port);
		start = my_gettimeofday();
		if (connect(s, &lsap->sa, lsap->len) == 0) {
			/* Unlikely, for me even localhost fails :) */
			DMSG("connect succeeded");
			goto open;
		}
		/* Check for untypical errors... */
		if (errno != EAGAIN && errno != EINPROGRESS
		 && errno != ECONNREFUSED
		) {
			bb_perror_nomsg_and_die();
		}

		while (1) {
			if (errno == ECONNREFUSED) {
				DMSG("port %u: ECONNREFUSED", port);
				closed_ports++;
				break;
			}
			DERR("port %u errno %d @%lu", port, errno, my_gettimeofday() - start);
			if ((my_gettimeofday() - start) > rtt)
				break;
			/* Can sleep (much) longer than this.
			 * We check rtt BEFORE we usleep, otherwise
			 * on localhost we'll do zero writes done (!)
			 * before we exceed (rather small) rtt */
			usleep(rtt/8);
			DMSG("write to port %u @%lu", port, my_gettimeofday() - start);
			if (write(s, " ", 1) >= 0) { /* We were able to write to the socket */
 open:
				open_ports++;
				printf("%5u\ttcp\topen\t%s\n", port, my_getservbyport(port));
				break;
			}
		}
		DMSG("out of loop @%lu", my_gettimeofday() - start);

		/* Estimate new rtt - we don't want to wait entire timeout
		 * for each port. *4 allows for rise in net delay.
		 * We increase rtt quickly (*4), decrease slowly (4/8 == 1/2)
		 * because we don't want to accidentally miss ports. */
		rtt = (my_gettimeofday() - start) * 4;
		if (rtt < min_timeout)
			rtt = min_timeout;
		if (rtt > timeout)
			rtt = timeout;
		/* Clean up */
		close(s);
	}
	if (ENABLE_FEATURE_CLEAN_UP) free(lsap);

	printf("%d closed, %d open, %d timed out ports\n",
					closed_ports,
					open_ports,
					max_port - (closed_ports + open_ports));
	return EXIT_SUCCESS;
}
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to