在ICMP協議的應用中,我們使用Ping命令進行操作的任務也是比較多的。那麽這裏我們主要介紹的就是Linux下用ICMP實現簡單的Ping功能。如果目的主機在工 輸出在工狀態 如果5妙內無相應 用SIGALRM信號中斷進程。那麽現在就讓我們看看具體的Linux下用ICMP實現的Ping功能具體的代碼進行壹下介紹吧。
1.#include "unp.h"
2.void send_echo_req(int sockfd, struct sockaddr_in *dstaddr);
3.uint16_t in_cksum(uint16_t *addr, int len);
4.void recv_echo_reply(int sockfd);
5.int main(int argc, char **argv)
6.{
7.int sockfd;
8.struct sockaddr_in dstaddr;
9.if ((sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1)
10.err_sys("socket");
11.bzero(&dstaddr, sizeof(dstaddr));
12.dstaddr.sin_family = AF_INET;
13.dstaddr.sin_port = htons(0);
14.if (inet_pton(AF_INET, argv[1], &dstaddr.sin_addr) <= 0)
15.err_sys("inet_pton");
16.send_echo_req(sockfd, &dstaddr);
17.recv_echo_reply(sockfd);
18.exit(0);
19.}
20.void send_echo_req(int sockfd, struct sockaddr_in *dstaddr)
21.{
22.char buf[100];
23.size_t len = sizeof(struct icmp);
24.struct icmp *icmp;
25.socklen_t dstlen = sizeof(struct sockaddr_in);
26.bzero(buf, sizeof(buf));
27.icmp = (struct icmp *)buf;
28.icmp->icmp_type = ICMP_ECHO;
29.icmp->icmp_code = 0;
30.icmp->icmp_id = getpid();
31.icmp->icmp_seq = 1;
32.icmp->icmp_cksum = in_cksum((uint16_t *) icmp, sizeof(struct icmp));
33.if (sendto(sockfd, buf, len, 0, (SA *)dstaddr, dstlen) == -1)
34.err_sys("sendto");
35.}
36.void recv_echo_reply(int sockfd)
37.{
38.char buf[100];
39.ssize_t n;
40.struct ip *ip;
41.struct icmp *icmp;
42.while (1) {
43.alarm(5); /* set timeout */
44.if ((n = read(sockfd, buf, sizeof(buf))) == -1)
45.err_sys("read");
46.ip = (struct ip *)buf;
47.if (ip->ip_p != IPPROTO_ICMP) {
48.fprintf(stderr, "protocol error.
49.");
50.exit(1);
51.}
52.icmp = (struct icmp *)(buf + sizeof(struct ip));
53.if (icmp->icmp_type == ICMP_ECHOREPLY) {
54.if (icmp->icmp_id != getpid()) {
55.fprintf(stderr, "not this process.
56.");
57.exit(1);
58.} else {
59.printf("destination host is alive.
60.");
61.break;
62.}
63.}
64.}
65.}
66.uint16_t in_cksum(uint16_t *addr, int len)
67.{
68.int nleft = len;
69.uint32_t sum = 0;
70.uint16_t *w = addr;
71.uint16_t answer = 0;
72.while (nleft > 1) {
73.sum += *w++;
74.nleft -= 2;
75.}
76.if (nleft == 1) {
77.*(unsigned char *)(&answer) = *(unsigned char *)w ;
78.sum += answer;
79.}
80.sum = (sum >> 16) + (sum & 0xffff);
81.sum += (sum >> 16);
82.answer = ~sum;
83.return(answer);
84.}
85.void err_sys(const char *errmsg)
86.{
87.perror(errmsg);
88.exit(1);
89.}
以上就是Linux ICMP的ping功能實現的具體代碼。