From ff at octo.it Fri Feb 13 14:24:36 2015 From: ff at octo.it (Florian Forster) Date: Fri, 13 Feb 2015 14:24:36 +0100 Subject: [liboping] liboping patches In-Reply-To: References: Message-ID: <20150213132436.GE9096@verplant.org> 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 (IPv4) or C (IPv6) option. It is the caller's > responsibility to chose a valid bit combination. For details, read the L > and L manual pages, as well as I2474>. > > +=item B > + > +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 on platforms which don't have SO_MARK. > + > =back > > The I 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: