[liboping] liboping patches

Florian Forster ff at octo.it
Fri Feb 13 14:24:36 CET 2015


Hi Daniel,

first of all, sorry that it took me >1 year to reply :( I hope late is
better than never …

Thank you very much for your patches! I've merged them into master so
they will be included in the next release! If you find any problems (I
could, for example, picture my summary of what "mark" does to be
incorrect) please let me know :)

Best regards,
—octo

On Thu, Jan 09, 2014 at 11:38:54AM +0000, Daniel Collins wrote:
> Hi
> 
> I've implemented support for setting packet marks and exposed the
> timeout option through the oping program.
> 
> Any comments welcome :)
> 
> -- 
> Daniel Collins
> Junior Developer
> daniel.collins at smoothwall.net
> 
> Smoothwall Ltd
> Phone: +44 (0­) 8701 999500
> www.smoothwall.net
> 
> Smoothwall Limited is registered in England, Company Number: 4298247
> and whose registered address is 1 John Charles Way, Leeds, LS12 6QA
> United Kingdom

> diff --git a/src/liboping.c b/src/liboping.c
> index 74122a8..dbb441b 100644
> --- a/src/liboping.c
> +++ b/src/liboping.c
> @@ -142,6 +142,9 @@ struct pingobj
>  
>  	char                    *device;
>  
> +	char                    set_mark;
> +	int                     mark;
> +
>  	char                     errmsg[PING_ERRMSG_LEN];
>  
>  	pinghost_t              *head;
> @@ -1318,6 +1321,19 @@ int ping_setopt (pingobj_t *obj, int option, void *value)
>  		} /* case PING_OPT_DEVICE */
>  		break;
>  
> +		case PING_OPT_MARK:
> +		{
> +#ifdef SO_MARK
> +			obj->mark     = *(int*)(value);
> +			obj->set_mark = 1;
> +#else /* SO_MARK */
> +			ping_set_errno (obj, ENOTSUP);
> +			ret = -1;
> +#endif /* !SO_MARK */
> +			
> +		} /* case PING_OPT_MARK */
> +		break;
> +
>  		default:
>  			ret = -2;
>  	} /* switch (option) */
> @@ -1509,6 +1525,23 @@ int ping_host_add (pingobj_t *obj, const char *host)
>  			}
>  		}
>  #endif /* SO_BINDTODEVICE */
> +#ifdef SO_MARK
> +		if(obj->set_mark)
> +		{
> +			if(setsockopt(ph->fd, SOL_SOCKET, SO_MARK, &(obj->mark), sizeof(obj->mark)) != 0)
> +			{
> +#if WITH_DEBUG
> +				char errbuf[PING_ERRMSG_LEN];
> +				dprintf ("setsockopt (SO_MARK): %s\n",
> +						sstrerror (errno, errbuf, sizeof (errbuf)));
> +#endif
> +				ping_set_errno (obj, errno);
> +				close (ph->fd);
> +				ph->fd = -1;
> +				continue;
> +			}
> +		}
> +#endif
>  #ifdef SO_TIMESTAMP
>  		if (1) /* {{{ */
>  		{
> diff --git a/src/mans/ping_setopt.pod b/src/mans/ping_setopt.pod
> index 5331467..40bf238 100644
> --- a/src/mans/ping_setopt.pod
> +++ b/src/mans/ping_setopt.pod
> @@ -75,6 +75,12 @@ C<IP_TOS> (IPv4) or C<IPV6_TCLASS> (IPv6) option. It is the caller's
>  responsibility to chose a valid bit combination. For details, read the L<ip(7)>
>  and L<ipv6(7)> manual pages, as well as I<RFCE<nbsp>2474>.
>  
> +=item B<PING_OPT_MARK>
> +
> +Mark (as in netfilter) outgoing packets using the SO_MARK socket option. Takes
> +an int* pointer as a value. Setting this requires CAP_NET_ADMIN under Linux.
> +Fails with C<operation not supported> on platforms which don't have SO_MARK.
> +
>  =back
>  
>  The I<val> argument is a pointer to the new value. It must not be NULL. It is
> diff --git a/src/oping.h b/src/oping.h
> index cd7d62f..4af42b0 100644
> --- a/src/oping.h
> +++ b/src/oping.h
> @@ -53,6 +53,7 @@ typedef struct pingobj pingobj_t;
>  #define PING_OPT_SOURCE  0x10
>  #define PING_OPT_DEVICE  0x20
>  #define PING_OPT_QOS     0x40
> +#define PING_OPT_MARK    0x80
>  
>  #define PING_DEF_TIMEOUT 1.0
>  #define PING_DEF_TTL     255

> diff --git a/src/oping.c b/src/oping.c
> index 3cfe6d8..333bdad 100644
> --- a/src/oping.c
> +++ b/src/oping.c
> @@ -121,6 +121,7 @@ static double  opt_interval   = 1.0;
>  static int     opt_addrfamily = PING_DEF_AF;
>  static char   *opt_srcaddr    = NULL;
>  static char   *opt_device     = NULL;
> +static char   *opt_mark       = NULL;
>  static char   *opt_filename   = NULL;
>  static int     opt_count      = -1;
>  static int     opt_send_ttl   = 64;
> @@ -268,6 +269,7 @@ static void usage_exit (const char *name, int status) /* {{{ */
>  			"               Use \"-Q help\" for a list of valid options.\n"
>  			"  -I srcaddr   source address\n"
>  			"  -D device    outgoing interface name\n"
> +			"  -m mark      mark to set on outgoing packets\n"
>  			"  -f filename  filename to read hosts from\n"
>  
>  			"\noping "PACKAGE_VERSION", http://verplant.org/liboping/\n"
> @@ -471,7 +473,7 @@ static int read_options (int argc, char **argv) /* {{{ */
>  
>  	while (1)
>  	{
> -		optchar = getopt (argc, argv, "46c:hi:I:t:Q:f:D:");
> +		optchar = getopt (argc, argv, "46c:hi:I:t:Q:f:D:m:");
>  
>  		if (optchar == -1)
>  			break;
> @@ -526,6 +528,10 @@ static int read_options (int argc, char **argv) /* {{{ */
>  				opt_device = optarg;
>  				break;
>  
> +			case 'm':
> +				opt_mark = optarg;
> +				break;
> +
>  			case 't':
>  			{
>  				int new_send_ttl;
> @@ -1101,6 +1107,23 @@ int main (int argc, char **argv) /* {{{ */
>  		}
>  	}
>  
> +	if(opt_mark != NULL)
> +	{
> +		char *endp;
> +		int mark = strtoul(opt_mark, &endp, 0);
> +		if(opt_mark[0] != '\0' && *endp == '\0')
> +		{
> +			if(ping_setopt(ping, PING_OPT_MARK, (void*)(&mark)) != 0)
> +			{
> +				fprintf (stderr, "Setting mark failed: %s\n",
> +					ping_get_error (ping));
> +			}
> +		}
> +		else{
> +			fprintf(stderr, "Ignoring invalid mark: %s\n", optarg);
> +		}
> +	}
> +
>  	if (opt_filename != NULL)
>  	{
>  		FILE *infile;

> diff --git a/src/oping.c b/src/oping.c
> index 333bdad..2dd92ed 100644
> --- a/src/oping.c
> +++ b/src/oping.c
> @@ -118,6 +118,7 @@ typedef struct ping_context
>  } ping_context_t;
>  
>  static double  opt_interval   = 1.0;
> +static double  opt_timeout    = PING_DEF_TIMEOUT;
>  static int     opt_addrfamily = PING_DEF_AF;
>  static char   *opt_srcaddr    = NULL;
>  static char   *opt_device     = NULL;
> @@ -264,6 +265,7 @@ static void usage_exit (const char *name, int status) /* {{{ */
>  			"  -4|-6        force the use of IPv4 or IPv6\n"
>  			"  -c count     number of ICMP packets to send\n"
>  			"  -i interval  interval with which to send ICMP packets\n"
> +			"  -w timeout   time to wait for replies, in seconds\n"
>  			"  -t ttl       time to live for each ICMP packet\n"
>  			"  -Q qos       Quality of Service (QoS) of outgoing packets\n"
>  			"               Use \"-Q help\" for a list of valid options.\n"
> @@ -473,7 +475,7 @@ static int read_options (int argc, char **argv) /* {{{ */
>  
>  	while (1)
>  	{
> -		optchar = getopt (argc, argv, "46c:hi:I:t:Q:f:D:m:");
> +		optchar = getopt (argc, argv, "46c:hi:I:t:Q:f:D:m:w:");
>  
>  		if (optchar == -1)
>  			break;
> @@ -516,6 +518,23 @@ static int read_options (int argc, char **argv) /* {{{ */
>  						opt_interval = new_interval;
>  				}
>  				break;
> +
> +			case 'w':
> +			{
> +				char *endp;
> +				double t = strtod(optarg, &endp);
> +				if(optarg[0] != '\0' && *endp == '\0')
> +				{
> +					opt_timeout = t;
> +				}
> +				else{
> +					fprintf (stderr, "Ignoring invalid timeout: %s\n",
> +							optarg);
> +				}
> +
> +				break;
> +			}
> +
>  			case 'I':
>  				{
>  					if (opt_srcaddr != NULL)
> @@ -1086,6 +1105,12 @@ int main (int argc, char **argv) /* {{{ */
>  		/* printf ("ts_int = %i.%09li\n", (int) ts_int.tv_sec, ts_int.tv_nsec); */
>  	}
>  
> +	if (ping_setopt (ping, PING_OPT_TIMEOUT, (void*)(&opt_timeout)) != 0)
> +	{
> +		fprintf (stderr, "Setting timeout failed: %s\n",
> +				ping_get_error (ping));
> +	}
> +
>  	if (opt_addrfamily != PING_DEF_AF)
>  		ping_setopt (ping, PING_OPT_AF, (void *) &opt_addrfamily);
>  


-- 
Florian octo Forster
Hacker in training
GnuPG: 0x0C705A15
http://octo.it/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://mailman.verplant.org/pipermail/liboping/attachments/20150213/5a4ae74b/attachment.sig>


More information about the liboping mailing list