3
#include <boost/format.hpp>
7
PcapPacketReader::PcapPacketReader(const string& fname) : d_fname(fname)
9
d_fp=fopen(fname.c_str(),"r");
11
unixDie("Unable to open file");
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 (??)
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());
21
if( d_pfh.linktype!=1)
22
throw runtime_error((format("Unsupported link type %d") % d_pfh.linktype).str());
24
d_runts = d_oversized = d_correctpackets = d_nonetheripudp = 0;
27
PcapPacketReader::~PcapPacketReader()
33
void PcapPacketReader::checkedFreadSize(void* ptr, size_t size)
35
int ret=fread(ptr, 1, size, d_fp);
37
unixDie( (format("Error reading %d bytes from %s") % size % d_fname).str());
42
if((size_t)ret != size)
43
throw EofException((format("Incomplete read from '%s', got only %d bytes") % d_fname % ret).str());
46
bool PcapPacketReader::getUDPPacket()
50
checkedFread(&d_pheader);
54
if(d_pheader.caplen > sizeof(d_buffer)) {
56
throw runtime_error((format("Can't handle a %d byte packet, have space for %d") % d_pheader.caplen % sizeof(d_buffer)).str());
59
checkedFreadSize(d_buffer, d_pheader.caplen);
61
if(d_pheader.caplen!=d_pheader.len) {
66
d_ether=reinterpret_cast<struct ether_header*>(d_buffer);
67
d_ip=reinterpret_cast<struct ip*>(d_buffer + sizeof(struct ether_header));
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);
86
PcapPacketWriter::PcapPacketWriter(const string& fname, PcapPacketReader& ppr) : d_fname(fname), d_ppr(ppr)
88
d_fp=fopen(fname.c_str(),"w");
90
unixDie("Unable to open file");
93
int flags=fcntl(fileno(d_fp),F_GETFL,0);
94
fcntl(fileno(d_fp), F_SETFL,flags&(~O_NONBLOCK)); // bsd needs this in stdin (??)
96
fwrite(&ppr.d_pfh, 1, sizeof(ppr.d_pfh), d_fp);
100
void PcapPacketWriter::write()
102
fwrite(&d_ppr.d_pheader, 1, sizeof(d_ppr.d_pheader), d_fp);
103
fwrite(d_ppr.d_buffer, 1, d_ppr.d_pheader.caplen, d_fp);
106
PcapPacketWriter::~PcapPacketWriter()