Merge branches 'mark' and 'timeout'
authorFlorian Forster <ff@octo.it>
Fri, 13 Feb 2015 12:46:06 +0000 (13:46 +0100)
committerFlorian Forster <ff@octo.it>
Fri, 13 Feb 2015 12:46:06 +0000 (13:46 +0100)
src/liboping.c
src/mans/ping_setopt.pod
src/oping.c
src/oping.h

index 40a0ba2..dd9da46 100644 (file)
@@ -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) /* {{{ */
                {
index 11c63d8..ba7e44f 100644 (file)
@@ -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
index 3ae226c..6263a4d 100644 (file)
@@ -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;
index 9f8d5e1..e5bc5fa 100644 (file)
@@ -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