Code

liboping: Add support for SO_MARK.
authorDaniel Collins <daniel.collins@smoothwall.net>
Thu, 9 Jan 2014 11:38:54 +0000 (11:38 +0000)
committerFlorian Forster <ff@octo.it>
Fri, 13 Feb 2015 11:54:01 +0000 (12:54 +0100)
Marks packets, which can be used for filtering and routing in Linux.

src/liboping.c
src/mans/ping_setopt.pod
src/oping.h

index 40a0ba21b570bab19fea04fc71d8c69231125173..dd9da461b9baa4efef879367579e56ea956979d2 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 11c63d8f13b3d454b47ce939a02973be4508d3c6..ba7e44feb3ae2962dbbde019ac0e9620f750c9ae 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 9f8d5e18b25044a6b5f74c91120beabcf881bbc6..e5bc5fa9c284e981d137a17a40751b3e62a55a0e 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