Implement ping(8)'s -L option in ping6:
authorflorian <florian@openbsd.org>
Sun, 25 Oct 2015 12:47:26 +0000 (12:47 +0000)
committerflorian <florian@openbsd.org>
Sun, 25 Oct 2015 12:47:26 +0000 (12:47 +0000)
Disable the loopback, so the transmitting host doesn't see the ICMP
requests. For multicast pings.
OK benno@

sbin/ping6/ping6.8
sbin/ping6/ping6.c

index b597b93..cbfa002 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ping6.8,v 1.57 2015/10/17 13:08:14 florian Exp $
+.\"    $OpenBSD: ping6.8,v 1.58 2015/10/25 12:47:26 florian Exp $
 .\"    $KAME: ping6.8,v 1.57 2002/05/26 13:18:25 itojun Exp $
 .\"
 .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -28,7 +28,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd $Mdocdate: October 17 2015 $
+.Dd $Mdocdate: October 25 2015 $
 .Dt PING6 8
 .Os
 .Sh NAME
@@ -36,7 +36,7 @@
 .Nd send ICMPv6 ECHO_REQUEST packets to network hosts
 .Sh SYNOPSIS
 .Nm ping6
-.Op Fl dEefHmnqv
+.Op Fl dEefHLmnqv
 .Op Fl c Ar count
 .Op Fl g Ar gateway
 .Op Fl h Ar hoplimit
@@ -132,6 +132,10 @@ The default is to wait for one second between each packet.
 This option is incompatible with the
 .Fl f
 option.
+.It Fl L
+Disable the loopback, so the transmitting host doesn't see the ICMP
+requests.
+For multicast pings.
 .It Fl l Ar preload
 If
 .Ar preload
index 47ab09d..02d0dc6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ping6.c,v 1.131 2015/10/24 16:59:15 florian Exp $     */
+/*     $OpenBSD: ping6.c,v 1.132 2015/10/25 12:47:26 florian Exp $     */
 /*     $KAME: ping6.c,v 1.163 2002/10/25 02:19:06 itojun Exp $ */
 
 /*
@@ -148,6 +148,10 @@ struct payload {
 #define F_AUD_MISS     0x400000
 u_int options;
 
+/* multicast options */
+int moptions;
+#define        MULTICAST_NOLOOP        0x001
+
 #define DUMMY_PORT     10101
 
 /*
@@ -235,7 +239,7 @@ main(int argc, char *argv[])
        struct cmsghdr *scmsgp = NULL;
        struct in6_pktinfo *pktinfo = NULL;
        double intval;
-       int mflag = 0;
+       int mflag = 0, loop = 1;
        uid_t uid;
        u_int rtableid = 0;
 
@@ -250,7 +254,7 @@ main(int argc, char *argv[])
        preload = 0;
        datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN];
        while ((ch = getopt(argc, argv,
-           "c:dEefg:Hh:I:i:l:mNnp:qS:s:V:vw:")) != -1) {
+           "c:dEefg:Hh:I:i:Ll:mNnp:qS:s:V:vw:")) != -1) {
                switch (ch) {
                case 'c':
                        npackets = strtonum(optarg, 0, INT_MAX, &errstr);
@@ -326,6 +330,10 @@ main(int argc, char *argv[])
                        }
                        options |= F_INTERVAL;
                        break;
+               case 'L':
+                       moptions |= MULTICAST_NOLOOP;
+                       loop = 0;
+                       break;
                case 'l':
                        if (getuid()) {
                                errno = EPERM;
@@ -463,6 +471,11 @@ main(int argc, char *argv[])
        if ((options & F_FLOOD) && (options & (F_AUD_RECV | F_AUD_MISS)))
                warnx("No audible output for flood pings");
 
+       if ((moptions & MULTICAST_NOLOOP) &&
+           setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop,
+           sizeof(loop)) < 0)
+               err(1, "setsockopt IP6_MULTICAST_LOOP");
+
        if (datalen >= sizeof(struct payload)) {
                /* we can time transfer */
                timing = 1;
@@ -1645,7 +1658,7 @@ void
 usage(void)
 {
        (void)fprintf(stderr,
-           "usage: ping6 [-dEefHmnqv] [-c count] [-g gateway] [-h hoplimit] "
+           "usage: ping6 [-dEefHLmnqv] [-c count] [-g gateway] [-h hoplimit] "
            "[-I sourceaddr]\n\t[-i wait] [-l preload] [-p pattern] "
            "[-s packetsize] [-V rtable]\n\t[-w maxwait] host\n");
        exit(1);