要求
利用socket中的sock_stream套接字实现一个TCP公开扫描程序,要求:
输入
用户通过程序可以设定扫描的目的地址;
用户可以设定扫描端口的范围;
输出
显示被扫描目标开启了那些端口;
程序的验证:
在shell下输入命令“netstat -lnt”,对比自己程序的输出结果
基本流程
注意点
printf("%d\t%s\n",start_port,servent_pointer->s_name);
当 servent_pointer->s_name 为NULL的时候,执行这句语句会造成段错误。
- 扫描127.0.0.1 和 192.168.43.122 的执行结果是不同的。
完整代码
/*tcpscan.c*/
#include<stdlib.h>
#include<stdio.h>
#include<sys/socket.h>
#include<netdb.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
int is_connect(int port, char *addr)
{
int sockfd;
struct sockaddr_in server;
int ret;
int stat = 1;
sockfd=socket(AF_INET,SOCK_STREAM,0);
if (-1==sockfd)
{
perror("can not create socket\n");
exit(-1);
}
memset(&server,0,sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(addr);
server.sin_port = htons(port);
ret=connect(sockfd,(struct sockaddr*)&server,sizeof(struct sockaddr));
close(sockfd);
if(ret<0)
{
ret = 0;
}else{
ret = 1;
}
return ret;
}
int main(int argc,char** argv)
{
if(4!= argc)
{
fprintf(stderr,"%s scanIP start_port end_port\n",argv[0]);
exit(1);
}
struct servent *servent_pointer ;
int start_port = atoi(argv[2]);
int end_port = atoi(argv[3]);
printf("servent_pointer:%s\n",argv[1]);
printf("start_port:%d\n",start_port);
printf("end_port:%d\n",end_port);
for(; start_port<= end_port ; start_port++ )
{
if(is_connect(start_port,argv[1]) > 0)
{
servent_pointer = getservbyport(htons(start_port),NULL);
if(servent_pointer != NULL)
{
printf("%d\t%s\n",start_port,servent_pointer->s_name);
}else{
printf("%d\tunkown\n",start_port);
}
}
}
return 0;
}
运行步骤
- 运行netstat -lnt,查看本地端口开放情况
-
在root用户下编译源文件,生成可执行文件
-
扫描本地端口
./tcpscan 127.0.0.1 1 10000
./tcpscan 192.168.43.122 1 10000
- 对比自己程序的输出结果与“netstat -lnt”的输出结果
自己程序输出结果正确