Linux Ping工具的源代码是如何实现网络连通性检测的?

Linux中的ping命令是一个用于测试网络连接的工具,它通过发送ICMP回显请求消息到目标主机并等待回应来检查网络的连通性,以下是一个简单的C语言实现的ping命令源代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <time.h>
#define PACKET_SIZE 64
#define MAX_WAIT_TIME 5000
int main(int argc, char *argv[]) {
    if (argc != 2) {
        printf("Usage: %s <hostname>n", argv[0]);
        exit(1);
    }
    struct hostent *host = gethostbyname(argv[1]);
    if (host == NULL) {
        perror("gethostbyname");
        exit(1);
    }
    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(80); // ICMP uses port 80
    memcpy(&server.sin_addr, host->h_addr, host->h_length);
    int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    if (sockfd < 0) {
        perror("socket");
        exit(1);
    }
    char packet[PACKET_SIZE];
    memset(packet, 0, PACKET_SIZE);
    // Set up the ICMP header
    struct icmphdr *icmp = (struct icmphdr *)packet;
    icmp->type = ICMP_ECHO;
    icmp->code = 0;
    icmp->checksum = 0; // Placeholder for checksum calculation
    icmp->un.echo.id = getpid();
    icmp->un.echo.sequence = 1;
    // Calculate checksum
    icmp->checksum = in_cksum((unsigned short *)icmp, sizeof(struct icmphdr));
    // Send the packet
    if (sendto(sockfd, packet, sizeof(packet), 0, (struct sockaddr *)&server, sizeof(server)) < 0) {
        perror("sendto");
        exit(1);
    }
    // Wait for a response
    struct timeval timeout;
    timeout.tv_sec = MAX_WAIT_TIME / 1000;
    timeout.tv_usec = (MAX_WAIT_TIME % 1000) * 1000;
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
    struct sockaddr_in from;
    socklen_t fromlen = sizeof(from);
    int bytes_received = recvfrom(sockfd, packet, PACKET_SIZE, 0, (struct sockaddr *)&from, &fromlen);
    if (bytes_received < 0) {
        perror("recvfrom");
        exit(1);
    }
    // Process the received packet
    icmp = (struct icmphdr *)packet;
    if (icmp->type == ICMP_ECHOREPLY && icmp->un.echo.id == getpid()) {
        printf("Received echo reply from %sn", argv[1]);
    } else {
        printf("No echo reply received from %sn", argv[1]);
    }
    close(sockfd);
    return 0;
}

这个示例代码仅用于演示目的,实际的ping命令会有更多的功能和错误处理,由于使用了原始套接字(SOCK_RAW),此代码可能需要以root权限运行。

Linux Ping工具的源代码是如何实现网络连通性检测的?插图1
(图片来源网络,侵删)

以上内容就是解答有关linux ping源代码的详细内容了,我相信这篇文章可以为您解决一些疑惑,有任何问题欢迎留言反馈,谢谢阅读。

Linux Ping工具的源代码是如何实现网络连通性检测的?插图3
(图片来源网络,侵删)

本文来源于互联网,如若侵权,请联系管理员删除,本文链接:https://www.9969.net/75839.html

小末小末
上一篇 2024年10月14日 00:09
下一篇 2024年10月14日 00:26

相关推荐