std::unique_ptr PcapParser::getPacketFromPcap()

in katran/lib/testing/PcapParser.cpp [80:131]


std::unique_ptr<folly::IOBuf> PcapParser::getPacketFromPcap() {
  const struct pcaprec_hdr_s* pcaprec_hdr;
  std::string tmpBuf;
  uint32_t pkt_len;
  bool res;
  if (inputFileName_.empty()) {
    LOG(INFO) << "no input filed specified";
    return nullptr;
  }
  auto fd = inputFile_.fd();
  if (firstRead_) {
    firstRead_ = false;
    // read pcap header in the beginning of the file and some sanity checking
    const struct pcap_hdr_s* pcap_hdr;
    res = folly::readFile(fd, tmpBuf, sizeof(struct pcap_hdr_s));
    if (!res || tmpBuf.size() != sizeof(struct pcap_hdr_s)) {
      LOG(ERROR) << "cant read pcap_hdr_s from input file";
      return nullptr;
    }
    pcap_hdr = reinterpret_cast<const struct pcap_hdr_s*>(tmpBuf.c_str());

    VLOG(2) << "pcap hdr:"
            << "\nversion major: " << pcap_hdr->version_major
            << "\nversion minor: " << pcap_hdr->version_minor
            << "\nmagic number: " << pcap_hdr->magic_number
            << "\nnetwork: " << pcap_hdr->network;

    snaplen_ = pcap_hdr->snaplen;
    VLOG(2) << "snaplen: " << snaplen_;
  }
  // read per record header and some sanity checking.
  res = folly::readFile(fd, tmpBuf, sizeof(struct pcaprec_hdr_s));
  if (!res || tmpBuf.size() != sizeof(struct pcaprec_hdr_s)) {
    LOG(ERROR) << "cant read pcaprec_hdr_s from input file";
    return nullptr;
  }
  pcaprec_hdr = reinterpret_cast<const struct pcaprec_hdr_s*>(tmpBuf.c_str());
  pkt_len = pcaprec_hdr->incl_len;
  VLOG(2) << "pckt len: " << pkt_len;
  if (pkt_len > snaplen_) {
    LOG(INFO) << "error in pcap file. incl_len > snaplen";
    return nullptr;
  }
  // read pckt from pcap file
  res = folly::readFile(fd, tmpBuf, pkt_len);
  if (!res || tmpBuf.size() != pkt_len) {
    LOG(ERROR) << "cant read packet from pcap file";
    return nullptr;
  }
  auto buf = folly::IOBuf::copyBuffer(tmpBuf);
  return buf;
}