上一篇
如何深入理解Linux Ping命令的源码?
- 行业动态
- 2024-10-04
- 4467
Linux的ping命令源码可以在其内核源代码中找到,具体路径为:net/ipv4/icmp.c和net/core/dev.c。
Linux中的ping命令是一个网络诊断工具,用于测试主机之间网络的连通性,它通过发送ICMP回显请求消息到目标主机,并等待接收到ICMP回显应答消息来验证网络连接是否正常,以下是一个简单的ping命令源码实现,使用C语言编写:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <netinet/ip_icmp.h> #include <sys/socket.h> #include <sys/time.h> #include <sys/types.h> #define PACKET_SIZE 64 #define MAX_WAIT_TIME 5 unsigned short checksum(void *b, int len) { unsigned short *buf = b; unsigned int sum = 0; unsigned short result; for (sum = 0; len > 1; len = 2) sum += *buf++; if (len == 1) sum += *(unsigned char *)buf; sum = (sum >> 16) + (sum & 0xFFFF); sum += (sum >> 16); result = ~sum; return result; } int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: %s <IP address> ", argv[0]); exit(1); } struct sockaddr_in dest_addr; int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (sockfd < 0) { perror("socket error"); exit(1); } memset(&dest_addr, 0, sizeof(dest_addr)); dest_addr.sin_family = AF_INET; dest_addr.sin_addr.s_addr = inet_addr(argv[1]); char sendbuf[PACKET_SIZE]; memset(sendbuf, 0, PACKET_SIZE); struct icmphdr *icmp = (struct icmphdr *)sendbuf; icmp>type = ICMP_ECHO; icmp>code = 0; icmp>checksum = 0; icmp>un.echo.id = getpid(); icmp>un.echo.sequence = 1; icmp>checksum = checksum((unsigned short *)icmp, sizeof(struct icmphdr)); if (sendto(sockfd, sendbuf, sizeof(sendbuf), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) <= 0) { perror("sendto error"); exit(1); } struct timeval timeout; timeout.tv_sec = MAX_WAIT_TIME; timeout.tv_usec = 0; setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); char recvbuf[PACKET_SIZE]; struct sockaddr_in from; socklen_t fromlen = sizeof(from); int nbytes = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&from, &fromlen); if (nbytes < 0) { perror("recvfrom error"); exit(1); } struct icmphdr *icmp_recv = (struct icmphdr *)recvbuf; if (icmp_recv>type == ICMP_ECHOREPLY && icmp_recv>un.echo.id == getpid()) { printf("Received echo reply from %s, sequence = %u, time = %ld ms ", inet_ntoa(from.sin_addr), icmp_recv>un.echo.sequence, (long)(icmp_recv>un.echo.data / 1000)); } else { printf("No echo reply received from %s ", inet_ntoa(from.sin_addr)); } close(sockfd); return 0; }
这个程序首先创建一个原始套接字,然后构建一个ICMP回显请求数据包,并将其发送到指定的IP地址,程序设置一个超时时间,等待接收ICMP回显应答数据包,如果收到应答,程序将打印出相关信息,否则输出未收到应答的消息。
小伙伴们,上文介绍了“linux ping 源码”的内容,你了解清楚吗?希望对你有所帮助,任何问题可以给我留言,让我们下期再见吧。
本站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本站,有问题联系侵删!
本文链接:http://www.xixizhuji.com/fuzhu/11541.html