]> git.ipfire.org Git - thirdparty/mtr.git/commitdiff
Add support for setting SO_MARK through --mark option. 48/head
authorJoão Taveira Araújo <joao.taveira@gmail.com>
Wed, 18 Jun 2014 18:55:52 +0000 (19:55 +0100)
committerJoão Taveira Araújo <joao.taveira@gmail.com>
Wed, 18 Jun 2014 18:55:52 +0000 (19:55 +0100)
This emulates the -m option for ping provided in iputils. When coupled
with iptables, this option provides a means of using source routing to
force probes through a consistent nexthop on multihomed systems.

mtr.c
net.c

diff --git a/mtr.c b/mtr.c
index 416b744bb310535988127448ecfc686c329239f8..722528631c50aeed15800476d5925c96b9e67693 100644 (file)
--- a/mtr.c
+++ b/mtr.c
@@ -76,6 +76,9 @@ int   enablempls = 0;
 int   cpacketsize = 64;          /* default packet size */
 int   bitpattern = 0;
 int   tos = 0;
+#ifdef SO_MARK
+int   mark = -1;
+#endif
 int   reportwide = 0;
 int af = DEFAULT_AF;
 int mtrtype = IPPROTO_ICMP;     /* Use ICMP as default packet type */
@@ -293,6 +296,9 @@ void parse_arg (int argc, char **argv)
 #ifdef IPINFO
     { "ipinfo", 1, 0, 'y' },    /* IP info lookup */
     { "aslookup", 0, 0, 'z' },  /* Do AS lookup (--ipinfo 0) */
+#endif
+#ifdef SO_MARK
+    { "mark", 1, 0, 'M' },      /* use SO_MARK */
 #endif
     { 0, 0, 0, 0 }
   };
@@ -470,6 +476,15 @@ void parse_arg (int argc, char **argv)
     case 'z':
       fprintf( stderr, "IPINFO not enabled.\n" );
       break;
+#endif
+#ifdef SO_MARK
+    case 'M':
+      mark = atoi (optarg);
+      if (mark < 0) {
+        fprintf( stderr, "SO_MARK must be positive.\n" );
+        exit(EXIT_FAILURE);
+      }
+      break;
 #endif
     }
   }
@@ -579,6 +594,9 @@ int main(int argc, char **argv)
 #ifdef IPINFO
            "\t\t[--ipinfo=item_no|-y item_no]\n"
            "\t\t[--aslookup|-z]\n"
+#endif
+#ifdef SO_MARK
+           "\t\t[--mark=NUM]\n"
 #endif
            "\t\t[--psize=bytes/-s bytes] [--order fields]\n"            /* ok */
            "\t\t[--report-wide|-w] [--inet] [--inet6] [--max-ttl=NUM] [--first-ttl=NUM]\n"
diff --git a/net.c b/net.c
index 0721ad71764e7546fd81ca7c742e3a0b63d95618..7d51fd029c06c8c21f658b3d8419fe5a3a188592 100644 (file)
--- a/net.c
+++ b/net.c
@@ -210,6 +210,9 @@ extern int af;                      /* address family of remote target */
 extern int mtrtype;            /* type of query packet used */
 extern int remoteport;          /* target port for TCP tracing */
 extern int timeout;             /* timeout for TCP connections */
+#ifdef SO_MARK
+extern int mark;               /* SO_MARK to set for ping packet*/
+#endif
 
 /* return the number of microseconds to wait before sending the next
    ping */
@@ -381,6 +384,13 @@ void net_send_tcp(int index)
 #endif
   }
 
+#ifdef SO_MARK
+    if (mark >= 0 && setsockopt( s, SOL_SOCKET, SO_MARK, &mark, sizeof mark ) ) {
+      perror( "setsockopt SO_MARK" );
+      exit( EXIT_FAILURE );
+    }
+#endif
+
   switch (local.ss_family) {
   case AF_INET:
     port = ntohs(local4->sin_port);
@@ -481,6 +491,13 @@ void net_send_query(int index)
 #endif
   }
 
+#ifdef SO_MARK
+    if (mark >= 0 && setsockopt( sendsock, SOL_SOCKET, SO_MARK, &mark, sizeof mark ) ) {
+      perror( "setsockopt SO_MARK" );
+      exit( EXIT_FAILURE );
+    }
+#endif
+
   switch ( mtrtype ) {
   case IPPROTO_ICMP:
     icmp = (struct ICMPHeader *)(packet + iphsize);