一、概述
IP Utils,也称为inetutils,是一个常用于网络操作的工具包,包含了多个工具,例如ping、traceroute、telnet、ftp等等。它也是Linux、Unix操作系统中的标准网络工具包之一。在本文中,我们将会对IP Utils提供的一些工具和API进行详细的介绍。
二、ping工具
ping命令是极为常见的网络工具之一,用来测试本地计算机与目标计算机之间的网络连接质量。在IP Utils中,我们可以使用以下代码段来实现对远程主机的ping操作:
#include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <netdb.h> int main(int argc, char *argv[]) { char *destip; struct hostent *host; struct sockaddr_in dest_addr; int sockfd, recv_bytes, optval; socklen_t optlen = sizeof(optval); if(argc != 2) { printf("Usage: %s <ipaddress>\n", argv[0]); return 0; } destip = argv[1]; sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, optlen); bzero(&dest_addr, sizeof(dest_addr)); dest_addr.sin_family = AF_INET; dest_addr.sin_addr.s_addr = inet_addr(destip); if((host = gethostbyname(destip)) != NULL) { bcopy(host->h_addr, &dest_addr.sin_addr, host->h_length); } printf("Ping %s...\n", argv[1]); while(1) { if(sendto(sockfd, NULL, 0, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) < 0) { perror("sendto"); break; } recv_bytes = recv(sockfd, NULL, 0, 0); if(recv_bytes > 0) { printf("%d bytes from %s: icmp_seq=1 ttl=%d\n", recv_bytes, destip, dest_addr.sin_family); } sleep(1); } close(sockfd); return 0; }
在上面的代码段中,我们使用了socket()函数来创建新的原始套接字。在setsockopt()函数中,我们开启了SO_REUSEADDR选项,这将允许我们在关闭后重新使用原始套接字。我们也使用了gethostbyname()函数,这将返回与远程主机对应的hostent结构体,其中包含了主机的IP地址。
三、traceroute工具
traceroute命令可以用来跟踪数据包在网络中传输的路径。在IP Utils中,我们可以使用以下代码段来实现traceroute操作:
#include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <netdb.h> #include <sys/time.h> #include <sys/socket.h> #define MAX_HOPS 64 int main(int argc, char *argv[]) { int ttl = 1; int sockfd, recv_bytes; char *destip; struct sockaddr_in dest_addr; char recv_buff[512]; struct timeval tv; if(argc != 2) { printf("Usage: %s <ipaddress>\n", argv[0]); return 0; } destip = argv[1]; bzero(&dest_addr, sizeof(dest_addr)); dest_addr.sin_family = AF_INET; dest_addr.sin_addr.s_addr = inet_addr(destip); sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); setsockopt(sockfd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)); printf("Traceroute to %s (%s), %d hops max\n", destip, inet_ntoa(dest_addr.sin_addr), MAX_HOPS); while(ttl <= MAX_HOPS) { setsockopt(sockfd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)); tv.tv_sec = 1; tv.tv_usec = 0; setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO,&tv, sizeof(tv)); struct sockaddr_in src_addr; socklen_t addrlen = sizeof(src_addr); bzero(&src_addr, sizeof(src_addr)); printf("%d\t", ttl); for(int i = 1; i <= 3; ++i) { gettimeofday(&tv, NULL); double t1 = tv.tv_sec * 1000 + (double)tv.tv_usec / 1000; if(sendto(sockfd, NULL, 0, 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr)) < 0) { printf("\t*\t"); continue; } if((recv_bytes = recvfrom(sockfd, recv_buff, sizeof(recv_buff), 0, (struct sockaddr*)&src_addr, &addrlen)) < 0) { printf("\t*\t"); continue; } gettimeofday(&tv, NULL); double t2 = tv.tv_sec * 1000 + (double)tv.tv_usec / 1000; double rtt = t2 - t1; printf("%.2fms\t", rtt); } printf("\n"); ++ttl; if(src_addr.sin_addr.s_addr == dest_addr.sin_addr.s_addr) { printf("%s\t", inet_ntoa(src_addr.sin_addr)); break; } } close(sockfd); return 0; }
在上面的代码段中,我们使用了SO_RCVTIMEO选项来在接收数据时设置超时时间。通过使用sendto()和recvfrom()函数,我们可以从套接字中接收和发送数据包。在traceroute中,我们不断地增加TTL,然后对目标计算机进行ping操作,以查找数据包传输的路径。如果路径中出现了与目标计算机的IP地址相同的主机,则可确定数据包已经到达目的地。
四、telnet工具
telnet命令是一种常用的用来远程连接计算机的工具。在IP Utils中,我们可以使用以下代码来实现telnet操作:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #define MAXLINE 4096 int main(int argc, char **argv) { int sockfd, n; char recvline[MAXLINE + 1]; struct sockaddr_in servaddr; if(argc != 3) { printf("usage: %s <ipaddress> <portnumber>\n", argv[0]); return 0; } if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); return 0; } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(atoi(argv[2])); if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) { printf("inet_pton error for %s\n", argv[1]); return 0; } if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) { perror("connect"); return 0; } while((n = read(sockfd, recvline, MAXLINE)) > 0) { recvline[n] = 0; if(fputs(recvline, stdout) == EOF) { perror("fputs"); return 0; } } if(n < 0) { perror("read"); return 0; } return 0; }
在上面的代码段中,我们使用了socket()函数来创建一个新的套接字,并使用connect()函数来将套接字连接到目标计算机。接着,我们可以使用read()函数来接收数据,并使用fputs()函数来将数据输出到控制台上。
五、结论
本文介绍了IP Utils网络工具包,并详细介绍了其中的几个常用工具,包括ping、traceroute、telnet等。通过使用这些工具,我们可以更好地了解网络和计算机之间的通信方式,并对网络连接进行更精确的测试和调试。