From: Florian Forster Date: Fri, 13 Feb 2015 12:46:06 +0000 (+0100) Subject: Merge branches 'mark' and 'timeout' X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=0a2a9fe209b27e37d15096fa730bac9520dfeced;hp=a336f1ecc9665dc1d2f20fd8dfe6d9a93bb41b25;p=liboping.git Merge branches 'mark' and 'timeout' --- diff --git a/src/liboping.c b/src/liboping.c index 40a0ba2..dd9da46 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; @@ -1322,6 +1325,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) */ @@ -1508,6 +1524,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 11c63d8..ba7e44f 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.c b/src/oping.c index 3ae226c..6263a4d 100644 --- a/src/oping.c +++ b/src/oping.c @@ -196,6 +196,7 @@ static double opt_timeout = PING_DEF_TIMEOUT; 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; @@ -437,6 +438,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" #if USE_NCURSES " -u / -U force / disable UTF-8 output\n" @@ -647,7 +649,7 @@ static int read_options (int argc, char **argv) /* {{{ */ while (1) { - optchar = getopt (argc, argv, "46c:hi:I:t:Q:f:D:Z:P:w:" + optchar = getopt (argc, argv, "46c:hi:I:t:Q:f:D:Z:P:m:w:" #if USE_NCURSES "uUg:" #endif @@ -724,6 +726,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; @@ -1756,6 +1762,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.h b/src/oping.h index 9f8d5e1..e5bc5fa 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