/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2011-2018, Regents of the University of California.
 *
 * This file is part of ndn-tools (Named Data Networking Essential Tools).
 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
 *
 * ndn-tools 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.
 *
 * ndn-tools 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
 * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "ndndump.hpp"

#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>

#include <pcap/sll.h>

#include <iomanip>
#include <sstream>

#include <ndn-cxx/lp/nack.hpp>
#include <ndn-cxx/lp/packet.hpp>
#include <ndn-cxx/net/ethernet.hpp>
#include <ndn-cxx/util/string-helper.hpp>

#include <boost/endian/conversion.hpp>

namespace ndn {
namespace dump {

namespace endian = boost::endian;

class OutputFormatter : noncopyable
{
public:
  OutputFormatter(std::ostream& os, std::string d)
    : m_os(os)
    , m_delim(std::move(d))
  {
  }

  OutputFormatter&
  addDelimiter()
  {
    if (!m_isEmpty) {
      m_wantDelim = true;
    }
    return *this;
  }

private:
  std::ostream& m_os;
  std::string m_delim;
  bool m_isEmpty = true;
  bool m_wantDelim = false;

  template<typename T>
  friend OutputFormatter& operator<<(OutputFormatter&, const T&);
};

template<typename T>
OutputFormatter&
operator<<(OutputFormatter& out, const T& val)
{
  if (out.m_wantDelim) {
    out.m_os << out.m_delim;
    out.m_wantDelim = false;
  }
  out.m_os << val;
  out.m_isEmpty = false;
  return out;
}

NdnDump::~NdnDump()
{
  if (m_pcap)
    pcap_close(m_pcap);
}

void
NdnDump::run()
{
  char errbuf[PCAP_ERRBUF_SIZE] = {};

  if (inputFile.empty() && interface.empty()) {
    const char* defaultDevice = pcap_lookupdev(errbuf);

    if (defaultDevice == nullptr) {
      BOOST_THROW_EXCEPTION(Error(errbuf));
    }

    interface = defaultDevice;
  }

  std::string action;
  if (!interface.empty()) {
    m_pcap = pcap_open_live(interface.data(), 65535, wantPromisc, 1000, errbuf);
    if (m_pcap == nullptr) {
      BOOST_THROW_EXCEPTION(Error("Cannot open interface " + interface + ": " + errbuf));
    }
    action = "listening on " + interface;
  }
  else {
    m_pcap = pcap_open_offline(inputFile.data(), errbuf);
    if (m_pcap == nullptr) {
      BOOST_THROW_EXCEPTION(Error("Cannot open file '" + inputFile + "' for reading: " + errbuf));
    }
    action = "reading from file " + inputFile;
  }

  m_dataLinkType = pcap_datalink(m_pcap);
  const char* dltName = pcap_datalink_val_to_name(m_dataLinkType);
  const char* dltDesc = pcap_datalink_val_to_description(m_dataLinkType);
  std::string formattedDlt = dltName ? dltName : to_string(m_dataLinkType);
  if (dltDesc) {
    formattedDlt += " ("s + dltDesc + ")";
  }

  std::cerr << "ndndump: " << action << ", link-type " << formattedDlt << std::endl;

  switch (m_dataLinkType) {
  case DLT_EN10MB:
  case DLT_LINUX_SLL:
  case DLT_PPP:
    // we know how to handle these
    break;
  default:
    BOOST_THROW_EXCEPTION(Error("Unsupported link-layer header type " + formattedDlt));
  }

  if (!pcapFilter.empty()) {
    if (wantVerbose) {
      std::cerr << "ndndump: using pcap filter: " << pcapFilter << std::endl;
    }

    bpf_program program;
    int res = pcap_compile(m_pcap, &program, pcapFilter.data(), 1, PCAP_NETMASK_UNKNOWN);
    if (res < 0) {
      BOOST_THROW_EXCEPTION(Error("Cannot compile pcap filter '" + pcapFilter + "': " + pcap_geterr(m_pcap)));
    }

    res = pcap_setfilter(m_pcap, &program);
    pcap_freecode(&program);
    if (res < 0) {
      BOOST_THROW_EXCEPTION(Error("Cannot set pcap filter: "s + pcap_geterr(m_pcap)));
    }
  }

  auto callback = [] (uint8_t* user, const pcap_pkthdr* pkthdr, const uint8_t* payload) {
    reinterpret_cast<const NdnDump*>(user)->printPacket(pkthdr, payload);
  };

  if (pcap_loop(m_pcap, -1, callback, reinterpret_cast<uint8_t*>(this)) < 0) {
    BOOST_THROW_EXCEPTION(Error("pcap_loop: "s + pcap_geterr(m_pcap)));
  }
}

void
NdnDump::printPacket(const pcap_pkthdr* pkthdr, const uint8_t* payload) const
{
  // sanity checks
  if (pkthdr->caplen == 0) {
    std::cout << "[Invalid header: caplen=0]" << std::endl;
    return;
  }
  if (pkthdr->len == 0) {
    std::cout << "[Invalid header: len=0]" << std::endl;
    return;
  }
  else if (pkthdr->len < pkthdr->caplen) {
    std::cout << "[Invalid header: len(" << pkthdr->len
              << ") < caplen(" << pkthdr->caplen << ")]" << std::endl;
    return;
  }

  std::ostringstream os;
  OutputFormatter out(os, ", ");

  bool shouldPrint = false;
  switch (m_dataLinkType) {
  case DLT_EN10MB:
    shouldPrint = printEther(out, payload, pkthdr->len);
    break;
  case DLT_LINUX_SLL:
    shouldPrint = printLinuxSll(out, payload, pkthdr->len);
    break;
  case DLT_PPP:
    shouldPrint = printPpp(out, payload, pkthdr->len);
    break;
  default:
    BOOST_ASSERT(false);
    return;
  }

  if (shouldPrint) {
    if (wantTimestamp) {
      printTimestamp(std::cout, pkthdr->ts);
    }
    std::cout << os.str() << std::endl;
  }
}

void
NdnDump::printTimestamp(std::ostream& os, const timeval& tv) const
{
  /// \todo Add more timestamp formats (time since previous packet, time since first packet, ...)
  os << tv.tv_sec
     << "."
     << std::setfill('0') << std::setw(6) << tv.tv_usec
     << " ";
}

bool
NdnDump::dispatchByEtherType(OutputFormatter& out, const uint8_t* pkt, size_t len, uint16_t etherType) const
{
  out.addDelimiter();

  switch (etherType) {
  case ETHERTYPE_IP:
    return printIp4(out, pkt, len);
  case ethernet::ETHERTYPE_NDN:
  case 0x7777: // NDN ethertype used in ndnSIM
    out << "Ethernet";
    return printNdn(out, pkt, len);
  default:
    out << "[Unsupported ethertype " << AsHex{etherType} << "]";
    return true;
  }
}

bool
NdnDump::dispatchByIpProto(OutputFormatter& out, const uint8_t* pkt, size_t len, uint8_t ipProto) const
{
  out.addDelimiter();

  switch (ipProto) {
  case IPPROTO_TCP:
    return printTcp(out, pkt, len);
  case IPPROTO_UDP:
    return printUdp(out, pkt, len);
  default:
    out << "[Unsupported IP proto " << static_cast<int>(ipProto) << "]";
    return true;
  }
}

bool
NdnDump::printEther(OutputFormatter& out, const uint8_t* pkt, size_t len) const
{
  // IEEE 802.3 Ethernet

  if (len < ethernet::HDR_LEN) {
    out << "Truncated Ethernet frame, length " << len;
    return true;
  }

  auto ether = reinterpret_cast<const ether_header*>(pkt);
  pkt += ethernet::HDR_LEN;
  len -= ethernet::HDR_LEN;

  return dispatchByEtherType(out, pkt, len, endian::big_to_native(ether->ether_type));
}

bool
NdnDump::printLinuxSll(OutputFormatter& out, const uint8_t* pkt, size_t len) const
{
  // Linux "cooked" capture encapsulation
  // https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html

  if (len < SLL_HDR_LEN) {
    out << "Truncated LINUX_SLL frame, length " << len;
    return true;
  }

  auto sll = reinterpret_cast<const sll_header*>(pkt);
  pkt += SLL_HDR_LEN;
  len -= SLL_HDR_LEN;

  return dispatchByEtherType(out, pkt, len, endian::big_to_native(sll->sll_protocol));
}

bool
NdnDump::printPpp(OutputFormatter& out, const uint8_t* pkt, size_t len) const
{
  // PPP, as per RFC 1661 and RFC 1662; if the first 2 bytes are 0xff and 0x03,
  // it's PPP in HDLC-like framing, with the PPP header following those two bytes,
  // otherwise it's PPP without framing, and the packet begins with the PPP header.
  // The data in the frame is not octet-stuffed or bit-stuffed.

  if (len < 2) {
    out << "Truncated PPP frame, length " << len;
    return true;
  }

  if (pkt[0] == 0xff && pkt[1] == 0x03) {
    // PPP in HDLC-like framing, skip the Address and Control fields
    if (len < 4) {
      out << "Truncated PPP frame, length " << len;
      return true;
    }
    pkt += 2;
    len -= 2;
  }

  unsigned int proto = pkt[0];
  if (proto & 0x1) {
    // Protocol field is compressed in 1 byte
    pkt += 1;
    len -= 1;
  }
  else {
    // Protocol field is 2 bytes, in network byte order
    proto = (proto << 8) | pkt[1];
    pkt += 2;
    len -= 2;
  }

  switch (proto) {
  case 0x0077: // NDN in PPP frame, used by ndnSIM pcap traces
    // For some reason, ndnSIM produces PPP frames with 2 extra bytes
    // between the protocol field and the beginning of the NDN packet
    if (len < 2) {
      out << "Truncated NDN/PPP frame";
      return true;
    }
    pkt += 2;
    len -= 2;
    out << "PPP";
    return printNdn(out, pkt, len);
  default:
    out << "[Unsupported PPP proto " << AsHex{proto} << "]";
    return true;
  }
}

static void
printIpAddress(OutputFormatter& out, int af, const void* addr)
{
  char addrStr[1 + std::max(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)] = {};
  if (inet_ntop(af, addr, addrStr, sizeof(addrStr))) {
    out << addrStr;
  }
  else {
    out << "???";
  }
}

bool
NdnDump::printIp4(OutputFormatter& out, const uint8_t* pkt, size_t len) const
{
  out.addDelimiter() << "IP ";

  if (len < sizeof(ip)) {
    out << "truncated header, length " << len;
    return true;
  }

  auto ih = reinterpret_cast<const ip*>(pkt);
  if (ih->ip_v != 4) {
    // huh? link layer said this was an IPv4 packet but IP header says otherwise
    out << "bad version " << ih->ip_v;
    return true;
  }

  size_t ipHdrLen = ih->ip_hl * 4;
  if (ipHdrLen < sizeof(ip)) {
    out << "bad header length " << ipHdrLen;
    return true;
  }

  size_t ipLen = endian::big_to_native(ih->ip_len);
  if (ipLen < ipHdrLen) {
    out << "bad length " << ipLen;
    return true;
  }
  if (ipLen > len) {
    out << "truncated packet, " << ipLen - len << " bytes missing";
    return true;
  }
  // if we reached this point, the following is true:
  //     sizeof(ip) <= ipHdrLen <= ipLen <= len

  printIpAddress(out, AF_INET, &ih->ip_src);
  out << " > ";
  printIpAddress(out, AF_INET, &ih->ip_dst);

  pkt += ipHdrLen;
  len -= ipHdrLen;

  return dispatchByIpProto(out, pkt, len, ih->ip_p);
}

bool
NdnDump::printTcp(OutputFormatter& out, const uint8_t* pkt, size_t len) const
{
  out.addDelimiter() << "TCP";

  if (len < sizeof(tcphdr)) {
    out << " truncated header, length " << len;
    return true;
  }

  auto th = reinterpret_cast<const tcphdr*>(pkt);
  size_t tcpHdrLen = th->th_off * 4;
  if (tcpHdrLen < sizeof(tcphdr)) {
    out << " bad header length " << tcpHdrLen;
    return true;
  }
  if (tcpHdrLen > len) {
    out << " truncated header, " << tcpHdrLen - len << " bytes missing";
    return true;
  }

  pkt += tcpHdrLen;
  len -= tcpHdrLen;

  out.addDelimiter() << "length " << len;

  return printNdn(out, pkt, len);
}

bool
NdnDump::printUdp(OutputFormatter& out, const uint8_t* pkt, size_t len) const
{
  out.addDelimiter() << "UDP";

  if (len < sizeof(udphdr)) {
    out << " truncated header, length " << len;
    return true;
  }

  auto uh = reinterpret_cast<const udphdr*>(pkt);
  size_t udpLen = endian::big_to_native(uh->uh_ulen);
  if (udpLen < sizeof(udphdr)) {
    out << " bad length " << udpLen;
    return true;
  }
  if (udpLen > len) {
    out << " truncated packet, " << udpLen - len << " bytes missing";
    return true;
  }
  else {
    len = udpLen;
  }

  pkt += sizeof(udphdr);
  len -= sizeof(udphdr);

  out.addDelimiter() << "length " << len;

  return printNdn(out, pkt, len);
}

bool
NdnDump::printNdn(OutputFormatter& out, const uint8_t* pkt, size_t len) const
{
  if (len == 0) {
    return false;
  }
  out.addDelimiter();

  bool isOk = false;
  Block block;
  std::tie(isOk, block) = Block::fromBuffer(pkt, len);
  if (!isOk) {
    // if packet is incomplete, we will not be able to process it
    out << "NDN truncated packet, length " << len;
    return true;
  }

  lp::Packet lpPacket;
  Block netPacket;

  if (block.type() == lp::tlv::LpPacket) {
    out << "NDNLPv2";
    try {
      lpPacket.wireDecode(block);
    }
    catch (const tlv::Error& e) {
      out << " invalid packet: " << e.what();
      return true;
    }

    Buffer::const_iterator begin, end;
    if (lpPacket.has<lp::FragmentField>()) {
      std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
    }
    else {
      out << " idle";
      return true;
    }

    bool isOk = false;
    std::tie(isOk, netPacket) = Block::fromBuffer(&*begin, std::distance(begin, end));
    if (!isOk) {
      // if network packet is fragmented, we will not be able to process it
      out << " fragment";
      return true;
    }
  }
  else {
    netPacket = std::move(block);
  }
  out.addDelimiter();

  try {
    switch (netPacket.type()) {
      case tlv::Interest: {
        Interest interest(netPacket);
        if (!matchesFilter(interest.getName())) {
          return false;
        }

        if (lpPacket.has<lp::NackField>()) {
          lp::Nack nack(interest);
          nack.setHeader(lpPacket.get<lp::NackField>());
          out << "NACK (" << nack.getReason() << "): " << interest;
        }
        else {
          out << "INTEREST: " << interest;
        }
        break;
      }
      case tlv::Data: {
        Data data(netPacket);
        if (!matchesFilter(data.getName())) {
          return false;
        }

        out << "DATA: " << data.getName();
        break;
      }
      default: {
        out << "[Unsupported NDN packet type " << netPacket.type() << "]";
        break;
      }
    }
  }
  catch (const tlv::Error& e) {
    out << "invalid network packet: " << e.what();
  }

  return true;
}

bool
NdnDump::matchesFilter(const Name& name) const
{
  if (!nameFilter)
    return true;

  /// \todo Switch to NDN regular expressions
  return std::regex_match(name.toUri(), *nameFilter);
}

} // namespace dump
} // namespace ndn
