]>
Commit | Line | Data |
---|---|---|
ab06937b | 1 | #include "dnspcap.hh" |
11212b81 | 2 | #include <boost/format.hpp> |
ab06937b | 3 | |
11212b81 | 4 | using namespace boost; |
ab06937b BH |
5 | PcapPacketReader::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 | 23 | PcapPacketReader::~PcapPacketReader() |
ab06937b BH |
24 | { |
25 | fclose(d_fp); | |
26 | } | |
27 | ||
28 | ||
29 | void 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 | ||
42 | bool PcapPacketReader::getUDPPacket() | |
43 | try | |
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 | } | |
77 | catch(EofException) { | |
78 | return false; | |
79 | } | |
80 | ||
81 | ||
82 | PcapPacketWriter::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 | ||
92 | void 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 | 98 | PcapPacketWriter::~PcapPacketWriter() |
ab06937b BH |
99 | { |
100 | fclose(d_fp); | |
101 | } |