/*
* filename: scan.c
* DESC: A scaner with mutiple threads
* command: ./scan [ip1] [ip2] ... [ip5]
* Author: linjian
* E-mail: lin.jian1986@gmail.com
* Date: 2008/10/27
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "../my_error.h"
#define IP_NUM 5 // the number of the ip to scan
#define MAX_PORT 5000 // the max port number
#define THREAD_NUM 100 // the thread number
#define SEG_LEN 100 // the segment between min_port and max_port
typedef struct port_segment {
struct in_addr dest;
unsigned int min_port;
unsigned int max_port;
} port_segment;
/*
* @dest_addr: the destinite address
* DESC: how to scan the address
*/
int do_scan( struct sockaddr_in dest_addr )
{
int sockfd;
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
my_error( "socket failed" );
/* connect with the sever */
if ( connect(sockfd, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr)) < 0 ) {
close( sockfd );
return -1;
}
else
printf( "%s : port (%d) has found.\n", inet_ntoa(dest_addr.sin_addr), ntohs(dest_addr.sin_port) );
return 1;
}
/*
* @arg: the pointer points to the dest address
* DESC: do the scan with every port
*/
void *scan( void *arg )
{
port_segment port;
struct sockaddr_in dest_addr;
/* copy the struct to port */
memcpy( &port, arg, sizeof(struct port_segment) );
memset( &dest_addr, 0, sizeof(struct sockaddr_in) );
dest_addr.sin_family = AF_INET;
dest_addr.sin_addr.s_addr = port.dest.s_addr;
for ( int i = port.min_port; i <= port.max_port; ++i ) {
dest_addr.sin_port = htons( i );
/* do the scan with every port */
if ( do_scan(dest_addr) < 0 )
continue;
}
return NULL;
}
int main( int argc, char *argv[] )
{
pthread_t *thread;
struct in_addr dest_ip[ IP_NUM ]; // IP_NUM ip address
if ( argc < 2 ) {
fprintf( stderr, "usage: ./scan [ip1] [ip2] .. [ip5]\n" );
exit ( EXIT_FAILURE );
}
/* copy all the ip address into dest_ip */
for ( int i = 1; i < argc; ++i ) {
if ( inet_aton(argv[i], &dest_ip[i - 1]) == 0 ) {
fprintf( stderr, "invalid ip address.\n" );
exit ( EXIT_FAILURE );
}
}
/* malloc THREAD_NUM thread */
thread = ( pthread_t * )malloc( THREAD_NUM * sizeof(pthread_t) );
for ( int j = 0; j < argc - 1; ++j ) {
for ( int i = 0; i < THREAD_NUM; ++i ) {
port_segment port;
port.dest = dest_ip[ j ];
port.min_port = i * SEG_LEN + 1;
/* the last segment */
if ( i == (THREAD_NUM - 1) )
port.max_port = MAX_PORT;
else
port.max_port = port.min_port + SEG_LEN - 1;
/* create threads to scan the ports */
if ( pthread_create(&thread[i], NULL, scan, (void *)&port) != 0 )
my_error( "pthread_create failed" );
/* waiting for the sub threads exit */
pthread_join( thread[i], NULL );
}
}
/* free the memory */
free( thread );
return 0;
}
|