int ident; /* our pid */
int socket4 = 0;
#ifndef IPV6
-int *allsocket[2] = { &socket4, NULL };
int hints_ai_family = AF_INET;
#else
int socket6 = 0;
-int *allsocket[3] = { &socket4, &socket6, NULL };
int hints_ai_family = AF_UNSPEC;
#endif
switch( c )
{
case '4':
+ if(hints_ai_family != AF_UNSPEC) {
+ fprintf(stderr, "%s: can't specify both -4 and -6\n", prog);
+ exit(1);
+ }
hints_ai_family = AF_INET;
- // FIXME: check that -4 and -6 not used together
break;
case '6':
+#ifdef IPV6
+ if(hints_ai_family != AF_UNSPEC) {
+ fprintf(stderr, "%s: can't specify both -4 and -6\n", prog);
+ exit(1);
+ }
hints_ai_family = AF_INET6;
- // FIXME: check that -4 and -6 not used together
+#else
+ fprintf(stderr, "%s: IPv6 not supported by this binary\n", prog);
+ exit(1);
+#endif
break;
case 'M':
#ifdef IP_MTU_DISCOVER
- {
+ if(socket4) {
int val = IP_PMTUDISC_DO;
- int **sp;
- for(sp=&allsocket[0]; *sp; sp++) {
- if (setsockopt(**sp, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val))) {
- perror("setsockopt IP_MTU_DISCOVER");
- }
+ if (setsockopt(socket4, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val))) {
+ perror("setsockopt IP_MTU_DISCOVER");
+ }
+ }
+ if(socket6) {
+ int val = IPV6_PMTUDISC_DO;
+ if (setsockopt(socket6, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val, sizeof(val))) {
+ perror("setsockopt IPV6_MTU_DISCOVER");
}
}
#else
- fprintf(stderr, "-M option not supported on this platform\n");
+ fprintf(stderr, "%s, -M option not supported on this platform\n", prog);
exit(1);
#endif
break;
case 'I':
#ifdef SO_BINDTODEVICE
- {
- int **sp;
- for(sp=&allsocket[0]; *sp; sp++) {
- if (setsockopt(**sp, SOL_SOCKET, SO_BINDTODEVICE, optarg, strlen(optarg))) {
- perror("binding to specific interface (SO_BINTODEVICE)");
- }
+ if(socket4) {
+ if (setsockopt(socket4, SOL_SOCKET, SO_BINDTODEVICE, optarg, strlen(optarg))) {
+ perror("binding to specific interface (SO_BINTODEVICE)");
}
}
+#ifdef IPV6
+ if(socket6) {
+ if (setsockopt(socket6, SOL_SOCKET, SO_BINDTODEVICE, optarg, strlen(optarg))) {
+ perror("binding to specific interface (SO_BINTODEVICE), IPV6");
+ }
+ }
+#endif
#else
printf( "%s: cant bind to a particular net interface since SO_BINDTODEVICE is not supported on your os.\n", argv[0] );
exit(3);;
case 'O':
if (sscanf(optarg,"%i",&tos)){
- int **sp;
- for(sp=&allsocket[0]; *sp; sp++) {
- if ( setsockopt(**sp, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) {
+ if(socket4) {
+ if ( setsockopt(socket4, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) {
perror("setting type of service octet IP_TOS");
}
}
+#ifdef IPV6
+ if(socket6) {
+ if ( setsockopt(socket6, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos))) {
+ perror("setting type of service octet IPV6_TCLASS");
+ }
+ }
+#endif
}
else {
usage(1);
}/* SWITCH */
}/* WHILE */
+ /* if we are called 'fping6', assume '-6' */
+ if(strstr(argv[0], "fping6")) {
+ hints_ai_family = AF_INET6;
+ }
+
/* validate various option settings */
if (ttl > 255) {
- fprintf(stderr, "ttl %u out of range\n", ttl);
+ fprintf(stderr, "%s: ttl %u out of range\n", prog, ttl);
exit(1);
}
if( unreachable_flag && alive_flag )
{
- fprintf( stderr, "%s: specify only one of a, u\n", argv[0] );
+ fprintf( stderr, "%s: specify only one of a, u\n", prog);
exit(1);
}/* IF */
if( count_flag && loop_flag )
{
- fprintf( stderr, "%s: specify only one of c, l\n", argv[0] );
+ fprintf( stderr, "%s: specify only one of c, l\n", prog);
exit(1);
}/* IF */
/* set the TTL, if the -H option was set (otherwise ttl will be = 0) */
if(ttl > 0) {
- int **sp;
- for(sp=&allsocket[0]; *sp; sp++) {
- if (setsockopt(**sp, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl))) {
+ if(socket4) {
+ if (setsockopt(socket4, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl))) {
perror("setting time to live");
}
}
+#ifdef IPV6
+ if(socket6) {
+ if (setsockopt(socket6, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl))) {
+ perror("setting time to live");
+ }
+ }
+#endif
}
#if HAVE_SO_TIMESTAMP
{
int opt = 1;
- int **sp;
- for(sp=&allsocket[0]; *sp; sp++) {
- if (setsockopt(**sp, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt))) {
+ if(socket4) {
+ if (setsockopt(socket4, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt))) {
perror("setting SO_TIMESTAMP option");
}
}
+#ifdef IPV6
+ if(socket6) {
+ if (setsockopt(socket6, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt))) {
+ perror("setting SO_TIMESTAMP option (IPv6)");
+ }
+ }
+#endif
}
#endif
addr_hints.ai_flags = AI_NUMERICHOST;
ret = getaddrinfo(addr, NULL, &addr_hints, &addr_res);
if(ret) {
- fprintf(stderr, "Error: can't parse address %s: %s\n", addr, gai_strerror(ret));
+ fprintf(stderr, "%s, can't parse address %s: %s\n", prog, addr, gai_strerror(ret));
exit(1);
}
if(addr_res->ai_family != AF_INET) {
- fprintf(stderr, "Error: -g works only with IPv4 addresses\n");
+ fprintf(stderr, "%s: -g works only with IPv4 addresses\n", prog);
exit(1);
}
net_addr = ntohl(((struct sockaddr_in *) addr_res->ai_addr)->sin_addr.s_addr);
/* check mask */
if(mask < 1 || mask > 32) {
- fprintf(stderr, "Error: netmask must be between 1 and 32 (is: %s)\n", mask_str);
+ fprintf(stderr, "%s: netmask must be between 1 and 32 (is: %s)\n", prog, mask_str);
exit(1);
}
addr_hints.ai_flags = AI_NUMERICHOST;
ret = getaddrinfo(start, NULL, &addr_hints, &addr_res);
if(ret) {
- fprintf(stderr, "Error: can't parse address %s: %s\n", start, gai_strerror(ret));
+ fprintf(stderr, "%s: can't parse address %s: %s\n", prog, start, gai_strerror(ret));
exit(1);
}
if(addr_res->ai_family != AF_INET) {
freeaddrinfo(addr_res);
- fprintf(stderr, "Error: -g works only with IPv4 addresses\n");
+ fprintf(stderr, "%s: -g works only with IPv4 addresses\n", prog);
exit(1);
}
start_long = ntohl(((struct sockaddr_in *) addr_res->ai_addr)->sin_addr.s_addr);
addr_hints.ai_flags = AI_NUMERICHOST;
ret = getaddrinfo(end, NULL, &addr_hints, &addr_res);
if(ret) {
- fprintf(stderr, "Error: can't parse address %s: %s\n", end, gai_strerror(ret));
+ fprintf(stderr, "%s: can't parse address %s: %s\n", prog, end, gai_strerror(ret));
exit(1);
}
if(addr_res->ai_family != AF_INET) {
freeaddrinfo(addr_res);
- fprintf(stderr, "Error: -g works only with IPv4 addresses\n");
+ fprintf(stderr, "%s: -g works only with IPv4 addresses\n", prog);
exit(1);
}
end_long = ntohl(((struct sockaddr_in *) addr_res->ai_addr)->sin_addr.s_addr);
freeaddrinfo(addr_res);
if(end_long > start_long + MAX_GENERATE) {
- fprintf(stderr, "Error: -g parameter generates too many addresses\n");
+ fprintf(stderr, "%s: -g parameter generates too many addresses\n", prog);
exit(1);
}
FILE *out = is_error ? stderr : stdout;
fprintf(out, "\n" );
fprintf(out, "Usage: %s [options] [targets...]\n", prog );
+ fprintf(out, " -4 only use IPv4 addresses\n" );
+ fprintf(out, " -6 only use IPv6 addresses\n" );
fprintf(out, " -a show targets that are alive\n" );
fprintf(out, " -A show targets by address\n" );
fprintf(out, " -b n amount of ping data to send, in bytes (default %d)\n", DEFAULT_PING_DATA_SIZE);