]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnspcap.hh
dnsdist: Fix DNS over plain HTTP broken by `reloadAllCertificates()`
[thirdparty/pdns.git] / pdns / dnspcap.hh
1 /*
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22 #pragma once
23 #include <cstdio>
24 #include <stdexcept>
25 #include "iputils.hh"
26 #include <string>
27 #include "misc.hh"
28 #include <iostream>
29 #define __FAVOR_BSD
30 #include <netinet/in_systm.h>
31 #include <netinet/ip.h>
32 #include <netinet/ip6.h>
33 #include <netinet/udp.h>
34 #if defined(__NetBSD__)
35 #include <net/if.h>
36 #include <net/if_ether.h>
37 #elif defined (__OpenBSD__)
38 #include <net/if.h>
39 #include <netinet/if_ether.h>
40 #elif defined (__SVR4) && defined (__sun)
41 #include <sys/ethernet.h>
42 #else
43 #include <net/ethernet.h>
44 #endif
45
46 #include "namespaces.hh"
47
48 struct pdns_pcap_file_header {
49 uint32_t magic;
50 uint16_t version_major;
51 uint16_t version_minor;
52 uint32_t thiszone; /* gmt to local correction */
53 uint32_t sigfigs; /* accuracy of timestamps */
54 uint32_t snaplen; /* max length saved portion of each pkt */
55 uint32_t linktype; /* data link type (LINKTYPE_*) */
56 };
57
58
59 struct pdns_timeval
60 {
61 uint32_t tv_sec{0};
62 uint32_t tv_usec{0};
63 };
64
65 struct pdns_pcap_pkthdr {
66 struct pdns_timeval ts; /* time stamp */
67 uint32_t caplen{0}; /* length of portion present */
68 uint32_t len{0}; /* length this packet (off wire) */
69 };
70
71 struct pdns_lcc_header {
72 uint16_t lcc_pkttype;/* packet type */
73 uint16_t lcc_hatype;/* link-layer address type */
74 uint16_t lcc_halen;/* link-layer address length */
75 uint8_t lcc_addr[8];/* link-layer address */
76 uint16_t lcc_protocol;/* protocol */
77 };
78
79 class PcapPacketReader
80 {
81 public:
82 class EofException : public runtime_error
83 {
84 public:
85 EofException(const string& str="PcapPacketReader::EofException") : runtime_error(str)
86 {
87 }
88 };
89
90 PcapPacketReader(const string& fname);
91
92 template<typename T>
93 void checkedFread(T* ptr)
94 {
95 checkedFreadSize(ptr, sizeof(*ptr));
96 }
97
98 void checkedFreadSize(void* ptr, size_t size) ;
99
100 bool getUDPPacket();
101
102 ComboAddress getSource() const;
103 ComboAddress getDest() const;
104
105 struct pdns_lcc_header* d_lcc{nullptr};
106 struct ether_header* d_ether{nullptr};
107 struct ip *d_ip{nullptr};
108 struct ip6_hdr *d_ip6{nullptr};
109 const struct tcphdr *d_tcp{nullptr};
110 const struct udphdr *d_udp{nullptr};
111 const uint8_t* d_payload{nullptr};
112 unsigned int d_len{0};
113 struct pdns_pcap_pkthdr d_pheader;
114
115 pdns_pcap_file_header d_pfh;
116 unsigned int d_runts, d_oversized, d_correctpackets, d_nonetheripudp;
117 alignas (struct ip) char d_readbuffer[32768];
118 char *d_buffer;
119 size_t d_bufsize;
120 private:
121 pdns::UniqueFilePtr d_fp{nullptr};
122 string d_fname;
123 unsigned int d_skipMediaHeader;
124 };
125
126 class PcapPacketWriter
127 {
128 public:
129 PcapPacketWriter(const string& fname, const PcapPacketReader& ppr);
130 PcapPacketWriter(const string& fname);
131
132 void write();
133 void setPPR(const PcapPacketReader& ppr) { d_ppr = &ppr; }
134
135 private:
136 string d_fname;
137 const PcapPacketReader* d_ppr{nullptr};
138
139 pdns::UniqueFilePtr d_fp{nullptr};
140 bool d_first{true};
141 };