├── scanner.log ├── log ├── scanner ├── lib ├── packet ├── thread_pool ├── libscanner.so ├── mm.c ├── Makefile ├── util.c ├── register.c ├── packet.c ├── thread_pool.c ├── hash.c └── scanner.c ├── plugins ├── tcp │ ├── tcp.so │ ├── Makefile │ └── tcp.c ├── FIN_scanner │ ├── FIN │ ├── FIN.so │ ├── Makefile │ └── FIN.c └── plugin1 │ ├── demo.so │ ├── Makefile │ └── demo.c ├── scanner框架说明文档.doc ├── Makefile ├── auto.sh ├── include ├── mm.h ├── util.h ├── register.h ├── packet.h ├── thread_pool.h ├── hash.h └── scanner.h ├── fuck └── src └── main.c /scanner.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /log: -------------------------------------------------------------------------------- 1 | 主机打开了端口: 80 2 | -------------------------------------------------------------------------------- /scanner: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuriyao/Scanner/HEAD/scanner -------------------------------------------------------------------------------- /lib/packet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuriyao/Scanner/HEAD/lib/packet -------------------------------------------------------------------------------- /lib/thread_pool: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuriyao/Scanner/HEAD/lib/thread_pool -------------------------------------------------------------------------------- /lib/libscanner.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuriyao/Scanner/HEAD/lib/libscanner.so -------------------------------------------------------------------------------- /plugins/tcp/tcp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuriyao/Scanner/HEAD/plugins/tcp/tcp.so -------------------------------------------------------------------------------- /scanner框架说明文档.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuriyao/Scanner/HEAD/scanner框架说明文档.doc -------------------------------------------------------------------------------- /plugins/FIN_scanner/FIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuriyao/Scanner/HEAD/plugins/FIN_scanner/FIN -------------------------------------------------------------------------------- /plugins/plugin1/demo.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuriyao/Scanner/HEAD/plugins/plugin1/demo.so -------------------------------------------------------------------------------- /plugins/FIN_scanner/FIN.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuriyao/Scanner/HEAD/plugins/FIN_scanner/FIN.so -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | scanner:src/main.c lib/libscanner.so 2 | gcc -o scanner -g src/main.c -I include -lscanner -ldl -------------------------------------------------------------------------------- /auto.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd lib 3 | rm libscanner.so 4 | make 5 | cd ../ 6 | rm scanner 7 | make 8 | 9 | -------------------------------------------------------------------------------- /plugins/tcp/Makefile: -------------------------------------------------------------------------------- 1 | tcp.so:tcp.c 2 | gcc -shared -o tcp.so tcp.c -I ../../include -lscanner 3 | cp tcp.so ../ -------------------------------------------------------------------------------- /plugins/FIN_scanner/Makefile: -------------------------------------------------------------------------------- 1 | FIN.so:FIN.c 2 | gcc -shared -o FIN.so FIN.c -I ../../include -lscanner 3 | cp FIN.so ../ -------------------------------------------------------------------------------- /plugins/plugin1/Makefile: -------------------------------------------------------------------------------- 1 | demo.so:demo.c 2 | gcc -shared -o demo.so demo.c -I ../../include -lscanner 3 | cp demo.so ../ -------------------------------------------------------------------------------- /include/mm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 内存管理 3 | **/ 4 | #ifndef MM_H 5 | #define MM_H 6 | 7 | void* mm_malloc(int size); 8 | void mm_free(void *p); 9 | 10 | #endif -------------------------------------------------------------------------------- /lib/mm.c: -------------------------------------------------------------------------------- 1 | /** 2 | * 内存管理 3 | **/ 4 | #include 5 | 6 | void* mm_malloc(int size) 7 | { 8 | return malloc(size ? size : 1); 9 | } 10 | 11 | void mm_free(void *p) 12 | { 13 | free(p); 14 | } 15 | -------------------------------------------------------------------------------- /lib/Makefile: -------------------------------------------------------------------------------- 1 | libscanner.so:hash.c mm.c register.c scanner.c packet.c thread_pool.c util.c 2 | gcc -shared -o libscanner.so hash.c mm.c register.c scanner.c packet.c thread_pool.c util.c -I ../include -lpthread 3 | sudo cp libscanner.so /lib/ -------------------------------------------------------------------------------- /fuck: -------------------------------------------------------------------------------- 1 | Calling init function init_demo 2 | init 3 | The host open 22 4 | The host open 24 5 | The host open 25 6 | The host open 21 7 | The host open 2000 8 | The host open 8000 9 | The host open 8080 10 | The host open 8088 11 | The host open 27017 12 | The host open 28017 13 | -------------------------------------------------------------------------------- /plugins/plugin1/demo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "register.h" 3 | #include "scanner.h" 4 | 5 | static int tcp_scanner(int port) 6 | { 7 | printf("I am scan port %d\n", port); 8 | } 9 | 10 | void init_demo() 11 | { 12 | //register_scanner(DEFAULT_SCANNER, tcp_scanner, SCAN_TCP); 13 | printf("init\n"); 14 | } 15 | -------------------------------------------------------------------------------- /include/util.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 调试工具 3 | **/ 4 | /*打印包信息*/ 5 | #include 6 | 7 | #ifndef UTIL_H 8 | #define UTIL_H 9 | 10 | static void print_pack(char *pack, int len) 11 | { 12 | int i = 0; 13 | int k = 0; 14 | printf("-------------packet info----------"); 15 | for(i = 0; i < len; i ++, k++) 16 | { 17 | if(k % 16 == 0) 18 | { 19 | printf("\n%3d:\t", k); 20 | } 21 | printf("%02x ", (unsigned char)pack[i]); 22 | } 23 | printf("\n-------------------------------\n"); 24 | } 25 | 26 | /** 27 | * 日志系统初始化 28 | * @filename 日志名,为空时使用标准输出 29 | */ 30 | int scanner_log_init(char *filename); 31 | 32 | /** 33 | * 打印日志 34 | * 参数同printf 35 | */ 36 | void scanner_log(char *fmt, ...); 37 | 38 | 39 | void scanner_log_exit(); 40 | #endif -------------------------------------------------------------------------------- /include/register.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 注册处理函数 3 | **/ 4 | #ifndef REGISTER_H 5 | #define REGISTER_H 6 | #include "scanner.h" 7 | 8 | /** 9 | * 注册扫描函数 10 | * @port 扫描函数需要扫描的端口,如果是DEFALULT_SCANNER会使函数成为默认的扫描函数 11 | * @scan_func 扫描函数,其参数port是正在扫描的端口号,如果端口是打开的返回1,否则返回0 12 | * @type 扫描器使用的扫描方式: 13 | #define SCAN_HALF 1 //半开 14 | #define SCAN_FIN 2 //fin 15 | #define SCAN_TCP 3 //tcp 16 | #define SCAN_UDP 4 //udp 17 | #define SCAN_MIXED 5 //混合 18 | * 注册成功返回0,否则返回负的错误号,并置errno 19 | */ 20 | extern int register_scanner(int port, int (*scan_func)(int port), int type); 21 | 22 | /** 23 | * 添加处理的收尾函数 24 | **/ 25 | extern int register_over(void (*over)(void), int type); 26 | 27 | #define DEFAULT_SCANNER -1 28 | 29 | /*扫描函数的信息*/ 30 | struct scan_func_info 31 | { 32 | /*扫描函数*/ 33 | int (*scan_func)(int); 34 | /*扫描函数所采用的扫描方式*/ 35 | int type; 36 | }; 37 | 38 | #define PORT_MAX ((1 << 16) - 1) 39 | 40 | #endif -------------------------------------------------------------------------------- /lib/util.c: -------------------------------------------------------------------------------- 1 | /**/ 2 | #include "util.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | static FILE *log_file; 14 | static pthread_mutex_t log_mutex; 15 | static char log_buffer[1024 * 4]; 16 | 17 | int scanner_log_init(char *filename) 18 | { 19 | if(filename) 20 | { 21 | log_file = fopen(filename, "w"); 22 | if(!log_file) 23 | return -1; 24 | } 25 | else 26 | log_file = stdout; 27 | pthread_mutex_init(&log_mutex, NULL); 28 | return 0; 29 | } 30 | 31 | 32 | void scanner_log(char *fmt, ...) 33 | { 34 | char *time_str; 35 | va_list ap; 36 | va_start(ap, fmt); 37 | /*加锁,避免冲突*/ 38 | pthread_mutex_lock(&log_mutex); 39 | /*打印时间*/ 40 | //fprintf(log_file, "%s:\t", ctime(NULL)); 41 | /*打印log*/ 42 | vfprintf(log_file, fmt, ap); 43 | fflush(log_file); 44 | pthread_mutex_unlock(&log_mutex); 45 | va_end(ap); 46 | } 47 | 48 | void scanner_log_exit() 49 | { 50 | fclose(log_file); 51 | } -------------------------------------------------------------------------------- /include/packet.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 处理底层的包 3 | **/ 4 | #ifndef PACKET_H 5 | #define PACKET_H 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /** 12 | * 构造ip头 13 | * @iph 需要进行构造的ip头 14 | * @proto 协议 15 | * @ttl 16 | * @src_ip 转换到大端模式的源ip 17 | * @des_ip 转换到大端模式的目的ip 18 | * @data_len ip协议的有效载荷,(包括tcp头,udp,icmp头)的长度 19 | * 构造成功,返回0,否则返回负的错误号,并置errno 20 | */ 21 | int ip_pack(struct ip *iph, int proto, int ttl, u_int32_t src_ip, u_int32_t dest_ip, int data_len); 22 | 23 | /** 24 | * 构造tcp头 25 | * 参数都是可以自解释的,详见tcp头部的定义(所有参数不要转为大端模式) 26 | * tcp头和data必须是连在一起的,并且data指向tcp的有效载荷数据 27 | **/ 28 | int tcp_pack(struct tcphdr *tcp, u_int32_t src_ip, u_int32_t dst_ip, int src_port, int dest_port, u_int32_t seq, u_int32_t ack_seq, int ack, int psh, int rst, int syn, int fin, int window, char *data, int data_len); 29 | 30 | /** 31 | * 构造tcp的syn报文 32 | * @buffer 报文存放的缓冲区 33 | * @len 缓冲区的大小 34 | * @src_port 35 | * @dest_port 36 | * @seq 包的序列号 37 | * 成功返回报文大小,否则返回负数 38 | **/ 39 | int tcp_syn_pack(char *buffer, int len, u_int32_t src_ip, u_int32_t dst_ip, int src_port, int dest_port, u_int32_t seq); 40 | 41 | 42 | int tcp_fin_pack(char *buffer,int len,u_int32_t src_ip,u_int32_t dest_ip,int src_port,int dest_port); 43 | #endif 44 | -------------------------------------------------------------------------------- /plugins/tcp/tcp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "register.h" 10 | #include "scanner.h" 11 | #include 12 | #include 13 | #include 14 | 15 | static int tcp_scanner(int port) 16 | { 17 | int raw_socket; 18 | raw_socket = socket(AF_INET,SOCK_RAW,IPPROTO_TCP); 19 | struct sockaddr_in *_target; 20 | struct sockaddr_in target; 21 | 22 | if(raw_socket < 0) 23 | { 24 | printf("init MySocket failed\n"); 25 | exit(0); 26 | return 0; 27 | } 28 | 29 | const int on = 1; 30 | if(setsockopt(raw_socket,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on)) < 0) 31 | { 32 | printf("Setting IP_HDRINCL Error!\n"); 33 | exit(0); 34 | return 0; 35 | } 36 | 37 | 38 | _target = get_scan_addr(); 39 | memcpy(&target, _target, sizeof(target)); 40 | 41 | if(connect(raw_socket, (struct sockaddr*)&target,sizeof(target)) < 0) 42 | { 43 | printf("Connect Error: %s(errno:%d)\n", (char*)strerror(errno),errno); 44 | exit(0); 45 | return 0; 46 | } 47 | printf("Connect Successful!\n"); 48 | close(raw_socket); 49 | exit(0); 50 | return 1; 51 | 52 | } 53 | 54 | void init_tcp() 55 | { 56 | 57 | register_scanner(80, tcp_scanner, SCAN_TCP); 58 | 59 | printf("init\n"); 60 | } 61 | -------------------------------------------------------------------------------- /lib/register.c: -------------------------------------------------------------------------------- 1 | #include "register.h" 2 | #include "scanner.h" 3 | #include "mm.h" 4 | #include 5 | #include 6 | 7 | 8 | 9 | int register_scanner(int port, int (*scan_func)(int port), int type) 10 | { 11 | char number_buffer[10]; 12 | struct linear_node *linear_node, *v; 13 | struct scan_func_info *scan_func_info; 14 | 15 | /*参数检查*/ 16 | if(scan_func == NULL || (port < DEFAULT_SCANNER) || port > PORT_MAX) 17 | { 18 | errno = EINVAL; 19 | return -errno; 20 | } 21 | if(port == DEFAULT_SCANNER) 22 | { 23 | return add_global_scanner(scan_func, type); 24 | } 25 | /**/ 26 | sprintf(number_buffer, "%d", port); 27 | /*看看是否已经存在注册函数列表*/ 28 | linear_node = (struct linear_node*)hash_get(scanner_table, number_buffer); 29 | 30 | /**/ 31 | scan_func_info = (struct scan_func_info*)mm_malloc(sizeof(struct scan_func_info)); 32 | if(!scan_func_info) 33 | goto error1; 34 | v = (struct linear_node*)mm_malloc(sizeof(struct linear_node)); 35 | if(!v) 36 | goto error2; 37 | /*初始化一下*/ 38 | scan_func_info->scan_func = scan_func; 39 | scan_func_info->type = type; 40 | v->next = NULL; 41 | v->data = (void*)scan_func_info; 42 | /*还没有注册函数*/ 43 | if(!linear_node) 44 | { 45 | hash_insert(scanner_table, number_buffer, v); 46 | } 47 | else 48 | { 49 | /*采用头插法的变形,插入第二个*/ 50 | v->next = linear_node->next; 51 | linear_node->next = v; 52 | } 53 | return 0; 54 | 55 | error2: 56 | mm_free(scan_func_info); 57 | error1: 58 | errno = ENOMEM; 59 | return -errno; 60 | } 61 | 62 | int register_over(void (*over)(void), int type) 63 | { 64 | return add_over_func(over, type); 65 | } -------------------------------------------------------------------------------- /include/thread_pool.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 实现线程池 3 | * author: jeffyao 4 | **/ 5 | #include 6 | #include 7 | #ifndef THREAD_POOL_H 8 | #define THREAD_POOL_H 9 | 10 | enum thread_state 11 | { 12 | /*线程正在运行*/ 13 | THREAD_RUNNING, 14 | /*线程正在等待分配任务*/ 15 | THREAD_WAITING, 16 | /*线程正在关闭*/ 17 | THREAD_EXITING, 18 | }; 19 | 20 | struct args 21 | { 22 | /*传递给工作函数的参数*/ 23 | void *arg; 24 | /*指向线程节点*/ 25 | struct thread_node *self; 26 | /*指向线程池*/ 27 | struct thread_pool *thread_pool; 28 | }; 29 | 30 | struct thread_node 31 | { 32 | /*线程号*/ 33 | pthread_t thread; 34 | /*是否已经初始化*/ 35 | int is_init; 36 | /*是否还活跃*/ 37 | volatile int is_alive; 38 | /*工作函数*/ 39 | volatile void (*func)(void*); 40 | /*参数*/ 41 | volatile struct args args; 42 | /*指向自身*/ 43 | int self_index; 44 | /*指向下一个空闲节点*/ 45 | int next; 46 | /*是否空闲*/ 47 | int is_free; 48 | /*互斥量*/ 49 | pthread_mutex_t mutex; 50 | /*条件变量*/ 51 | pthread_cond_t cond; 52 | /*线程状态*/ 53 | enum thread_state state; 54 | }; 55 | 56 | struct thread_pool 57 | { 58 | /*线程池的线程数量*/ 59 | int number; 60 | /*线程数组*/ 61 | struct thread_node *threads; 62 | /*指向第一个空闲的线程*/ 63 | volatile int head; 64 | /*可用的空闲线程数量*/ 65 | sem_t sem; 66 | /*结构的互斥量*/ 67 | pthread_mutex_t mutex; 68 | }; 69 | 70 | /** 71 | * 创建线程池 72 | * @thread_max_number 线程的最大数量 73 | * 如果创建成功,返回线程池指针,否则返回NULL,并置errno 74 | **/ 75 | struct thread_pool* thread_pool_create(int thread_max_number); 76 | 77 | /** 78 | * 分发一个任务 79 | * @thread_pool 80 | * @func 81 | * @arg 82 | * 如果分发成功,返回0,否则返回负数,并置errno 83 | * 注意,这个函数只负责任务的分发,函数执行结束,不代表任务执行结束 84 | **/ 85 | int thread_distribute(struct thread_pool *thread_pool, void (*func)(void*), void *arg); 86 | 87 | 88 | /** 89 | * 销毁线程池 90 | **/ 91 | void thread_pool_destroy(struct thread_pool *thread_pool); 92 | 93 | #endif -------------------------------------------------------------------------------- /include/hash.h: -------------------------------------------------------------------------------- 1 | /** 2 | * hash表操作 3 | **/ 4 | #ifndef HASH_H 5 | #define HASH_H 6 | /*当hash表的节点数目是hash表容量的2/3时触发重新申请表*/ 7 | #define TRIGGER(capacity, number) ((number) * 3 > (capacity << 1)) 8 | 9 | #define DUMMY ((void*)1) 10 | 11 | /*hash表的节点*/ 12 | struct HashNode 13 | { 14 | //key 15 | char *key; 16 | //value 17 | void *value; 18 | }; 19 | 20 | /*hash表*/ 21 | struct HashTable 22 | { 23 | //计算两个key是否相等的函数,返回0表示相等 24 | int (*key_equal)(void *k1, void *k2); 25 | //拷贝value值,为空直接赋值 26 | void* (*copy_value)(void *src); 27 | //为value申请空间的函数 28 | //释放value值的函数 29 | void (*free_value)(void *value); 30 | //hash表的节点容量 31 | int capacity; 32 | //hash表的节点数目 33 | int number; 34 | //hash表头 35 | struct HashNode **head; 36 | }; 37 | 38 | typedef struct HashIter 39 | { 40 | struct HashTable *table; 41 | int index; 42 | }HashIter; 43 | 44 | /*创建一个hash表*/ 45 | struct HashTable* hash_new(int pre_max/*预估的最大节点数量的1.5倍*/, 46 | int (*key_equal)(void *k1, void *k2), 47 | void* (*copy_value)(void *src), 48 | void (*free_value)(void *value)); 49 | 50 | /*向hash表中插入一组数据*/ 51 | void hash_insert(struct HashTable *table, char *key, void *value); 52 | 53 | /*获得指定key值的value*/ 54 | void* hash_get(struct HashTable *table, char *key); 55 | 56 | /*删除制定key值的节点*/ 57 | void hash_del(struct HashTable *table, char *key); 58 | 59 | struct HashTable* hash_new_str(int pre_max/*预估的最大节点数量的1.5倍*/); 60 | 61 | /*向hash表中插入一组数据*/ 62 | void insert_str(struct HashTable *table, char *key, char *value); 63 | 64 | /*获得指定key值的value*/ 65 | char* get_str(struct HashTable *table, char *key); 66 | 67 | /*删除制定key值的节点*/ 68 | void del_str(struct HashTable *table, char *key); 69 | 70 | /** 71 | * 创建一个hash表的迭代器 72 | **/ 73 | HashIter* hash_create_iter(struct HashTable *table); 74 | 75 | /** 76 | * 77 | **/ 78 | struct HashNode* hash_next(HashIter *iter); 79 | 80 | #endif -------------------------------------------------------------------------------- /include/scanner.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | **/ 4 | #ifndef SCANNER_H 5 | #define SCANNER_H 6 | #include 7 | /** 8 | * 初始化扫描器 9 | **/ 10 | int scanner_init(char *addr, int _scan_method, char *nic); 11 | 12 | int scanner_work(int type, int arg1, int arg2); 13 | 14 | void scan_exit(); 15 | 16 | /** 17 | * 添加一个全局扫描器 18 | **/ 19 | int add_global_scanner(int (*func)(int), int type); 20 | 21 | /** 22 | * 添加收尾函数 23 | **/ 24 | int add_over_func(void (*func)(), int type); 25 | 26 | /** 27 | * 获得本机的ip,已转为网络字节序 28 | * @fd 套接口 29 | */ 30 | u_int32_t get_local_ip(int fd); 31 | 32 | /*获取扫描的地址*/ 33 | struct sockaddr_in* get_scan_addr(); 34 | 35 | /*已废弃*/ 36 | extern struct scan_func_info *default_scanner_info; 37 | /*注册的扫描函数表*/ 38 | extern struct HashTable *scanner_table; 39 | /*全局扫描函数列表*/ 40 | struct linear_node *global_scanner; 41 | 42 | /*扫描器的工作方法*/ 43 | /*仅开放服务端口扫描*/ 44 | #define SCAN_OPEN_PORT_ONLY 1 45 | /*全部扫描*/ 46 | #define SCAN_ALL 2 47 | /*低端口扫描(0-1024)*/ 48 | #define SCAN_LOW 3 49 | /*高端口扫描*/ 50 | #define SCAN_HIGH 4 51 | /*低端口+高端口随机扫描*/ 52 | #define SCAN_LOW_RAND_HIGH 5 53 | /*部分端口(0-2000)扫描*/ 54 | #define SCAN_PART 6 55 | /*指定端口扫描*/ 56 | #define SCAN_FIXED 7 57 | /*指定范围扫描*/ 58 | #define SCAN_RANGE 8 59 | 60 | /*扫描使用的方法*/ 61 | /*半开扫描*/ 62 | #define SCAN_HALF 1 63 | /*FIN方式*/ 64 | #define SCAN_FIN 2 65 | /*tcp*/ 66 | #define SCAN_TCP 3 67 | /*udp*/ 68 | #define SCAN_UDP 4 69 | /*混合*/ 70 | #define SCAN_MIXED 5 71 | /*通用扫描*/ 72 | #define SCAN_GENERAL 6 73 | 74 | struct linear_node 75 | { 76 | void *data; 77 | //int (*scan_func)(int port); 78 | struct linear_node *next; 79 | }; 80 | 81 | 82 | /*扫描结果*/ 83 | struct scan_result_node 84 | { 85 | /*扫描成功的端口号*/ 86 | int port; 87 | /*所采用的扫描方式*/ 88 | int type; 89 | 90 | }; 91 | 92 | struct over_func_info 93 | { 94 | void (*over)(); 95 | int type; 96 | }; 97 | 98 | #endif -------------------------------------------------------------------------------- /plugins/FIN_scanner/FIN.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "scanner.h" 6 | #include "packet.h" 7 | #include "register.h" 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "util.h" 16 | 17 | #define SRC_PORT 9000 18 | 19 | 20 | 21 | static unsigned int _open_port_num = 0; 22 | static unsigned int _close_port_num = 0; 23 | 24 | /* 25 | * FIN扫描是建立在TCP基础上的, 26 | * 其思想是关闭的端口会用适当的RST来回复FIN数据包 27 | * 但是打开的端口会忽略对FIN数据包的回复(Unix系统) 28 | * NT无法扫描,可区分操作系统类别 29 | * port 为端口号 30 | */ 31 | static int FIN_scanner(int port) 32 | { 33 | //scanner_log("%s\n", "I am fin"); 34 | int skfd; 35 | struct sockaddr_in target;//目标地址的相关信息 36 | struct sockaddr_in *_target;//处理多线程 37 | 38 | struct tcphdr *tcp; 39 | 40 | u_int32_t dst_ip; 41 | u_int32_t src_ip; 42 | 43 | int fin_ret; 44 | int sock_len ,i,j; 45 | char buffer[8192]; 46 | 47 | if((skfd=socket(AF_INET,SOCK_RAW,IPPROTO_TCP)) < 0){ 48 | perror("Create Error"); 49 | return -errno; 50 | } 51 | src_ip = get_local_ip(skfd); 52 | //获取目标的地址和端口号 53 | _target = get_scan_addr(); 54 | memcpy(&target,_target,sizeof(*_target)); 55 | target.sin_port = htons(port); 56 | memcpy(&dst_ip,&target.sin_addr,4); 57 | //scanner_log("target ip %s\n", inet_ntoa(target.sin_addr)); 58 | //scanner_log("target port %d\n", port); 59 | //scanner_log("src port%d\n",SRC_PORT); 60 | //scanner_log("src ip %u\n", src_ip); 61 | // 62 | fin_ret = tcp_fin_pack(buffer,8192,src_ip,dst_ip,SRC_PORT,port); 63 | if(fin_ret < 0){ 64 | perror("tcp_fin_pack"); 65 | return fin_ret; 66 | } 67 | fin_ret = sendto(skfd,buffer,fin_ret,0,(struct sockaddr*)&target,sizeof(target)); 68 | 69 | if(fin_ret < 0){ 70 | perror("sendto"); 71 | return -errno; 72 | } 73 | 74 | sock_len = sizeof(target); 75 | for (i = 0; i < 20; i++) 76 | { 77 | fin_ret = recvfrom(skfd, buffer,8192, MSG_DONTWAIT , (struct sockaddr*)&target,&sock_len); 78 | if(fin_ret < 0 && (errno != EAGAIN) && (errno != EWOULDBLOCK)){ 79 | perror("recvfrom"); 80 | close(skfd); 81 | }else if(fin_ret >= sizeof(struct ip) + sizeof(struct tcphdr)){ 82 | //检测Tcp报文的RST字段,为1,则表明该端口关闭,否则可能打开,或者为NT系统 83 | tcp = (struct tcphdr*)(buffer + ((struct ip*)buffer)->ip_hl * 4); 84 | if(tcp->rst){ 85 | _close_port_num ++; 86 | close(skfd); 87 | return 1; 88 | }else{ 89 | _open_port_num++; 90 | close(skfd); 91 | return 1; 92 | } 93 | } 94 | usleep( 100 * 1000); 95 | } 96 | 97 | _open_port_num++; 98 | close(skfd); 99 | return 0; 100 | } 101 | 102 | /* 103 | 所有的端口扫描完成之后执行此程序 104 | 输出端口打开、关闭的统计情况 105 | 对于Windows操作系统扫描得出的结果应该是all-closed 106 | 但是忽略其它因素,当关闭端口所占比例大于90%,则初步认定为windows系统 107 | 否则为Unix操作系统 108 | */ 109 | 110 | static void over() 111 | { 112 | float total = (float)( _open_port_num + _close_port_num); 113 | float open_port_rate = _open_port_num / total; 114 | float close_port_rate = 1 - open_port_rate; 115 | scanner_log("The number of open-port is %d, ",_open_port_num); 116 | scanner_log("account for a rate of %.2f\n", open_port_rate); 117 | scanner_log("The number of closed-port is %d, ",_close_port_num); 118 | scanner_log("account for a rate of %.2f\n", close_port_rate); 119 | 120 | //if(close_port_rate >= 0.8){ 121 | //scanner_log("%s\n", "The server's operating system is likely to be Windows"); 122 | // }else{ 123 | //scanner_log("%s\n", "The server's operating system is likely to be Unix/Linux"); 124 | // } 125 | 126 | } 127 | 128 | 129 | /* 130 | 向scanner系统框架中注册 FIN扫描函数 131 | DEFAULT_SCANNER 为默认扫描方式, 132 | FIN_scanner为注册的函数名, 133 | SCAN_FIN为扫描方式参数,为FIN扫描 134 | */ 135 | void init_FIN() 136 | { 137 | register_scanner(DEFAULT_SCANNER, FIN_scanner, SCAN_FIN); 138 | register_over(over, SCAN_FIN); 139 | //scanner_log("init\n"); 140 | } 141 | 142 | 143 | 144 | 145 | int main(int argc, char **argv) 146 | { 147 | init_FIN(); 148 | } -------------------------------------------------------------------------------- /lib/packet.c: -------------------------------------------------------------------------------- 1 | #include "packet.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | /** 8 | * 9 | **/ 10 | static u_int16_t _net_cksum(unsigned char *data, int len) 11 | { 12 | int sum = 0; 13 | int odd = len & 0x01; 14 | 15 | while(len & 0xfffe) 16 | { 17 | sum += *(unsigned short*)data; 18 | data += 2; 19 | len -= 2; 20 | } 21 | if(odd) 22 | { 23 | unsigned short tmp = ((*data)); 24 | sum += tmp; 25 | } 26 | sum = (sum >> 16) + (sum & 0xffff); 27 | sum += (sum >> 16); 28 | 29 | return ~sum; 30 | } 31 | 32 | /*计算ip段的校验和*/ 33 | u_int16_t ip_chksum(struct ip *ip) 34 | { 35 | //return _net_cksum((void*)ip, sizeof(struct ip)); 36 | long sum = 0; 37 | int len = sizeof(struct ip); 38 | 39 | while ( len >1 ) { 40 | sum += *((unsigned short *) ip); 41 | if (sum & 0x80000000) 42 | sum = (sum & 0xFFFF) + (sum >> 16) ; 43 | len -= 2; 44 | ip = (struct ip*)((unsigned long)ip + 2); 45 | } 46 | 47 | if ( len ) 48 | 49 | sum += ( unsigned short ) * (unsigned char *) ip; 50 | 51 | while ( sum >> 16) 52 | 53 | sum =(sum & 0xFFFF) + (sum>> 16); 54 | 55 | return ~sum; 56 | } 57 | 58 | int ip_pack(struct ip *iph, int proto, int ttl, u_int32_t src_ip, u_int32_t dest_ip, int data_len) 59 | { 60 | /*参数检查*/ 61 | if(!iph) 62 | { 63 | errno = EINVAL; 64 | return -errno; 65 | } 66 | /*参数修正*/ 67 | ttl = (ttl <= 0) ? 1 : ttl; 68 | ttl = (ttl > 255) ? 255 : ttl; 69 | /*开始构造*/ 70 | /*使用ipv4*/ 71 | iph->ip_v = 4; 72 | /*ip头部不带选项*/ 73 | iph->ip_hl = 5; 74 | iph->ip_tos = 0; 75 | iph->ip_len = htons(20 + data_len); 76 | /*设置标志,为进程号*/ 77 | iph->ip_id = getpid(); 78 | /*偏移为0*/ 79 | iph->ip_off = 0; 80 | iph->ip_ttl = ttl; 81 | iph->ip_p = proto; 82 | /*待会计算校验和*/ 83 | iph->ip_sum = 0; 84 | memcpy((void*)&iph->ip_src, (void*)&src_ip, sizeof(src_ip)); 85 | memcpy((void*)&iph->ip_dst, (void*)&dest_ip, sizeof(dest_ip)); 86 | /*正式开始计算校验和*/ 87 | iph->ip_sum = ip_chksum(iph); 88 | return 0; 89 | } 90 | 91 | int tcp_pack(struct tcphdr *tcp, u_int32_t src_ip, u_int32_t dst_ip, int src_port, int dest_port, u_int32_t seq, u_int32_t ack_seq, int ack, int psh, int rst, int syn, int fin, int window, char *data, int data_len) 92 | { 93 | char buffer[8192]; 94 | unsigned short hdr_len = htons(sizeof(struct tcphdr)); 95 | 96 | if(!tcp || !data || data_len < 0 || data_len > 8192 - sizeof(struct tcphdr) - 12) 97 | { 98 | errno = EINVAL; 99 | return -errno; 100 | } 101 | memset(tcp, 0, sizeof(*tcp)); 102 | /*构造tcp头*/ 103 | tcp->source = htons(src_port); 104 | tcp->dest = htons(dest_port); 105 | tcp->seq = htonl(seq); 106 | tcp->ack_seq = htonl(ack_seq); 107 | tcp->ack = ack ? 1 : 0; 108 | tcp->psh = psh ? 1 : 0; 109 | tcp->rst = rst ? 1 : 0; 110 | tcp->syn = syn ? 1 : 0; 111 | tcp->fin = fin ? 1 : 0; 112 | tcp->window = htons((unsigned short)window); 113 | tcp->doff = 5; 114 | /*开始计算校验和*/ 115 | memcpy(buffer, &src_ip, 4); 116 | memcpy(buffer + 4, &dst_ip, 4); 117 | buffer[8] = 0; 118 | buffer[9] = IPPROTO_TCP; 119 | memcpy(buffer + 10, &hdr_len, 2); 120 | memcpy(buffer + 12, tcp, sizeof(struct tcphdr)); 121 | if(data_len > 0) 122 | memcpy(buffer + 12 + sizeof(struct tcphdr), data, data_len); 123 | tcp->check = _net_cksum(buffer, 12 + sizeof(struct tcphdr) + data_len); 124 | return 0; 125 | } 126 | 127 | int tcp_syn_pack(char *buffer, int len, u_int32_t src_ip, u_int32_t dst_ip, int src_port, int dest_port, u_int32_t seq) 128 | { 129 | int ret; 130 | if(!buffer || len < sizeof(struct tcphdr)) 131 | { 132 | errno = EINVAL; 133 | return -errno; 134 | } 135 | ret = tcp_pack((struct tcphdr*)buffer, src_ip, dst_ip, src_port, dest_port, seq, 0, 0, 0, 0, 1, 0, 4096, buffer + sizeof(struct tcphdr), 0); 136 | return sizeof(struct tcphdr); 137 | } 138 | 139 | int tcp_fin_pack(char *buffer,int len,u_int32_t src_ip,u_int32_t dest_ip,int src_port,int dest_port) 140 | { 141 | int ret; 142 | if(!buffer || len < sizeof(struct tcphdr)){ 143 | errno = EINVAL; 144 | return -errno; 145 | } 146 | ret = tcp_pack((struct tcphdr*)buffer,src_ip,dest_ip,src_port,dest_port,0x10000000,0,0,0,0,0,1,4096,buffer + sizeof (struct tcphdr),0); 147 | //ret = tcp_pack((struct tcphdr*)buffer,src_ip,dest_ip,src_port,dest_port,1000,0,0,0,0,0,0,4096,buffer + sizeof (struct tcphdr),0); 148 | return sizeof(struct tcphdr); 149 | } 150 | 151 | #define PACKET_DEBUG 152 | #ifdef PACKET_DEBUG 153 | int main(int argc, char **argv) 154 | { 155 | struct ip ip; 156 | ip_pack(&ip, IPPROTO_TCP, 10, 0x1234, 0x2345, 0); 157 | } 158 | #endif -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | #include "scanner.h" 2 | #include "register.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | /*判断是否为插件*/ 14 | static int is_plugin(char *name) 15 | { 16 | int len = strlen(name); 17 | return strcmp(name + len - 3, ".so") == 0; 18 | } 19 | 20 | /** 21 | * 加载plugins文件夹下的插件 22 | **/ 23 | static int load_plugins() 24 | { 25 | char buffer[512]; 26 | /*插件的目录*/ 27 | DIR *plugin_dir; 28 | struct dirent *plugin; 29 | /*动态加载的句柄*/ 30 | void *handler; 31 | /**/ 32 | void (*plugin_init)(); 33 | /*初始化函数名称前缀*/ 34 | char *plugin_name_prefix = "init_"; 35 | 36 | /*打开插件所在的文件夹*/ 37 | plugin_dir = opendir("plugins"); 38 | if(!plugin_dir) 39 | { 40 | perror("opendir"); 41 | return -1; 42 | } 43 | /*加载每一个可能的插件*/ 44 | while((plugin = readdir(plugin_dir)) != NULL) 45 | { 46 | if(is_plugin(plugin->d_name)) 47 | { 48 | /*获得插件的名字*/ 49 | sprintf(buffer, "plugins/%s", plugin->d_name); 50 | /*加载插件*/ 51 | handler = (void*)dlopen(buffer, RTLD_NOW); 52 | if(!handler) 53 | { 54 | perror("dlopen"); 55 | continue; 56 | } 57 | /*获得插件的初始化函数*/ 58 | sprintf(buffer, "%s", plugin_name_prefix); 59 | memcpy(buffer + strlen(buffer), plugin->d_name, strlen(plugin->d_name) - 3); 60 | buffer[strlen(plugin_name_prefix) + strlen(plugin->d_name) - 3] = '\0'; 61 | printf("Calling init function %s\n", buffer); 62 | plugin_init = (void(*)())dlsym(handler, buffer); 63 | if(plugin_init) 64 | { 65 | plugin_init(); 66 | } 67 | else 68 | { 69 | dlclose(handler); 70 | } 71 | } 72 | } 73 | } 74 | /*扫描方式*/ 75 | static int scan_method = SCAN_GENERAL; 76 | /*参数1*/ 77 | static int arg1 = 0; 78 | static int arg2 = PORT_MAX; 79 | /*主机名*/ 80 | static char host_name[256]; 81 | static int host_gived = 0; 82 | /**/ 83 | static char log_file[1024] = "scanner.log"; 84 | static int log_file_gived = 0; 85 | /*网卡*/ 86 | static char nic[256] = "eth1"; 87 | 88 | static struct option opts[] = { 89 | {"host", required_argument, NULL, 'h'}, 90 | {"port", optional_argument, NULL, 'p'}, 91 | {"type", optional_argument, NULL, 't'}, 92 | {"logfile", optional_argument, NULL, 'f'}, 93 | {"nic", optional_argument, NULL, 'n'} 94 | }; 95 | 96 | /*解析参数*/ 97 | static int parse_args(int argc, char **argv) 98 | { 99 | int opt; 100 | char type[20]; 101 | int i = 0; 102 | 103 | /*使用的是scanner hostname*/ 104 | if(argc == 2) 105 | { 106 | 107 | if(strlen(argv[1]) > 255) 108 | { 109 | printf("Host-name %s 太长了\n", argv[1]); 110 | return -1; 111 | } 112 | strcpy(host_name, argv[1]); 113 | host_gived = 1; 114 | return 0; 115 | } 116 | 117 | while((opt = getopt_long(argc, argv, "h:p:t:f:n:", opts, NULL)) != -1) 118 | { 119 | switch(opt) 120 | { 121 | case 'h': 122 | if(strlen(optarg) > 255) 123 | { 124 | printf("Host-name %s 太长了\n", optarg); 125 | return -1; 126 | } 127 | strcpy(host_name, optarg); 128 | host_gived = 1; 129 | break; 130 | case 'p': 131 | //printf("port %s\n", optarg); 132 | sscanf(optarg, "%d-%d", &arg1, &arg2); 133 | if(arg1 < 0 || arg2 < 0 || arg1 > arg2 || arg2 > PORT_MAX) 134 | { 135 | printf("端口范围不合法\n"); 136 | return -1; 137 | } 138 | break; 139 | case 'f': 140 | if(strlen(optarg) > 1023) 141 | { 142 | printf("日志文件名太长\n"); 143 | return -1; 144 | } 145 | strcpy(log_file, optarg); 146 | log_file_gived = 1; 147 | break; 148 | case 'n': 149 | if(strlen(optarg) > 255) 150 | { 151 | printf("网卡名称太长\n"); 152 | return -1; 153 | } 154 | strcpy(nic, optarg); 155 | break; 156 | 157 | case 't': 158 | if(strlen(optarg) > 19) 159 | { 160 | printf("未定义的扫描类型:%s\n", optarg); 161 | return -1; 162 | } 163 | strcpy(type, optarg); 164 | for(i = 0; i < strlen(type); i ++) 165 | type[i] = toupper(type[i]); 166 | /*通用扫描*/ 167 | if(strcmp(type, "GEN") == 0) 168 | scan_method = SCAN_GENERAL; 169 | /**/ 170 | else if(strcmp(type, "FIN") == 0) 171 | scan_method = SCAN_FIN; 172 | else if(strcmp(type, "TCP") == 0) 173 | scan_method = SCAN_TCP; 174 | else if(strcmp(type, "UDP") == 0) 175 | scan_method = SCAN_UDP; 176 | else if(strcmp(type, "MIX") == 0) 177 | scan_method = SCAN_MIXED; 178 | else 179 | scan_method = SCAN_HALF; 180 | break; 181 | default: 182 | break; 183 | } 184 | } 185 | if(!host_gived) 186 | { 187 | printf("主机名是必须的\n"); 188 | return -1; 189 | } 190 | return 0; 191 | } 192 | 193 | int main(int argc, char **argv) 194 | { 195 | int ret; 196 | 197 | 198 | /*解析参数*/ 199 | ret = parse_args(argc, argv); 200 | if(ret < 0) 201 | exit(-1); 202 | 203 | printf("Scanning %s from %d to %d with method %d\n", host_name, arg1, arg2, scan_method); 204 | 205 | /*初始化日志*/ 206 | ret = scanner_log_init(log_file_gived ? log_file : NULL); 207 | if(ret < 0) 208 | { 209 | perror("scanner_log_init"); 210 | exit(-1); 211 | } 212 | /*初始化扫描器*/ 213 | ret = scanner_init(host_name, scan_method, nic); 214 | if(ret < 0) 215 | { 216 | perror("scanner_init"); 217 | exit(-1); 218 | } 219 | /*加载插件*/ 220 | load_plugins(); 221 | 222 | /*开始执行*/ 223 | scanner_work(SCAN_RANGE, arg1, arg2); 224 | 225 | /*执行结束,清理内存*/ 226 | scan_exit(); 227 | /*关闭日志*/ 228 | scanner_log_exit(); 229 | return 0; 230 | 231 | } -------------------------------------------------------------------------------- /lib/thread_pool.c: -------------------------------------------------------------------------------- 1 | /** 2 | * gcc -o thread_pool thread_pool.c -I ../include -lpthread 3 | **/ 4 | #include "thread_pool.h" 5 | #include 6 | #include 7 | #include 8 | #include "mm.h" 9 | /** 10 | * 创建线程池 11 | * @thread_max_number 线程的最大数量 12 | * 如果创建成功,返回线程池指针,否则返回NULL,并置errno 13 | **/ 14 | struct thread_pool* thread_pool_create(int thread_max_number) 15 | { 16 | struct thread_pool *thread_pool; 17 | int i = 0; 18 | struct thread_node *nodes; 19 | 20 | if(thread_max_number <= 0) 21 | { 22 | errno = EINVAL; 23 | return (struct thread_pool*)0; 24 | } 25 | /**/ 26 | thread_pool = (struct thread_pool*)mm_malloc(sizeof(struct thread_pool)); 27 | if(!thread_pool) 28 | goto error1; 29 | /*申请线程数组*/ 30 | thread_pool->threads = (struct thread_node*)mm_malloc(sizeof(struct thread_node) * thread_max_number); 31 | if(!thread_pool->threads) 32 | goto error2; 33 | /*先初始化线程池控制块*/ 34 | thread_pool->number = thread_max_number; 35 | thread_pool->head = 0; 36 | pthread_mutex_init(&thread_pool->mutex, NULL); 37 | sem_init(&thread_pool->sem, 0, thread_max_number); 38 | /*初始化线程数组*/ 39 | nodes = thread_pool->threads; 40 | //memset(nodes, 0, sizeof(struct thread_node) * thread_max_number); 41 | for(i = 0; i < thread_max_number; i ++) 42 | { 43 | nodes[i].is_init = 0; 44 | nodes[i].is_alive = 1; 45 | nodes[i].next = i + 1; 46 | nodes[i].is_free = 1; 47 | nodes[i].args.self = &nodes[i]; 48 | nodes[i].args.thread_pool = thread_pool; 49 | nodes[i].self_index = i; 50 | pthread_mutex_init(&nodes[i].mutex, NULL); 51 | pthread_cond_init(&nodes[i].cond, NULL); 52 | } 53 | nodes[thread_max_number - 1].next = -1; 54 | return thread_pool; 55 | error2: 56 | mm_free(thread_pool); 57 | error1: 58 | errno = ENOMEM; 59 | return (struct thread_pool*)0; 60 | } 61 | 62 | static void* _worker(void *arg) 63 | { 64 | struct args *args = (struct args*)arg; 65 | volatile void (*func)(void*); 66 | void *v; 67 | 68 | 69 | while(args->self->is_alive) 70 | { 71 | pthread_mutex_lock(&args->self->mutex); 72 | func = args->self->func; 73 | v = args->arg; 74 | args->self->is_free = 0; 75 | args->self->state = THREAD_RUNNING; 76 | pthread_mutex_unlock(&args->self->mutex); 77 | /*开始执行任务*/ 78 | func(v); 79 | /**/ 80 | pthread_mutex_lock(&args->self->mutex); 81 | /*修改线程的控制信息,使其可以再次被分发调度*/ 82 | args->self->is_free = 1; 83 | args->self->state = THREAD_WAITING; 84 | pthread_mutex_lock(&args->thread_pool->mutex); 85 | args->self->next = args->thread_pool->head; 86 | args->thread_pool->head = args->self->self_index; 87 | //printf("head %d\n", args->thread_pool->head); 88 | sem_post(&args->thread_pool->sem); 89 | pthread_mutex_unlock(&args->thread_pool->mutex); 90 | /*让线程睡眠,等待调度*/ 91 | //printf("I am waiting for call\n"); 92 | pthread_cond_wait(&args->self->cond, &args->self->mutex); 93 | pthread_mutex_unlock(&args->self->mutex); 94 | } 95 | pthread_mutex_lock(&args->self->mutex); 96 | args->self->state = THREAD_EXITING; 97 | args->self->is_init = 0; 98 | pthread_mutex_unlock(&args->self->mutex); 99 | return NULL; 100 | } 101 | 102 | /** 103 | * 分发一个任务 104 | * @thread_pool 105 | * @func 106 | * @arg 107 | * 如果分发成功,返回0,否则返回负数,并置errno 108 | * 注意,这个函数只负责任务的分发,函数执行结束,不代表任务执行结束 109 | **/ 110 | int thread_distribute(struct thread_pool *thread_pool, void (*func)(void*), void *arg) 111 | { 112 | int index; 113 | struct thread_node *node; 114 | int ret; 115 | int out = 0; 116 | 117 | if(!thread_pool || !func) 118 | { 119 | errno = EINVAL; 120 | return -errno; 121 | } 122 | /*等待有空闲的线程节点*/ 123 | sem_wait(&thread_pool->sem); 124 | pthread_mutex_lock(&thread_pool->mutex); 125 | /*获取空闲的线程*/ 126 | index = thread_pool->head; 127 | //printf("index:%d\n", index); 128 | assert(index >= 0); 129 | /*改变空闲节点的头*/ 130 | thread_pool->head = thread_pool->threads[index].next; 131 | /*为分发线程进行尊卑*/ 132 | node = thread_pool->threads + index; 133 | pthread_mutex_lock(&node->mutex); 134 | node->args.arg = arg; 135 | node->func = func; 136 | node->is_free = 0; 137 | //printf("hello\n"); 138 | /*线程是在等待分发*/ 139 | if(node->is_init) 140 | { 141 | /*唤醒线程*/ 142 | pthread_cond_signal(&node->cond); 143 | } 144 | /*还没有初始化,需要创建新线程*/ 145 | else 146 | { 147 | //printf("create thread\n"); 148 | ret = pthread_create(&node->thread, NULL, _worker, (void*)&node->args); 149 | /*创建线程失败*/ 150 | if(ret < 0) 151 | { 152 | perror("pthread_create"); 153 | /*节点归还线程池*/ 154 | node->is_free = 1; 155 | node->next = thread_pool->head; 156 | thread_pool->head = index; 157 | out = -1; 158 | sem_post(&thread_pool->sem); 159 | } 160 | else 161 | { 162 | node->is_init = 1; 163 | node->is_alive = 1; 164 | } 165 | 166 | } 167 | pthread_mutex_unlock(&node->mutex); 168 | 169 | pthread_mutex_unlock(&thread_pool->mutex); 170 | 171 | return out; 172 | } 173 | 174 | 175 | /** 176 | * 销毁线程池 177 | **/ 178 | void thread_pool_destroy(struct thread_pool *thread_pool) 179 | { 180 | int i = 0; 181 | struct thread_node *nodes; 182 | 183 | if(!thread_pool) 184 | return; 185 | 186 | nodes = thread_pool->threads; 187 | /*挨个销毁线程*/ 188 | for(i = 0; i < thread_pool->number; i ++) 189 | { 190 | pthread_mutex_lock(&nodes[i].mutex); 191 | if(nodes[i].is_init) 192 | { 193 | nodes[i].is_alive = 0; 194 | /*等待线程结束*/ 195 | while(nodes[i].state == THREAD_RUNNING) 196 | { 197 | pthread_mutex_unlock(&nodes[i].mutex); 198 | usleep(500); 199 | pthread_mutex_lock(&nodes[i].mutex); 200 | } 201 | /*唤醒线程,让它自然结束*/ 202 | pthread_cond_signal(&nodes[i].cond); 203 | pthread_mutex_unlock(&nodes[i].mutex); 204 | pthread_join(nodes[i].thread, NULL); 205 | pthread_mutex_lock(&nodes[i].mutex); 206 | } 207 | pthread_mutex_unlock(&nodes[i].mutex); 208 | /*销毁线程信息*/ 209 | pthread_mutex_destroy(&nodes[i].mutex); 210 | pthread_cond_destroy(&nodes[i].cond); 211 | } 212 | /*销毁线程池控制块*/ 213 | pthread_mutex_destroy(&thread_pool->mutex); 214 | sem_destroy(&thread_pool->sem); 215 | mm_free(thread_pool->threads); 216 | mm_free(thread_pool); 217 | } 218 | 219 | //#define THREAD_POOL_DEBUG 220 | #ifdef THREAD_POOL_DEBUG 221 | 222 | 223 | void print(void *arg) 224 | { 225 | printf("%d\n", (int)arg); 226 | sleep(1); 227 | } 228 | int main(int argc, char **argv) 229 | { 230 | struct thread_pool *pool = thread_pool_create(10); 231 | int i = 0; 232 | 233 | for(i = 0; i < 500; i ++) 234 | { 235 | thread_distribute(pool, print, (void*)i); 236 | } 237 | thread_pool_destroy(pool); 238 | return 0; 239 | } 240 | #endif -------------------------------------------------------------------------------- /lib/hash.c: -------------------------------------------------------------------------------- 1 | /** 2 | * 使用开放定址法实现的hash表(使用二次探测的方式) 3 | **/ 4 | #include "hash.h" 5 | #include 6 | #include 7 | #include "mm.h" 8 | 9 | 10 | static int _get_empty(struct HashTable *table, char *key); 11 | 12 | /*主hash函数*/ 13 | static int hash_func(char *key) 14 | { 15 | int len, ret, i; 16 | 17 | if(!key) 18 | return 0; 19 | len = strlen(key); 20 | ret = key[0]; 21 | for(i = 1; i < len; i ++) 22 | ret ^= key[i]; 23 | ret ^= len; 24 | return (ret & 0x7FFFFFFF); 25 | } 26 | 27 | /*二次探测函数*/ 28 | static int second_hash(char *key) 29 | { 30 | int len, ret, i; 31 | 32 | if(!key) 33 | return 0; 34 | len = strlen(key); 35 | ret = key[0] << 4 + key[0]; 36 | for(i = 1; i < len; i ++) 37 | ret ^= key[i] << 4 + key[i]; 38 | ret ^= len; 39 | return (ret & 0x7FFFFFFF); 40 | } 41 | 42 | static struct HashNode* _get_node() 43 | { 44 | return (struct HashNode*)mm_malloc(sizeof(struct HashNode)); 45 | } 46 | 47 | /*向hash表中插入节点,只能用于导入原有的hash表内容*/ 48 | static void _insert(struct HashTable *table, struct HashNode *node) 49 | { 50 | int index = _get_empty(table, node->key); 51 | table->head[index] = node; 52 | } 53 | 54 | /*调整hash表的容量*/ 55 | static void _resize(struct HashTable *table) 56 | { 57 | int size = table->capacity; 58 | int new_size = size << 1; 59 | int i; 60 | struct HashNode **head = table->head; 61 | 62 | /*重新分配hash表的存储空间*/ 63 | table->head = (struct HashNode**)mm_malloc(new_size * sizeof(struct HashNode)); 64 | memset(table->head, 0, new_size * sizeof(struct HashNode*)); 65 | table->number = 0; 66 | table->capacity = new_size; 67 | /*导入原先的内容*/ 68 | for(i = 0; i < size; i ++) 69 | { 70 | if(head[i] != NULL && head[i] != DUMMY) 71 | { 72 | _insert(table, head[i]); 73 | table->number ++; 74 | } 75 | } 76 | mm_free(head); 77 | } 78 | 79 | /** 80 | * 寻找制定key值对应的节点的索引 81 | **/ 82 | static int _find(struct HashTable *table, char* key) 83 | { 84 | struct HashNode **head; 85 | int hash_value; 86 | int begin; 87 | if(!table || !key) 88 | return -1; 89 | head = table->head; 90 | hash_value = hash_func(key) % table->capacity; 91 | begin = hash_value; 92 | if(!head[hash_value]) 93 | return -1; 94 | 95 | if(head[hash_value] == DUMMY || strcmp(key, head[hash_value]->key) != 0) 96 | { 97 | /*进行二次探测*/ 98 | hash_value = second_hash(key) % table->capacity; 99 | if(!head[hash_value]) 100 | return -1; 101 | // 102 | if(head[hash_value] == DUMMY || strcmp(key, head[hash_value]->key) != 0) 103 | { 104 | //hash_value = (hash_value + 1) % table->number; 105 | begin = hash_value; 106 | while(1) 107 | { 108 | hash_value = (hash_value + 1) % table->capacity; 109 | /*空节点或者找了一圈*/ 110 | if(!head[hash_value] || begin == hash_value) 111 | return -1; 112 | if(head[hash_value] != DUMMY && strcmp(key, head[hash_value]->key) == 0) 113 | return hash_value; 114 | } 115 | 116 | } 117 | else 118 | return hash_value; 119 | } 120 | else 121 | return hash_value; 122 | 123 | } 124 | 125 | /*找到一个空闲的位置*/ 126 | static int _get_empty(struct HashTable *table, char *key) 127 | { 128 | int hash_value ; 129 | struct HashNode **head; 130 | if(!table || !key) 131 | return -1; 132 | 133 | head = table->head; 134 | //一次探测 135 | hash_value = hash_func(key) % table->capacity; 136 | if(!head[hash_value] || head[hash_value] == DUMMY) 137 | return hash_value; 138 | //二次探测 139 | hash_value = second_hash(key) % table->capacity; 140 | if(!head[hash_value] || head[hash_value] == DUMMY) 141 | return hash_value; 142 | //递增hash_value探测 143 | while(1) 144 | { 145 | hash_value = (hash_value + 1) % table->capacity; 146 | if(!head[hash_value] || head[hash_value] == DUMMY) 147 | return hash_value; 148 | } 149 | } 150 | 151 | /*创建一个hash表*/ 152 | struct HashTable* hash_new(int pre_max/*预估的最大节点数量的1.5倍*/, 153 | int (*key_equal)(void *k1, void *k2), 154 | void* (*copy_value)(void *src), 155 | void (*free_value)(void *value)) 156 | { 157 | struct HashTable* table = (struct HashTable*)mm_malloc(sizeof(struct HashTable)); 158 | pre_max = (pre_max >= 3) ? pre_max : 3; 159 | table->head = (struct HashNode**)mm_malloc(pre_max * sizeof(struct HashNode*)); 160 | memset(table->head, 0, pre_max * sizeof(struct HashNode*)); 161 | table->key_equal = key_equal; 162 | table->copy_value = copy_value; 163 | table->free_value = free_value; 164 | table->capacity = pre_max; 165 | table->number = 0; 166 | return table; 167 | } 168 | 169 | 170 | /*向hash表中插入一组数据*/ 171 | void hash_insert(struct HashTable *table, char *key, void *value) 172 | { 173 | int index; 174 | struct HashNode *node; 175 | 176 | if(!table || !key) 177 | return; 178 | 179 | index = _find(table, key); 180 | if(index == -1) 181 | { 182 | if(TRIGGER(table->capacity, table->number + 1)) 183 | _resize(table); 184 | index = _get_empty(table, key); 185 | node = (struct HashNode*)mm_malloc(sizeof(struct HashNode)); 186 | node->key = (char*)mm_malloc(strlen(key) + 1); 187 | strcpy(node->key, key); 188 | if(table->copy_value) 189 | node->value = table->copy_value(value); 190 | else 191 | node->value = value; 192 | table->head[index] = node; 193 | table->number ++; 194 | } 195 | else 196 | { 197 | 198 | if(table->free_value) 199 | table->free_value(table->head[index]->value); 200 | if(table->copy_value) 201 | table->head[index]->value = table->copy_value(value); 202 | else 203 | table->head[index]->value = value; 204 | } 205 | } 206 | 207 | 208 | /*获得指定key值的value*/ 209 | void* hash_get(struct HashTable *table, char *key) 210 | { 211 | int index; 212 | if(!table || !key) 213 | return NULL; 214 | index = _find(table, key); 215 | if(index == -1) 216 | return NULL; 217 | return table->head[index]->value; 218 | } 219 | 220 | void hash_del(struct HashTable *table, char *key) 221 | { 222 | int index; 223 | struct HashNode *node; 224 | if(!table || !key) 225 | return; 226 | index = _find(table, key); 227 | if(index == -1) 228 | return; 229 | node = table->head[index]; 230 | mm_free(node->key); 231 | if(table->free_value) 232 | table->free_value(node->value); 233 | mm_free(node); 234 | } 235 | 236 | /** 237 | * 创建一个hash表的迭代器 238 | **/ 239 | HashIter* hash_create_iter(struct HashTable *table) 240 | { 241 | struct HashIter *iter = (struct HashIter*)mm_malloc(sizeof(struct HashIter)); 242 | if(!iter || !table) 243 | return NULL; 244 | iter->table = table; 245 | iter->index = 0; 246 | return iter; 247 | } 248 | 249 | /** 250 | * 251 | **/ 252 | struct HashNode* hash_next(HashIter *iter) 253 | { 254 | int i = 0; 255 | 256 | if(!iter) 257 | return NULL; 258 | for(i = iter->index; i < iter->table->capacity; i ++) 259 | { 260 | if(iter->table->head[i] != NULL && iter->table->head != DUMMY) 261 | { 262 | iter->index = i + 1; 263 | return iter->table->head[i]; 264 | } 265 | } 266 | return NULL; 267 | } 268 | 269 | 270 | static int key_equal_str(void *k1, void *k2) 271 | { 272 | char *_k1 = (char*)k1; 273 | char *_k2 = (char*)k2; 274 | return strcmp(_k1, _k2); 275 | } 276 | 277 | static void* copy_value_str(void *value) 278 | { 279 | char *_v = (char*)value; 280 | char *ret; 281 | if(!_v) 282 | return NULL; 283 | ret = (char*)mm_malloc(strlen(_v) + 1); 284 | strcpy(ret, _v); 285 | return ret; 286 | } 287 | 288 | static void free_value_str(void *value) 289 | { 290 | mm_free(value); 291 | } 292 | 293 | struct HashTable* hash_new_str(int pre_max/*预估的最大节点数量的1.5倍*/) 294 | { 295 | return hash_new(pre_max, key_equal_str, copy_value_str, free_value_str); 296 | } 297 | 298 | /*向hash表中插入一组数据*/ 299 | void insert_str(struct HashTable *table, char *key, char *value) 300 | { 301 | hash_insert(table, key, value);struct HashTable *var_table; 302 | } 303 | 304 | /*获得指定key值的value*/ 305 | char* get_str(struct HashTable *table, char *key) 306 | { 307 | (char*)hash_get(table, key); 308 | } 309 | 310 | /*删除制定key值的节点*/ 311 | void del_str(struct HashTable *table, char *key) 312 | { 313 | hash_del(table, key); 314 | } 315 | 316 | #ifdef HASH_DEBUG 317 | 318 | int main(int argc, char **argv) 319 | { 320 | char *kws[] = {"hello", "demo", "Ok", "fuck", "ass", "hole", "god", "charge", "hello", "bitch"}; 321 | struct HashTable *table = hash_new(3, key_equal, copy_value, free_value); 322 | int i; 323 | for(i = 0; i < sizeof(kws) / sizeof(char*); i ++) 324 | { 325 | hash_insert(table, kws[i], kws[i]); 326 | } 327 | for(i = 0; i < sizeof(kws) / sizeof(char*); i ++) 328 | { 329 | hash_del(table, kws[i]); 330 | } 331 | printf("%s %s\n", (char*)hash_get(table, "hello"), (char*)hash_get(table, "fuck")); 332 | hash_insert(table, "hello", "bitch"); 333 | printf("%s\n", (char*)hash_get(table, "hello")); 334 | 335 | return 0; 336 | } 337 | #endif -------------------------------------------------------------------------------- /lib/scanner.c: -------------------------------------------------------------------------------- 1 | #include "scanner.h" 2 | #include "hash.h" 3 | #include "register.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "util.h" 15 | #include "thread_pool.h" 16 | /** 17 | * 18 | **/ 19 | /*默认的扫描函数*/ 20 | static struct scan_func_info _default_scanner_info; 21 | /*已废弃*/ 22 | struct scan_func_info *default_scanner_info = &_default_scanner_info; 23 | 24 | /*用于全局扫描(扫描全部端口)*/ 25 | struct linear_node *global_scanner = NULL; 26 | /*扫描的线程池*/ 27 | static struct thread_pool *scan_thread_pool; 28 | /*选用的扫描方式*/ 29 | static int scan_method = SCAN_GENERAL; 30 | /*注册的扫描函数表*/ 31 | struct HashTable *scanner_table = NULL; 32 | /*扫描结果*/ 33 | struct linear_node *scan_reslut = NULL; 34 | /**/ 35 | struct sockaddr_in global_sockaddr; 36 | /*over函数的链表*/ 37 | struct linear_node *over_lists = NULL; 38 | static char nic[256]; 39 | 40 | struct sockaddr_in* get_scan_addr() 41 | { 42 | return &global_sockaddr; 43 | } 44 | 45 | /** 46 | * 添加一个全局扫描器 47 | **/ 48 | int add_global_scanner(int (*func)(int), int type) 49 | { 50 | struct scan_func_info *scan_func_info; 51 | struct linear_node *node; 52 | if(!func) 53 | { 54 | errno = EINVAL; 55 | return -1; 56 | } 57 | node = (struct linear_node*)mm_malloc(sizeof(struct linear_node)); 58 | if(!node) 59 | { 60 | errno = ENOMEM; 61 | return -1; 62 | } 63 | scan_func_info = (struct scan_func_info*)mm_malloc(sizeof(struct scan_func_info)); 64 | if(!scan_func_info) 65 | { 66 | mm_free(node); 67 | errno = ENOMEM; 68 | return -1; 69 | } 70 | scan_func_info->scan_func = func; 71 | scan_func_info->type = type; 72 | node->next = NULL; 73 | node->data = (void*)scan_func_info; 74 | if(!global_scanner) 75 | global_scanner = node; 76 | else 77 | { 78 | node->next = global_scanner->next; 79 | global_scanner->next = node; 80 | } 81 | return 0; 82 | } 83 | 84 | int add_over_func(void (*func)(), int type) 85 | { 86 | struct over_func_info *over_func_info; 87 | struct linear_node *node; 88 | 89 | node = (struct linear_node*)mm_malloc(sizeof(struct linear_node)); 90 | if(!node) 91 | goto error1; 92 | over_func_info = (struct over_func_info*)mm_malloc(sizeof(struct over_func_info)); 93 | if(!over_func_info) 94 | goto error2; 95 | over_func_info->over = func; 96 | over_func_info->type = type; 97 | node->data = (void*)over_func_info; 98 | node->next = NULL; 99 | if(!over_lists) 100 | over_lists = node; 101 | else 102 | { 103 | node->next = over_lists->next; 104 | over_lists->next = node; 105 | } 106 | return 0; 107 | error2: 108 | mm_free(node); 109 | error1: 110 | errno = ENOMEM; 111 | return -1; 112 | } 113 | 114 | /*获得本机的ip,已转为网络字节序*/ 115 | u_int32_t get_local_ip(int fd) 116 | { 117 | struct ifreq if_data; 118 | u_int32_t addr_p; 119 | 120 | strcpy (if_data.ifr_name, nic); 121 | if (ioctl (fd, SIOCGIFADDR, &if_data) < 0) 122 | { 123 | /* 124 | *取名为eth0的的IP地址 125 | *这是个interface的地址 126 | */ 127 | perror("ioctl"); 128 | exit(1); 129 | } 130 | memcpy ((void *) &addr_p, (void *) &if_data.ifr_addr.sa_data + 2, 4); 131 | return addr_p; 132 | } 133 | /*所有的开放端口*/ 134 | static int open_ports[] = {21, 25, 80, 53, 110}; 135 | 136 | /*半开扫描*/ 137 | static int half_scanner(int port) 138 | { 139 | char buffer[8192]; 140 | int raw_sock; 141 | struct sockaddr_in *_dest; 142 | int ret; 143 | static u_int32_t seq = 0x12345678; 144 | struct sockaddr_in dest; 145 | int sock_len; 146 | int i = 0; 147 | struct tcphdr *tcp; 148 | u_int32_t current_seq = seq; 149 | u_int32_t dst_ip; 150 | 151 | /*创建用于发送tcp包的原始套接字*/ 152 | raw_sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); 153 | if(raw_sock < 0) 154 | { 155 | perror("socket"); 156 | return -errno; 157 | } 158 | /*获取扫描地址*/ 159 | _dest = get_scan_addr(); 160 | memcpy(&dest, _dest, sizeof(dest)); 161 | //dest = *dest; 162 | dest.sin_port = htons(port); 163 | /*构造syn包*/ 164 | memcpy(&dst_ip, &dest.sin_addr, 4); 165 | ret = tcp_syn_pack((struct tcphdr*)buffer, 8192, get_local_ip(raw_sock), dst_ip, 5643, port, seq ++); 166 | if(ret < 0) 167 | { 168 | perror("tcp_syn_pack"); 169 | return ret; 170 | } 171 | //print_pack(buffer, ret); 172 | //ip_pack((struct ip*)buffer, IPPROTO_TCP, 255) 173 | /*发送*/ 174 | ret = sendto(raw_sock, buffer, ret, 0, (struct sockaddr*)&dest, sizeof(dest)); 175 | if(ret < 0) 176 | { 177 | perror("sendto"); 178 | return -errno; 179 | } 180 | /*接收对应的报文*/ 181 | sock_len = sizeof(dest); 182 | /*尝试接收20次,每次间隔100ms,所以最长延迟2s*/ 183 | for(i = 0; i < 40; i ++) 184 | { 185 | ret = recvfrom(raw_sock, buffer, 8192, MSG_DONTWAIT,(struct sockaddr*)&dest, &sock_len); 186 | if(ret < 0 && (errno != EAGAIN) && (errno != EWOULDBLOCK)) 187 | { 188 | perror("recvfrom"); 189 | close(raw_sock); 190 | return 0; 191 | } 192 | else if(ret >= sizeof(struct ip) + sizeof(struct tcphdr)) 193 | { 194 | /*定位到tcp报文*/ 195 | tcp = (struct tcphdr*)(buffer + ((struct ip*)buffer)->ip_hl * 4); 196 | /*检测是否是合格的确认报文*/ 197 | if(tcp->ack && tcp->seq && tcp->ack_seq == htonl(current_seq + 1)) 198 | { 199 | scanner_log("主机打开了端口:%10d\n", port); 200 | //fflush(stdout); 201 | close(raw_sock); 202 | return 1; 203 | } 204 | //printf("recv one %x %x %x\n", tcp->ack, tcp->syn, ntohl(tcp->ack_seq)); 205 | } 206 | usleep(10 * 1000); 207 | } 208 | //printf("The host didn't open %d\n", port); 209 | //fflush(stdout); 210 | close(raw_sock); 211 | return 0; 212 | } 213 | 214 | /*用于扫描函数表的内部函数*/ 215 | static int key_equal(void *k1, void *k2) 216 | { 217 | return strcmp((char*)k1, (char*)k2); 218 | } 219 | 220 | static void* copy_value(void *src) 221 | { 222 | return src; 223 | } 224 | 225 | static void free_value(void *value) 226 | { 227 | ; 228 | } 229 | 230 | int scanner_init(char *addr, int _scan_method, char *_nic) 231 | { 232 | unsigned long inaddr; 233 | struct hostent *host; 234 | 235 | /*设置默认的扫函数*/ 236 | default_scanner_info->scan_func = half_scanner; 237 | default_scanner_info->type = SCAN_HALF; 238 | /*初始化扫描结果*/ 239 | scan_reslut = NULL; 240 | 241 | /*初始化扫描函数表*/ 242 | scanner_table = hash_new(10, key_equal, copy_value, free_value); 243 | if(!scanner_table) 244 | return -1; 245 | /*解析地址*/ 246 | memset((void*)&global_sockaddr, 0, sizeof(global_sockaddr)); 247 | inaddr = inet_addr(addr); 248 | if(inaddr == INADDR_NONE) 249 | { 250 | host = gethostbyname(addr); 251 | if(!host) 252 | { 253 | printf("gethostbyname"); 254 | return -1; 255 | } 256 | memcpy((char*)&global_sockaddr.sin_addr, host->h_addr, host->h_length); 257 | } 258 | else 259 | { 260 | memcpy((char*)&global_sockaddr.sin_addr, (char*)&inaddr, sizeof(inaddr)); 261 | } 262 | global_sockaddr.sin_family = AF_INET; 263 | /*初始化线程池*/ 264 | scan_thread_pool = thread_pool_create(200); 265 | if(!scan_thread_pool) 266 | { 267 | perror("thread_pool_create"); 268 | return -1; 269 | } 270 | /*扫描方式*/ 271 | scan_method = _scan_method; 272 | /*设置网卡*/ 273 | strcpy(nic, _nic); 274 | /*将半开扫描设为全局扫描器*/ 275 | return add_global_scanner(half_scanner, SCAN_HALF); 276 | } 277 | 278 | /** 279 | * 记录扫描成功的端口信息 280 | * 281 | */ 282 | static int record_scan_ok(int port, int type) 283 | { 284 | struct linear_node *linear_node; 285 | struct scan_result_node *result; 286 | 287 | result = (struct scan_result_node*)mm_malloc(sizeof(struct scan_result_node)); 288 | if(!result) 289 | goto error1; 290 | linear_node = (struct linear_node*)mm_malloc(sizeof(struct linear_node)); 291 | if(!linear_node) 292 | goto error2; 293 | result->port = port; 294 | result->type = type; 295 | linear_node->data = (void*)result; 296 | linear_node->next = NULL; 297 | if(!scan_reslut) 298 | { 299 | scan_reslut = linear_node; 300 | } 301 | else 302 | { 303 | linear_node->next = scan_reslut->next; 304 | scan_reslut->next = linear_node; 305 | } 306 | return 0; 307 | error2: 308 | mm_free(result); 309 | error1: 310 | errno = ENOMEM; 311 | return -errno; 312 | } 313 | 314 | /*用来扫描某个具体的端口*/ 315 | static void _scan_one(void *arg) 316 | { 317 | int port = (int)arg; 318 | char number_buffer[10]; 319 | struct linear_node *linear_node; 320 | int ret; 321 | int (*scan_func)(int port); 322 | 323 | sprintf(number_buffer, "%d", port); 324 | 325 | /*调用全局的函数*/ 326 | linear_node = global_scanner; 327 | while(linear_node) 328 | { 329 | if(scan_method == SCAN_GENERAL || ((struct scan_func_info*)linear_node->data)->type == scan_method) 330 | { 331 | scan_func = ((struct scan_func_info*)linear_node->data)->scan_func; 332 | ret = scan_func(port); 333 | if(ret == 1) 334 | { 335 | 336 | } 337 | } 338 | linear_node = linear_node->next; 339 | } 340 | 341 | /*调用注册函数*/ 342 | linear_node = (struct linear_node*)hash_get(scanner_table, number_buffer); 343 | 344 | while(linear_node) 345 | { 346 | if(scan_method == SCAN_GENERAL || ((struct scan_func_info*)linear_node->data)->type == scan_method) 347 | { 348 | scan_func = ((struct scan_func_info*)linear_node->data)->scan_func; 349 | ret = scan_func(port); 350 | if(ret == 1) 351 | { 352 | 353 | } 354 | } 355 | linear_node = linear_node->next; 356 | } 357 | } 358 | 359 | static void scan_one(int port) 360 | { 361 | thread_distribute(scan_thread_pool, _scan_one, (void*)port); 362 | } 363 | 364 | /*扫描结束,调用处理函数*/ 365 | static void _over_handle(void *arg) 366 | { 367 | struct linear_node *node = over_lists; 368 | 369 | while(node) 370 | { 371 | if(scan_method == SCAN_GENERAL || scan_method == ((struct over_func_info*)node->data)->type) 372 | { 373 | ((struct over_func_info*)node->data)->over(); 374 | } 375 | node = node->next; 376 | } 377 | } 378 | 379 | static void over_handle() 380 | { 381 | thread_distribute(scan_thread_pool, _over_handle, NULL); 382 | } 383 | /** 384 | * 扫描器开始工作 385 | * @type 扫描方式 386 | * @arg1, @arg2 由方式解释 387 | */ 388 | int scanner_work(int type, int arg1, int arg2) 389 | { 390 | int i = 0; 391 | long k; 392 | 393 | switch(type) 394 | { 395 | case SCAN_OPEN_PORT_ONLY: 396 | for(i = 0; i < sizeof(open_ports) / sizeof(int); i ++) 397 | { 398 | scan_one(open_ports[i]); 399 | } 400 | break; 401 | case SCAN_LOW: 402 | for(i = 0; i < 1024; i ++) 403 | { 404 | scan_one(i); 405 | } 406 | break; 407 | case SCAN_HIGH: 408 | for(i = 1025; i <= PORT_MAX; i ++) 409 | scan_one(i); 410 | break; 411 | case SCAN_ALL: 412 | for(i = 0; i <= PORT_MAX; i ++) 413 | scan_one(i); 414 | break; 415 | case SCAN_PART: 416 | for(i = 0; i < 2000; i ++) 417 | scan_one(i); 418 | break; 419 | case SCAN_FIXED: 420 | scan_one(arg1); 421 | break; 422 | case SCAN_RANGE: 423 | for(i = arg1; i <= arg2; i ++) 424 | scan_one(i); 425 | break; 426 | case SCAN_LOW_RAND_HIGH: 427 | for(i = 0; i < 1024; i ++) 428 | scan_one(i); 429 | srandom(time(NULL)); 430 | for(i = 1025; i <= PORT_MAX; i += 100) 431 | { 432 | k = random(); 433 | k %= 100; 434 | scan_one(i + k); 435 | } 436 | break; 437 | default: 438 | errno = EINVAL; 439 | return -EINVAL; 440 | } 441 | /*收尾处理*/ 442 | over_handle(); 443 | return 0; 444 | } 445 | 446 | void scan_exit() 447 | { 448 | thread_pool_destroy(scan_thread_pool); 449 | } 450 | 451 | --------------------------------------------------------------------------------