]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnspcap.hh
Merge pull request #4055 from rgacogne/dnspcap2protobuf-cov-fixes
[thirdparty/pdns.git] / pdns / dnspcap.hh
1 #ifndef PDNS_DNSPCAP_HH
2 #define PDNS_DNSPCAP_HH
3
4 #include <cstdio>
5 #include <stdexcept>
6 #include "iputils.hh"
7 #include <string>
8 #include "misc.hh"
9 #include <iostream>
10 #define __FAVOR_BSD
11 #include <netinet/in_systm.h>
12 #include <netinet/ip.h>
13 #include <netinet/ip6.h>
14 #include <netinet/udp.h>
15 #if defined(__NetBSD__)
16 #include <net/if.h>
17 #include <net/if_ether.h>
18 #elif defined (__OpenBSD__)
19 #include <net/if.h>
20 #include <netinet/if_ether.h>
21 #elif defined (__SVR4) && defined (__sun)
22 #include <sys/ethernet.h>
23 #else
24 #include <net/ethernet.h>
25 #endif
26 #include <vector>
27 #include <boost/format.hpp>
28 #include "namespaces.hh"
29
30 struct pdns_pcap_file_header {
31 uint32_t magic;
32 uint16_t version_major;
33 uint16_t version_minor;
34 uint32_t thiszone; /* gmt to local correction */
35 uint32_t sigfigs; /* accuracy of timestamps */
36 uint32_t snaplen; /* max length saved portion of each pkt */
37 uint32_t linktype; /* data link type (LINKTYPE_*) */
38 };
39
40
41 struct pdns_timeval
42 {
43 uint32_t tv_sec{0};
44 uint32_t tv_usec{0};
45 };
46
47 struct pdns_pcap_pkthdr {
48 struct pdns_timeval ts; /* time stamp */
49 uint32_t caplen{0}; /* length of portion present */
50 uint32_t len{0}; /* length this packet (off wire) */
51 };
52
53 struct pdns_lcc_header {
54 uint16_t lcc_pkttype;/* packet type */
55 uint16_t lcc_hatype;/* link-layer address type */
56 uint16_t lcc_halen;/* link-layer address length */
57 uint8_t lcc_addr[8];/* link-layer address */
58 uint16_t lcc_protocol;/* protocol */
59 };
60
61 class PcapPacketReader
62 {
63 public:
64 class EofException : public runtime_error
65 {
66 public:
67 EofException(const string& str="") : runtime_error(str)
68 {
69 }
70 };
71
72 PcapPacketReader(const string& fname);
73
74 ~PcapPacketReader();
75
76 template<typename T>
77 void checkedFread(T* ptr)
78 {
79 checkedFreadSize(ptr, sizeof(*ptr));
80 }
81
82 void checkedFreadSize(void* ptr, size_t size) ;
83
84 bool getUDPPacket();
85
86 ComboAddress getSource() const;
87 ComboAddress getDest() const;
88
89 struct pdns_lcc_header* d_lcc{nullptr};
90 struct ether_header* d_ether{nullptr};
91 struct ip *d_ip{nullptr};
92 struct ip6_hdr *d_ip6{nullptr};
93 const struct tcphdr *d_tcp{nullptr};
94 const struct udphdr *d_udp{nullptr};
95 const uint8_t* d_payload{nullptr};
96 unsigned int d_len{0};
97 struct pdns_pcap_pkthdr d_pheader;
98
99 pdns_pcap_file_header d_pfh;
100 unsigned int d_runts, d_oversized, d_correctpackets, d_nonetheripudp;
101 char d_buffer[32768];
102 private:
103 FILE* d_fp;
104 string d_fname;
105 int d_skipMediaHeader;
106 };
107
108 class PcapPacketWriter
109 {
110 public:
111 PcapPacketWriter(const string& fname, const PcapPacketReader& ppr);
112 PcapPacketWriter(const string& fname);
113
114 void write();
115 void setPPR(const PcapPacketReader& ppr) { d_ppr = &ppr; }
116 ~PcapPacketWriter();
117
118 private:
119 string d_fname;
120 const PcapPacketReader* d_ppr{nullptr};
121
122 FILE *d_fp;
123 bool d_first{true};
124 };
125
126 #endif // DNSPCAP_HH