dump: import code from ndndump repository
Code is copied from ndndump:commit:c266031924d723b9a73be29ebb66fd6db26aade5,
with minor changes for removing trailing whitespaces.
Build script is rewritten.
refs #2692
Change-Id: I07eec2f87542f1328b851cc2c4e5c9b6279db7da
diff --git a/.jenkins.d/00-deps.sh b/.jenkins.d/00-deps.sh
index 141b466..78cef3b 100755
--- a/.jenkins.d/00-deps.sh
+++ b/.jenkins.d/00-deps.sh
@@ -21,5 +21,5 @@
set -x
sudo apt-get update -qq -y
sudo apt-get -qq -y install build-essential pkg-config $BOOST_PKG \
- libcrypto++-dev libsqlite3-dev
+ libcrypto++-dev libsqlite3-dev libpcap-dev
fi
diff --git a/.waf-tools/boost.py b/.waf-tools/boost.py
new file mode 100644
index 0000000..dedb9d8
--- /dev/null
+++ b/.waf-tools/boost.py
@@ -0,0 +1,378 @@
+#!/usr/bin/env python
+# encoding: utf-8
+#
+# partially based on boost.py written by Gernot Vormayr
+# written by Ruediger Sonderfeld <ruediger@c-plusplus.de>, 2008
+# modified by Bjoern Michaelsen, 2008
+# modified by Luca Fossati, 2008
+# rewritten for waf 1.5.1, Thomas Nagy, 2008
+# rewritten for waf 1.6.2, Sylvain Rouquette, 2011
+
+'''
+
+This is an extra tool, not bundled with the default waf binary.
+To add the boost tool to the waf file:
+$ ./waf-light --tools=compat15,boost
+ or, if you have waf >= 1.6.2
+$ ./waf update --files=boost
+
+When using this tool, the wscript will look like:
+
+ def options(opt):
+ opt.load('compiler_cxx boost')
+
+ def configure(conf):
+ conf.load('compiler_cxx boost')
+ conf.check_boost(lib='system filesystem')
+
+ def build(bld):
+ bld(source='main.cpp', target='app', use='BOOST')
+
+Options are generated, in order to specify the location of boost includes/libraries.
+The `check_boost` configuration function allows to specify the used boost libraries.
+It can also provide default arguments to the --boost-static and --boost-mt command-line arguments.
+Everything will be packaged together in a BOOST component that you can use.
+
+When using MSVC, a lot of compilation flags need to match your BOOST build configuration:
+ - you may have to add /EHsc to your CXXFLAGS or define boost::throw_exception if BOOST_NO_EXCEPTIONS is defined.
+ Errors: C4530
+ - boost libraries will try to be smart and use the (pretty but often not useful) auto-linking feature of MSVC
+ So before calling `conf.check_boost` you might want to disabling by adding:
+ conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB']
+ Errors:
+ - boost might also be compiled with /MT, which links the runtime statically.
+ If you have problems with redefined symbols,
+ self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
+ self.env['CXXFLAGS_%s' % var] += ['/MD', '/EHsc']
+Passing `--boost-linkage_autodetect` might help ensuring having a correct linkage in some basic cases.
+
+'''
+
+import sys
+import re
+from waflib import Utils, Logs, Errors
+from waflib.Configure import conf
+
+BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib', '/usr/lib/x86_64-linux-gnu', '/usr/lib/i386-linux-gnu', '/usr/local/ndn/lib']
+BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include', '/usr/local/ndn/include']
+BOOST_VERSION_FILE = 'boost/version.hpp'
+BOOST_VERSION_CODE = '''
+#include <iostream>
+#include <boost/version.hpp>
+int main() { std::cout << BOOST_LIB_VERSION << ":" << BOOST_VERSION << std::endl; }
+'''
+BOOST_SYSTEM_CODE = '''
+#include <boost/system/error_code.hpp>
+int main() { boost::system::error_code c; }
+'''
+BOOST_THREAD_CODE = '''
+#include <boost/thread.hpp>
+int main() { boost::thread t; }
+'''
+
+# toolsets from {boost_dir}/tools/build/v2/tools/common.jam
+PLATFORM = Utils.unversioned_sys_platform()
+detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il'
+detect_clang = lambda env: (PLATFORM == 'darwin') and 'clang-darwin' or 'clang'
+detect_mingw = lambda env: (re.search('MinGW', env.CXX[0])) and 'mgw' or 'gcc'
+BOOST_TOOLSETS = {
+ 'borland': 'bcb',
+ 'clang': detect_clang,
+ 'como': 'como',
+ 'cw': 'cw',
+ 'darwin': 'xgcc',
+ 'edg': 'edg',
+ 'g++': detect_mingw,
+ 'gcc': detect_mingw,
+ 'icpc': detect_intel,
+ 'intel': detect_intel,
+ 'kcc': 'kcc',
+ 'kylix': 'bck',
+ 'mipspro': 'mp',
+ 'mingw': 'mgw',
+ 'msvc': 'vc',
+ 'qcc': 'qcc',
+ 'sun': 'sw',
+ 'sunc++': 'sw',
+ 'tru64cxx': 'tru',
+ 'vacpp': 'xlc'
+}
+
+
+def options(opt):
+ opt = opt.add_option_group('Boost Options')
+
+ opt.add_option('--boost-includes', type='string',
+ default='', dest='boost_includes',
+ help='''path to the directory where the boost includes are, e.g., /path/to/boost_1_55_0/stage/include''')
+ opt.add_option('--boost-libs', type='string',
+ default='', dest='boost_libs',
+ help='''path to the directory where the boost libs are, e.g., /path/to/boost_1_55_0/stage/lib''')
+ opt.add_option('--boost-static', action='store_true',
+ default=False, dest='boost_static',
+ help='link with static boost libraries (.lib/.a)')
+ opt.add_option('--boost-mt', action='store_true',
+ default=False, dest='boost_mt',
+ help='select multi-threaded libraries')
+ opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
+ help='''select libraries with tags (dgsyp, d for debug), see doc Boost, Getting Started, chapter 6.1''')
+ opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect',
+ help="auto-detect boost linkage options (don't get used to it / might break other stuff)")
+ opt.add_option('--boost-toolset', type='string',
+ default='', dest='boost_toolset',
+ help='force a toolset e.g. msvc, vc90, gcc, mingw, mgw45 (default: auto)')
+ py_version = '%d%d' % (sys.version_info[0], sys.version_info[1])
+ opt.add_option('--boost-python', type='string',
+ default=py_version, dest='boost_python',
+ help='select the lib python with this version (default: %s)' % py_version)
+
+
+@conf
+def __boost_get_version_file(self, d):
+ dnode = self.root.find_dir(d)
+ if dnode:
+ return dnode.find_node(BOOST_VERSION_FILE)
+ return None
+
+@conf
+def boost_get_version(self, d):
+ """silently retrieve the boost version number"""
+ node = self.__boost_get_version_file(d)
+ if node:
+ try:
+ txt = node.read()
+ except (OSError, IOError):
+ Logs.error("Could not read the file %r" % node.abspath())
+ else:
+ re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.+)"', re.M)
+ m1 = re_but1.search(txt)
+
+ re_but2 = re.compile('^#define\\s+BOOST_VERSION\\s+(\\d+)', re.M)
+ m2 = re_but2.search(txt)
+
+ if m1 and m2:
+ return (m1.group(1), m2.group(1))
+
+ return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(":")
+
+@conf
+def boost_get_includes(self, *k, **kw):
+ includes = k and k[0] or kw.get('includes', None)
+ if includes and self.__boost_get_version_file(includes):
+ return includes
+ for d in Utils.to_list(self.environ.get('INCLUDE', '')) + BOOST_INCLUDES:
+ if self.__boost_get_version_file(d):
+ return d
+ if includes:
+ self.end_msg('headers not found in %s' % includes)
+ self.fatal('The configuration failed')
+ else:
+ self.end_msg('headers not found, please provide a --boost-includes argument (see help)')
+ self.fatal('The configuration failed')
+
+
+@conf
+def boost_get_toolset(self, cc):
+ toolset = cc
+ if not cc:
+ build_platform = Utils.unversioned_sys_platform()
+ if build_platform in BOOST_TOOLSETS:
+ cc = build_platform
+ else:
+ cc = self.env.CXX_NAME
+ if cc in BOOST_TOOLSETS:
+ toolset = BOOST_TOOLSETS[cc]
+ return isinstance(toolset, str) and toolset or toolset(self.env)
+
+
+@conf
+def __boost_get_libs_path(self, *k, **kw):
+ ''' return the lib path and all the files in it '''
+ if 'files' in kw:
+ return self.root.find_dir('.'), Utils.to_list(kw['files'])
+ libs = k and k[0] or kw.get('libs', None)
+ if libs:
+ path = self.root.find_dir(libs)
+ files = path.ant_glob('*boost_*')
+ if not libs or not files:
+ for d in Utils.to_list(self.environ.get('LIB', [])) + BOOST_LIBS:
+ path = self.root.find_dir(d)
+ if path:
+ files = path.ant_glob('*boost_*')
+ if files:
+ break
+ path = self.root.find_dir(d + '64')
+ if path:
+ files = path.ant_glob('*boost_*')
+ if files:
+ break
+ if not path:
+ if libs:
+ self.end_msg('libs not found in %s' % libs)
+ self.fatal('The configuration failed')
+ else:
+ self.end_msg('libs not found, please provide a --boost-libs argument (see help)')
+ self.fatal('The configuration failed')
+
+ self.to_log('Found the boost path in %r with the libraries:' % path)
+ for x in files:
+ self.to_log(' %r' % x)
+ return path, files
+
+@conf
+def boost_get_libs(self, *k, **kw):
+ '''
+ return the lib path and the required libs
+ according to the parameters
+ '''
+ path, files = self.__boost_get_libs_path(**kw)
+ t = []
+ if kw.get('mt', False):
+ t.append('mt')
+ if kw.get('abi', None):
+ t.append(kw['abi'])
+ tags = t and '(-%s)+' % '-'.join(t) or ''
+ toolset = self.boost_get_toolset(kw.get('toolset', ''))
+ toolset_pat = '(-%s[0-9]{0,3})+' % toolset
+ version = '(-%s)+' % self.env.BOOST_VERSION
+
+ def find_lib(re_lib, files):
+ for file in files:
+ if re_lib.search(file.name):
+ self.to_log('Found boost lib %s' % file)
+ return file
+ return None
+
+ def format_lib_name(name):
+ if name.startswith('lib') and self.env.CC_NAME != 'msvc':
+ name = name[3:]
+ return name[:name.rfind('.')]
+
+ libs = []
+ for lib in Utils.to_list(k and k[0] or kw.get('lib', None)):
+ py = (lib == 'python') and '(-py%s)+' % kw['python'] or ''
+ # Trying libraries, from most strict match to least one
+ for pattern in ['boost_%s%s%s%s%s' % (lib, toolset_pat, tags, py, version),
+ 'boost_%s%s%s%s' % (lib, tags, py, version),
+ 'boost_%s%s%s' % (lib, tags, version),
+ # Give up trying to find the right version
+ 'boost_%s%s%s%s' % (lib, toolset_pat, tags, py),
+ 'boost_%s%s%s' % (lib, tags, py),
+ 'boost_%s%s' % (lib, tags)]:
+ self.to_log('Trying pattern %s' % pattern)
+ file = find_lib(re.compile(pattern), files)
+ if file:
+ libs.append(format_lib_name(file.name))
+ break
+ else:
+ self.end_msg('lib %s not found in %s' % (lib, path.abspath()))
+ self.fatal('The configuration failed')
+
+ return path.abspath(), libs
+
+
+@conf
+def check_boost(self, *k, **kw):
+ """
+ Initialize boost libraries to be used.
+
+ Keywords: you can pass the same parameters as with the command line (without "--boost-").
+ Note that the command line has the priority, and should preferably be used.
+ """
+ if not self.env['CXX']:
+ self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
+
+ params = {'lib': k and k[0] or kw.get('lib', None)}
+ for key, value in self.options.__dict__.items():
+ if not key.startswith('boost_'):
+ continue
+ key = key[len('boost_'):]
+ params[key] = value and value or kw.get(key, '')
+
+ var = kw.get('uselib_store', 'BOOST')
+
+ self.start_msg('Checking boost includes')
+ self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params)
+ versions = self.boost_get_version(inc)
+ self.env.BOOST_VERSION = versions[0]
+ self.env.BOOST_VERSION_NUMBER = int(versions[1])
+ self.end_msg("%d.%d.%d" % (int(versions[1]) / 100000,
+ int(versions[1]) / 100 % 1000,
+ int(versions[1]) % 100))
+ if Logs.verbose:
+ Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
+
+ if not params['lib']:
+ return
+ self.start_msg('Checking boost libs')
+ suffix = params.get('static', None) and 'ST' or ''
+ path, libs = self.boost_get_libs(**params)
+ self.env['%sLIBPATH_%s' % (suffix, var)] = [path]
+ self.env['%sLIB_%s' % (suffix, var)] = libs
+ self.end_msg('ok')
+ if Logs.verbose:
+ Logs.pprint('CYAN', ' path : %s' % path)
+ Logs.pprint('CYAN', ' libs : %s' % libs)
+
+
+ def try_link():
+ if 'system' in params['lib']:
+ self.check_cxx(
+ fragment=BOOST_SYSTEM_CODE,
+ use=var,
+ execute=False,
+ )
+ if 'thread' in params['lib']:
+ self.check_cxx(
+ fragment=BOOST_THREAD_CODE,
+ use=var,
+ execute=False,
+ )
+
+ if params.get('linkage_autodetect', False):
+ self.start_msg("Attempting to detect boost linkage flags")
+ toolset = self.boost_get_toolset(kw.get('toolset', ''))
+ if toolset in ['vc']:
+ # disable auto-linking feature, causing error LNK1181
+ # because the code wants to be linked against
+ self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
+
+ # if no dlls are present, we guess the .lib files are not stubs
+ has_dlls = False
+ for x in Utils.listdir(path):
+ if x.endswith(self.env.cxxshlib_PATTERN % ''):
+ has_dlls = True
+ break
+ if not has_dlls:
+ self.env['STLIBPATH_%s' % var] = [path]
+ self.env['STLIB_%s' % var] = libs
+ del self.env['LIB_%s' % var]
+ del self.env['LIBPATH_%s' % var]
+
+ # we attempt to play with some known-to-work CXXFLAGS combinations
+ for cxxflags in (['/MD', '/EHsc'], []):
+ self.env.stash()
+ self.env["CXXFLAGS_%s" % var] += cxxflags
+ try:
+ try_link()
+ self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var]))
+ e = None
+ break
+ except Errors.ConfigurationError as exc:
+ self.env.revert()
+ e = exc
+
+ if e is not None:
+ self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=e)
+ self.fatal('The configuration failed')
+ else:
+ self.end_msg("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain")
+ self.fatal('The configuration failed')
+ else:
+ self.start_msg('Checking for boost linkage')
+ try:
+ try_link()
+ except Errors.ConfigurationError as e:
+ self.end_msg("Could not link against boost libraries using supplied options")
+ self.fatal('The configuration failed')
+ self.end_msg('ok')
diff --git a/tools/dump/config.hpp b/tools/dump/config.hpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/dump/config.hpp
diff --git a/tools/dump/main.cpp b/tools/dump/main.cpp
new file mode 100644
index 0000000..c8cff68
--- /dev/null
+++ b/tools/dump/main.cpp
@@ -0,0 +1,132 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2011-2014, Regents of the University of California,
+ *
+ * This file is part of ndndump, the packet capture and analysis tool for Named Data
+ * Networking (NDN).
+ *
+ * ndndump is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndndump is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndndump, e.g., in COPYING file. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "ndndump.hpp"
+
+#include <boost/program_options/options_description.hpp>
+#include <boost/program_options/variables_map.hpp>
+#include <boost/program_options/parsers.hpp>
+
+namespace po = boost::program_options;
+
+namespace boost {
+
+void
+validate(boost::any& v,
+ const std::vector<std::string>& values,
+ boost::regex*, int)
+{
+ po::validators::check_first_occurrence(v);
+ const std::string& str = po::validators::get_single_string(values);
+ v = boost::any(boost::regex(str));
+}
+
+} // namespace boost
+
+void
+usage(std::ostream& os, const std::string& appName, const po::options_description& options)
+{
+ os << "Usage:\n"
+ << " " << appName << " [-i interface] [-f name-filter] [tcpdump-expression] \n"
+ << "\n"
+ << "Default tcpdump-expression:\n"
+ << " '(ether proto 0x8624) || (tcp port 6363) || (udp port 6363)'\n"
+ << "\n";
+ os << options;
+}
+
+int
+main(int argc, char* argv[])
+{
+ ndn::tools::Ndndump instance;
+
+ po::options_description visibleOptions;
+ visibleOptions.add_options()
+ ("help,h", "Produce this help message")
+ ("interface,i", po::value<std::string>(&instance.interface),
+ "Interface from which to dump packets")
+ ("read,r", po::value<std::string>(&instance.inputFile),
+ "Read packets from file")
+ ("verbose,v",
+ "When parsing and printing, produce verbose output")
+ // ("write,w", po::value<std::string>(&instance.outputFile),
+ // "Write the raw packets to file rather than parsing and printing them out")
+ ("filter,f", po::value<boost::regex>(&instance.nameFilter),
+ "Regular expression to filter out Interest and Data packets")
+ ;
+
+ po::options_description hiddenOptions;
+ hiddenOptions.add_options()
+ ("pcap-program", po::value<std::vector<std::string> >());
+ ;
+
+ po::positional_options_description positionalArguments;
+ positionalArguments
+ .add("pcap-program", -1);
+
+ po::options_description allOptions;
+ allOptions
+ .add(visibleOptions)
+ .add(hiddenOptions)
+ ;
+
+ po::variables_map vm;
+
+ try {
+ po::store(po::command_line_parser(argc, argv)
+ .options(allOptions)
+ .positional(positionalArguments)
+ .run(),
+ vm);
+ po::notify(vm);
+ }
+ catch (std::exception& e) {
+ std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
+ usage(std::cerr, argv[0], visibleOptions);
+ return 1;
+ }
+
+ if (vm.count("help") > 0) {
+ usage(std::cout, argv[0], visibleOptions);
+ return 0;
+ }
+
+ if (vm.count("verbose") > 0) {
+ instance.isVerbose = true;
+ }
+
+ if (vm.count("pcap-program") > 0) {
+ typedef std::vector<std::string> Strings;
+ const Strings& items = vm["pcap-program"].as<Strings>();
+
+ std::ostringstream os;
+ std::copy(items.begin(), items.end(), std::ostream_iterator<std::string>(os, " "));
+ instance.pcapProgram = os.str();
+ }
+
+ if (vm.count("read") > 0 && vm.count("interface") > 0) {
+ std::cerr << "ERROR: Conflicting -r and -i options" << std::endl;
+ usage(std::cerr, argv[0], visibleOptions);
+ return 2;
+ }
+
+ instance.run();
+
+ return 0;
+}
diff --git a/tools/dump/ndndump.cpp b/tools/dump/ndndump.cpp
new file mode 100644
index 0000000..e018cd6
--- /dev/null
+++ b/tools/dump/ndndump.cpp
@@ -0,0 +1,338 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2011-2014, Regents of the University of California,
+ *
+ * This file is part of ndndump, the packet capture and analysis tool for Named Data
+ * Networking (NDN).
+ *
+ * ndndump is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndndump is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndndump, e.g., in COPYING file. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "ndndump.hpp"
+
+#include "config.hpp"
+
+#include "tcpdump/tcpdump-stdinc.h"
+
+namespace ndn {
+namespace tools {
+// namespace is necessary for now to prevent clashing with system includes
+// this will not be needed after ndn-cxx/common.hpp will stop including <boost/asio.hpp>
+
+#include "tcpdump/ether.h"
+#include "tcpdump/ip.h"
+#include "tcpdump/udp.h"
+#include "tcpdump/tcp.h"
+
+} // namespace tools
+} // namespace ndn
+
+#include <boost/lexical_cast.hpp>
+
+#include <iomanip>
+
+#include <ndn-cxx/interest.hpp>
+#include <ndn-cxx/data.hpp>
+
+namespace ndn {
+namespace tools {
+
+// const uint8_t NDNLP_HEADER[] = {'N', 'd', 'n', 'l', 'p'};
+
+const size_t MAX_SNAPLEN = 65535;
+
+void
+Ndndump::run()
+{
+ if (inputFile.empty() && interface.empty()) {
+ char errbuf[PCAP_ERRBUF_SIZE];
+ const char* pcapDevice = pcap_lookupdev(errbuf);
+
+ if (pcapDevice == 0) {
+ throw Error(errbuf);
+ }
+
+ interface = pcapDevice;
+ }
+
+ if (isVerbose) {
+ if (!interface.empty()) {
+ std::cerr << "ndndump: listening on " << interface << std::endl;
+ }
+ else {
+ std::cerr << "ndndump: reading from " << inputFile << std::endl;
+ }
+
+ if (!nameFilter.empty()) {
+ std::cerr << "ndndump: using name filter " << nameFilter << std::endl;
+ }
+ }
+
+ if (!interface.empty()) {
+ char errbuf[PCAP_ERRBUF_SIZE];
+ m_pcap = pcap_open_live(interface.c_str(), MAX_SNAPLEN, 0, 1000, errbuf);
+ if (m_pcap == 0) {
+ throw Error("Cannot open interface " + interface + "(" + errbuf + ")");
+ }
+ }
+ else {
+ char errbuf[PCAP_ERRBUF_SIZE];
+ m_pcap = pcap_open_offline(inputFile.c_str(), errbuf);
+ if (m_pcap == 0) {
+ throw Error("Cannot file " + inputFile + " for reading (" + errbuf + ")");
+ }
+ }
+
+ if (!pcapProgram.empty()) {
+ if (isVerbose) {
+ std::cerr << "ndndump: pcap_filter = " << pcapProgram << std::endl;
+ }
+
+ bpf_program program;
+ int returnValue = pcap_compile(m_pcap, &program, pcapProgram.c_str(), 0, PCAP_NETMASK_UNKNOWN);
+
+ if (returnValue < 0) {
+ throw Error("Cannot parse tcpdump expression '" + pcapProgram +
+ "' (" + pcap_geterr(m_pcap) + ")");
+ }
+
+ returnValue = pcap_setfilter(m_pcap, &program);
+ pcap_freecode(&program);
+
+ if (returnValue < 0) {
+ throw Error(std::string("pcap_setfilter failed (") + pcap_geterr(m_pcap) + ")");
+ }
+ }
+
+ m_dataLinkType = pcap_datalink(m_pcap);
+ if (m_dataLinkType != DLT_EN10MB &&
+ m_dataLinkType != DLT_PPP)
+ {
+ throw Error("Unsupported pcap format (" + boost::lexical_cast<std::string>(m_dataLinkType));
+ }
+
+ pcap_loop(m_pcap, -1, &Ndndump::onCapturedPacket, reinterpret_cast<uint8_t*>(this));
+}
+
+
+void
+Ndndump::onCapturedPacket(const struct pcap_pkthdr* header, const uint8_t* packet)
+{
+ std::ostringstream os;
+ printInterceptTime(os, header);
+
+ const uint8_t* payload = packet;
+ ssize_t payloadSize = header->len;
+
+ int frameType = skipDataLinkHeaderAndGetFrameType(payload, payloadSize);
+ if (frameType < 0) {
+ std::cerr << "Unknown frame type" << std::endl;
+ return;
+ }
+
+ int returnValue = skipAndProcessFrameHeader(frameType, payload, payloadSize, os);
+ if (returnValue < 0) {
+ return;
+ }
+
+ bool isOk = false;
+ Block block;
+ std::tie(isOk, block) = Block::fromBuffer(payload, payloadSize);
+ if (!isOk) {
+ // if packet is fragmented, we will not be able to process it
+ return;
+ }
+
+ /// \todo Detect various header (LocalControlHeader, NDNLP, etc.)
+
+ try {
+ if (block.type() == tlv::Interest) {
+ Interest interest(block);
+ if (matchesFilter(interest.getName())) {
+ std::cout << os.str() << ", " << "INTEREST: " << interest << std::endl;
+ }
+ }
+ else if (block.type() == tlv::Data) {
+ Data data(block);
+ if (matchesFilter(data.getName())) {
+ std::cout << os.str() << ", " << "DATA: " << data.getName() << std::endl;
+ }
+ }
+ }
+ catch (tlv::Error& e) {
+ std::cerr << e.what() << std::endl;
+ }
+}
+
+void
+Ndndump::printInterceptTime(std::ostream& os, const struct pcap_pkthdr* header)
+{
+ os << header->ts.tv_sec
+ << "."
+ << std::setfill('0') << std::setw(6) << header->ts.tv_usec;
+
+ // struct tm* tm;
+ // if (flags.unit_time) {
+ // os << (int) header->ts.tv_sec
+ // << "."
+ // << setfill('0') << setw(6) << (int)header->ts.tv_usec;
+ // } else {
+ // tm = localtime(&(header->ts.tv_sec));
+ // os << (int)tm->tm_hour << ":"
+ // << setfill('0') << setw(2) << (int)tm->tm_min<< ":"
+ // << setfill('0') << setw(2) << (int)tm->tm_sec<< "."
+ // << setfill('0') << setw(6) << (int)header->ts.tv_usec;
+ // }
+ os << " ";
+}
+
+int
+Ndndump::skipDataLinkHeaderAndGetFrameType(const uint8_t*& payload, ssize_t& payloadSize)
+{
+ int frameType = 0;
+
+ switch (m_dataLinkType) {
+ case DLT_EN10MB: // Ethernet frames can have Ethernet or 802.3 encapsulation
+ {
+ const ether_header* etherHeader = reinterpret_cast<const ether_header*>(payload);
+
+ if (payloadSize < 0) {
+ std::cerr << "Invalid pcap Ethernet frame" << std::endl;
+ return -1;
+ }
+
+ frameType = ntohs(etherHeader->ether_type);
+ payloadSize -= ETHER_HDRLEN;
+ payload += ETHER_HDRLEN;
+
+ break;
+ }
+ case DLT_PPP:
+ {
+ frameType = *payload;
+ payloadSize--;
+ payload++;
+
+ if (!(frameType & 1)) {
+ frameType = (frameType << 8) | *payload;
+ payloadSize--;
+ payload++;
+ }
+
+ if (payloadSize < 0) {
+ std::cerr << "Invalid PPP frame" << std::endl;
+ return -1;
+ }
+
+ break;
+ }
+ }
+
+ return frameType;
+}
+
+int
+Ndndump::skipAndProcessFrameHeader(int frameType,
+ const uint8_t*& payload, ssize_t& payloadSize,
+ std::ostream& os)
+{
+ switch (frameType)
+ {
+ case /*ETHERTYPE_IP*/0x0800:
+ case DLT_EN10MB: // pcap encapsulation
+ {
+ const ip* ipHeader = reinterpret_cast<const ip*>(payload);
+ size_t ipHeaderSize = IP_HL(ipHeader) * 4;
+ if (ipHeaderSize < 20) {
+ std::cerr << "invalid IP header len " << ipHeaderSize << " bytes" << std::endl;
+ return -1;
+ }
+
+ os << "From: " << inet_ntoa(ipHeader->ip_src) << ", ";
+ os << "To: " << inet_ntoa(ipHeader->ip_dst);
+
+ payloadSize -= ipHeaderSize;
+ payload += ipHeaderSize;
+
+ if (payloadSize < 0) {
+ std::cerr << "Invalid pcap IP packet" << std::endl;
+ return -1;
+ }
+
+ switch (ipHeader->ip_p) {
+ case IPPROTO_UDP:
+ {
+ // if (!flags.udp)
+ // return -1;
+
+ payloadSize -= sizeof(udphdr);
+ payload += sizeof(udphdr);
+
+ if (payloadSize < 0) {
+ std::cerr << "Invalid pcap UDP/IP packet" << std::endl;
+ return -1;
+ }
+
+ os << ", Tunnel Type: UDP";
+ break;
+ }
+ case IPPROTO_TCP:
+ {
+ // if (!flags.tcp)
+ // return -1;
+
+ const tcphdr* tcpHeader = reinterpret_cast<const tcphdr*>(payload);
+ size_t tcpHeaderSize = TH_OFF(tcpHeader) * 4;
+
+ if (tcpHeaderSize < 20) {
+ std::cerr << "Invalid TCP Header len: "<< tcpHeaderSize <<" bytes" << std::endl;
+ return -1;
+ }
+
+ payloadSize -= tcpHeaderSize;
+ payload += tcpHeaderSize;
+
+ if (payloadSize < 0) {
+ std::cerr << "Invalid pcap TCP/IP packet" << std::endl;
+ return -1;
+ }
+
+ os << ", Tunnel Type: TCP";
+ break;
+ }
+ default:
+ return -1;
+ }
+
+ break;
+ }
+ case /*ETHERTYPE_NDN*/0x7777:
+ os << "Tunnel Type: EthernetFrame";
+ break;
+ case /*ETHERTYPE_NDNLP*/0x8624:
+ os << "Tunnel Type: EthernetFrame";
+ break;
+ case 0x0077: // pcap
+ os << "Tunnel Type: PPP";
+ payloadSize -= 2;
+ payload += 2;
+ break;
+ default:
+ return -1;
+ break; // do nothing if it is not a recognized type of a packet
+ }
+
+ return 0;
+}
+
+} // namespace tools
+} // namespace ndn
diff --git a/tools/dump/ndndump.hpp b/tools/dump/ndndump.hpp
new file mode 100644
index 0000000..b5c3470
--- /dev/null
+++ b/tools/dump/ndndump.hpp
@@ -0,0 +1,113 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2011-2014, Regents of the University of California,
+ *
+ * This file is part of ndndump, the packet capture and analysis tool for Named Data
+ * Networking (NDN).
+ *
+ * ndndump is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndndump is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndndump, e.g., in COPYING file. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef NDNDUMP_NDNDUMP_HPP
+#define NDNDUMP_NDNDUMP_HPP
+
+#include <pcap.h>
+
+#include <ndn-cxx/name.hpp>
+#include <boost/regex.hpp>
+
+namespace ndn {
+namespace tools {
+
+class Ndndump : noncopyable
+{
+public:
+ class Error : public std::runtime_error
+ {
+ public:
+ explicit
+ Error(const std::string& what)
+ : std::runtime_error(what)
+ {
+ }
+ };
+
+ Ndndump()
+ : isVerbose(false)
+ , pcapProgram("(ether proto 0x8624) || (tcp port 6363) || (udp port 6363)")
+ // , isSuccinct(false)
+ // , isMatchInverted(false)
+ // , shouldPrintStructure(false)
+ // , isTcpOnly(false)
+ // , isUdpOnly(false)
+ {
+ }
+
+ void
+ run();
+
+private:
+ static void
+ onCapturedPacket(uint8_t* userData, const struct pcap_pkthdr* header, const uint8_t* packet)
+ {
+ reinterpret_cast<Ndndump*>(userData)->onCapturedPacket(header, packet);
+ }
+
+ void
+ onCapturedPacket(const struct pcap_pkthdr* header, const uint8_t* packet);
+
+ void
+ printInterceptTime(std::ostream& os, const struct pcap_pkthdr* header);
+
+ int
+ skipDataLinkHeaderAndGetFrameType(const uint8_t*& payload, ssize_t& payloadSize);
+
+ int
+ skipAndProcessFrameHeader(int frameType,
+ const uint8_t*& payload, ssize_t& payloadSize,
+ std::ostream& os);
+
+ bool
+ matchesFilter(const Name& name)
+ {
+ if (nameFilter.empty())
+ return true;
+
+ /// \todo Switch to NDN regular expressions
+
+ return boost::regex_match(name.toUri(), nameFilter);
+ }
+
+public:
+ bool isVerbose;
+ // bool isSuccinct;
+ // bool isMatchInverted;
+ // bool shouldPrintStructure;
+ // bool isTcpOnly;
+ // bool isUdpOnly;
+
+ std::string pcapProgram;
+ std::string interface;
+ boost::regex nameFilter;
+ std::string inputFile;
+ // std::string outputFile;
+
+private:
+ pcap_t* m_pcap;
+ int m_dataLinkType;
+};
+
+
+} // namespace tools
+} // namespace ndn
+
+#endif // NDNDUMP_NDNDUMP_HPP
diff --git a/tools/dump/tcpdump/README b/tools/dump/tcpdump/README
new file mode 100644
index 0000000..0cfa186
--- /dev/null
+++ b/tools/dump/tcpdump/README
@@ -0,0 +1 @@
+Header files in this directory are borrowed from tcpdump (http://www.tcpdump.org/)
diff --git a/tools/dump/tcpdump/ether.h b/tools/dump/tcpdump/ether.h
new file mode 100644
index 0000000..e8b3a71
--- /dev/null
+++ b/tools/dump/tcpdump/ether.h
@@ -0,0 +1,59 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/ether.h,v 1.8 2002-12-11 07:13:51 guy Exp $ (LBL) */
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)if_ether.h 8.3 (Berkeley) 5/2/95
+ */
+
+#define ETHERMTU 1500
+
+/*
+ * The number of bytes in an ethernet (MAC) address.
+ */
+#define ETHER_ADDR_LEN 6
+
+/*
+ * Structure of a DEC/Intel/Xerox or 802.3 Ethernet header.
+ */
+struct ether_header {
+ u_int8_t ether_dhost[ETHER_ADDR_LEN];
+ u_int8_t ether_shost[ETHER_ADDR_LEN];
+ u_int16_t ether_type;
+};
+
+/*
+ * Length of a DEC/Intel/Xerox or 802.3 Ethernet header; note that some
+ * compilers may pad "struct ether_header" to a multiple of 4 bytes,
+ * for example, so "sizeof (struct ether_header)" may not give the right
+ * answer.
+ */
+#define ETHER_HDRLEN 14
diff --git a/tools/dump/tcpdump/ip.h b/tools/dump/tcpdump/ip.h
new file mode 100644
index 0000000..8a97632
--- /dev/null
+++ b/tools/dump/tcpdump/ip.h
@@ -0,0 +1,164 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/ip.h,v 1.12 2007-09-14 01:29:28 guy Exp $ (LBL) */
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ip.h 8.2 (Berkeley) 6/1/94
+ */
+
+/*
+ * Definitions for internet protocol version 4.
+ * Per RFC 791, September 1981.
+ */
+#define IPVERSION 4
+
+/*
+ * Structure of an internet header, naked of options.
+ *
+ * We declare ip_len and ip_off to be short, rather than u_short
+ * pragmatically since otherwise unsigned comparisons can result
+ * against negative integers quite easily, and fail in subtle ways.
+ */
+struct ip {
+ u_int8_t ip_vhl; /* header length, version */
+#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4)
+#define IP_HL(ip) ((ip)->ip_vhl & 0x0f)
+ u_int8_t ip_tos; /* type of service */
+ u_int16_t ip_len; /* total length */
+ u_int16_t ip_id; /* identification */
+ u_int16_t ip_off; /* fragment offset field */
+#define IP_DF 0x4000 /* dont fragment flag */
+#define IP_MF 0x2000 /* more fragments flag */
+#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
+ u_int8_t ip_ttl; /* time to live */
+ u_int8_t ip_p; /* protocol */
+ u_int16_t ip_sum; /* checksum */
+ struct in_addr ip_src,ip_dst; /* source and dest address */
+} UNALIGNED;
+
+#define IP_MAXPACKET 65535 /* maximum packet size */
+
+/*
+ * Definitions for IP type of service (ip_tos)
+ */
+#define IPTOS_LOWDELAY 0x10
+#define IPTOS_THROUGHPUT 0x08
+#define IPTOS_RELIABILITY 0x04
+
+/*
+ * Definitions for IP precedence (also in ip_tos) (hopefully unused)
+ */
+#define IPTOS_PREC_NETCONTROL 0xe0
+#define IPTOS_PREC_INTERNETCONTROL 0xc0
+#define IPTOS_PREC_CRITIC_ECP 0xa0
+#define IPTOS_PREC_FLASHOVERRIDE 0x80
+#define IPTOS_PREC_FLASH 0x60
+#define IPTOS_PREC_IMMEDIATE 0x40
+#define IPTOS_PREC_PRIORITY 0x20
+#define IPTOS_PREC_ROUTINE 0x00
+
+/*
+ * Definitions for options.
+ */
+#define IPOPT_COPIED(o) ((o)&0x80)
+#define IPOPT_CLASS(o) ((o)&0x60)
+#define IPOPT_NUMBER(o) ((o)&0x1f)
+
+#define IPOPT_CONTROL 0x00
+#define IPOPT_RESERVED1 0x20
+#define IPOPT_DEBMEAS 0x40
+#define IPOPT_RESERVED2 0x60
+
+#define IPOPT_EOL 0 /* end of option list */
+#define IPOPT_NOP 1 /* no operation */
+
+#define IPOPT_RR 7 /* record packet route */
+#define IPOPT_TS 68 /* timestamp */
+#define IPOPT_RFC1393 82 /* traceroute RFC 1393 */
+#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */
+#define IPOPT_LSRR 131 /* loose source route */
+#define IPOPT_SATID 136 /* satnet id */
+#define IPOPT_SSRR 137 /* strict source route */
+#define IPOPT_RA 148 /* router-alert, rfc2113 */
+
+/*
+ * Offsets to fields in options other than EOL and NOP.
+ */
+#define IPOPT_OPTVAL 0 /* option ID */
+#define IPOPT_OLEN 1 /* option length */
+#define IPOPT_OFFSET 2 /* offset within option */
+#define IPOPT_MINOFF 4 /* min value of above */
+
+/*
+ * Time stamp option structure.
+ */
+struct ip_timestamp {
+ u_int8_t ipt_code; /* IPOPT_TS */
+ u_int8_t ipt_len; /* size of structure (variable) */
+ u_int8_t ipt_ptr; /* index of current entry */
+ u_int8_t ipt_oflwflg; /* flags, overflow counter */
+#define IPTS_OFLW(ip) (((ipt)->ipt_oflwflg & 0xf0) >> 4)
+#define IPTS_FLG(ip) ((ipt)->ipt_oflwflg & 0x0f)
+ union ipt_timestamp {
+ u_int32_t ipt_time[1];
+ struct ipt_ta {
+ struct in_addr ipt_addr;
+ u_int32_t ipt_time;
+ } ipt_ta[1];
+ } ipt_timestamp;
+} UNALIGNED;
+
+/* flag bits for ipt_flg */
+#define IPOPT_TS_TSONLY 0 /* timestamps only */
+#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
+#define IPOPT_TS_PRESPEC 3 /* specified modules only */
+
+/* bits for security (not byte swapped) */
+#define IPOPT_SECUR_UNCLASS 0x0000
+#define IPOPT_SECUR_CONFID 0xf135
+#define IPOPT_SECUR_EFTO 0x789a
+#define IPOPT_SECUR_MMMM 0xbc4d
+#define IPOPT_SECUR_RESTR 0xaf13
+#define IPOPT_SECUR_SECRET 0xd788
+#define IPOPT_SECUR_TOPSECRET 0x6bc5
+
+/*
+ * Internet implementation parameters.
+ */
+#define MAXTTL 255 /* maximum time to live (seconds) */
+#define IPDEFTTL 64 /* default ttl, from RFC 1340 */
+#define IPFRAGTTL 60 /* time to live for frags, slowhz */
+#define IPTTLDEC 1 /* subtracted when forwarding */
+
+#define IP_MSS 576 /* default maximum segment size */
+
+/* in print-ip.c */
+extern int nextproto4_cksum(const struct ip *, const u_int8_t *, u_int, u_int);
diff --git a/tools/dump/tcpdump/tcp.h b/tools/dump/tcpdump/tcp.h
new file mode 100644
index 0000000..1961157
--- /dev/null
+++ b/tools/dump/tcpdump/tcp.h
@@ -0,0 +1,116 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/tcp.h,v 1.14 2007-12-09 00:30:47 guy Exp $ (LBL) */
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)tcp.h 8.1 (Berkeley) 6/10/93
+ */
+
+typedef u_int32_t tcp_seq;
+/*
+ * TCP header.
+ * Per RFC 793, September, 1981.
+ */
+struct tcphdr {
+ u_int16_t th_sport; /* source port */
+ u_int16_t th_dport; /* destination port */
+ tcp_seq th_seq; /* sequence number */
+ tcp_seq th_ack; /* acknowledgement number */
+ u_int8_t th_offx2; /* data offset, rsvd */
+ u_int8_t th_flags;
+ u_int16_t th_win; /* window */
+ u_int16_t th_sum; /* checksum */
+ u_int16_t th_urp; /* urgent pointer */
+};
+
+#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
+
+/* TCP flags */
+#define TH_FIN 0x01
+#define TH_SYN 0x02
+#define TH_RST 0x04
+#define TH_PUSH 0x08
+#define TH_ACK 0x10
+#define TH_URG 0x20
+#define TH_ECNECHO 0x40 /* ECN Echo */
+#define TH_CWR 0x80 /* ECN Cwnd Reduced */
+
+
+#define TCPOPT_EOL 0
+#define TCPOPT_NOP 1
+#define TCPOPT_MAXSEG 2
+#define TCPOLEN_MAXSEG 4
+#define TCPOPT_WSCALE 3 /* window scale factor (rfc1323) */
+#define TCPOPT_SACKOK 4 /* selective ack ok (rfc2018) */
+#define TCPOPT_SACK 5 /* selective ack (rfc2018) */
+#define TCPOPT_ECHO 6 /* echo (rfc1072) */
+#define TCPOPT_ECHOREPLY 7 /* echo (rfc1072) */
+#define TCPOPT_TIMESTAMP 8 /* timestamp (rfc1323) */
+#define TCPOLEN_TIMESTAMP 10
+#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */
+#define TCPOPT_CC 11 /* T/TCP CC options (rfc1644) */
+#define TCPOPT_CCNEW 12 /* T/TCP CC options (rfc1644) */
+#define TCPOPT_CCECHO 13 /* T/TCP CC options (rfc1644) */
+#define TCPOPT_SIGNATURE 19 /* Keyed MD5 (rfc2385) */
+#define TCPOLEN_SIGNATURE 18
+#define TCP_SIGLEN 16 /* length of an option 19 digest */
+#define TCPOPT_AUTH 20 /* Enhanced AUTH option */
+#define TCPOPT_UTO 28 /* tcp user timeout (rfc5482) */
+#define TCPOLEN_UTO 4
+#define TCPOPT_MPTCP 30 /* MPTCP options */
+#define TCPOPT_EXPERIMENT2 254 /* experimental headers (rfc4727) */
+
+#define TCPOPT_TSTAMP_HDR \
+ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
+
+#ifndef TELNET_PORT
+#define TELNET_PORT 23
+#endif
+#ifndef BGP_PORT
+#define BGP_PORT 179
+#endif
+#define NETBIOS_SSN_PORT 139
+#ifndef OPENFLOW_PORT
+#define OPENFLOW_PORT 6633
+#endif
+#ifndef PPTP_PORT
+#define PPTP_PORT 1723
+#endif
+#define BEEP_PORT 10288
+#ifndef NFS_PORT
+#define NFS_PORT 2049
+#endif
+#define MSDP_PORT 639
+#define RPKI_RTR_PORT 323
+#define LDP_PORT 646
+#ifndef SMB_PORT
+#define SMB_PORT 445
+#endif
diff --git a/tools/dump/tcpdump/tcpdump-stdinc.h b/tools/dump/tcpdump/tcpdump-stdinc.h
new file mode 100644
index 0000000..34cfb76
--- /dev/null
+++ b/tools/dump/tcpdump/tcpdump-stdinc.h
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2002 - 2003
+ * NetGroup, Politecnico di Torino (Italy)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Politecnico di Torino nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/tcpdump-stdinc.h,v 1.18 2007-11-24 18:13:33 mcr Exp $ (LBL)
+ */
+
+/*
+ * Include the appropriate OS header files on Windows and various flavors
+ * of UNIX, and also define some additional items and include various
+ * non-OS header files on Windows, and; this isolates most of the platform
+ * differences to this one file.
+ */
+
+#ifndef tcpdump_stdinc_h
+#define tcpdump_stdinc_h
+
+#ifdef WIN32
+
+#include <stdio.h>
+#include <winsock2.h>
+#include <Ws2tcpip.h>
+#include "bittypes.h"
+#include <ctype.h>
+#include <time.h>
+#include <io.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <net/netdb.h> /* in wpcap's Win32/include */
+
+#ifndef NBBY
+#define NBBY 8
+#endif
+
+#if !defined(__MINGW32__) && !defined(__WATCOMC__)
+#undef toascii
+#define isascii __isascii
+#define toascii __toascii
+#define stat _stat
+#define open _open
+#define fstat _fstat
+#define read _read
+#define close _close
+#define O_RDONLY _O_RDONLY
+#endif /* __MINGW32__ */
+
+#ifdef __MINGW32__
+#include <stdint.h>
+#endif
+
+/* Protos for missing/x.c functions (ideally <missing/addrinfo.h>
+ * should be used, but it clashes with <ws2tcpip.h>).
+ */
+extern const char *inet_ntop (int, const void *, char *, size_t);
+extern int inet_pton (int, const char *, void *);
+extern int inet_aton (const char *cp, struct in_addr *addr);
+
+/*
+ * With MSVC, for C, __inline is used to make a function an inline.
+ */
+#ifdef _MSC_VER
+#define inline __inline
+#endif
+
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN 46
+#endif
+
+#ifndef toascii
+#define toascii(c) ((c) & 0x7f)
+#endif
+
+#ifndef caddr_t
+typedef char* caddr_t;
+#endif /* caddr_t */
+
+#define MAXHOSTNAMELEN 64
+#define NI_MAXHOST 1025
+#define snprintf _snprintf
+#define vsnprintf _vsnprintf
+#define RETSIGTYPE void
+
+#else /* WIN32 */
+
+#include <ctype.h>
+#include <unistd.h>
+#include <netdb.h>
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#else
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <sys/param.h>
+#include <sys/types.h> /* concession to AIX */
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#ifdef TIME_WITH_SYS_TIME
+#include <time.h>
+#endif
+
+#include <arpa/inet.h>
+
+#endif /* WIN32 */
+
+#ifndef HAVE___ATTRIBUTE__
+#define __attribute__(x)
+#endif
+
+/*
+ * Used to declare a structure unaligned, so that the C compiler,
+ * if necessary, generates code that doesn't assume alignment.
+ * This is required because there is no guarantee that the packet
+ * data we get from libpcap/WinPcap is properly aligned.
+ *
+ * This assumes that, for all compilers that support __attribute__:
+ *
+ * 1) they support __attribute__((packed));
+ *
+ * 2) for all instruction set architectures requiring strict
+ * alignment, declaring a structure with that attribute
+ * causes the compiler to generate code that handles
+ * misaligned 2-byte, 4-byte, and 8-byte integral
+ * quantities.
+ *
+ * It does not (yet) handle compilers where you can get the compiler
+ * to generate code of that sort by some other means.
+ *
+ * This is required in order to, for example, keep the compiler from
+ * generating, for
+ *
+ * if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) {
+ *
+ * in print-bootp.c, code that loads the first 4-byte word of a
+ * "struct bootp", masking out the bp_hops field, and comparing the result
+ * against 0x01010600.
+ *
+ * Note: this also requires that padding be put into the structure,
+ * at least for compilers where it's implemented as __attribute__((packed)).
+ */
+#if defined(_MSC_VER) && defined(UNALIGNED)
+/* MSVC may have its own macro defined with the same name and purpose. */
+#else
+#define UNALIGNED __attribute__((packed))
+#endif
+
+#if defined(WIN32) || defined(MSDOS)
+ #define FOPEN_READ_TXT "rt"
+ #define FOPEN_READ_BIN "rb"
+ #define FOPEN_WRITE_TXT "wt"
+ #define FOPEN_WRITE_BIN "wb"
+#else
+ #define FOPEN_READ_TXT "r"
+ #define FOPEN_READ_BIN FOPEN_READ_TXT
+ #define FOPEN_WRITE_TXT "w"
+ #define FOPEN_WRITE_BIN FOPEN_WRITE_TXT
+#endif
+
+#if defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__) && !defined(__ntohl)
+ #undef ntohl
+ #undef ntohs
+ #undef htonl
+ #undef htons
+
+ static __inline__ unsigned long __ntohl (unsigned long x);
+ static __inline__ unsigned short __ntohs (unsigned short x);
+
+ #define ntohl(x) __ntohl(x)
+ #define ntohs(x) __ntohs(x)
+ #define htonl(x) __ntohl(x)
+ #define htons(x) __ntohs(x)
+
+ static __inline__ unsigned long __ntohl (unsigned long x)
+ {
+ __asm__ ("xchgb %b0, %h0\n\t" /* swap lower bytes */
+ "rorl $16, %0\n\t" /* swap words */
+ "xchgb %b0, %h0" /* swap higher bytes */
+ : "=q" (x) : "0" (x));
+ return (x);
+ }
+
+ static __inline__ unsigned short __ntohs (unsigned short x)
+ {
+ __asm__ ("xchgb %b0, %h0" /* swap bytes */
+ : "=q" (x) : "0" (x));
+ return (x);
+ }
+#endif
+
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/*
+ * The Apple deprecation workaround macros below were adopted from the
+ * FreeRADIUS server code under permission of Alan DeKok and Arran Cudbard-Bell.
+ */
+
+#define XSTRINGIFY(x) #x
+
+/*
+ * Macros for controlling warnings in GCC >= 4.2 and clang >= 2.8
+ */
+#define DIAG_JOINSTR(x,y) XSTRINGIFY(x ## y)
+#define DIAG_DO_PRAGMA(x) _Pragma (#x)
+
+#if defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402
+# define DIAG_PRAGMA(x) DIAG_DO_PRAGMA(GCC diagnostic x)
+# if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
+# define DIAG_OFF(x) DIAG_PRAGMA(push) DIAG_PRAGMA(ignored DIAG_JOINSTR(-W,x))
+# define DIAG_ON(x) DIAG_PRAGMA(pop)
+# else
+# define DIAG_OFF(x) DIAG_PRAGMA(ignored DIAG_JOINSTR(-W,x))
+# define DIAG_ON(x) DIAG_PRAGMA(warning DIAG_JOINSTR(-W,x))
+# endif
+#elif defined(__clang__) && ((__clang_major__ * 100) + __clang_minor__ >= 208)
+# define DIAG_PRAGMA(x) DIAG_DO_PRAGMA(clang diagnostic x)
+# define DIAG_OFF(x) DIAG_PRAGMA(push) DIAG_PRAGMA(ignored DIAG_JOINSTR(-W,x))
+# define DIAG_ON(x) DIAG_PRAGMA(pop)
+#else
+# define DIAG_OFF(x)
+# define DIAG_ON(x)
+#endif
+
+/*
+ * For dealing with APIs which are only deprecated in OSX (like the OpenSSL API)
+ */
+#ifdef __APPLE__
+# define USES_APPLE_DEPRECATED_API DIAG_OFF(deprecated-declarations)
+# define USES_APPLE_RST DIAG_ON(deprecated-declarations)
+#else
+# define USES_APPLE_DEPRECATED_API
+# define USES_APPLE_RST
+#endif
+
+/*
+ * end of Apple deprecation workaround macros
+ */
+
+#endif /* tcpdump_stdinc_h */
diff --git a/tools/dump/tcpdump/udp.h b/tools/dump/tcpdump/udp.h
new file mode 100644
index 0000000..d712dfc
--- /dev/null
+++ b/tools/dump/tcpdump/udp.h
@@ -0,0 +1,99 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/udp.h,v 1.13 2007-08-08 17:20:58 hannes Exp $ (LBL) */
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)udp.h 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * Udp protocol header.
+ * Per RFC 768, September, 1981.
+ */
+struct udphdr {
+ u_int16_t uh_sport; /* source port */
+ u_int16_t uh_dport; /* destination port */
+ u_int16_t uh_ulen; /* udp length */
+ u_int16_t uh_sum; /* udp checksum */
+};
+
+#define TFTP_PORT 69 /*XXX*/
+#define KERBEROS_PORT 88 /*XXX*/
+#define SUNRPC_PORT 111 /*XXX*/
+#define SNMP_PORT 161 /*XXX*/
+#define NTP_PORT 123 /*XXX*/
+#define SNMPTRAP_PORT 162 /*XXX*/
+#define ISAKMP_PORT 500 /*XXX*/
+#define SYSLOG_PORT 514 /* rfc3164 */
+#define TIMED_PORT 525 /*XXX*/
+#define RIP_PORT 520 /*XXX*/
+#define LDP_PORT 646
+#define AODV_PORT 654 /*XXX*/
+#define OLSR_PORT 698 /* rfc3626 */
+#define KERBEROS_SEC_PORT 750 /*XXX*/
+#define L2TP_PORT 1701 /*XXX*/
+#define SIP_PORT 5060
+#define ISAKMP_PORT_NATT 4500 /* rfc3948 */
+#define ISAKMP_PORT_USER1 7500 /*XXX - nonstandard*/
+#define ISAKMP_PORT_USER2 8500 /*XXX - nonstandard*/
+#define RX_PORT_LOW 7000 /*XXX*/
+#define RX_PORT_HIGH 7009 /*XXX*/
+#define NETBIOS_NS_PORT 137
+#define NETBIOS_DGRAM_PORT 138
+#define CISCO_AUTORP_PORT 496 /*XXX*/
+#define RADIUS_PORT 1645
+#define RADIUS_NEW_PORT 1812
+#define RADIUS_ACCOUNTING_PORT 1646
+#define RADIUS_NEW_ACCOUNTING_PORT 1813
+#define HSRP_PORT 1985 /*XXX*/
+#define LMP_PORT 701 /* rfc4204 */
+#define LWRES_PORT 921
+#define VQP_PORT 1589
+#define ZEPHYR_SRV_PORT 2103
+#define ZEPHYR_CLT_PORT 2104
+#define VAT_PORT 3456
+#define MPLS_LSP_PING_PORT 3503 /* draft-ietf-mpls-lsp-ping-02.txt */
+#define BFD_CONTROL_PORT 3784 /* draft-katz-ward-bfd-v4v6-1hop-00.txt */
+#define BFD_ECHO_PORT 3785 /* draft-katz-ward-bfd-v4v6-1hop-00.txt */
+#define WB_PORT 4567
+#define SFLOW_PORT 6343 /* http://www.sflow.org/developers/specifications.php */
+#define LWAPP_DATA_PORT 12222 /* draft-ohara-capwap-lwapp-04.txt */
+#define LWAPP_CONTROL_PORT 12223 /* draft-ohara-capwap-lwapp-04.txt */
+#define OTV_PORT 8472 /* draft-hasmit-otv-04 */
+#define VXLAN_PORT 4789 /* draft-mahalingam-dutt-dcops-vxlan-04 */
+
+#ifdef INET6
+#define RIPNG_PORT 521 /*XXX*/
+#define DHCP6_SERV_PORT 546 /*XXX*/
+#define DHCP6_CLI_PORT 547 /*XXX*/
+#define BABEL_PORT 6696
+#define BABEL_PORT_OLD 6697
+#endif
diff --git a/tools/dump/wscript b/tools/dump/wscript
new file mode 100644
index 0000000..28e58b6
--- /dev/null
+++ b/tools/dump/wscript
@@ -0,0 +1,42 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+top = '../..'
+
+ATTRIBUTE_CHECK='''
+#include <stdlib.h>
+
+static void foo(void) __attribute__ ((noreturn));
+
+static void
+foo(void)
+{
+ exit(1);
+}
+
+int
+main(int argc, char** argv)
+{
+ foo();
+}
+'''
+
+def configure(conf):
+ conf.check(header_name="inttypes.h", mandatory=False)
+ conf.check(header_name="stdint.h", mandatory=False)
+ conf.check(header_name="sys/bitypes.h", mandatory=False)
+ conf.check(fragment=ATTRIBUTE_CHECK, msg="Checking for __attribute__", mandatory=False)
+
+ conf.check(header_name=["sys/types.h", "sys/time.h", "time.h"], define="TIME_WITH_SYS_TIME",
+ mandatory=False)
+
+ conf.check_cfg(path='pcap-config',
+ package="libpcap", args=['--libs', '--cflags'],
+ uselib_store='PCAP', mandatory=True)
+
+def build(bld):
+ bld.program(
+ features='cxx',
+ target='../../bin/ndndump',
+ source=bld.path.ant_glob(['*.cpp']),
+ includes='.',
+ use='core-objects BOOST PCAP',
+ )
diff --git a/wscript b/wscript
index 900bc17..0b5aee1 100644
--- a/wscript
+++ b/wscript
@@ -6,11 +6,11 @@
def options(opt):
opt.load(['compiler_cxx', 'gnu_dirs'])
- opt.load(['default-compiler-flags', 'sphinx_build'], tooldir=['.waf-tools'])
+ opt.load(['default-compiler-flags', 'sphinx_build', 'boost'], tooldir=['.waf-tools'])
def configure(conf):
conf.load(['compiler_cxx', 'gnu_dirs',
- 'default-compiler-flags', 'sphinx_build'])
+ 'default-compiler-flags', 'sphinx_build', 'boost'])
if not os.environ.has_key('PKG_CONFIG_PATH'):
os.environ['PKG_CONFIG_PATH'] = ':'.join([
@@ -20,6 +20,8 @@
conf.check_cfg(package='libndn-cxx', args=['--cflags', '--libs'],
uselib_store='NDN_CXX', mandatory=True)
+ conf.check_boost(lib='system iostreams regex')
+
conf.recurse('tools')
def build(bld):