Chinaunix首页 | 论坛 | 博客
  • 博客访问: 34292
  • 博文数量: 8
  • 博客积分: 1482
  • 博客等级: 上尉
  • 技术积分: 90
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-18 13:55
文章分类

全部博文(8)

文章存档

2011年(1)

2008年(7)

我的朋友

分类: C/C++

2008-10-28 01:38:38

   之前曾经写过一个简单的端口扫描程序,没有多线程,今天晚上参照一个程序写了一个多线程扫描端口程序。思路还是那个程序的,当作学习吧。默认线程数为100,可以在命令行下输入5个IP地址,当然,要更多个也行,改一下代码就可以了。代码和执行结果如下:

/*
 * 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;
}

ken@ken-laptop:~/linux_c/$ ./scan 127.0.0.1
127.0.0.1 : port (7) has found.
127.0.0.1 : port (13) has found.
127.0.0.1 : port (631) has found.

阅读(2279) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~