新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > Linux實用技巧 用ICMP實現簡單的Ping功能

        Linux實用技巧 用ICMP實現簡單的Ping功能

        作者: 時間:2016-10-08 來源:網絡 收藏

        如果目的主機在工 輸出在工狀態 如果5妙內無相應 用SIGALRM信號中斷進程

        本文引用地址:http://www.104case.com/article/201610/305451.htm

        #include unp.h

        void send_echo_req(int sockfd, struct sockaddr_in *dstaddr);

        uint16_t in_cksum(uint16_t *addr, int len);

        void recv_echo_reply(int sockfd);

        int main(int argc, char **argv)

        {

        int sockfd;

        struct sockaddr_in dstaddr;

        if ((sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1)

        err_sys(socket);

        bzero(dstaddr, sizeof(dstaddr));

        dstaddr.sin_family = AF_INET;

        dstaddr.sin_port = htons(0);

        if (inet_pton(AF_INET, argv[1], dstaddr.sin_addr) = 0)

        err_sys(inet_pton);

        send_echo_req(sockfd, dstaddr);

        recv_echo_reply(sockfd);

        exit(0);

        }

        void send_echo_req(int sockfd, struct sockaddr_in *dstaddr)

        {

        char buf[100];

        size_t len = sizeof(struct icmp);

        struct icmp *icmp;

        socklen_t dstlen = sizeof(struct sockaddr_in);

        bzero(buf, sizeof(buf));

        icmp = (struct icmp *)buf;

        icmp->icmp_type = ICMP_ECHO;

        icmp->icmp_code = 0;

        icmp->icmp_id = getpid();

        icmp->icmp_seq = 1;

        icmp->icmp_cksum = in_cksum((uint16_t *) icmp, sizeof(struct icmp));

        if (sendto(sockfd, buf, len, 0, (SA *)dstaddr, dstlen) == -1)

        err_sys(sendto);

        }

        void recv_echo_reply(int sockfd)

        {

        char buf[100];

        ssize_t n;

        struct ip *ip;

        struct icmp *icmp;

        while (1) {

        alarm(5); /* set timeout */

        if ((n = read(sockfd, buf, sizeof(buf))) == -1)

        err_sys(read);

        ip = (struct ip *)buf;

        if (ip->ip_p != IPPROTO_ICMP) {

        fprintf(stderr, protocol error.rn);

        exit(1);

        }

        icmp = (struct icmp *)(buf + sizeof(struct ip));

        if (icmp->icmp_type == ICMP_ECHOREPLY) {

        if (icmp->icmp_id != getpid()) {

        fprintf(stderr, not this process.rn);

        exit(1);

        } else {

        printf(destination host is alive.rn);

        break;

        }

        }

        }

        }

        uint16_t in_cksum(uint16_t *addr, int len)

        {

        int nleft = len;

        uint32_t sum = 0;

        uint16_t *w = addr;

        uint16_t answer = 0;

        while (nleft > 1) {

        sum += *w++;

        nleft -= 2;

        }

        if (nleft == 1) {

        *(unsigned char *)(answer) = *(unsigned char *)w ;

        sum += answer;

        }

        sum = (sum >> 16) + (sum 0xffff);

        sum += (sum >> 16);

        answer = ~sum;

        return(answer);

        }

        void err_sys(const char *errmsg)

        {

        perror(errmsg);

        exit(1);

        }



        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 赣榆县| 新乡市| 西丰县| 章丘市| 友谊县| 广西| 台州市| 晋宁县| 台南市| 望江县| 曲松县| 正定县| 德江县| 车险| 镇沅| 辽宁省| 英山县| 新乡县| 松江区| 龙江县| 新乐市| 通江县| 蒲江县| 上杭县| 肃宁县| 凤山市| 大足县| 嘉禾县| 奈曼旗| 吉隆县| 南平市| 绥德县| 芜湖县| 尼勒克县| 恩施市| 隆昌县| 常熟市| 苏州市| 南充市| 彭山县| 香格里拉县|