dump: capture in promisc mode by default, with an option to disable it

Change-Id: I75d9580616f0af588291897b27fe376921fef11f
diff --git a/manpages/ndndump.rst b/manpages/ndndump.rst
index 65d1ea1..51737bb 100644
--- a/manpages/ndndump.rst
+++ b/manpages/ndndump.rst
@@ -6,61 +6,72 @@
 
 ::
 
-    ndndump [-hV] [-i INTERFACE] [-r FILE] [-f FILTER] [EXPRESSION]
+    ndndump [-hvV] [-i INTERFACE] [-r FILE] [-f FILTER] [PCAP-FILTER]
 
 Description
 -----------
 
-:program:`ndndump` is a traffic analysis tool that captures Interest, Data, and Nack packets on the
-wire and displays brief information about captured packets.
+:program:`ndndump` is a traffic analysis tool that captures NDN packets on the wire and
+displays brief information about them.
 
 Currently, :program:`ndndump` is capable of extracting Interest, Data, and Nack packets from:
 
-* Ethernet
+* Ethernet frame
 * PPP link (e.g., pcap trace from ndnSIM)
 * IPv4 UDP unicast tunnel
 * IPv4 UDP multicast group
-* IPv4 TCP tunnel, when Interest/Data/Nack is aligned to the front of a TCP segment
+* IPv4 TCP tunnel, when Interest/Data/Nack is aligned to the beginning of a TCP segment
+
+For more complex scenarios, including the case of NDN packets that span multiple IP fragments
+or multiple TCP segments, it is recommended to use the **NDN Wireshark dissector**, either via
+:manpage:`wireshark(1)` or :manpage:`tshark(1)`.
 
 Options
 -------
 
-.. option:: -h
+.. option:: -h, --help
 
     Print help and exit.
 
-.. option:: -V
+.. option:: -i INTERFACE, --interface=INTERFACE
 
-    Print version and exit.
-
-.. option:: -i INTERFACE
-
-    Listen on the specified interface.
+    Listen on *INTERFACE*.
     If unspecified, ndndump searches the system interface list for the lowest numbered,
     configured up interface (excluding loopback).
+    On Linux, a value of "any" can be used to capture packets from all interfaces.
+    Note that captures on the "any" pseudo-interface will not be done in promiscuous mode.
 
-.. option:: -r FILE
+.. option:: -r FILE, --read=FILE
 
-    Read packets from the specified file (which was created with :manpage:`tcpdump(8)` using its ``-w`` option).
+    Read packets from *FILE*, which can be created by :manpage:`tcpdump(8)` with its
+    ``-w`` option, or by similar programs.
 
-.. option:: -v
+.. option:: -f FILTER, --filter=FILTER
+
+    Print a packet only if its name matches the regular expression *FILTER*.
+
+.. option:: -p, --no-promiscuous-mode
+
+    Do not put the interface into promiscuous mode.
+
+.. option:: -v, --verbose
 
     Produce verbose output.
 
-.. option:: -f FILTER
+.. option:: -V, --version
 
-    Print a packet only if its Name matches the regular expression ``FILTER``.
+    Print ndndump and libpcap version strings and exit.
 
-.. option:: EXPRESSION
+.. option:: PCAP-FILTER
 
-    Selects which packets will be analyzed, in :manpage:`pcap-filter(7)` format.
-    If no :option:`EXPRESSION` is given, a default expression is implied which can be seen with ``-h`` option.
+    :option:`PCAP-FILTER` is an expression in :manpage:`pcap-filter(7)` format that
+    selects which packets will be analyzed.
+    If no :option:`PCAP-FILTER` is given, a default filter is used. The default filter
+    can be seen with the :option:`--help` option.
 
 Examples
 --------
 
-Capture on eth1 and print packets containing "ping":
-
-::
+Capture on eth1 and print packets containing "ping"::
 
     ndndump -i eth1 -f '.*ping.*'
diff --git a/tools/dump/main.cpp b/tools/dump/main.cpp
index 25a0226..ebec765 100644
--- a/tools/dump/main.cpp
+++ b/tools/dump/main.cpp
@@ -73,7 +73,8 @@
                     "read packets from the specified file; use \"-\" to read from standard input")
     ("filter,f",    po::value<std::string>(&nameFilter),
                     "print packet only if name matches this regular expression")
-    ("verbose,v",   po::bool_switch(&instance.isVerbose),
+    ("no-promiscuous-mode,p", po::bool_switch(), "do not put the interface into promiscuous mode")
+    ("verbose,v",   po::bool_switch(&instance.wantVerbose),
                     "print more detailed information about each packet")
     ("version,V",   "print program version and exit")
     ;
@@ -138,6 +139,8 @@
     instance.pcapFilter = os.str();
   }
 
+  instance.wantPromisc = !vm["no-promiscuous-mode"].as<bool>();
+
   try {
     instance.run();
   }
diff --git a/tools/dump/ndndump.cpp b/tools/dump/ndndump.cpp
index 4c6d814..4c43826 100644
--- a/tools/dump/ndndump.cpp
+++ b/tools/dump/ndndump.cpp
@@ -82,7 +82,7 @@
 
   std::string action;
   if (!interface.empty()) {
-    m_pcap = pcap_open_live(interface.data(), 65535, 0, 1000, errbuf);
+    m_pcap = pcap_open_live(interface.data(), 65535, wantPromisc, 1000, errbuf);
     if (m_pcap == nullptr) {
       BOOST_THROW_EXCEPTION(Error("Cannot open interface " + interface + ": " + errbuf));
     }
@@ -117,7 +117,7 @@
   }
 
   if (!pcapFilter.empty()) {
-    if (isVerbose) {
+    if (wantVerbose) {
       std::cerr << "ndndump: using pcap filter: " << pcapFilter << std::endl;
     }
 
diff --git a/tools/dump/ndndump.hpp b/tools/dump/ndndump.hpp
index 7b5e240..4de7f57 100644
--- a/tools/dump/ndndump.hpp
+++ b/tools/dump/ndndump.hpp
@@ -87,7 +87,8 @@
   std::string inputFile;
   std::string pcapFilter = getDefaultPcapFilter();
   optional<std::regex> nameFilter;
-  bool isVerbose = false;
+  bool wantPromisc = true;
+  bool wantVerbose = false;
 
 private:
   pcap_t* m_pcap = nullptr;