热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ICMP协议写的ping函数

ICMP是(InternetControlMessageProtocol)Internet控制报文协议。它是TCPIP协议族的一个子协议,

ICMP是(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。

 

unsigned short cal_chksum(unsigned short *addr, int len)
{
    int nleft=len;
    int sum=0;
    unsigned short *w=addr;
    unsigned short 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;
}

 

 

int ping( char *ips, int timeout)
{
    struct timeval timeo;
    int sockfd;
    struct sockaddr_in addr;
    struct sockaddr_in from;

 

    struct timeval *tval;
    struct ip *iph;
    struct icmp *icmp;

 

    char sendpacket[PACKET_SIZE];
    char recvpacket[PACKET_SIZE];

 

    int n, ret = SUCCESS;
    pid_t pid;
    int maxfds = 0, CountNum = 0;
    fd_set readfds;

 

    bzero(&addr,sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(ips);  

 

    sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    if (sockfd <0)
    {
        syslog(LOG_INFO,"ip:%s,socket error",ips);
        return ERROR;
    }

 

    timeo.tv_sec &#61; timeout / 1000;
    timeo.tv_usec &#61; timeout % 1000;

 

    if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo)) &#61;&#61; -1)
    {
        syslog(LOG_INFO,"ip:%s,setsockopt error",ips);
        close(sockfd);
        return ERROR;
    }

 

    memset(sendpacket, 0, sizeof(sendpacket));

 

    // PID ping Sequence ID
    pid&#61;getpid();
    int i,packsize;
    icmp&#61;(struct icmp*)sendpacket;
    icmp->icmp_type&#61;ICMP_ECHO;
    icmp->icmp_code&#61;0;
    icmp->icmp_cksum&#61;0;
    icmp->icmp_seq&#61;0;
    icmp->icmp_id&#61;pid;
    packsize&#61;8&#43;56;
    tval&#61; (struct timeval *)icmp->icmp_data;
    gettimeofday(tval,NULL);
    icmp->icmp_cksum&#61;cal_chksum((unsigned short *)icmp,packsize);

 

    n &#61; sendto(sockfd, (char *)&sendpacket, packsize, 0, (struct sockaddr *)&addr, sizeof(addr));
    if (n <1)
    {
        printf("ip:%s,sendto error.\n",ips);
        close(sockfd);
        return ERROR;
    }

 

    CountNum &#61; 0;
    while(CountNum&#43;&#43;    {
        FD_ZERO(&readfds);
        FD_SET(sockfd, &readfds);
        maxfds &#61; sockfd &#43; 1;
        n &#61; select(maxfds, &readfds, NULL, NULL, &timeo);
        if (n <&#61; 0)
        {
            printf("ip:%s,Time out error.\n",ips);
            ret&#61; ERROR;
            break;
        }

 

        //accept
        memset(recvpacket, 0, sizeof(recvpacket));
        int fromlen &#61; sizeof(from);
        n &#61; recvfrom(sockfd, recvpacket, sizeof(recvpacket), 0, (struct sockaddr *)&from, &fromlen);
        if (n <1)
        {
            printf("ip:%s, recvfrom error.\n",ips);
            ret&#61; ERROR;
            break;
        }

 

        // Check this echo reply if belong to myself
        char *from_ip &#61; (char *)inet_ntoa(from.sin_addr);
        printf("fomr ip:%s.\n",from_ip);
        if (strcmp(from_ip,ips) !&#61; 0)
        {
            printf("ip:%s,Ip wrong.\n",ips);
            ret &#61; ERROR;
            break;
        }

 

        iph &#61; (struct ip *)recvpacket;

 

        icmp&#61;(struct icmp *)(recvpacket &#43; (iph->ip_hl<<2));

 

        printf("ip:%s,icmp->icmp_type:%d,icmp->icmp_id:%d.\n",ips,icmp->icmp_type,icmp->icmp_id);
        //check reply contents
        if (icmp->icmp_type &#61;&#61; ICMP_ECHOREPLY && icmp->icmp_id &#61;&#61; pid)
        {
            //ping success
            ret &#61; SUCCESS;
            break;
        }
        else
        {
            //continue wait
            continue;
        }
    }

 

    close(sockfd);

 

    if(ret &#61;&#61; SUCCESS)
    {
        printf("Connect:%s success!\n",ips);
    }
    else
    {
        printf("Connect:%s FAIL!!!\n",ips);
    }
    return ret;
}

 

转:https://www.cnblogs.com/zcblogs/p/3644920.html



推荐阅读
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • javascript分页类支持页码格式
    前端时间因为项目需要,要对一个产品下所有的附属图片进行分页显示,没考虑ajax一张张请求,所以干脆一次性全部把图片out,然 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 在List和Set集合中存储Object类型的数据元素 ... [详细]
  • Python 程序转换为 EXE 文件:详细解析 .py 脚本打包成独立可执行文件的方法与技巧
    在开发了几个简单的爬虫 Python 程序后,我决定将其封装成独立的可执行文件以便于分发和使用。为了实现这一目标,首先需要解决的是如何将 Python 脚本转换为 EXE 文件。在这个过程中,我选择了 Qt 作为 GUI 框架,因为之前对此并不熟悉,希望通过这个项目进一步学习和掌握 Qt 的基本用法。本文将详细介绍从 .py 脚本到 EXE 文件的整个过程,包括所需工具、具体步骤以及常见问题的解决方案。 ... [详细]
  • 浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • JUC(三):深入解析AQS
    本文详细介绍了Java并发工具包中的核心类AQS(AbstractQueuedSynchronizer),包括其基本概念、数据结构、源码分析及核心方法的实现。 ... [详细]
  • importpymysql#一、直接连接mysql数据库'''coonpymysql.connect(host'192.168.*.*',u ... [详细]
  • 本文详细介绍了如何使用Python中的smtplib库来发送带有附件的邮件,并提供了完整的代码示例。作者:多测师_王sir,时间:2020年5月20日 17:24,微信:15367499889,公司:上海多测师信息有限公司。 ... [详细]
  • 通过使用Sqoop导入工具,可以精确控制并高效地将表数据的特定子集导入到HDFS中。具体而言,可以通过在导入命令中添加WHERE子句来指定所需的数据范围,从而在数据库服务器上执行相应的SQL查询,并将查询结果高效地存储到HDFS中。这种方法不仅提高了数据导入的灵活性,还确保了数据的准确性和完整性。 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 在处理数据库中所有用户表的彻底清除时,目前尚未发现单一命令能够实现这一目标。因此,需要采用一种较为繁琐的方法来逐个删除相关表及其结构。具体操作可以通过编写PL/SQL脚本来实现,该脚本将动态生成并执行删除表的SQL语句。尽管这种方法相对复杂,但在缺乏更简便手段的情况下,仍是一种有效的解决方案。未来或许可以通过数据库管理工具或更高版本的数据库系统提供更简洁的处理方式。 ... [详细]
  • 在探讨 MySQL 正则表达式 REGEXP 的功能与应用之前,我们先通过一个小实验来对比 REGEXP 和 LIKE 的性能。通过具体的代码示例,我们将评估这两种查询方式的效率,以确定 REGEXP 是否值得深入研究。实验结果将为后续的详细解析提供基础。 ... [详细]
  • 在重新安装Ubuntu并配置Django和PyCharm后,忘记测试MySQL连接,导致在后续配置过程中遇到错误:ERROR 2003 (HY000) - 无法连接到本地服务器 ‘127.0.0.1’ (111)。本文将详细介绍该错误的原因及解决步骤,帮助用户快速恢复MySQL服务的正常运行。我们将从检查网络配置、验证MySQL服务状态、配置防火墙规则等方面入手,提供全面的故障排除指南。 ... [详细]
author-avatar
弱柳纤纤_
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有