]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnspcap.cc
6 #include <boost/format.hpp>
9 #include "namespaces.hh"
10 PcapPacketReader::PcapPacketReader(const string
& fname
) : d_fname(fname
)
12 d_fp
=fopen(fname
.c_str(),"r");
14 unixDie("Unable to open file " + fname
);
16 int flags
=fcntl(fileno(d_fp
),F_GETFL
,0);
17 fcntl(fileno(d_fp
), F_SETFL
,flags
&(~O_NONBLOCK
)); // bsd needs this in stdin (??)
21 if(d_pfh
.magic
!= 2712847316UL)
22 throw runtime_error((format("PCAP file %s has bad magic %x, should be %x") % fname
% d_pfh
.magic
% 2712847316UL).str());
24 if( d_pfh
.linktype
==1) {
25 d_skipMediaHeader
=sizeof(struct ether_header
);
27 else if(d_pfh
.linktype
==101) {
30 else if(d_pfh
.linktype
==113) {
33 else throw runtime_error((format("Unsupported link type %d") % d_pfh
.linktype
).str());
35 d_runts
= d_oversized
= d_correctpackets
= d_nonetheripudp
= 0;
38 PcapPacketReader::~PcapPacketReader()
44 void PcapPacketReader::checkedFreadSize(void* ptr
, size_t size
)
46 int ret
=fread(ptr
, 1, size
, d_fp
);
48 unixDie( (format("Error reading %d bytes from %s") % size
% d_fname
).str());
53 if((size_t)ret
!= size
)
54 throw EofException((format("Incomplete read from '%s', got only %d bytes") % d_fname
% ret
).str());
57 bool PcapPacketReader::getUDPPacket()
61 checkedFread(&d_pheader
);
62 if(!d_pheader
.caplen
) {
67 if(d_pheader
.caplen
> sizeof(d_buffer
)) {
69 throw runtime_error((format("Can't handle a %d byte packet, have space for %d") % d_pheader
.caplen
% sizeof(d_buffer
)).str());
72 checkedFreadSize(d_buffer
, d_pheader
.caplen
);
74 if(d_pheader
.caplen
!=d_pheader
.len
) {
79 d_ether
=reinterpret_cast<struct ether_header
*>(d_buffer
);
80 d_lcc
=reinterpret_cast<struct pdns_lcc_header
*>(d_buffer
);
82 d_ip
=reinterpret_cast<struct ip
*>(d_buffer
+ d_skipMediaHeader
);
83 d_ip6
=reinterpret_cast<struct ip6_hdr
*>(d_buffer
+ d_skipMediaHeader
);
84 uint16_t contentCode
=0;
86 contentCode
=ntohs(d_ether
->ether_type
);
87 else if(d_pfh
.linktype
==101) {
93 else if(d_pfh
.linktype
==113)
94 contentCode
=ntohs(d_lcc
->lcc_protocol
);
96 if(contentCode
==0x0800 && d_ip
->ip_p
==17) { // udp
97 d_udp
=reinterpret_cast<const struct udphdr
*>(d_buffer
+ d_skipMediaHeader
+ 4 * d_ip
->ip_hl
);
98 d_payload
= (unsigned char*)d_udp
+ sizeof(struct udphdr
);
99 d_len
= ntohs(d_udp
->uh_ulen
) - sizeof(struct udphdr
);
100 if((const char*)d_payload
+ d_len
> d_buffer
+ d_pheader
.caplen
) {
107 if(contentCode
==0x86dd && d_ip6
->ip6_ctlun
.ip6_un1
.ip6_un1_nxt
==17) { // udpv6, we ignore anything with extension hdr
108 d_udp
=reinterpret_cast<const struct udphdr
*>(d_buffer
+ d_skipMediaHeader
+ sizeof(struct ip6_hdr
));
109 d_payload
= (unsigned char*)d_udp
+ sizeof(struct udphdr
);
110 d_len
= ntohs(d_udp
->uh_ulen
) - sizeof(struct udphdr
);
111 if((const char*)d_payload
+ d_len
> d_buffer
+ d_pheader
.caplen
) {
124 catch(EofException
) {
128 ComboAddress
PcapPacketReader::getSource() const
131 if(d_ip
->ip_v
== 4) {
132 ret
.sin4
.sin_family
= AF_INET
;
133 ret
.sin4
.sin_addr
= d_ip
->ip_src
;
134 ret
.sin4
.sin_port
= d_udp
->uh_sport
; // should deal with TCP too!
136 ret
.sin6
.sin6_family
= AF_INET6
;
137 ret
.sin6
.sin6_addr
= d_ip6
->ip6_src
;
138 ret
.sin6
.sin6_port
= d_udp
->uh_sport
; // should deal with TCP too!
143 ComboAddress
PcapPacketReader::getDest() const
146 if(d_ip
->ip_v
== 4) {
147 ret
.sin4
.sin_family
= AF_INET
;
148 ret
.sin4
.sin_addr
= d_ip
->ip_dst
;
149 ret
.sin4
.sin_port
= d_udp
->uh_dport
; // should deal with TCP too!
151 ret
.sin6
.sin6_family
= AF_INET6
;
152 ret
.sin6
.sin6_addr
= d_ip6
->ip6_dst
;
153 ret
.sin6
.sin6_port
= d_udp
->uh_dport
; // should deal with TCP too!
158 PcapPacketWriter::PcapPacketWriter(const string
& fname
, PcapPacketReader
& ppr
) : d_fname(fname
), d_ppr(ppr
)
160 d_fp
=fopen(fname
.c_str(),"w");
162 unixDie("Unable to open file");
164 int flags
=fcntl(fileno(d_fp
),F_GETFL
,0);
165 fcntl(fileno(d_fp
), F_SETFL
,flags
&(~O_NONBLOCK
)); // bsd needs this in stdin (??)
167 fwrite(&ppr
.d_pfh
, 1, sizeof(ppr
.d_pfh
), d_fp
);
170 void PcapPacketWriter::write()
172 fwrite(&d_ppr
.d_pheader
, 1, sizeof(d_ppr
.d_pheader
), d_fp
);
173 fwrite(d_ppr
.d_buffer
, 1, d_ppr
.d_pheader
.caplen
, d_fp
);
176 PcapPacketWriter::~PcapPacketWriter()