想象一个海湾, 许多私人船停靠在这里。该位置称为海港, 字面上是海上或海上的港口。每个想要停靠那里, 请求登陆服务的人都使用相同的端口。海港使用分配给各个船的泊位号来工作。港口名称和泊位号组合成船只识别的"谁, 什么, 在哪里"。
ip地址和端口的概念相似。这里的sea_port_name类似于IP地址, 而后者与network_port_no匹配。
端口编号是为了保持一致性和进行编程。最常用和最知名的端口是专用于Internet的编号为0到1023的端口, 但出于特殊目的, 它们可以扩展得更高。每个端口组或范围都被分配了专门的工作或功能, 这通常就是它们的全部工作。通常, 所有相同的系统服务或功能在接收服务器上使用相同的端口号, 并且无论情况如何, 它们都保持一致。
当犯罪分子将房屋作为抢劫目标时, 通常他或她检查的第一件事是是否有打开的窗户或门可以通过它进入房屋。安全技术人员通常使用称为端口扫描程序的设备/软件, 使他们可以扫描所有端口以审核计算机是否存在漏洞。只要个人计算机上有开放端口, 就可能会丢失数据, 感染病毒, 甚至可能会破坏整个系统。
开发端口扫描程序并不像看起来那样困难。扫描仪的最终结果如下:
INPUT : IPv4 address, Port Range
FUNCTION : Enter an IP address and a port range
where the program will then attempt to
find open ports on the given computer
by connecting to each of them. On any
successful connection ports, mark the
port as open.
OUTPUT : Status of port (open/closed)
创建端口扫描程序的三步过程
步骤1:建立main()
我们创建一个main()函数, 该函数接受必需的参数(server_ip, start_port, end_port)。服务器IP必须为IPv4, 尽管我们也可以将其扩展为接受IPv6。自己尝试!
int main(int argc, char *argv[])
{
if (argc <4)
{
printf ("Please enter the server IP address"
" and range of ports to be scanned\n");
printf ("USAGE: %s IPv4 First_Port Last_Port\n", argv[0]);
exit(1);
}
char tIP[16] = {0};
strcpy(tIP, argv[1]); //Copy the IPv4 address
char First_Port[6] = {0};
strcpy(First_Port, argv[2]); //Copy the start_port
char Last_Port[6] = {0};
strcpy(Last_Port, argv[3]); //Copy the end_port
//Start port-scanner
port_scanner(tIP, First_Port, Last_Port);
return 0;
}
步骤2:建立port_scanner()
- 创建一个新函数port_scanner()。我们遍历所提供范围内的所有端口, 然后对每个端口进行检查。
- 创建一个" struct addrinfo提示", 并使用适当的值对其进行初始化。
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
"提示"是指向结构addrinfo的可选指针, 如所定义。此结构可用于提供有关调用者支持或希望使用的套接字类型的提示。 –从FreeBSD手册页。
- 为将从服务器获取的server_address初始化一个指针。
现在, 打电话" getaddrinfo(tIP, tport, &hints和&serv_addr)"具有适当的参数。 getaddrinfo()函数分配并初始化一个addrinfo结构的链接列表, 该列表针对与节点和服务匹配的每个网络地址, 受提示强加的任何限制, 并在第4个参数中返回指向列表开头的指针, 在这个案例 "serv_addr"。链接列表中的项目通过ai_next领域。
附加信息:
链表可能具有多个addrinfo结构的原因有很多, 其中包括:网络主机是多宿主的, 可以通过多种协议访问(例如, AF_INET和AF_INET6);或者可以从多种套接字类型(例如, 一个SOCK_STREAM地址和另一个SOCK_DGRAM地址)获得相同的服务。
通常, 应用程序应尝试按返回地址的顺序使用地址。
步骤3:连接插座
遍历链表中收到的所有addrinfo, 并创建一个套接字。上面获得的addrinfo结构中包含" socket()"的值。 (使用指针" temp"遍历linked_list的每个节点。)
sockfd = socket(temp->ai_family, temp->ai_socktype, temp->ai_protocol);
if (sockfd <0)
{
printf("Port %d is NOT open.\n", port);
continue;
}
如果套接字创建失败, 请尝试使用其他节点中的值。一旦套接字创建成功, 请尝试使用" connect()"连接到它。如果连接成功, 那么恭喜你, 套接字已打开, 否则尝试使用其他addrinfo节点。如果它们都无法通过linked_list工作, 则套接字已关闭。这是相同的代码,
status = connect(sockfd, temp->ai_addr, temp->ai_addrlen);
if (status<0)
{
printf("Port %d is NOT open.\n", port);
close(sockfd);
continue;
}
printf("Port %d is open.\n", port);
close(sockfd);
" freeaddrinfo()"函数释放为动态分配的链接列表" serv_addr"分配的内存。最好使用它代替" free()"。
可以从以下位置下载本教程的完整源代码这里.
注意:该程序的代码并不长, 但是如何使用getaddrinfo导出地址非常重要。 c中几乎所有的网络应用程序都具有相似的前两个步骤。第三步取决于应用程序的目的.
有关freeaddrinfo返回的结构的更多信息, 请阅读这个有关套接字参数的文档和详细信息, 请参阅这个文档。
关于作者:
Pinkesh Badjatiya来自海得拉巴IIIT的冰雹。他是一个极富建议心的极客。可见他的项目工作这里。
如果你还希望在此处展示你的博客, 请参阅日志用于在lsbin上撰写访客博客。