Linux C/C++ fping命令(检查主机是否存在)

ping基本上是验证网络连接的最简单工具。我们可以验证专用或公共网络中任意两个设备之间的连接。但是今天我们要讲的是fping,因为fping是一个类似ping的程序,它使用Internet控制消息协议(ICMP)回显请求来确定目标主机是否正在响应。

fping与ping的不同之处在于,您可以在命令行上指定任意数量的目标,或者指定包含要ping的目标列表的文件。fping不会发送到一个目标直到超时或回复,而是发送一个ping数据包,然后以循环方式转到下一个目标。

在默认模式下,如果目标回复,则会将其标记并从要检查的目标列表中删除;如果目标在某个时间限制和/或重试限制内没有响应,则将其指定为不可访问。

fping 命令介绍

Usage: fping [options] [targets...]
   -a         show targets that are alive
   -A         show targets by address
   -b n       amount of ping data to send, in bytes (default 56)
   -B f       set exponential backoff factor to f
   -c n       count of pings to send to each target (default 1)
   -C n       same as -c, report results in verbose format
   -D         print timestamp before each output line
   -e         show elapsed time on return packets
   -f file    read list of targets from a file ( - means stdin) (only if no -g specified)
   -g         generate target list (only if no -f specified)
                (specify the start and end IP in the target list, or supply a IP netmask)
                (ex. fping -g 192.168.1.0 192.168.1.255 or fping -g 192.168.1.0/24)
   -H n       Set the IP TTL value (Time To Live hops)
   -i n       interval between sending ping packets (in millisec) (default 25)
   -I if      bind to a particular interface
   -l         loop sending pings forever
   -m         ping multiple interfaces on target host
   -M         set the Don't Fragment flag
   -n         show targets by name (-d is equivalent)
   -N         output compatible for netdata (-l -Q are required)
   -o         show the accumulated outage time (lost packets * packet interval)
   -O n       set the type of service (tos) flag on the ICMP packets
   -p n       interval between ping packets to one target (in millisec)
                (in looping and counting modes, default 1000)
   -q         quiet (don't show per-target/per-ping results)
   -Q n       same as -q, but show summary every n seconds
   -r n       number of retries (default 3)
   -R         random packet data (to foil link data compression)
   -s         print final stats
   -S addr    set source address
   -t n       individual target initial timeout (in millisec) (default 500)
   -T n       ignored (for compatibility with fping 2.4)
   -u         show targets that are unreachable
   -v         show version
   targets    list of targets to check (if no -f specified)

1.检查www.baidu.com是否存在


2. 检查192.168.227.1/24主机是否存在:

将同时显示多个IP地址,它将显示状态为活动或无法访问

3.从文件中读取目标列表

我们创建了一个名为fping.txt的文件,其IP地址到fping

  1. 检查192.168.227.1到192.168.227.5之间的主机是否存在

shell脚本快速判断网段内主机存活数

ping 检测的时候会一般加上-c参数来指定请求次数,避免使用Ctrl+C结束命令执行

在这里插入图片描述

当要检测的主机较多时,直接使用ping命令搬砖有点力不从心,写个脚本方便点。

### Main ###
if [ $# -ne 1 ]; then
	echo -e "Enter a single IPv4 addr, IPv4 range, or IPv4 addr with cidr.\n"
	echo "cmd example, bash liveSearcher.sh 172.16.0.0/16"
	echo "cmd example, bash liveSearcher.sh 192.18.1.0-1.254"    
	echo "cmd example, bash liveSearcher.sh 10.10.10.100"    

elif [ $1 == "--help" -o  $1 == "-h" ]; then
    echo -e "Enter a single IPv4 addr, IPv4 range, or IPv4 addr with cidr.\n"
	echo "cmd example, bash liveSearcher.sh 10.0.0.0/8"
	echo "cmd example, bash liveSearcher.sh 192.168.1.0-25.0.254"
	echo "cmd example, bash liveSearcher.sh 192.168.1.200"

# single IPv4 ping
elif [[ $1 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
	echo -e "Scanning " $1 '\n'
	ping -c1 $1 2>/dev/null|egrep -i "bytes from " |cut -d" " -f4,6 
	echo -e "\nLive host search:  Complete"
									
# range IPv4 sweep
elif [[ $1 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\-[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] || 
	 [[ $1 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\-[0-9]{1,3}\.[0-9]{1,3}$ ]] ||
	 [[ $1 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\-[0-9]{1,3}$ ]] && 
	 [[ $RANGELENGTH -eq 0 && ${RANGECHECK[0]} -gt ${IPRCHECK[3]} ]] || 
	 [[ $RANGELENGTH -eq 1 && ${RANGECHECK[0]} -gt ${IPRCHECK[2]} ]] || 
	 [[ $RANGELENGTH -eq 2 && ${RANGECHECK[0]} -gt ${IPRCHECK[1]} ]] &&
	 [[ ${RANGECHECK[0]} -le 255 && ${RANGECHECK[1]} -le 255 && ${RANGECHECK[2]} -le 255 ]] &&
	 [[ ${IPRCHECK[0]} -le 255 && ${IPRCHECK[1]} -le 255 && ${IPRCHECK[2]} -le 255 && ${IPRCHECK[3]} -le 255 ]]; then
	 range_sweep

# subnet IPv4 sweep
elif [[ $CIDR =~ [0-9]{1,2} ]] && 
	 [ $CIDR -le 30 -a $CIDR -ge 8 ] && 
	 [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] &&
	 [[ ${IPCHECK[0]} -le 255 && ${IPCHECK[1]} -le 255 && ${IPCHECK[2]} -le 255 && ${IPCHECK[3]} -le 255 ]]; then
	 subnet_sweep

else
	echo -e "\nerror in user input"
	exit 1
fi

运行结果:

在这里插入图片描述
fping命令代码实现



int main( int argc, char **argv )
{

...

    if(uid = getuid()) {
        seteuid( getuid() );
    }


...


    while( ( c = getopt( argc, argv, "gedhlmnqusaAvDz:t:H:i:p:f:r:c:b:C:Q:B:S:I:T:O:" ) ) != EOF )
    {
        switch( c )
        {
        case 't':
            if( !( timeout = ( unsigned int )atoi( optarg ) * 100 ) )
                usage(1);

            break;
        
        case 'r':
            retry = ( unsigned int )atoi( optarg );
            break;
        
        case 'i':
            if( !( interval = ( unsigned int )atoi( optarg ) * 100 ) )
                usage(1);

            break;

        case 'p':
            if( !( perhost_interval = ( unsigned int )atoi( optarg ) * 100 ) )
                usage(1);

            break;

        case 'c':
            if( !( count = ( unsigned int )atoi( optarg ) ) )
                usage(1);
            
            count_flag = 1;
            break;
        
        case 'C':
            if( !( count = ( unsigned int )atoi( optarg ) ) )
                usage(1);
            
            count_flag = 1;
            report_all_rtts_flag = 1;
            break;

        case 'b':
            errno = 0;
            ping_data_size = (unsigned int) strtol(optarg, (char **)NULL, 10);
            if( errno )
                usage(1);
            
            break;

        case 'h':
            usage(0);
            break;

        case 'q':
            verbose_flag = 0;
            quiet_flag = 1;
            break;

        case 'Q':
            verbose_flag = 0;
            quiet_flag = 1;
            if( !( report_interval = ( unsigned int )atoi( optarg ) * 100000 ) )
                usage(1);
            
            break;

        case 'e':
            elapsed_flag = 1;
            break;

        case 'm':
            multif_flag = 1;
            break;

        case 'd': 
        case 'n':
            name_flag = 1;
            break;

        case 'A':
            addr_flag = 1;
            break;

        case 'B':
            if( !( backoff = atof( optarg ) ) )
                usage(1);
            
            break;

        case 's':
            stats_flag = 1;
            break;

        case 'D':
            timestamp_flag = 1;
            break;

        case 'l':
            loop_flag = 1;
            backoff_flag = 0;
            break;

        case 'u':
            unreachable_flag = 1;
            break;

        case 'a':
            alive_flag = 1;
            break;

        case 'H':  
            if( !( ttl = ( u_int )atoi( optarg ) ))
                usage(1);
            break;  

        case 'v':
            printf( "%s: Version %s\n", argv[0], VERSION);
            printf( "%s: comments to %s\n", argv[0], EMAIL );
            exit( 0 );

        case 'f': 

            filename = optarg;
            generate_flag = 0;
            break;

        case 'g':

            generate_flag = 1;
            break;

        case 'S':
#ifndef IPV6
            if( ! inet_pton( AF_INET, optarg, &src_addr ) )
#else
            if( ! inet_pton( AF_INET6, optarg, &src_addr ) )
#endif
                usage(1);
            src_addr_present = 1;
            break;

        case 'I':

            printf( "%s: cant bind to a particular net interface since SO_BINDTODEVICE is not supported on your os.\n", argv[0] );

            break;

        case 'T':

            break;

        case 'O':
            if (sscanf(optarg,"%i",&tos))
            {
                if ( setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) 
                {
                    perror("setting type of service octet IP_TOS");
                }
            }
            break;
        default:
            usage(1);
            break;

        }
    }

...

    return 0;
}

...
long timeval_diff( struct timeval *a, struct timeval *b )
{
    long sec_diff = a->tv_sec - b->tv_sec;
    if(sec_diff == 0) 
    {
        return (a->tv_usec - b->tv_usec) / 10;
    }
    else if(sec_diff < 100) 
    {
        return (sec_diff * 1000000 + a->tv_usec - b->tv_usec) / 10;
    }
    else 
    {

        return sec_diff * 100000;
    }
}

void timeval_add(struct timeval *a, long t_10u)
{
    t_10u *= 10;
    a->tv_sec += (t_10u + a->tv_usec) / 1000000;
    a->tv_usec = (t_10u + a->tv_usec) % 1000000;
}

char * sprint_tm( int t )
{
    static char buf[10];

    if( t < 0 ) 
    {
        /* negative (unexpected) */
        sprintf( buf, "%.2g", (double) t / 100 );
    }
    else if( t < 100 ) 
    {
        /* <= 0.99 ms */
        sprintf( buf, "0.%02d", t );
    }
    else if( t < 1000 )
     {
        /* 1.00 - 9.99 ms */
        sprintf( buf, "%d.%02d", t / 100, t % 100 );
    }
    else if( t < 10000 ) 
    {
        /* 10.0 - 99.9 ms */
        sprintf( buf, "%d.%d", t / 100, ( t % 100 ) / 10 );
    }
    else if( t < 100000000 ) 
    {
        /* 100 - 1'000'000 ms */
        sprintf( buf, "%d", t / 100 );
    }
    else 
    {
        sprintf( buf, "%.2e", (double) (t / 100) );
    }

    return buf ;
}


If you need the complete source code of fping, please add WeChat number (c17865354792)​

总结

fping是一个小型命令行工具,用于向网络主机发送ICMP(Internet控制消息协议)回显请求,类似于ping,但在ping多个主机时性能更高。fping与ping的完全不同之处在于,您可以在命令行上定义任意数量的主机,或者使用要ping的IP地址或主机列表指定文件。

Welcome to follow WeChat official account【程序猿编码

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值