Compare Revisions

The credentials to download the source code are:
 Username: svnusers
 Password: svnusers

Ignore whitespace Rev 3318 → Rev 3319

/branches/STF525/ccsrc/Protocols/Pcap/pcap_layer.cc
18,11 → 18,25
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
HANDLE pcap_getevent(pcap_t *p);
}
typedef struct {
bpf_int32 tv_sec; /* seconds */
bpf_int32 tv_usec; /* microseconds */
}pcap_o_timeval;
 
typedef struct pcap_o_pkthdr {
pcap_o_timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
}pcap_o_pkthdr;
#else
typedef struct pcap_pkthdr pcap_o_pkthdr;
typedef struct timeval pcap_o_timeval;
#endif
 
#include "loggers.hh"
 
pcap_layer::pcap_layer(const std::string& p_type, const std::string& param) : layer(p_type), PORT(p_type.c_str()), _params(), _device(NULL), _pcap_h(-1), _thread(NULL), _running(FALSE), _resume(), _sent_file(NULL), _time_key("pcap_layer::Handle_Fd_Event_Readable") {
bool online = false;
loggers::get_instance().log(">>> pcap_layer::pcap_layer: %s, %s", to_string().c_str(), param.c_str());
_fd[0] = -1; _fd[1] = -1;
// Setup parameters
35,25 → 49,27
// Fetch the network address and network mask
bpf_u_int32 mask; // subnet mask
bpf_u_int32 net; // ip address
if (pcap_lookupnet(_params[params::nic].c_str(), &net, &mask, error_buffer) != 0) {
loggers::get_instance().error("pcap_layer::pcap_layer: pcap_layer::pcap_layer: Failed to fetch newtork address for device %s", _params[params::nic].c_str());
std::string nic;
online = true;
#ifdef __CYGWIN__
nic = std::string("\\Device\\NPF_{") + _params[params::nic] + "}";
#else
nic = _params[params::nic];
#endif
if (pcap_lookupnet(nic.c_str(), &net, &mask, error_buffer) != 0) {
loggers::get_instance().error("pcap_layer::pcap_layer: pcap_layer::pcap_layer: Failed to fetch newtork address for device %s", nic.c_str());
}
loggers::get_instance().log("pcap_layer::pcap_layer: Device %s Network address: %d", _params[params::nic].c_str(), net);
loggers::get_instance().log("pcap_layer::pcap_layer: Device %s Network address: %d", nic.c_str(), net);
// Open the device
_device = pcap_open_live(_params[params::nic].c_str(), 65536, 1, 1000, error_buffer); // TODO Replace hard coded values by pcap_layer::<constants>
_device = pcap_open_live(nic.c_str(), 65536, 1, 1000, error_buffer); // TODO Replace hard coded values by pcap_layer::<constants>
if (_device == NULL) {
loggers::get_instance().error("pcap_layer::pcap_layer: Failed to open device %s", _params[params::nic].c_str());
loggers::get_instance().error("pcap_layer::pcap_layer: Failed to open device %s", nic.c_str());
} // else, continue
// Set non-blocking flag for the polling procedure
if (pcap_setnonblock(_device, 1, error_buffer) != 0) {
loggers::get_instance().error("pcap_layer::pcap_layer: Failed to set blocking mode: %s", error_buffer);
}
#if defined (__CYGWIN__)
if (pipe2(_fd, O_NONBLOCK) == -1) {
loggers::get_instance().error("pcap_layer::pcap_layer: Failed to create a pipe: %s", ::strerror(errno));
}
_pcap_h = _fd[0];
#else
#if ! defined (__CYGWIN__)
// Retrieve the device file handler
_pcap_h = pcap_get_selectable_fd(_device);
if (_pcap_h == -1) {
91,6 → 107,7
loggers::get_instance().error("pcap_layer::pcap_layer: Failed to open PCAP file %s", error_buffer);
}
}
 
// Setup filter
std::string filter = "";
it = _params.find(params::mac_src);
126,14 → 143,18
}
pcap_freecode(&f);
}
 
// Pass the device file handler to the polling procedure
if (_pcap_h != -1) { // Live capture
Handler_Add_Fd_Read(_pcap_h);
} else { // Offline capture
} else { // Offline capture or cygwin
// Create a pipe
if (pipe2(_fd, O_NONBLOCK) == -1) {
loggers::get_instance().error("pcap_layer::pcap_layer: Failed to create a pipe: %s", ::strerror(errno));
}
if(online){
_pcap_h = _fd[0];
}
// Pass the pipe handler to the polling procedure
loggers::get_instance().log("pcap_layer::pcap_layer: Call handler with descriptor %d", _fd[0]);
Handler_Add_Fd_Read(_fd[0]);
205,14 → 226,17
HANDLE h = pcap_getevent(_device);
_running = TRUE;
while (_running) { // Loop while _running flag is up
DWORD rc = WaitForSingleObject(h, 100);
DWORD rc = WaitForSingleObject(h, 1000);
if(rc == 0){
// event raised
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
if (_resume.try_lock() == TRUE) { // Previous packet was consumed, lock for the next one
write(_fd[1], "\n", 1); // Any character will do the job
} else { // not ready yet
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}else if(rc == 0x00000102L) { // timeout
}else {
}
}
return NULL;
264,9 → 288,9
void pcap_layer::Handle_Fd_Event_Readable(int fd) {
//loggers::get_instance().log(">>> pcap_layer::Handle_Fd_Event_Readable: %d", fd);
struct pcap_pkthdr *pkt_header;
pcap_o_pkthdr *pkt_header;
const u_char *pkt_data;
int result = pcap_next_ex(_device, &pkt_header, &pkt_data);
int result = pcap_next_ex(_device, (struct pcap_pkthdr**)&pkt_header, &pkt_data);
if (result == 1) { // Succeed
if (pkt_header->caplen > 14) { // Reject too small packet
//loggers::get_instance().log("pcap_layer::Handle_Fd_Event_Readable: %.6d - %d", pkt_header->ts.tv_usec, pkt_header->len);