root/trunk/pdns/pdns/dnspcap.cc @ 429

Revision 429, 2.7 KB (checked in by ahu, 8 years ago)

last bsd-isms

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