]>
Commit | Line | Data |
---|---|---|
12471842 PL |
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 | */ | |
e8c59f2d | 22 | #pragma once |
ab06937b BH |
23 | #include <cstdio> |
24 | #include <stdexcept> | |
a5d9353e | 25 | #include "iputils.hh" |
ab06937b | 26 | #include <string> |
11212b81 BH |
27 | #include "misc.hh" |
28 | #include <iostream> | |
0b86fb59 | 29 | #define __FAVOR_BSD |
3042f1ba | 30 | #include <netinet/in_systm.h> |
11212b81 | 31 | #include <netinet/ip.h> |
bf32bff8 | 32 | #include <netinet/ip6.h> |
11212b81 | 33 | #include <netinet/udp.h> |
b35da1b6 | 34 | #if defined(__NetBSD__) |
525d1f90 PD |
35 | #include <net/if.h> |
36 | #include <net/if_ether.h> | |
b35da1b6 FO |
37 | #elif defined (__OpenBSD__) |
38 | #include <net/if.h> | |
39 | #include <netinet/if_ether.h> | |
c833728c | 40 | #elif defined (__SVR4) && defined (__sun) |
8f3456a7 | 41 | #include <sys/ethernet.h> |
525d1f90 | 42 | #else |
0b86fb59 | 43 | #include <net/ethernet.h> |
525d1f90 | 44 | #endif |
a48e03da | 45 | |
10f4eea8 | 46 | #include "namespaces.hh" |
ab06937b | 47 | |
7be3bc79 BH |
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 | ||
a1e7d16d BH |
59 | struct pdns_timeval |
60 | { | |
d7729968 RG |
61 | uint32_t tv_sec{0}; |
62 | uint32_t tv_usec{0}; | |
a1e7d16d BH |
63 | }; |
64 | ||
7be3bc79 | 65 | struct pdns_pcap_pkthdr { |
a1e7d16d | 66 | struct pdns_timeval ts; /* time stamp */ |
d7729968 RG |
67 | uint32_t caplen{0}; /* length of portion present */ |
68 | uint32_t len{0}; /* length this packet (off wire) */ | |
7be3bc79 BH |
69 | }; |
70 | ||
2acf3098 BH |
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 | ||
ab06937b BH |
79 | class PcapPacketReader |
80 | { | |
81 | public: | |
82 | class EofException : public runtime_error | |
83 | { | |
84 | public: | |
e08c410b | 85 | EofException(const string& str="PcapPacketReader::EofException") : runtime_error(str) |
ab06937b BH |
86 | { |
87 | } | |
88 | }; | |
89 | ||
46c4985c | 90 | PcapPacketReader(const string& fname); |
ab06937b | 91 | |
ab06937b BH |
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 | ||
a5d9353e | 102 | ComboAddress getSource() const; |
103 | ComboAddress getDest() const; | |
104 | ||
d7729968 RG |
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}; | |
7be3bc79 | 113 | struct pdns_pcap_pkthdr d_pheader; |
11212b81 | 114 | |
7be3bc79 | 115 | pdns_pcap_file_header d_pfh; |
11212b81 | 116 | unsigned int d_runts, d_oversized, d_correctpackets, d_nonetheripudp; |
e6935cd0 PD |
117 | alignas (struct ip) char d_readbuffer[32768]; |
118 | char *d_buffer; | |
119 | size_t d_bufsize; | |
ab06937b | 120 | private: |
46c4985c | 121 | pdns::UniqueFilePtr d_fp{nullptr}; |
ab06937b | 122 | string d_fname; |
fe92c902 | 123 | unsigned int d_skipMediaHeader; |
ab06937b BH |
124 | }; |
125 | ||
126 | class PcapPacketWriter | |
127 | { | |
46c4985c | 128 | public: |
e795f590 | 129 | PcapPacketWriter(const string& fname, const PcapPacketReader& ppr); |
130 | PcapPacketWriter(const string& fname); | |
46c4985c | 131 | |
ab06937b | 132 | void write(); |
e795f590 | 133 | void setPPR(const PcapPacketReader& ppr) { d_ppr = &ppr; } |
ab06937b BH |
134 | |
135 | private: | |
136 | string d_fname; | |
d7729968 | 137 | const PcapPacketReader* d_ppr{nullptr}; |
ab06937b | 138 | |
46c4985c | 139 | pdns::UniqueFilePtr d_fp{nullptr}; |
e795f590 | 140 | bool d_first{true}; |
46c4985c | 141 | }; |