实验要求
- 能至少扫描5个IP地址;
- 针对每个iP地址,开设100个线程同时对其进行扫描;
- 如果端口打开,使用函数getservbyport获取其服务名,在屏幕上打印:IP port servername,如果是未知服务,则屏幕显示:ip port unkonown
实验环境
Red Hat 9
代码
ThreadsPortScan.c
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<errno.h>
void print_usage(char* str)
{
printf("the command %s usage is:\n",str);
printf("%s Ip_Address min_port max_port\n");
}
typedef struct portInfo{
struct in_addr dest_ip;
unsigned short int min_port;
unsigned short int max_port;
}Port;
int scanone(struct sockaddr_in scanip)
{
int sockfd;
if(-1==(sockfd=socket(AF_INET, SOCK_STREAM, 0)))
{
perror("error in generate socket\n");
exit(1);
}
int ret = connect(sockfd, (struct sockaddr*)&scanip, sizeof(scanip));
if(ret < 0){
if(errno == ECONNREFUSED)
{
close(sockfd);
return 0;
}
else{
close(sockfd);
return -1;
}
}
else if(ret == 0){
close(sockfd);
return 1;
}
return -1;
}
void *scanport(void* arg)
{
struct sockaddr_in scanip;
struct servent *serv;
char addr[100];
Port port;
int ret;
memcpy(&port, arg, sizeof(Port));
scanip.sin_family = AF_INET;
scanip.sin_addr.s_addr = port.dest_ip.s_addr;
unsigned short int i;
for(i=port.min_port; i<port.max_port; i++)
{
scanip.sin_port = htons(i);
ret = scanone(scanip);
if(ret == -1)
{
printf("scan port %d error.\n", i);
return;
}
else if(ret == 0)
continue;
else
{
serv = getservbyport(htons(i), "tcp");
inet_ntop(AF_INET, &scanip.sin_addr, addr, sizeof(addr));
if(NULL != serv)
printf("%s\t\t%d\t\tOPEN\t\t%s\n", addr, i, serv->s_name);
else
printf("%s\t\t%d\t\tOPEN\t\tUNKNOW\n", addr, i);
}
}
return;
}
int main(int argc, char**argv)
{
pthread_t *thread;
int sockfd;
struct servent* sp;
int min_port;
int max_port;
int thread_num;
struct in_addr scanip[5];
Port port;
if(argc < 3){
print_usage(argv[0]);
exit(-1);
}
int i;
for(i=0; i<argc-3; i++)
inet_aton(argv[i+1], &scanip[i]);
min_port = atoi(argv[i+1]);
max_port = atoi(argv[i+2]);
thread_num = 100;
//thread_num = atoi(argv[i+3]);
//if(max_port - min_port < thread_num)
//thread_num = max_port - min_port;
int len = (max_port - min_port) / thread_num;
if(max_port % thread_num != 0)
len++;
if((thread = (pthread_t*)malloc(sizeof(pthread_t) * thread_num * i)) == NULL)
printf("malloc thread error");
printf("\nAddress\t\t\tPort\t\tStatus\t\tProtocal\n");
int j, k;
for(j = 0; j < i; j++)
{
for(k=0; k < thread_num; k++)
{
Port port;
port.dest_ip = scanip[j];
port.min_port = k*len + min_port;
if(k == thread_num - 1)
port.max_port = max_port;
else
port.max_port = port.min_port + len - 1;
if(pthread_create(&thread[k+j*thread_num], NULL, scanport, (void*)&port)!=0)
{
free(thread);
printf("pthread_create error\n");
exit(-2);
}
//pthread_join(thread[k+j*thread_num], NULL);
}
for(k=0; k<thread_num; k++)
pthread_join(thread[k+j*thread_num], NULL);
}
if(thread != NULL)
free(thread);
return 0;
}
运行结果
由于没有太多的主机,因此只扫描了虚拟机和物理机两个IP地址。输入的命令表示目标主机IP(一个或多个,本程序设定最大个数为5个)、起始端口号、结束端口号,每个IP都会在这端口号范围内进行扫描。,且为100个并行线程。
来源:CSDN
作者:冷枭子
链接:https://blog.csdn.net/qq_42316621/article/details/104574047