pnscan-1.11.orig/0040755000076400007640000000000007447652767012031 5ustar olaolapnscan-1.11.orig/TODO0100644000076400007640000000003207446644222012473 0ustar olaolaIPv6 support? UDP scans? pnscan-1.11.orig/bm.c0100644000076400007640000000623507447650647012571 0ustar olaola/* Boyer-Moore string search as found on the internet using Google */ #include #include #include #include #include "bm.h" #define MAX(a,b) ((a) < (b) ? (b) : (a)) static void preBmBc(unsigned char *x, int m, int bmBc[]) { int i; for (i = 0; i < BM_ASIZE; ++i) bmBc[i] = m; for (i = 0; i < m - 1; ++i) bmBc[x[i]] = m - i - 1; } static void suffixes(unsigned char *x, int m, int *suff) { int f, g, i; f = 0; suff[m - 1] = m; g = m - 1; for (i = m - 2; i >= 0; --i) { if (i > g && suff[i + m - 1 - f] < i - g) suff[i] = suff[i + m - 1 - f]; else { if (i < g) g = i; f = i; while (g >= 0 && x[g] == x[g + m - 1 - f]) --g; suff[i] = f - g; } } } static int preBmGs(unsigned char *x, int m, int bmGs[]) { int i, j, *suff; suff = (int *) calloc(sizeof(int), m); if (suff == NULL) return -1; suffixes(x, m, suff); for (i = 0; i < m; ++i) bmGs[i] = m; j = 0; for (i = m - 1; i >= -1; --i) if (i == -1 || suff[i] == i + 1) for (; j < m - 1 - i; ++j) if (bmGs[j] == m) bmGs[j] = m - 1 - i; for (i = 0; i <= m - 2; ++i) bmGs[m - 1 - suff[i]] = m - 1 - i; free(suff); return 0; } int bm_init(BM *bmp, unsigned char *x, int m, int icase) { int i; memset(bmp, 0, sizeof(bmp)); bmp->icase = icase; bmp->bmGs = (int *) calloc(sizeof(int), m); if (bmp->bmGs == NULL) return -1; bmp->saved_m = m; bmp->saved_x = (unsigned char *) malloc(m); if (bmp->saved_x == NULL) return -2; for (i = 0; i < m; i++) bmp->saved_x[i] = icase ? tolower(x[i]) : x[i]; /* Preprocessing */ if (preBmGs(bmp->saved_x, m, bmp->bmGs) < 0) return -3; preBmBc((unsigned char *) bmp->saved_x, m, bmp->bmBc); return 0; } void bm_destroy(BM *bmp) { if (bmp->bmGs) free(bmp->bmGs); if (bmp->saved_x) free(bmp->saved_x); } /* Search for matches ** ** If mfun is defined, then call this function for each match. ** If mfun returns anything else but 0 abort the search. If the ** returned value is < 0 then return this value, else return the ** number of matches (so far). ** ** If mfun is NULL then stop at first match and return the position */ int bm_search(BM *bmp, unsigned char *y, int n, int (*mfun)(void *buf, int n, int pos)) { int i, j, c; int nm = 0; /* Searching */ j = 0; while (j <= n - bmp->saved_m) { for (i = bmp->saved_m - 1; i >= 0 && bmp->saved_x[i] == (bmp->icase ? tolower(y[i + j]) : y[i + j]); --i) ; if (i < 0) { if (mfun) { ++nm; c = mfun(y, n, j); if (c) return (c < 0 ? c : nm); j += bmp->bmGs[0]; } else return j; } else { unsigned char c = (bmp->icase ? tolower(y[i + j]) : y[i + j]); j += MAX(bmp->bmGs[i], bmp->bmBc[c] - bmp->saved_m + 1 + i); } } return mfun == NULL ? -1 : nm; } #if 0 int main(int argc, char *argv[]) { int pos; bm_setup(argv[1], strlen(argv[1])); pos = bm_search(argv[2], strlen(argv[2])); printf("Match at pos %d\n", pos); exit(0); } #endif pnscan-1.11.orig/bm.h0100644000076400007640000000071407447104457012563 0ustar olaola#ifndef PNSCAN_BM_H #define PNSCAN_BM_H #define BM_ASIZE 256 /* Allowed character code values */ typedef struct { int xsize; int *bmGs; int bmBc[BM_ASIZE]; unsigned char *saved_x; int saved_m; int icase; } BM; extern int bm_init(BM *bmp, unsigned char *x, int m, int icase); extern int bm_search(BM *bmp, unsigned char *y, int n, int (*mfun)(void *buf, int n, int pos)); extern void bm_destroy(BM *bmp); #endif pnscan-1.11.orig/Makefile0100644000076400007640000000322607447651262013456 0ustar olaola# Makefile for pnscan DESTDIR=/usr/local BINDIR=$(DESTDIR)/bin MANDIR=$(DESTDIR)/man MAN1DIR=$(MANDIR)/man1 TAR=tar GZIP=gzip MAKE=make INSTALL=./install-sh ## Solaris 8 with Gcc 3.0 GSO_CC=gcc -Wall -g -O -pthreads GSO_LDOPTS= GSO_LIBS= -lnsl -lsocket ## Solaris 8 with Forte C 6.2 SOL_CC=cc -mt -O SOL_LDOPTS= SOL_LIBS= -lpthread -lnsl -lsocket ## Linux 2.4 with Gcc 2.96 LNX_CC=gcc -Wall -g -O LNX_LDOPTS=-Wl,-s LNX_LIBS=-lpthread -lnsl OBJS = pnscan.o bm.o version.o default: @echo 'Use "make SYSTEM" where SYSTEM may be:' @echo ' lnx (Linux with GCC)' @echo ' gso (Solaris with GCC v3)' @echo ' sol (Solaris with Forte C)' @exit 1 lnx linux: @$(MAKE) all CC="$(LNX_CC)" LIBS="$(LNX_LIBS)" LDOPTS="$(LNX_LDOPTS)" gso: @$(MAKE) all CC="$(GSO_CC)" LIBS="$(GSO_LIBS)" LDOPTS="$(GSO_LDOPTS)" sol solaris: @$(MAKE) all CC="$(SOL_CC)" LIBS="$(SOL_LIBS)" LDOPTS="$(SOL_LDOPTS)" all: pnscan man: pnscan.1 ipsort.1 pnscan.1: pnscan.sgml docbook2man pnscan.sgml ipsort.1: ipsort.sgml docbook2man ipsort.sgml pnscan: $(OBJS) $(CC) $(LDOPTS) -o pnscan $(OBJS) $(LIBS) version: (PACKNAME=`basename \`pwd\`` ; echo 'char version[] = "'`echo $$PACKNAME | cut -d- -f2`'";' >version.c) clean distclean: -rm -f *.o *~ pnscan core manpage.* \#* dist: distclean version (PACKNAME=`basename \`pwd\`` ; cd .. ; $(TAR) cf - $$PACKNAME | $(GZIP) -9 >$$PACKNAME.tar.gz) install: install-bin install-man install-bin: all $(INSTALL) -c -m 755 pnscan $(BINDIR) $(INSTALL) -c -m 755 ipsort $(BINDIR) install-man: man $(INSTALL) -c -m 644 pnscan.1 $(MAN1DIR) $(INSTALL) -c -m 644 ipsort.1 $(MAN1DIR) install-all install-distribution: install pnscan-1.11.orig/LICENSE0100644000076400007640000000047107446575506013027 0ustar olaolaThis program is free software; you can redistribute it and/or modify it as you wish - as long as you don't claim that you wrote it. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. pnscan-1.11.orig/ipsort.sgml0100644000076400007640000000641407447652702014224 0ustar olaola manpage.1'. You may view the manual page with: `docbook-to-man manpage.sgml | nroff -man | less'. A typical entry in a Makefile or Makefile.am is: manpage.1: manpage.sgml docbook-to-man $< > $@ The docbook-to-man binary is found in the docbook-to-man package. Please remember that if you create the nroff version in one of the debian/rules file targets (such as build), you will need to include docbook-to-man in your Build-Depends control field. --> Peter"> Eriksson"> March 22, 2002"> 1"> pen@lysator.liu.se"> ipsort"> Debian"> GNU"> ]>
&dhemail;
&dhfirstname; &dhsurname; 2002 &dhusername; &dhdate;
&dhucpackage; &dhsection; &dhpackage; sort a file using IPv4 addresses at the beginning of each line. &dhpackage; filename DESCRIPTION This manual page documents briefly the &dhpackage; command. &dhpackage; is a tool that can sort a file using IPv4 addresses at the beginning of each line. It is implemented as a shell script front end to the normal sort command. SEE ALSO pnscan (1) and sort (1). AUTHOR &dhpackage; was written by &dhusername; &dhemail;. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts.
pnscan-1.11.orig/README0100644000076400007640000001003007446714361012664 0ustar olaolapnscan - a Parallell Network Scanner Copyright (c) 2002 Peter Eriksson ---------------------------------------------------------------------- This program is free software; you can redistribute it and/or modify it as you wish - as long as you don't claim that you wrote it. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ---------------------------------------------------------------------- INTRODUCTION Pnscan is a tool that can be used to survey TCP network services. For example, it can be used to survey the installed versions of SSH, FTP, SMTP, Web, IDENT and possibly other services. The latest version of pnscan can always be downloaded from: ftp://ftp.lysator.liu.se/pub/unix/pnscan There is also a small web page about it at: http://www.lysator.liu.se/~pen/pnscan If you like it then I'd gladly accept a nice bottle of whisky, some free beer or even just a "Thank you!" email :-) INSTALLATION Possibly edit the "Makefile" and the run 'make ' where currently may be: lnx Linux with GCC v2 gso Solaris with GCC v3 sol Solaris with Forte C When it has been built you can install it with "make install-all". It will by default install in /usr/local/bin and /usr/local/man/man1 USAGE Start pnscan with "-h" for online help. pnscan tries to be smart as to how many threads to start - it will dynamically start only as many as is needed to make progress in the scan - up to a maximum either as specified with the "-n" command line option, or 8 minus the maximum number of available file descriptors (pnscan tries to increase it to the max limit automatically) - or any internal limit on the system (Linux normally only allows 256 threads). Host ranges can be specified both as a CIDR - network name or IP address / mask bit length and as a range. When using CIDR notation - the first and last address is ignored (normally used for broadcasts) Some examples: 192.168.0.0/24 192.160.0.1:192.160.0.254 arpanet/8 The CIDR names are looked up in "networks" (/etc/networks or the YP/NIS+/whatever equivalent). The host ranges can also be specified as a range (or a single address) of hostnames or IP addresses: some.where.com:otherplace.where.com 192.168.10.27:192.168.11.194 localhost Service/Port ranges can be specified both via symbolic names looked up in "services" (/etc/services or YP/NIS+/whatever equivalent) or as numbers: ssh:telnet 22:23 113 The strings used with "-w" and "-r" may contain escaped characters. NUL characters are legal (\0) to use. pnscan by default will start printing the output from the first line recevied - *or* from the start of a match with "-r" (or from the first line of the first match if used with the "-l" option). EXAMPLES # Scan network 192.168.0.0/24 for SSH daemons on port 22 pnscan 192.168.0.0/24 22 pnscan 192.168.0.1:192.168.0.254 ssh # Scan hosts 192.168.10.34 ... 98 for IDENT servers, max 8 threads pnscan -n8 -w"VERSION" 192.168.10.34:192.168.10.98 113 # Scan host 127.0.0.1 for WWW servers on all ports pnscan -w"HEAD / HTTP/1.0\r\n\r\n" -r"Server:" 192.168.0.32 1:65525 pnscan -w"HEAD / HTTP/1.0\r\n\r\n" -r"Server:" localhost 1:65525 # Send binary data and expect the binary sequence FF 00 FF on port 145. pnscan -W"05 5A 37" -R"FF 00 FF" 192.168.0.32 145 # Scan for Roxen servers and print the whole Server-line pnscan -l -w"HEAD / HTTP/1.0\r\n\r\n" -r"Roxen" localhost 1:65525 # Scan for pidentd servers and try to locate the version pnscan -w"VERSION" 192.160.0.0/24 113 # Scan network arpanet/24 for daytime servers and sort them IP-numerically pnscan arpanet/10 daytime | ipsort # Read host (&port) lines from stdin and scan the selected hosts for SSH echo '192.160.10.11 ssh' | pnscan -v echo '192.160.10.12' | pnscan 22 WARNING Scanning of networks of which you do not have explicit permission to do probably will be considered abuse of network resources and may cause problems for you. So *please* use this tool with great care. pnscan-1.11.orig/pnscan.10100644000076400007640000000434407447652576013375 0ustar olaola.\" This manpage has been automatically generated by docbook2man .\" from a DocBook document. This tool can be found at: .\" .\" Please send any bug reports, improvements, comments, patches, .\" etc. to Steve Cheng . .TH "PNSCAN" "1" "25 March 2002" "" "" .SH NAME pnscan \- multi threaded port scanning tool .SH SYNOPSIS \fBpnscan\fR [ \fBoptions\fR] [ \fB \fR] \fBpnscan\fR [ \fBoptions\fR] [ \fB\fR] .SH "DESCRIPTION" .PP This manual page documents briefly the \fBpnscan\fR command. .PP \fBpnscan\fR is a tool that can be used to survey TCP network services. .PP When used with two command line arguments it will scan the indicated network/hosts and ports. When used without arguments or just one then it will read hostname/IP addresses from stdin and probe those. The single port/service argument is used as a default if no port is indicated on stdin .PP For example, it can be used to survey the installed versions of SSH, FTP, SMTP, Web, IDENT and possibly other services. .PP This program implements a multithreaded TCP port scanner. More information and new relaseses may be found at: http://www.lysator.liu.se/~pen/pnscan .SH "OPTIONS" .TP \fB-h\fR Show summary of options. .TP \fB-v\fR Be verbose. .TP \fB-V\fR Print version. .TP \fB-d\fR Print debugginf info. .TP \fB-s \fR Lookup and print hostnames. .TP \fB-S\fR Enable shutdown mode. .TP \fB-l\fR Line oriented output. .TP \fB-w \fR Request string to send. .TP \fB-r \fR Response string to look for. .TP \fB-W \fR Hex coded request string to send. .TP \fB-R \fR Hex coded response string to look for. .TP \fB-L \fR Max bytes of response to print. .TP \fB-t \fR Connect/Write/Read timeout. .TP \fB-n \fR Concurrent worker threads. .SH "SEE ALSO" .PP nmap (1) and ipsort (1). .SH "AUTHOR" .PP pnscan was written by Peter Eriksson . .PP Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts. pnscan-1.11.orig/pnscan.c0100644000076400007640000004736307447651060013452 0ustar olaola/* ** pnscan.c - Parallell Network Scanner ** ** Copyright (c) 2002 Peter Eriksson ** ** This program is free software; you can redistribute it and/or ** modify it as you wish - as long as you don't claim that you wrote ** it. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "bm.h" #define RESPONSE_MAX_SIZE 1024 extern char version[]; unsigned char *wstr = NULL; int wlen = 0; unsigned char *rstr = NULL; int rlen = 0; int debug = 0; int verbose = 0; int stop = 0; int tworkers = 1; /* Currently running worker threads */ int mworkers = 1; /* Peak started concurrent worker threads */ int aworkers = 0; /* Currently active probing worker threads */ int nworkers = 0; /* Max concurrent worker threads */ int timeout = 1000; /* ms */ int pr_sym = 0; int line_f = 0; int use_shutdown = 0; int maxlen = 64; int first_port = 0; int last_port = 0; unsigned long first_ip = 0x00000000; unsigned long last_ip = 0xFFFFFFFF; pthread_mutex_t cur_lock; unsigned long cur_ip; int cur_port; pthread_mutex_t print_lock; int ignore_case = 0; BM bmb; void print_version(FILE *fp) { fprintf(fp, "[PNScan, version %s - %s %s]\n", version, __DATE__, __TIME__); } int get_char_code(unsigned char **cp, int base) { int val = 0; int len = 0; while (len < (base == 16 ? 2 : 3) && ((**cp >= '0' && **cp < '0'+(base > 10 ? 10 : base)) || (base >= 10 && toupper(**cp) >= 'A' && toupper(**cp) < 'A'+base-10))) { val *= base; if (**cp >= '0' && **cp < '0'+(base > 10 ? 10 : base)) val += **cp - '0'; else if (base >= 10 && toupper(**cp) >= 'A' && toupper(**cp) < 'A'+base-10) val += toupper(**cp) - 'A' + 10; ++*cp; ++len; } return val & 0xFF; } int dehex(unsigned char *str) { unsigned char *wp, *rp; int val; rp = wp = str; while (*rp) { while (*rp && isspace(* (unsigned char *) rp)) ++rp; if (*rp == '\0') break; if (!isxdigit(* (unsigned char *) rp)) return -1; val = get_char_code(&rp, 16); *wp++ = val; } *wp = '\0'; return wp - str; } int deslash(unsigned char *str) { unsigned char *wp, *rp; rp = wp = str; while (*rp) { if (*rp != '\\') *wp++ = *rp++; else { switch (*++rp) { case 'n': *wp++ = 10; ++rp; break; case 'r': *wp++ = 13; ++rp; break; case 't': *wp++ = 9; ++rp; break; case 'b': *wp++ = 8; ++rp; break; case 'x': ++rp; *wp++ = get_char_code(&rp, 16); break; case '0': *wp++ = get_char_code(&rp, 8); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': *wp++ = get_char_code(&rp, 10); break; default: *wp++ = *rp++; break; } } } *wp = '\0'; return wp-str; } void print_host(FILE *fp, struct in_addr in, int port) { struct hostent *hep = NULL; if (pr_sym) { hep = gethostbyaddr((const char *) &in, sizeof(in), AF_INET); fprintf(fp, "%-15s : %-40s : %5d", inet_ntoa(in), hep ? hep->h_name : "(unknown)", port); } else fprintf(fp, "%-15s : %5d", inet_ntoa(in), port); } int t_write(int fd, unsigned char *buf, int len) { int tw, wl, code; struct pollfd pfd; tw = len; while (tw > 0) { pfd.fd = fd; pfd.events = POLLOUT; pfd.revents = 0; while ((code = poll(&pfd, 1, timeout)) < 0 && errno == EINTR) errno = 0; if (code == 0) { code = -1; errno = ETIMEDOUT; } while ((wl = write(fd, buf, tw)) < 0 && errno == EINTR) ; if (wl < 0) return wl; tw -= wl; buf += wl; } return len; } int t_read(int fd, unsigned char *buf, int size) { int len, code; struct pollfd pfd; pfd.fd = fd; pfd.events = POLLIN; pfd.revents = 0; while ((code = poll(&pfd, 1, timeout)) < 0 && errno == EINTR) errno = 0; if (code == 0) { errno = ETIMEDOUT; return -1; } while ((len = read(fd, buf, size)) < 0 && errno == EINTR) ; return len; } int is_text(unsigned char *cp, int slen) { while (slen > 0 && (isprint(*cp) || *cp == '\0' || *cp == '\t' || *cp == '\n' || *cp == '\r')) { --slen; ++cp; } return slen == 0; } int print_output(unsigned char *str, int slen) { unsigned char *cp = str; int len; len = 0; if (str == NULL) { printf("NULL"); return len; } if (slen >= 2 && cp[0] == IAC && cp[1] >= xEOF) { printf("TEL : "); while (len < slen && len < maxlen) { if (*cp == IAC) { ++len; printf(""); switch (*++cp) { case 0: return len; case DONT: printf(""); break; case DO: printf(""); break; case WONT: printf(""); break; case WILL: printf(""); break; case SB: printf(""); break; case GA: printf(""); break; case EL: printf(""); break; case EC: printf(""); break; case AYT: printf(""); break; case AO: printf(""); break; case IP: printf(""); break; case BREAK: printf(""); break; case DM: printf(""); break; case NOP: printf(""); break; case SE: printf(""); break; case EOR: printf(""); break; case ABORT: printf(""); break; case SUSP: printf(""); break; case xEOF: printf(""); break; default: printf("<0x%02X>", *cp); } } else if (isprint(*cp)) putchar(*cp); else { switch (*cp) { case '\n': if (line_f) return len; printf("\\n"); break; case '\r': if (line_f) return len; printf("\\r"); break; case '\t': printf("\\t"); break; case '\0': printf("\\0"); break; default: printf("\\x%02X", *cp); } } ++len; ++cp; } } else if (is_text(str, slen)) { printf("TXT : "); while (len < slen && len < maxlen) { if (isprint(* (unsigned char *) str)) putchar(*str); else switch (*str) { case '\0': printf("\\0"); break; case '\n': if (line_f) return len; printf("\\n"); break; case '\r': if (line_f) return len; printf("\\r"); break; case '\t': printf("\\t"); break; default: printf("\\x%02x", * (unsigned char *) str); } ++len; ++str; } } else { printf("HEX :"); while (len < slen && len < maxlen) { printf(" %02x", * (unsigned char *) str); ++len; ++str; } } return len; } int probe(unsigned long addr, int port) { int fd, code, len; struct sockaddr_in sin; unsigned char buf[RESPONSE_MAX_SIZE]; struct pollfd pfd; fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) return -1; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(port); sin.sin_addr.s_addr = htonl(addr); code = fcntl(fd, F_GETFL, 0); if (code < 0) { close(fd); return -1; } #ifdef FNDELAY code = fcntl(fd, F_SETFL, code|FNDELAY); #else code = fcntl(fd, F_SETFL, code|O_NONBLOCK); #endif if (code < 0) { close(fd); return -1; } while ((code = connect(fd, (struct sockaddr *) &sin, sizeof(sin))) < 0 && errno == EINTR) errno = 0; if (code < 0 && errno == EINPROGRESS) { pfd.fd = fd; pfd.events = POLLOUT; pfd.revents = 0; while ((code = poll(&pfd, 1, timeout)) < 0 && errno == EINTR) errno = 0; if (code == 0) { code = -1; errno = ETIMEDOUT; } } if (code < 0) { if (verbose) { pthread_mutex_lock(&print_lock); print_host(stderr, sin.sin_addr, port); fprintf(stderr, " : ERR : connect() failed: %s\n", strerror(errno)); pthread_mutex_unlock(&print_lock); } close(fd); return 0; } if (wstr) { code = t_write(fd, wstr, wlen); if (code < 0) { if (verbose) { pthread_mutex_lock(&print_lock); print_host(stderr, sin.sin_addr, port); fprintf(stderr, " : ERR : write() failed: %s\n", strerror(errno)); pthread_mutex_unlock(&print_lock); } close(fd); return 0; } } if (use_shutdown) shutdown(fd, 1); while ((len = t_read(fd, buf, sizeof(buf)-1)) < 0 && errno == EINTR) ; if (len < 0) { if (verbose) { pthread_mutex_lock(&print_lock); print_host(stderr, sin.sin_addr, port); fprintf(stderr, " : ERR : read() failed: %s\n", strerror(errno)); pthread_mutex_unlock(&print_lock); } close(fd); return -1; } buf[len] = '\0'; if (rstr) { int pos; pos = bm_search(&bmb, buf, len, NULL); if (pos >= 0) { if (line_f) while (pos > 0 && !(buf[pos-1] == '\n' || buf[pos-1] == '\r')) --pos; pthread_mutex_lock(&print_lock); print_host(stdout, sin.sin_addr, port); printf(" : "); print_output(buf+pos, len-pos); putchar('\n'); pthread_mutex_unlock(&print_lock); } } else { pthread_mutex_lock(&print_lock); print_host(stdout, sin.sin_addr, port); printf(" : "); print_output(buf, len); putchar('\n'); pthread_mutex_unlock(&print_lock); } close(fd); return 1; } void * r_worker(void *arg) { unsigned long addr; int port; pthread_t tid; pthread_mutex_lock(&cur_lock); while (!stop) { if (cur_ip <= last_ip) { port = cur_port; addr = cur_ip++; } else { if (cur_port >= last_port) { stop = 1; break; } port = ++cur_port; addr = cur_ip = first_ip; } if (aworkers >= tworkers-1 && tworkers < nworkers) { ++tworkers; if (pthread_create(&tid, NULL, r_worker, NULL) != 0) { --tworkers; nworkers = tworkers; } if (tworkers > mworkers) mworkers = tworkers; } ++aworkers; pthread_mutex_unlock(&cur_lock); probe(addr, port); pthread_mutex_lock(&cur_lock); --aworkers; } --tworkers; pthread_mutex_unlock(&cur_lock); fflush(stdout); return NULL; } int get_host(char *str, unsigned long *ip) { struct hostent *hep; unsigned long tip; hep = gethostbyname(str); if (hep && hep->h_addr_list &&hep->h_addr_list[0]) { tip = * (unsigned long *) (hep->h_addr_list[0]); *ip = ntohl(tip); return 1; } return inet_pton(AF_INET, str, ip); } int get_service(char *str, int *pp) { struct servent *sep; sep = getservbyname(str, "tcp"); if (sep) { *pp = ntohs(sep->s_port); return 1; } if (sscanf(str, "%u", pp) != 1) return -1; if (*pp < 1 || *pp > 65535) return 0; return 1; } void * f_worker(void *arg) { unsigned long addr; int port, code; char buf[1024]; char *host; char *serv; char *tokp; pthread_t tid; pthread_mutex_lock(&cur_lock); while (!stop) { if (fgets(buf, sizeof(buf), stdin) == NULL) { if (debug) fprintf(stderr, "*** GOT EOF ***\n"); stop = 1; break; } host = strtok_r(buf, " \t\n\r", &tokp); serv = strtok_r(NULL, " \t\n\r", &tokp); if (host == NULL || host[0] == '#') continue; if (get_host(host, &addr) != 1) { if (verbose) fprintf(stderr, "%s: invalid host\n", host); continue; } if (serv == NULL) { if (first_port == 0) { if (verbose) fprintf(stderr, "%s: missing service specification\n", host); continue; } port = first_port; } else { code = get_service(serv, &port); if (code != 1) { if (verbose) fprintf(stderr, "%s: invalid service (code=%d)\n", serv, code); continue; } } if (aworkers >= tworkers-1 && tworkers < nworkers) { ++tworkers; if (pthread_create(&tid, NULL, f_worker, NULL) != 0) { --tworkers; nworkers = tworkers; } if (tworkers > mworkers) mworkers = tworkers; } ++aworkers; pthread_mutex_unlock(&cur_lock); probe(addr, port); pthread_mutex_lock(&cur_lock); --aworkers; } --tworkers; pthread_mutex_unlock(&cur_lock); fflush(stdout); return NULL; } char *argv0 = "pnscan"; void usage(FILE *out) { fprintf(out, "Usage: %s [] [{| } | ]\n", argv0); fputs("\n\ This program implements a multithreaded TCP port scanner.\n\ More information may be found at:\n\ \thttp://www.lysator.liu.se/~pen/pnscan\n\ \n\ Command line options:\n", out); fprintf(out, "\t-h Display this information.\n"); fprintf(out, "\t-V Print version.\n"); fprintf(out, "\t-v Be verbose.\n"); fprintf(out, "\t-d Print debugging info.\n"); fprintf(out, "\t-s Lookup and print hostnames.\n"); fprintf(out, "\t-i Ignore case when scanning responses.\n"); fprintf(out, "\t-S Enable shutdown mode.\n"); fprintf(out, "\t-l Line oriented output.\n"); fprintf(out, "\t-w Request string to send.\n"); fprintf(out, "\t-W Hex coded request string to send.\n"); fprintf(out, "\t-r Response string to look for.\n"); fprintf(out, "\t-R Hex coded response string to look for.\n"); fprintf(out, "\t-L Max bytes to print.\n"); fprintf(out, "\t-t Connect/Write/Read timeout.\n"); fprintf(out, "\t-n Concurrent worker threads limit.\n"); } int get_network(char *str, unsigned long *np) { struct netent *nep; struct in_addr ia; nep = getnetbyname(str); if (nep) { ia = inet_makeaddr(nep->n_net, 0); *np = ntohl(ia.s_addr); return 1; } return inet_pton(AF_INET, str, np); } int get_ip_range(char *str, unsigned long *first_ip, unsigned long *last_ip) { char first[1024], last[1024]; int len; unsigned long ip; unsigned long mask = 0; if (sscanf(str, "%1023[^/ ] / %u", first, &len) == 2) { /* CIDR */ if (get_network(first, &ip) != 1 || len < 0 || len > 32) return -1; ip = ntohl(ip); *first_ip = ip+1; len = 32-len; while (len-- > 0) mask = ((mask << 1)|1); *last_ip = (ip|mask)-1; return 2; } switch (sscanf(str, "%1023[^: ] : %1023s", first, last)) { case 1: if (get_host(first, first_ip) != 1) return -1; *last_ip = *first_ip; return 1; case 2: if (get_host(first, first_ip) != 1) return -1; if (get_host(last, last_ip) != 1) return -1; return 2; } return -1; } int get_port_range(char *str, int *first_port, int *last_port) { char first[256], last[256]; switch (sscanf(str, "%255[^: ] : %255s", first, last)) { case 1: if (strcmp(first, "all") == 0) { *first_port = 1; *last_port = 65535; return 2; } if (get_service(first, first_port) != 1) return -1; *last_port = *first_port; return 1; case 2: if (get_service(first, first_port) != 1) return -1; if (get_service(last, last_port) != 1) return -1; return 2; } return -1; } void e_fun(void) { printf("mworkers = %d, tworkers = %d, aworkers = %d, nworkers = %d\n", mworkers, tworkers, aworkers, nworkers); } int main(int argc, char *argv[]) { int i, j; struct rlimit rlb; char *arg; argv0 = argv[0]; setlocale(LC_CTYPE, ""); first_port = 0; last_port = 0; getrlimit(RLIMIT_NOFILE, &rlb); rlb.rlim_cur = rlb.rlim_max; setrlimit(RLIMIT_NOFILE, &rlb); signal(SIGPIPE, SIG_IGN); nworkers = rlb.rlim_cur - 8; if (nworkers > 1024) nworkers = 1024; pthread_mutex_init(&cur_lock, NULL); pthread_mutex_init(&print_lock, NULL); for (i = 1; i < argc && argv[i][0] == '-'; i++) for (j = 1; j > 0 && argv[i][j]; ++j) switch (argv[i][j]) { case '-': ++i; goto EndOptions; case 'V': print_version(stdout); break; case 'd': ++debug; break; case 'i': ignore_case = 1; break; case 'v': ++verbose; break; case 'h': usage(stdout); exit(0); case 'l': ++line_f; break; case 's': ++pr_sym; break; case 'S': ++use_shutdown; break; case 'w': if (argv[i][2]) wstr = (unsigned char *) strdup(argv[i]+2); else wstr = (unsigned char *) strdup(argv[++i]); wlen = deslash(wstr); j = -2; break; case 'W': if (argv[i][2]) wstr = (unsigned char *) strdup(argv[i]+2); else wstr = (unsigned char *) strdup(argv[++i]); wlen = dehex(wstr); j = -2; break; case 'R': if (argv[i][2]) rstr = (unsigned char *) strdup(argv[i]+2); else rstr = (unsigned char *) strdup(argv[++i]); rlen = dehex(rstr); j = -2; break; case 'r': if (argv[i][2]) rstr = (unsigned char *) strdup(argv[i]+2); else rstr = (unsigned char *) strdup(argv[++i]); rlen = deslash(rstr); j = -2; break; case 'L': if (argv[i][2]) arg = argv[i]+2; else arg = argv[++i]; if (!arg || sscanf(arg, "%u", &maxlen) != 1) { fprintf(stderr, "%s: Invalid length specification: %s\n", argv[0], arg ? arg : ""); exit(1); } j = -2; break; case 't': if (argv[i][2]) arg = argv[i]+2; else arg = argv[++i]; if (!arg || sscanf(arg, "%u", &timeout) != 1) { fprintf(stderr, "%s: Invalid timeout specification: %s\n", argv[0], arg ? arg : ""); exit(1); } j = -2; break; case 'n': if (argv[i][2]) arg = argv[i]+2; else arg = argv[++i]; if (!arg || sscanf(arg, "%u", &nworkers) != 1) { fprintf(stderr, "%s: Invalid workers specification: %s\n", argv[0], arg ? arg : ""); exit(1); } j = -2; break; default: fprintf(stderr, "%s: unknown command line switch: -%c\n", argv[0], argv[i][j]); exit(1); } EndOptions: if (rstr) { if (bm_init(&bmb, rstr, rlen, ignore_case) < 0) { fprintf(stderr, "%s: Failed search string setup: %s\n", argv[0], rstr); exit(1); } } if (debug) atexit(e_fun); if (i == argc || i+1 == argc) { if (i + 1 == argc) get_service(argv[i], &first_port); f_worker(NULL); pthread_exit(NULL); return 1; /* Not reached */ } if (i + 2 != argc) { fprintf(stderr, "%s: Missing or extra argument(s). Use '-h' for help.\n", argv[0]); exit(1); } if (get_ip_range(argv[i], &first_ip, &last_ip) < 1) { fprintf(stderr, "%s: Invalid IP address range: %s\n", argv[0], argv[i]); exit(1); } if (get_port_range(argv[i+1], &first_port, &last_port) < 1) { fprintf(stderr, "%s: Invalid Port range: %s\n", argv[0], argv[i+1]); exit(1); } cur_ip = first_ip; cur_port = first_port; r_worker(NULL); pthread_exit(NULL); return 1; /* Not reached */ } pnscan-1.11.orig/ipsort.10100644000076400007640000000213407447652710013414 0ustar olaola.\" This manpage has been automatically generated by docbook2man .\" from a DocBook document. This tool can be found at: .\" .\" Please send any bug reports, improvements, comments, patches, .\" etc. to Steve Cheng . .TH "IPSORT" "1" "25 March 2002" "" "" .SH NAME ipsort \- sort a file using IPv4 addresses at the beginning of each line. .SH SYNOPSIS \fBipsort\fR\fB filename\fR .SH "DESCRIPTION" .PP This manual page documents briefly the \fBipsort\fR command. .PP \fBipsort\fR is a tool that can sort a file using IPv4 addresses at the beginning of each line. It is implemented as a shell script front end to the normal sort command. .SH "SEE ALSO" .PP pnscan (1) and sort (1). .SH "AUTHOR" .PP ipsort was written by Peter Eriksson . .PP Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts. pnscan-1.11.orig/install-sh0100755000076400007640000001273607447451153014025 0ustar olaola#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$cpprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 pnscan-1.11.orig/ipsort0100755000076400007640000000020407446644053013254 0ustar olaola#!/bin/sh # # Sort a file using IPv4 addresses in at the beginning of each line exec sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n "$@" pnscan-1.11.orig/pnscan.sgml0100644000076400007640000001501007447652521014155 0ustar olaola manpage.1'. You may view the manual page with: `docbook-to-man manpage.sgml | nroff -man | less'. A typical entry in a Makefile or Makefile.am is: manpage.1: manpage.sgml docbook-to-man $< > $@ The docbook-to-man binary is found in the docbook-to-man package. Please remember that if you create the nroff version in one of the debian/rules file targets (such as build), you will need to include docbook-to-man in your Build-Depends control field. --> Peter"> Eriksson"> March 22, 2002"> 1"> pen@lysator.liu.se"> pnscan"> Debian"> GNU"> ]>
&dhemail;
&dhfirstname; &dhsurname; 2002 &dhusername; &dhdate;
&dhucpackage; &dhsection; &dhpackage; multi threaded port scanning tool &dhpackage; <CIDR | host-range> <port-range> &dhpackage; DESCRIPTION This manual page documents briefly the &dhpackage; command. &dhpackage; is a tool that can be used to survey TCP network services. When used with two command line arguments it will scan the indicated network/hosts and ports. When used without arguments or just one then it will read hostname/IP addresses from stdin and probe those. The single port/service argument is used as a default if no port is indicated on stdin For example, it can be used to survey the installed versions of SSH, FTP, SMTP, Web, IDENT and possibly other services. This program implements a multithreaded TCP port scanner. More information and new relaseses may be found at: http://www.lysator.liu.se/~pen/pnscan OPTIONS Show summary of options. Be verbose. Print version. Print debugginf info. Lookup and print hostnames. Enable shutdown mode. Line oriented output. Request string to send. Response string to look for. Hex coded request string to send. Hex coded response string to look for. Max bytes of response to print. Connect/Write/Read timeout. Concurrent worker threads. SEE ALSO nmap (1) and ipsort (1). AUTHOR &dhpackage; was written by &dhusername; &dhemail;. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts.
pnscan-1.11.orig/ChangeLog0100644000076400007640000000041707447451153013564 0ustar olaola2002-03-24 Ola Lundqvist * pnscan.sgml Added the other options implemented in pnscan.c. 2002-03-22 Peter Eriksson * pnscan.c: Modified the threads startup code to dynamically only start as many threads as is needed. pnscan-1.11.orig/version.c0100644000076400007640000000003107447652767013651 0ustar olaolachar version[] = "1.11";