fpingのsource addressパッチ
DebianのパッケージではSourceAddreess指定可能だったりするのでFreeBSD用に移植してみました。
元ネタ: debian specific patch information for fping / 2.4b2-to-ipv6-16.1
Source Addressパッチ
このパッチはportsのパッチがすでにあたってる状態で適応してください。
元ネタはdebian specific patch information for fping / 2.4b2-to-ipv6-16.1からのほぼそのままの部分移植です。
- % diff -c4 ./fping.c ~noel/temp/BKUP.fping.c
*** ./fping.c 2011-10-06 17:38:55.000000000 +0900 --- /home/noel/temp/BKUP.fping.c 2011-10-06 17:38:47.000000000 +0900 *************** *** 284,291 **** --- 284,297 ---- u_int ping_pkt_size; u_int count = 1; u_int trials; u_int report_interval = 0; + int src_addr_present = 0; + #ifndef IPV6 + struct in_addr src_addr; + #else + struct in6_addr src_addr; + #endif /* global stats */ long max_reply = 0; long min_reply = 1000000; *************** *** 409,416 **** --- 415,424 ---- int advance; struct protoent *proto; char *buf; uid_t uid; + FPING_SOCKADDR sa; + /* check if we are root */ if( geteuid() ) { *************** *** 492,500 **** opterr = 1; /* get command line options */ ! while( ( c = getopt( argc, argv, "gedhlmnqusaAvz:t:i:p:f:r:c:b:C:Q:B:" ) ) != EOF ) { switch( c ) { case 't': --- 500,508 ---- opterr = 1; /* get command line options */ ! while( ( c = getopt( argc, argv, "gedhlmnqusaAvz:t:i:p:f:r:c:b:C:Q:B:S:" ) ) != EOF ) { switch( c ) { case 't': *************** *** 633,641 **** }/* ELSE */ break; #endif /* ENABLE_F_OPTION */ ! case 'g': /* use IP list generation */ /* mutually exclusive with using file input or command line targets */ generate_flag = 1; --- 641,657 ---- }/* ELSE */ break; #endif /* ENABLE_F_OPTION */ ! case 'S': ! #ifndef IPV6 ! if( ! inet_pton( AF_INET, optarg, &src_addr ) ) ! #else ! if( ! inet_pton( AF_INET6, optarg, &src_addr ) ) ! #endif ! usage(); ! src_addr_present = 1; ! break; case 'g': /* use IP list generation */ /* mutually exclusive with using file input or command line targets */ generate_flag = 1; *************** *** 964,971 **** --- 980,1003 ---- if( !num_hosts ) exit( 2 ); + /* set the source address */ + + if( src_addr_present ) + { + memset( &sa, 0, sizeof( FPING_SOCKADDR ) ); + #ifndef IPV6 + sa.sin_family = AF_INET; + sa.sin_addr = src_addr; + #else + sa.sin6_family = AF_INET6; + sa.sin6_addr = src_addr; + #endif + if ( bind( s, (struct sockaddr *)&sa, sizeof( sa ) ) < 0 ) + errno_crash_and_burn( "cannot bind source address" ); + } + /* allocate array to hold outstanding ping requests */ table = ( HOST_ENTRY** )malloc( sizeof( HOST_ENTRY* ) * num_hosts ); if( !table ) *************** *** 2739,2746 **** --- 2771,2779 ---- fprintf( stderr, " -q quiet (don't show per-target/per-ping results)\n" ); fprintf( stderr, " -Q n same as -q, but show summary every n seconds\n" ); fprintf( stderr, " -r n number of retries (default %d)\n", retry ); fprintf( stderr, " -s print final stats\n" ); + fprintf( stderr, " -S addr set source address\n" ); fprintf( stderr, " -t n individual target initial timeout (in millisec) (default %d)\n", timeout / 100 ); fprintf( stderr, " -u show targets that are unreachable\n" ); fprintf( stderr, " -v show version\n" ); fprintf( stderr, " targets list of targets to check (if no -f specified)\n" );