home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************/
- /* PORTSCANNER.C by Tennessee Carmel-Veilleux */
- /* Contact info: (I speak french and english :) */
- /* e-mail: veilleux@ameth.org */
- /* www: http://www.ameth.org/~veilleux */
- /* */
- /* Version 1.2 */
- /* The author of this program offers no waranty at all */
- /* about the correct execution of this software material. */
- /* Furthermore, the author can NOT be held responsible for */
- /* any physical or moral damage caused by the use of this */
- /* software. */
- /* */
- /* -> This program will scan for TCP ports listening on a */
- /* remote or local host inside the range you give to it.*/
- /* I offer no warranty over the accuracy though :) */
- /* There are 3 verbose modes: No info, service info, and*/
- /* full info. No info is good of you only want the list */
- /* of the ports, no more info. The best mode is Full */
- /* info, as you get error information,etc. The main */
- /* output is STDOUT, and ALL the errors go to STDERR. */
- /* */
- /* History: v1.0 : August 9 1998 -> First release */
- /* v1.2 : August 19 1998 -> Major release */
- /***********************************************************/
-
- #include <stdio.h>
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <unistd.h>
- #include <netdb.h>
- #include <sys/time.h>
- #include <fcntl.h>
- #include <arpa/inet.h>
- #include <string.h>
- #include <stdlib.h>
- #include <errno.h>
-
- #define VERSION "1.2"
-
- int sock = -1; /* Main socket */
- struct sockaddr_in address, address2; /* Address structure */
- struct sockaddr *sub_address; /* Address in subnet */
- int result; /* Temporary results for operations */
- u_short current_port = 0; /* Current port being scanned */
- u_short base_port = 1; /* Base port to start scanning from */
- u_short end_port = 1024; /* Port number to end scanning at */
- u_char start_address = 1; /* Subnet address to start at */
- u_char end_address = 254; /* Subnet address to finish at */
- int verbose = 0; /* Level of verbosity */
- struct hostent *host_info; /* Host information structure */
- struct servent *service_info; /* Service information structure */
- char addr[1024]; /* Address to connect to, 1024 chars max */
- int strobe = 0; /* 1 if we want strobe scanning */
- int subnet = 0; /* 1 if we want subnet scanning */
- int i; /* Counter variable */
-
- void port_scan(void);
- void print_usage(int finish);
- void print_help(int finish);
- void print_info(int finish);
-
- void print_usage(int finish) {
- fprintf(stderr,
- "Usage: portscan [-b start] [-e end] [-bm start] [-em end] [-v[v]] [-a] [-s] [-i] [-? | h] <address>\n");
- if (finish)
- exit(1);
- }
-
- void print_help(int finish) {
- print_usage(0);
- fprintf(stderr,"\n-b start: Specify the port at which we begin scanning\n");
- fprintf(stderr,"-e end: Specify the port at which we stop scanning\n");
- fprintf(stderr,"-bm: Subnet machine number at which to start scanning [dfl=1]\n");
- fprintf(stderr,"-em: Subnet machine number at which to stop scanning [dfl=254]\n");
- fprintf(stderr,"-v: Level 1 of verbosity, basic information\n");
- fprintf(stderr,"-vv: Level 2 of verbosity, full information report\n");
- fprintf(stderr,"-a: if we want subnet scanning (start at .1, end at .254)\n");
- fprintf(stderr,"-s: strobe scanning: scan only ports found in /etc/services, much faster\n");
- fprintf(stderr,"-? or -h: print this help text\n");
- fprintf(stderr,"-i: Copyright and version information\n");
- if (finish) exit(1);
- }
-
- void print_info(int finish) {
- fprintf(stderr,"portscanner v%s was written by Tennessee Carmel-Veilleux\n",VERSION);
- fprintf(stderr,"This version compiled on %s at %sEST\n",__DATE__,__TIME__);
- fprintf(stderr,"This program is licensed under the GPL. See www.gnu.org for more info on the license\n");
- if (finish) exit(1);
- }
-
- int main(int argc, char **argv)
- {
- if (argc < 2) {
- print_usage(1);
- }
-
- switch (argc) {
- case 2: if (!strcmp(argv[1],"-i")) {
- print_info(1);
- } else if ((!strcmp(argv[1],"-?")) || (!strcmp(argv[1],"-h"))) {
- print_help(1);
- } else {
- break;
- }
-
- default: for (i = 1; i < argc - 1; i++) {
- if (!strcmp(argv[i],"-v")) {
- verbose = 1;
- } else
- if (!strcmp(argv[i],"-vv")) {
- verbose = 2;
- } else
- if (!strcmp(argv[i],"-i")) {
- print_info(0);
- } else
- if ((!strcmp(argv[i],"-h")) || (!strcmp(argv[1],"-?"))) {
- print_help(0);
- } else
- if (!strcmp(argv[i],"-a")) {
- subnet = 1;
- } else
- if (!strcmp(argv[i],"-s")) {
- strobe = 1;
- } else
- if (!strcmp(argv[i],"-b")) {
- if ((i+1) > (argc - 1)) {
- print_usage(1);
- } else {
- base_port = (u_short)atoi(argv[i+1]);
- i++;
- }
- } else
- if (!strcmp(argv[i],"-e")) {
- if ((i+1) > (argc - 1)) {
- print_usage(1);
- } else {
- end_port = (u_short)atoi(argv[i+1]);
- i++;
- }
- } else
- if (!strcmp(argv[i],"-bm")) {
- if ((i+1) > (argc - 1)) {
- print_usage(1);
- } else {
- start_address = (u_char)atoi(argv[i+1]);
- i++;
- }
- } else
- if (!strcmp(argv[i],"-em")) {
- if ((i+1) > (argc - 1)) {
- print_usage(1);
- } else {
- end_address = (u_char)atoi(argv[i+1]);
- i++;
- }
- }
- }
- }
-
- if ((base_port > end_port) || ((short)base_port < 0)) {
- fprintf(stderr,"Bad port range : start=%d end=%d !\n", base_port, end_port);
- exit(1);
- }
-
- if ((start_address > end_address)) {
- fprintf(stderr,"Bad address range : start=%d end=%d !\n", start_address, end_address);
- exit(1);
- }
-
- if (subnet) printf("Subnet scanning enabled\n");
-
- bzero((char *)&address, sizeof(address));
- address.sin_family = AF_INET;
-
-
- strncpy(addr,argv[argc - 1],1023);
- addr[1023] = 0;
-
- if (verbose == 2) printf("Resolving: %s ->",addr);
- if ((host_info = gethostbyname(addr)))
- {
- bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
- if (verbose == 2) printf(" resolved\n");
- }
- else if ((address.sin_addr.s_addr = inet_addr(argv[1])) == INADDR_NONE)
- {
- fprintf(stderr,"Could not get %s host entry !\n",argv[1]);
- printf(" NOT resolved !!!\n");
- exit(1);
- }
- else if (verbose == 2) printf(" address valid\n");
-
- if (subnet) {
- if (verbose == 2) printf("Starting SUBNET port scanning\n");
- for (i=start_address; i <= end_address; i++) {
- sub_address = (struct sockaddr *)&address;
- sub_address->sa_data[5] = i;
-
- if (verbose == 2) printf("Current address: ");
-
- printf("%d.%d.%d.%d\n",(u_char)sub_address->sa_data[2],(u_char)sub_address->sa_data[3],
- (u_char)sub_address->sa_data[4],(u_char)sub_address->sa_data[5]);
-
- bcopy(sub_address,&address2,sizeof(address2));
-
- if (verbose == 2) {
- printf("Port range: %d to %d\n",base_port,end_port);
- }
- port_scan();
- printf("#\n");
- }
- if (verbose == 2) printf("SUBNET scanning completed\n");
- } else {
- sub_address = (struct sockaddr *)&address;
-
- if (verbose == 2) printf("Current address: ");
-
- printf("%d.%d.%d.%d\n",(u_char)sub_address->sa_data[2],(u_char)sub_address->sa_data[3],
- (u_char)sub_address->sa_data[4],(u_char)sub_address->sa_data[5]);
-
- bcopy(sub_address,&address2,sizeof(address2));
-
- if (verbose == 2) {
- printf("Port range: %d to %d\n",base_port,end_port);
- }
- port_scan();
- printf("#\n");
- }
- exit(0);
- }
-
- void port_scan(void) {
- int finished = 0; /* Set to 1 when strobe scanning is finished */
- int goodproto = 0; /* set to 1 if protocol returned in service info structure can be scanned */
-
- if ((strobe) && (verbose == 2)) {
- printf("Strobe scanning started...\n");
- setservent(1);
- }
-
- while (((base_port + current_port) <= end_port) || !finished) {
- /* fprintf(stderr,"Trying port: %d\n",base_port+current_port); */
- sock = socket(PF_INET, SOCK_STREAM, 0);
- if (sock == -1)
- {
- // fprintf(stderr, "Error assigning master socket: %s\n",sys_errlist[errno]);
- fprintf(stderr, "Error assigning master socket: sys_errlist[errno]\n");
- exit(-1);
- }
-
- if (strobe) {
- while(!goodproto) {
- service_info = getservent();
- if (!service_info) break;
- if (!strcmp(service_info->s_proto,"tcp") && (ntohs(service_info->s_port) <= end_port) && (ntohs(service_info->s_port) >= base_port)) {
- goodproto = 1;
- break;
- }
- }
- if (!goodproto) break;
-
- if (!service_info) {
- finished = 1;
- break;
- }
- if (goodproto) address2.sin_port = service_info->s_port;
- goodproto = 0;
- } else address2.sin_port = htons(base_port+current_port);
-
- if (!finished)
- if (connect(sock, (struct sockaddr *)&address2, sizeof(address2)) == 0) {
- switch (verbose) {
- case 0: if (strobe)
- printf("%d\n",ntohs(service_info->s_port));
- else
- printf("%d\n",base_port+current_port);
- break;
- case 1: if (!strobe) {
- service_info = getservbyport(htons(base_port+current_port),"tcp");
- if (!service_info) {
- printf("%d -> service name unknown\n",base_port+current_port);
- } else {
- printf("%d -> %s\n",base_port+current_port,service_info->s_name);
- }
- } else printf("%d -> %s\n",ntohs(service_info->s_port),service_info->s_name);
- break;
- case 2: if (!strobe) {
- service_info = getservbyport(htons(base_port+current_port),"tcp");
- if (!service_info) {
- printf("Port %d found. Service name unknown\n",base_port+current_port);
- } else {
- printf("Port %d found. Service name: %s\n",base_port+current_port,service_info->s_name);
- }
- } else {
- printf("Port %d found. Service name: %s\n",ntohs(service_info->s_port),service_info->s_name);
- }
- break;
- }
- } else if (errno == 113) {
- fprintf(stderr,"No route to host !\n");
- if (!subnet) {
- close(sock);
- exit(1);
- }
- }
- /* fprintf(stderr,"Error %d connecting socket %d to port %d: %s\n",
- errno,sock,base_port+current_port,sys_errlist[errno]); */
- close(sock);
- current_port++;
- if (base_port+current_port >= end_port) {
- finished = 1;
- }
- /* fprintf(stderr,"current_port: %d,b: %d,e:%d,b+c:%d\n", current_port, base_port,end_port,base_port+current_port); */
- }
-
- if (verbose == 2) printf("Port scan finished !\n");
- if (strobe) endservent();
- }
-
-