Mon, 8th Sep 2008 04:44:53
Never fear, this site is here

#pscan.c

Language: C
Written by doug on 2008-01-31 23:09:30

/*
 * author: kay ~ irc.nullnetwork.net
 * date: 14/10/2005
 * id like to be contacted if this code is every used anywhere else. just so i know.
 * compiling:
 *  win32 compile:
 *    gcc -o pscan pscan.c -lwsock32
 *  linux compile:
 *    gcc -o pscan pscan.c -lpthread
 */
/*
	very basic port scanner. wont tell you anything more useful other than what ports are accepting
	connections on a remote host. also its much slower than other scanners on low end machines
	(tested on a moderately fast windows system) but pretty fast on higher end machines (my decent
	linux server). i did increase the speed itll operate at tho by forking off some threads. however
	this also heights processor usage during the scan. the code is compilable on windows and linux
	systems. (tested on windows XP with gcc 3.2.3 and debian linux gcc 3.3.5)
*/

#ifdef WIN32
#	include <windows.h>
#else
#	include <sys/types.h>
#	include <sys/socket.h>
#	include <netinet/in.h>
#	include <netdb.h>
#	include <arpa/inet.h>
#	include <unistd.h>
#	include <pthread.h>
#endif

#include <stdio.h>

#define NUM_THREAD 50
#define DOWN_RANGE 1
#define UP_RANGE 65535

struct pscan_p {
	char * ip;
	int init_p;
	int end_p;
};

void * pscan(void * args);

int sckinit() {
#ifdef WIN32
	WSADATA wsaData;

	if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {
		puts("WASStartup Failed");
		return 0;
	}
#endif
	return 1;
}

void * pscan(void * args) {
struct sockaddr_in sck_addr_in;
struct hostent *host_info;
struct pscan_p * scan_args = (void *)args;
int cur_port = scan_args->init_p, sck = 0;
	
	for(;cur_port < scan_args->end_p; cur_port++) {
		sck_addr_in.sin_family = AF_INET; //This should be in host byte order as it is :)
		sck_addr_in.sin_addr.s_addr = inet_addr(scan_args->ip);
		sck_addr_in.sin_port = htons(cur_port); //htons == "Host TO Network Short"
		memset( &(sck_addr_in.sin_zero), 0, 8); //Fill the last 8 bytes with 0's
		sck = socket(AF_INET, SOCK_STREAM, 0);
		if (connect( sck , (struct sockaddr *)&sck_addr_in , sizeof(struct sockaddr) ) == -1) {
		} else {
			printf("%d open\n", cur_port);
		}
		close(sck);
	}

}

int main(int argc, char *argv[]) {
struct hostent *host_info;
char ip[16];
int i = 0;
struct pscan_p args[NUM_THREAD];
int current_init_p = DOWN_RANGE;
int p_seperation = (UP_RANGE - DOWN_RANGE) / NUM_THREAD;

#ifdef WIN32
	HANDLE hThread[NUM_THREAD];
	DWORD dwID[NUM_THREAD];
	DWORD dwRetVal = 0;
#else
	int err = 0, status;
	pthread_t thread;
#endif
	
	memset(ip, 0, 16);

	if (argc != 2) {
		puts("Usage: pscan <DNS>\n");
		return 1;
	}

	if (!sckinit()) {
		return 2;
	}
	
	if ((host_info = gethostbyname(argv[1])) == NULL) {
		puts("ERORR during call to gethostbyname()\n");
		return 3;
	}
	printf("HOST: %s, IP: %s\n", argv[1], inet_ntoa(*((struct in_addr *)host_info->h_addr)));
	
	strncpy(ip, inet_ntoa(*((struct in_addr *)host_info->h_addr)), 15);
	
	puts("starting scan...");
	puts("open ports:");
	
	for (; i < NUM_THREAD; i++) {
		args[i].ip = ip;
		args[i].init_p = current_init_p;
		if (i == NUM_THREAD - 1) {
			args[i].end_p = UP_RANGE;
		} else {
			args[i].end_p = current_init_p + p_seperation;	
		}
#ifdef WIN32
		hThread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)pscan, &args[i], 0, &dwID[i]);
#else
		if ( err = pthread_create( &thread, NULL, (void*)pscan, (void*)&args[i] ) ) {
			printf("n=%d ", err); perror("pthread_create()");
		}
		if ( err = pthread_join( thread,(void **) &status ) ) {
			printf("n=%d status=%d ", err, status); perror("pthread_join()");
		}
#endif
		current_init_p += p_seperation;
	}
#ifdef WIN32
	dwRetVal = WaitForMultipleObjects(NUM_THREAD, hThread, TRUE, INFINITE);
#endif
	for (; i < NUM_THREAD; i++) {
#ifdef WIN32
		CloseHandle(hThread[i]);
#endif
	}
	puts("scan complete\n");
		
#ifdef WIN32
	WSACleanup();
#endif
	return 0;
}
Powered by Debian, Jack Daniels, Guinness, and excessive quantities of caffeine and sugar.