]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/dnspcap.cc
make dns analysis tools more bsd-compatible
[thirdparty/pdns.git] / pdns / dnspcap.cc
CommitLineData
ab06937b 1#include "dnspcap.hh"
11212b81 2#include <boost/format.hpp>
ab06937b 3
11212b81 4using namespace boost;
ab06937b
BH
5PcapPacketReader::PcapPacketReader(const string& fname) : d_fname(fname)
6{
7 d_fp=fopen(fname.c_str(),"r");
8 if(!d_fp)
9 unixDie("Unable to open file");
10
11
12 checkedFread(&d_pfh);
13
14 if(d_pfh.magic != 2712847316UL)
15 throw runtime_error((format("PCAP file %s has bad magic %x, should be %x") % fname % d_pfh.magic % 2712847316UL).str());
16
17 if( d_pfh.linktype!=1)
18 throw runtime_error((format("Unsupported link type %d") % d_pfh.linktype).str());
19
11212b81 20 d_runts = d_oversized = d_correctpackets = d_nonetheripudp = 0;
ab06937b
BH
21}
22
11212b81 23PcapPacketReader::~PcapPacketReader()
ab06937b
BH
24{
25 fclose(d_fp);
26}
27
28
29void PcapPacketReader::checkedFreadSize(void* ptr, size_t size)
30{
31 int ret=fread(ptr, 1, size, d_fp);
32 if(ret < 0)
33 unixDie( (format("Error reading %d bytes from %s") % size % d_fname).str());
34
35 if(!ret)
36 throw EofException();
37
38 if((size_t)ret != size)
39 throw EofException((format("Incomplete read from '%s', got only %d bytes") % d_fname % ret).str());
40}
41
42bool PcapPacketReader::getUDPPacket()
43try
44{
45 for(;;) {
46 checkedFread(&d_pheader);
e0333255
BH
47 if(!d_pheader.caplen)
48 continue;
3042f1ba 49
ab06937b
BH
50 if(d_pheader.caplen > sizeof(d_buffer)) {
51 d_oversized++;
3042f1ba 52 throw runtime_error((format("Can't handle a %d byte packet, have space for %d") % d_pheader.caplen % sizeof(d_buffer)).str());
ab06937b 53 }
3042f1ba 54
ab06937b 55 checkedFreadSize(d_buffer, d_pheader.caplen);
3042f1ba
BH
56
57 if(d_pheader.caplen!=d_pheader.len) {
58 d_runts++;
59 continue;
60 }
61
11212b81 62 d_ether=reinterpret_cast<struct ether_header*>(d_buffer);
3042f1ba
BH
63 d_ip=reinterpret_cast<struct ip*>(d_buffer + sizeof(struct ether_header));
64
65 if(ntohs(d_ether->ether_type)==0x0800 && d_ip->ip_p==17) { // udp
66 d_udp=reinterpret_cast<const struct udphdr*>(d_buffer + sizeof(struct ether_header) + 4 * d_ip->ip_hl);
ab06937b
BH
67 d_payload = (unsigned char*)d_udp + sizeof(struct udphdr);
68 d_len = ntohs(d_udp->len) - sizeof(struct udphdr);
11212b81 69 d_correctpackets++;
ab06937b
BH
70 return true;
71 }
11212b81
BH
72 else {
73 d_nonetheripudp++;
74 }
ab06937b
BH
75 }
76}
77catch(EofException) {
78 return false;
79}
80
81
82PcapPacketWriter::PcapPacketWriter(const string& fname, PcapPacketReader& ppr) : d_fname(fname), d_ppr(ppr)
83{
84 d_fp=fopen(fname.c_str(),"w");
85 if(!d_fp)
86 unixDie("Unable to open file");
87
88 fwrite(&ppr.d_pfh, 1, sizeof(ppr.d_pfh), d_fp);
89
90}
91
92void PcapPacketWriter::write()
93{
94 fwrite(&d_ppr.d_pheader, 1, sizeof(d_ppr.d_pheader), d_fp);
95 fwrite(d_ppr.d_buffer, 1, d_ppr.d_pheader.caplen, d_fp);
96}
97
11212b81 98PcapPacketWriter::~PcapPacketWriter()
ab06937b
BH
99{
100 fclose(d_fp);
101}