免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 704 | 回复: 0
打印 上一主题 下一主题

用icmp实现简单ping功能 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-31 12:45 |只看该作者 |倒序浏览
如果目的主机在工 输出在工状态 如果5妙内无相应 用SIGALRM信号中断进程
               
               
                #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.\r\n");
                        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.\r\n");
                                exit(1);
                        } else {
                                printf("destination host is alive.\r\n");
                                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);
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/39758/showart_350758.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP