/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-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/>.
 */
/*
 * 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 <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>

namespace ndn {
namespace dump {

const size_t MAX_SNAPLEN = 65535;

Ndndump::Ndndump()
  : isVerbose(false)
  , pcapProgram("(ether proto 0x8624) || (tcp port 6363) || (udp port 6363)")
  // , isSuccinct(false)
  // , isMatchInverted(false)
  // , shouldPrintStructure(false)
  // , isTcpOnly(false)
  // , isUdpOnly(false)
{
}

void
Ndndump::run()
{
  if (inputFile.empty() && interface.empty()) {
    char errbuf[PCAP_ERRBUF_SIZE];
    const char* pcapDevice = pcap_lookupdev(errbuf);

    if (pcapDevice == nullptr) {
      BOOST_THROW_EXCEPTION(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 (!interface.empty()) {
    char errbuf[PCAP_ERRBUF_SIZE];
    m_pcap = pcap_open_live(interface.data(), MAX_SNAPLEN, 0, 1000, errbuf);
    if (m_pcap == nullptr) {
      BOOST_THROW_EXCEPTION(Error("Cannot open interface " + interface + " (" + errbuf + ")"));
    }
  }
  else {
    char errbuf[PCAP_ERRBUF_SIZE];
    m_pcap = pcap_open_offline(inputFile.data(), errbuf);
    if (m_pcap == nullptr) {
      BOOST_THROW_EXCEPTION(Error("Cannot open file " + inputFile + " for reading (" + errbuf + ")"));
    }
  }

  if (!pcapProgram.empty()) {
    if (isVerbose) {
      std::cerr << "ndndump: pcap_filter = " << pcapProgram << std::endl;
    }

    bpf_program program;
    int res = pcap_compile(m_pcap, &program, pcapProgram.data(), 0, PCAP_NETMASK_UNKNOWN);

    if (res < 0) {
      BOOST_THROW_EXCEPTION(Error("Cannot parse tcpdump expression '" + pcapProgram +
                                  "' (" + pcap_geterr(m_pcap) + ")"));
    }

    res = pcap_setfilter(m_pcap, &program);
    pcap_freecode(&program);

    if (res < 0) {
      BOOST_THROW_EXCEPTION(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 && m_dataLinkType != DLT_LINUX_SLL) {
    BOOST_THROW_EXCEPTION(Error("Unsupported pcap format (" + to_string(m_dataLinkType) + ")"));
  }

  pcap_loop(m_pcap, -1, &Ndndump::onCapturedPacket, reinterpret_cast<uint8_t*>(this));
}

void
Ndndump::onCapturedPacket(const pcap_pkthdr* header, const uint8_t* packet) const
{
  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 res = skipAndProcessFrameHeader(frameType, payload, payloadSize, os);
  if (res < 0) {
    return;
  }

  bool isOk = false;
  Block block;
  std::tie(isOk, block) = Block::fromBuffer(payload, payloadSize);
  if (!isOk) {
    // if packet is incomplete, we will not be able to process it
    if (payloadSize > 0) {
      std::cout << os.str() << ", " << "INCOMPLETE-PACKET" << ", size: " << payloadSize << std::endl;
    }
    return;
  }

  lp::Packet lpPacket;
  Block netPacket;

  if (block.type() == lp::tlv::LpPacket) {
    lpPacket = lp::Packet(block);

    Buffer::const_iterator begin, end;

    if (lpPacket.has<lp::FragmentField>()) {
      std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
    }
    else {
      std::cout << os.str() << ", " << "NDNLPv2-IDLE" << std::endl;
      return;
    }

    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
      std::cout << os.str() << ", " << "NDNLPv2-FRAGMENT" << std::endl;
      return;
    }
  }
  else {
    netPacket = block;
  }

  try {
    if (netPacket.type() == tlv::Interest) {
      Interest interest(netPacket);
      if (matchesFilter(interest.getName())) {

        if (lpPacket.has<lp::NackField>()) {
          lp::Nack nack(interest);
          nack.setHeader(lpPacket.get<lp::NackField>());

          std::cout << os.str() << ", " << "NACK: " << nack.getReason() << ", " << interest << std::endl;
        }
        else {
          std::cout << os.str() << ", " << "INTEREST: " << interest << std::endl;
        }
      }
    }
    else if (netPacket.type() == tlv::Data) {
      Data data(netPacket);
      if (matchesFilter(data.getName())) {
        std::cout << os.str() << ", " << "DATA: " << data.getName() << std::endl;
      }
    }
    else {
      std::cout << os.str() << ", " << "UNKNOWN-NETWORK-PACKET" << std::endl;
    }
  }
  catch (const tlv::Error& e) {
    std::cerr << e.what() << std::endl;
  }
}

void
Ndndump::printInterceptTime(std::ostream& os, const pcap_pkthdr* header) const
{
  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) const
{
  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_HDR_LEN;
      payload += ETHER_HDR_LEN;

      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;
    }
    case DLT_LINUX_SLL: {
      const sll_header* sllHeader = reinterpret_cast<const sll_header*>(payload);

      if (payloadSize < SLL_HDR_LEN) {
        std::cerr << "Invalid LINUX_SLL frame" << std::endl;
        return -1;
      }

      frameType = ntohs(sllHeader->sll_protocol);
      payloadSize -= SLL_HDR_LEN;
      payload += SLL_HDR_LEN;

      break;
    }
  }

  return frameType;
}

int
Ndndump::skipAndProcessFrameHeader(int frameType,
                                   const uint8_t*& payload, ssize_t& payloadSize,
                                   std::ostream& os) const
{
  switch (frameType) {
    case 0x0800: // ETHERTYPE_IP
    case DLT_EN10MB: { // pcap encapsulation
      const ip* ipHeader = reinterpret_cast<const ip*>(payload);
      size_t ipHeaderSize = ipHeader->ip_hl * 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 = tcpHeader->th_off * 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: // do nothing if it is not a recognized type of a packet
      return -1;
  }

  return 0;
}

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
