bmv2
Designing your own switch target with bmv2
Loading...
Searching...
No Matches
pcap_file.h
1/* Copyright 2013-present Barefoot Networks, Inc.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef BM_BM_SIM_PCAP_FILE_H_
17#define BM_BM_SIM_PCAP_FILE_H_
18
19#include <pcap.h>
20
21#include <stdexcept>
22#include <mutex>
23#include <cassert>
24#include <vector>
25#include <string>
26#include <memory>
27#include <unordered_map>
28
29#include "packet_handler.h"
30
31namespace bm {
32
33// A PcapPacket is a packet that has been read from a Pcap file.
34// These packets can only be created by the PcapFileIn class.
35class PcapPacket {
36 private:
37 unsigned port; // port index where packet originated
38 const u_char *data; // type defined in pcap.h
39 // The packet is only valid as long as the cursor
40 // in the PcapFileIn is not changed, since the pcap_header*
41 // points to a buffer returned by the pcap library.
42 const pcap_pkthdr *pcap_header;
43
44 PcapPacket(unsigned port, const u_char *data, const pcap_pkthdr *pcap_header)
45 : port(port),
46 data(data),
47 pcap_header(pcap_header) { }
48
49 // Only class that can call constructor
50 friend class PcapFileIn;
51
52 public:
53 static std::string timevalToString(const struct timeval *tv);
54
55 const char *getData() const { return reinterpret_cast<const char *>(data); }
56 unsigned getLength() const { return static_cast<unsigned>(pcap_header->len); }
57 const struct timeval *getTime() const { return &pcap_header->ts; }
58 unsigned getPort() const { return port; }
59};
60
61class PcapFileBase {
62 protected:
63 unsigned port; // port number represented by this file
64 std::string filename;
65
66 PcapFileBase(unsigned port, std::string filename);
67};
68
69// C++ wrapper around a pcap file that is used for reading:
70// A stream-like abstraction of a PCAP (Packet capture) file.
71// Assumes that all packets in a file are sorted on time.
72class PcapFileIn : public PcapFileBase {
73 public:
74 PcapFileIn(unsigned port, std::string filename);
75 virtual ~PcapFileIn();
76
77 // Returns pointer to current packet
78 std::unique_ptr<PcapPacket> current() const;
79 // Advances to next packet. Should be called before current().
80 // Returns 'false' on end of file.
81 bool moveNext();
82 // restart from the beginning
83 void reset();
84 // True if we have reached end of file.
85 bool atEOF() const;
86
87 private:
88 pcap_t *pcap;
89 pcap_pkthdr *current_header;
90 const u_char *current_data;
91
92 enum class State {
93 Uninitialized,
94 Opened,
95 Reading,
96 AtEnd
97 };
98
99 State state;
100
101 private:
102 void open();
103 bool advance();
104 void deallocate();
105
106 PcapFileIn(PcapFileIn const& ) = delete;
107 PcapFileIn& operator=(PcapFileIn const&) = delete;
108};
109
110
111class PcapFileOut :
112 public PcapFileBase {
113 public:
114 // port is not really used
115 PcapFileOut(unsigned port, std::string filename);
116 virtual ~PcapFileOut();
117 void writePacket(const char *data, unsigned length);
118
119 private:
120 pcap_t *pcap;
121 pcap_dumper_t *dumper;
122
123 PcapFileOut(PcapFileOut const& ) = delete;
124 PcapFileOut& operator=(PcapFileOut const&) = delete;
125};
126
127
128// Reads data from a set of Pcap files; returns packets in order
129// of their timestamps.
130class PcapFilesReader :
131 public PacketDispatcherIface {
132 public:
133 // Read packets from a set of files in timestamp order. Each file is
134 // associated to a port number corresponding to its index in the files vector.
135 // If 'respectTiming' is true, the PcapFilesReader only emits packets at the
136 // proper times, adjusted relative to the time of the 'start' call. In this
137 // case the 'start' method should probably be invoked by the caller on a
138 // separate thread. 'wait_time_in_seconds' is the time that the reader should
139 // wait before starting to process packets.
140 PcapFilesReader(bool respectTiming, unsigned wait_time_in_seconds);
141 // Add a file corresponding to the specified port.
142 void addFile(unsigned port, std::string file);
143 void start(); // start processing the pcap files
144
145 // Invoked every time a packet is read
146 PacketDispatcherIface::ReturnCode set_packet_handler(
147 const PacketHandler &handler, void *cookie);
148
149 private:
150 std::vector<std::unique_ptr<PcapFileIn>> files;
151 unsigned nonEmptyFiles;
152 unsigned wait_time_in_seconds;
153 bool respectTiming;
154 // Time when observable starts to read packets
155 struct timeval startTime;
156 // Time of first packet across all files
157 struct timeval firstPacketTime;
158 // constant zero (could be static, but it's easier to initialize it this way)
159 struct timeval zero;
160
161 // index of next file to read packet from
162 unsigned scheduledIndex;
163 bool started;
164
165 void scan();
166 void schedulePacket(unsigned index, const struct timeval *delay);
167 void timerFired(); // send a scheduled packet
168
169 PcapFilesReader(PcapFilesReader const& ) = delete;
170 PcapFilesReader& operator=(PcapFilesReader const&) = delete;
171
172 // Function to call when a packet is read
173 PacketHandler handler;
174 void *cookie;
175};
176
177
178// Writes data to a set of Pcap files.
179class PcapFilesWriter : public PacketReceiverIface {
180 public:
181 PcapFilesWriter();
182 // Add a file corresponding to the specified port.
183 void addFile(unsigned port, std::string file);
184 void send_packet(int port_num, const char *buffer, int len);
185
186 private:
187 std::unordered_map<unsigned, std::unique_ptr<PcapFileOut>> files;
188
189 PcapFilesWriter(PcapFilesWriter const& ) = delete;
190 PcapFilesWriter& operator=(PcapFilesWriter const&) = delete;
191};
192
193} // namespace bm
194
195#endif // BM_BM_SIM_PCAP_FILE_H_