change sniffer behaviour when stopping capture. workaround if pcap_findalldev fails
parent
46da36d3a0
commit
248a73a73c
|
@ -64,28 +64,46 @@ void __stdcall sniffer_receive(DWORD_PTR Param, DWORD_PTR ThParam, HANDLE hPacke
|
||||||
|
|
||||||
char *get_interface_name_by_index(unsigned int fidx)
|
char *get_interface_name_by_index(unsigned int fidx)
|
||||||
{
|
{
|
||||||
unsigned idx = 1;
|
unsigned int i, idx;
|
||||||
char errbuf[PCAP_ERRBUF_SIZE+4];
|
char errbuf[PCAP_ERRBUF_SIZE+4];
|
||||||
static char device_name[64]; // PKS, probably safe, due to snifferm mutex
|
static char device_name[64]; // PKS, probably safe, due to snifferm mutex
|
||||||
|
int if_error;
|
||||||
|
struct ifaces_list *ifaces;
|
||||||
pcap_if_t *interfaces, *int_iter;
|
pcap_if_t *interfaces, *int_iter;
|
||||||
|
|
||||||
|
interfaces = int_iter = NULL;
|
||||||
|
ifaces = NULL;
|
||||||
|
idx = 1;
|
||||||
|
|
||||||
memset(device_name, 0, sizeof(device_name));
|
memset(device_name, 0, sizeof(device_name));
|
||||||
|
|
||||||
interfaces = int_iter = NULL;
|
|
||||||
|
|
||||||
if(pcap_findalldevs(&interfaces, errbuf) == -1) {
|
if(pcap_findalldevs(&interfaces, errbuf) == -1) {
|
||||||
dprintf("Hmm, out of memory? (errno = %d, but probably not useful)", errno);
|
dprintf("pcap_findalldevs failed, trying netlink_get_interfaces, errbuf was : %s", errbuf);
|
||||||
return NULL;
|
if_error = netlink_get_interfaces(&ifaces);
|
||||||
|
if(if_error) {
|
||||||
|
dprintf("Error when retrieving interfaces info");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (i = 0; i < ifaces->entries; i++) {
|
||||||
|
if(fidx == ifaces->ifaces[i].index) {
|
||||||
|
strncpy(device_name, ifaces->ifaces[i].name, sizeof(device_name)-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else { //pcap_findalldevs suceeded
|
||||||
for(int_iter = interfaces; int_iter; int_iter = int_iter->next) {
|
for(int_iter = interfaces; int_iter; int_iter = int_iter->next) {
|
||||||
if(fidx == idx++) {
|
if(fidx == idx++) {
|
||||||
strncpy(device_name, int_iter->name, sizeof(device_name)-1);
|
strncpy(device_name, int_iter->name, sizeof(device_name)-1);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_freealldevs(interfaces);
|
if(interfaces)
|
||||||
|
pcap_freealldevs(interfaces);
|
||||||
|
if (ifaces)
|
||||||
|
free(ifaces);
|
||||||
|
|
||||||
return device_name[0] ? device_name : NULL;
|
return device_name[0] ? device_name : NULL;
|
||||||
|
|
||||||
|
@ -137,8 +155,8 @@ struct sockaddr_in6 *peername6;
|
||||||
/* mutex */
|
/* mutex */
|
||||||
LOCK *snifferm;
|
LOCK *snifferm;
|
||||||
|
|
||||||
#define SNIFFER_MAX_INTERFACES 128
|
#define SNIFFER_MAX_INTERFACES 128 // let's hope interface index don't go above this value
|
||||||
#define SNIFFER_MAX_QUEUE 210000 // ~300Mb @ 1514 bytes
|
#define SNIFFER_MAX_QUEUE 200000 // ~290Mb @ 1514 bytes
|
||||||
|
|
||||||
CaptureJob open_captures[SNIFFER_MAX_INTERFACES];
|
CaptureJob open_captures[SNIFFER_MAX_INTERFACES];
|
||||||
|
|
||||||
|
@ -151,6 +169,7 @@ DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet);
|
||||||
HANDLE pktsdk_interface_by_index(unsigned int fidx);
|
HANDLE pktsdk_interface_by_index(unsigned int fidx);
|
||||||
DWORD pktsdk_initialize(void);
|
DWORD pktsdk_initialize(void);
|
||||||
|
|
||||||
|
|
||||||
DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
|
DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
|
||||||
{
|
{
|
||||||
Packet *response = packet_create_response(packet);
|
Packet *response = packet_create_response(packet);
|
||||||
|
@ -166,11 +185,11 @@ DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
|
||||||
6: Accessible?
|
6: Accessible?
|
||||||
7: DHCP?
|
7: DHCP?
|
||||||
*/
|
*/
|
||||||
unsigned int idx = 1;
|
|
||||||
DWORD result = ERROR_SUCCESS;
|
DWORD result = ERROR_SUCCESS;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HANDLE hCfg;
|
HANDLE hCfg;
|
||||||
|
unsigned int idx = 1;
|
||||||
|
|
||||||
check_pssdk();
|
check_pssdk();
|
||||||
|
|
||||||
|
@ -233,6 +252,10 @@ DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
|
||||||
#else
|
#else
|
||||||
char errbuf[PCAP_ERRBUF_SIZE+4];
|
char errbuf[PCAP_ERRBUF_SIZE+4];
|
||||||
int aidx = htonl(1); // :~(
|
int aidx = htonl(1); // :~(
|
||||||
|
struct ifaces_list *ifaces;
|
||||||
|
uint32_t i;
|
||||||
|
int aidx_bigendian;
|
||||||
|
int mtu_bigendian;
|
||||||
|
|
||||||
int yes_int = htonl(1);
|
int yes_int = htonl(1);
|
||||||
int no_int = 0;
|
int no_int = 0;
|
||||||
|
@ -241,57 +264,106 @@ DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
|
||||||
pcap_if_t *interfaces, *int_iter;
|
pcap_if_t *interfaces, *int_iter;
|
||||||
|
|
||||||
interfaces = int_iter = NULL;
|
interfaces = int_iter = NULL;
|
||||||
|
ifaces = NULL;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
result = pcap_findalldevs(&interfaces, errbuf);
|
result = pcap_findalldevs(&interfaces, errbuf);
|
||||||
if(result) {
|
|
||||||
dprintf("pcap_findalldevs() failed, errbuf is %s", errbuf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int_iter = interfaces; int_iter; int_iter = int_iter->next)
|
if(!result) { // pcap_findalldevs suceeded
|
||||||
{
|
for(int_iter = interfaces; int_iter; int_iter = int_iter->next)
|
||||||
entries[0].header.type = TLV_TYPE_UINT;
|
{
|
||||||
entries[0].header.length = sizeof(unsigned int);
|
entries[0].header.type = TLV_TYPE_UINT;
|
||||||
entries[0].buffer = (PUCHAR)&aidx;
|
entries[0].header.length = sizeof(unsigned int);
|
||||||
|
entries[0].buffer = (PUCHAR)&aidx;
|
||||||
|
|
||||||
entries[1].header.type = TLV_TYPE_STRING;
|
entries[1].header.type = TLV_TYPE_STRING;
|
||||||
entries[1].header.length = strlen(int_iter->name)+1;
|
entries[1].header.length = strlen(int_iter->name)+1;
|
||||||
entries[1].buffer = int_iter->name;
|
entries[1].buffer = (PUCHAR)int_iter->name;
|
||||||
|
|
||||||
entries[2].header.type = TLV_TYPE_STRING;
|
entries[2].header.type = TLV_TYPE_STRING;
|
||||||
entries[2].header.length = strlen(int_iter->name)+1;
|
entries[2].header.length = strlen(int_iter->name)+1;
|
||||||
entries[2].buffer = int_iter->name;
|
entries[2].buffer = (PUCHAR)int_iter->name;
|
||||||
|
|
||||||
entries[3].header.type = TLV_TYPE_UINT;
|
entries[3].header.type = TLV_TYPE_UINT;
|
||||||
entries[3].header.length = sizeof(unsigned int);
|
entries[3].header.length = sizeof(unsigned int);
|
||||||
entries[3].buffer = (PUCHAR)&no_int; // xxx, get encapsulation type?
|
entries[3].buffer = (PUCHAR)&no_int; // xxx, get encapsulation type?
|
||||||
|
|
||||||
entries[4].header.type = TLV_TYPE_UINT;
|
entries[4].header.type = TLV_TYPE_UINT;
|
||||||
entries[4].header.length = sizeof(unsigned int);
|
entries[4].header.length = sizeof(unsigned int);
|
||||||
entries[4].buffer = (PUCHAR)&mtu_int; // PKS :-(
|
entries[4].buffer = (PUCHAR)&mtu_int; // PKS :-(
|
||||||
|
|
||||||
entries[5].header.type = TLV_TYPE_BOOL;
|
entries[5].header.type = TLV_TYPE_BOOL;
|
||||||
entries[5].header.length = sizeof(BOOL);
|
entries[5].header.length = sizeof(BOOL);
|
||||||
entries[5].buffer = (PUCHAR)&no_int; // check encaps options / crap
|
entries[5].buffer = (PUCHAR)&no_int; // check encaps options / crap
|
||||||
|
|
||||||
entries[6].header.type = TLV_TYPE_BOOL;
|
entries[6].header.type = TLV_TYPE_BOOL;
|
||||||
entries[6].header.length = sizeof(BOOL);
|
entries[6].header.length = sizeof(BOOL);
|
||||||
entries[6].buffer = (PUCHAR)&yes_int; // sure, why not.
|
entries[6].buffer = (PUCHAR)&yes_int; // sure, why not.
|
||||||
|
|
||||||
entries[7].header.type = TLV_TYPE_BOOL;
|
entries[7].header.type = TLV_TYPE_BOOL;
|
||||||
entries[7].header.length = sizeof(BOOL);
|
entries[7].header.length = sizeof(BOOL);
|
||||||
entries[7].buffer = (PUCHAR)&no_int; // hrm. not worth it.
|
entries[7].buffer = (PUCHAR)&no_int; // hrm. not worth it.
|
||||||
|
|
||||||
packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8);
|
packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8);
|
||||||
aidx = htonl(ntohl(aidx)+1); // :~(
|
aidx = htonl(ntohl(aidx)+1); // :~(
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
dprintf("pcap_findalldevs() failed, trying netlink_get_interfaces now, errbuf was %s", errbuf);
|
||||||
|
result = netlink_get_interfaces(&ifaces);
|
||||||
|
if(result) {
|
||||||
|
dprintf("Error when retrieving interfaces info");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// netlink_get_interfaces suceeded
|
||||||
|
for (i = 0; i < ifaces->entries; i++)
|
||||||
|
{
|
||||||
|
aidx_bigendian = htonl(ifaces->ifaces[i].index);
|
||||||
|
entries[0].header.type = TLV_TYPE_UINT;
|
||||||
|
entries[0].header.length = sizeof(uint32_t);
|
||||||
|
entries[0].buffer = (PUCHAR)&aidx_bigendian;
|
||||||
|
|
||||||
|
entries[1].header.type = TLV_TYPE_STRING;
|
||||||
|
entries[1].header.length = strlen(ifaces->ifaces[i].name)+1;
|
||||||
|
entries[1].buffer = (PUCHAR)ifaces->ifaces[i].name;
|
||||||
|
|
||||||
|
entries[2].header.type = TLV_TYPE_STRING;
|
||||||
|
entries[2].header.length = strlen(ifaces->ifaces[i].name)+1;
|
||||||
|
entries[2].buffer = (PUCHAR)ifaces->ifaces[i].name;
|
||||||
|
|
||||||
|
entries[3].header.type = TLV_TYPE_UINT;
|
||||||
|
entries[3].header.length = sizeof(unsigned int);
|
||||||
|
entries[3].buffer = (PUCHAR)&no_int; // xxx, get encapsulation type?
|
||||||
|
|
||||||
|
mtu_bigendian = htonl(ifaces->ifaces[i].mtu);
|
||||||
|
entries[4].header.type = TLV_TYPE_UINT;
|
||||||
|
entries[4].header.length = sizeof(uint32_t);
|
||||||
|
entries[4].buffer = (PUCHAR)&mtu_bigendian;
|
||||||
|
|
||||||
|
entries[5].header.type = TLV_TYPE_BOOL;
|
||||||
|
entries[5].header.length = sizeof(BOOL);
|
||||||
|
entries[5].buffer = (PUCHAR)&no_int; // check encaps options / crap
|
||||||
|
|
||||||
|
entries[6].header.type = TLV_TYPE_BOOL;
|
||||||
|
entries[6].header.length = sizeof(BOOL);
|
||||||
|
entries[6].buffer = (PUCHAR)&yes_int; // sure, why not.
|
||||||
|
|
||||||
|
entries[7].header.type = TLV_TYPE_BOOL;
|
||||||
|
entries[7].header.length = sizeof(BOOL);
|
||||||
|
entries[7].buffer = (PUCHAR)&no_int; // hrm. not worth it.
|
||||||
|
|
||||||
|
packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
|
if(ifaces)
|
||||||
|
free(ifaces);
|
||||||
if(interfaces)
|
if(interfaces)
|
||||||
pcap_freealldevs(interfaces);
|
pcap_freealldevs(interfaces);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
packet_transmit_response(result, remote, response);
|
packet_transmit_response(result, remote, response);
|
||||||
|
@ -419,7 +491,7 @@ void packet_handler(u_char *user, const struct pcap_pkthdr *h, const u_char *byt
|
||||||
|
|
||||||
if(j->idx_pkts >= j->max_pkts) j->idx_pkts = 0;
|
if(j->idx_pkts >= j->max_pkts) j->idx_pkts = 0;
|
||||||
|
|
||||||
if(j->pkts[j->idx_pkts]) free(j->pkts[j->idx_pkts]);
|
if(j->pkts[j->idx_pkts]) free((void*)(j->pkts[j->idx_pkts]));
|
||||||
|
|
||||||
j->pkts[j->idx_pkts++] = pkt;
|
j->pkts[j->idx_pkts++] = pkt;
|
||||||
|
|
||||||
|
@ -483,7 +555,7 @@ DWORD request_sniffer_capture_start(Remote *remote, Packet *packet) {
|
||||||
|
|
||||||
ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID);
|
ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID);
|
||||||
maxp = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_PACKET_COUNT);
|
maxp = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_PACKET_COUNT);
|
||||||
maxp = min(maxp, 200000);
|
maxp = min(maxp, SNIFFER_MAX_QUEUE);
|
||||||
maxp = max(maxp, 1);
|
maxp = max(maxp, 1);
|
||||||
|
|
||||||
result = ERROR_SUCCESS;
|
result = ERROR_SUCCESS;
|
||||||
|
@ -526,7 +598,7 @@ DWORD request_sniffer_capture_start(Remote *remote, Packet *packet) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
name = get_interface_name_by_index(ifid);
|
name = get_interface_name_by_index(ifh);
|
||||||
|
|
||||||
if(! name) {
|
if(! name) {
|
||||||
result = ERROR_INVALID_PARAMETER;
|
result = ERROR_INVALID_PARAMETER;
|
||||||
|
@ -626,7 +698,7 @@ DWORD request_sniffer_capture_start(Remote *remote, Packet *packet) {
|
||||||
|
|
||||||
DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet) {
|
DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet) {
|
||||||
Packet *response = packet_create_response(packet);
|
Packet *response = packet_create_response(packet);
|
||||||
unsigned int ifid,i;
|
unsigned int ifid;
|
||||||
CaptureJob *j;
|
CaptureJob *j;
|
||||||
DWORD result;
|
DWORD result;
|
||||||
|
|
||||||
|
@ -670,13 +742,8 @@ DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet) {
|
||||||
thread_join(j->thread); // should take less than 1 second :p
|
thread_join(j->thread); // should take less than 1 second :p
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(i=0; i<j->max_pkts; i++) {
|
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
|
||||||
if(!j->pkts[i]) break;
|
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int) j->cur_bytes);
|
||||||
PktDestroy(j->pkts[i]);
|
|
||||||
j->pkts[i] = NULL;
|
|
||||||
}
|
|
||||||
free(j->pkts);
|
|
||||||
memset(j, 0, sizeof(CaptureJob));
|
|
||||||
|
|
||||||
lock_release(snifferm);
|
lock_release(snifferm);
|
||||||
|
|
||||||
|
@ -687,7 +754,62 @@ DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet) {
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD request_sniffer_capture_release(Remote *remote, Packet *packet) {
|
||||||
|
Packet *response = packet_create_response(packet);
|
||||||
|
unsigned int ifid,i;
|
||||||
|
CaptureJob *j;
|
||||||
|
DWORD result;
|
||||||
|
|
||||||
|
check_pssdk();
|
||||||
|
dprintf("sniffer>> release_capture()");
|
||||||
|
|
||||||
|
ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID);
|
||||||
|
dprintf("sniffer>> release_capture(0x%.8x)", ifid);
|
||||||
|
|
||||||
|
result = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
do {
|
||||||
|
// the interface is invalid
|
||||||
|
if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) {
|
||||||
|
result = ERROR_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
j = &open_captures[ifid];
|
||||||
|
|
||||||
|
// the interface is not being captured
|
||||||
|
#ifdef _WIN32
|
||||||
|
if(! j->adp || j->active == 1)
|
||||||
|
#else
|
||||||
|
if(! j->pcap || j->active == 1)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
result = ERROR_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock_acquire(snifferm);
|
||||||
|
|
||||||
|
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
|
||||||
|
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int) j->cur_bytes);
|
||||||
|
dprintf("sniffer>> release_capture() interface %d released %d packets/%d bytes", j->intf, j->cur_pkts, j->cur_bytes);
|
||||||
|
|
||||||
|
for(i=0; i<j->max_pkts; i++) {
|
||||||
|
if(!j->pkts[i]) break;
|
||||||
|
PktDestroy(j->pkts[i]);
|
||||||
|
j->pkts[i] = NULL;
|
||||||
|
}
|
||||||
|
free(j->pkts);
|
||||||
|
memset(j, 0, sizeof(CaptureJob));
|
||||||
|
|
||||||
|
lock_release(snifferm);
|
||||||
|
|
||||||
|
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
packet_transmit_response(result, remote, response);
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD request_sniffer_capture_stats(Remote *remote, Packet *packet) {
|
DWORD request_sniffer_capture_stats(Remote *remote, Packet *packet) {
|
||||||
Packet *response = packet_create_response(packet);
|
Packet *response = packet_create_response(packet);
|
||||||
|
@ -722,9 +844,10 @@ DWORD request_sniffer_capture_stats(Remote *remote, Packet *packet) {
|
||||||
result = ERROR_INVALID_PARAMETER;
|
result = ERROR_INVALID_PARAMETER;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
lock_acquire(snifferm);
|
||||||
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
|
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
|
||||||
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int) j->cur_bytes);
|
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int) j->cur_bytes);
|
||||||
|
lock_release(snifferm);
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
packet_transmit_response(result, remote, response);
|
packet_transmit_response(result, remote, response);
|
||||||
|
@ -733,7 +856,7 @@ DWORD request_sniffer_capture_stats(Remote *remote, Packet *packet) {
|
||||||
|
|
||||||
DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet) {
|
DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet) {
|
||||||
Packet *response = packet_create_response(packet);
|
Packet *response = packet_create_response(packet);
|
||||||
unsigned int ifid;
|
unsigned int ifid, i;
|
||||||
unsigned int bcnt;
|
unsigned int bcnt;
|
||||||
CaptureJob *j;
|
CaptureJob *j;
|
||||||
DWORD result;
|
DWORD result;
|
||||||
|
@ -753,13 +876,13 @@ DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet) {
|
||||||
// the interface is invalid
|
// the interface is invalid
|
||||||
if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) {
|
if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) {
|
||||||
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
|
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
|
||||||
break;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
j = &open_captures[ifid];
|
j = &open_captures[ifid];
|
||||||
if(! j->dbuf) {
|
if(! j->dbuf) {
|
||||||
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
|
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
|
||||||
break;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(j->didx + bcnt > j->dlen) {
|
if(j->didx + bcnt > j->dlen) {
|
||||||
|
@ -777,8 +900,22 @@ DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet) {
|
||||||
j->dbuf = NULL;
|
j->dbuf = NULL;
|
||||||
j->didx = 0;
|
j->didx = 0;
|
||||||
j->dlen = 0;
|
j->dlen = 0;
|
||||||
|
// if dump occurs when interface is not active, i.e sniff has ended, release info
|
||||||
|
if (j->active == 0) {
|
||||||
|
dprintf("sniffer>> capture_dump_read, release CaptureJob");
|
||||||
|
lock_acquire(snifferm);
|
||||||
|
for(i=0; i<j->max_pkts; i++) {
|
||||||
|
if(!j->pkts[i]) break;
|
||||||
|
PktDestroy(j->pkts[i]);
|
||||||
|
j->pkts[i] = NULL;
|
||||||
|
}
|
||||||
|
free(j->pkts);
|
||||||
|
memset(j, 0, sizeof(CaptureJob));
|
||||||
|
lock_release(snifferm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
packet_transmit_response(result, remote, response);
|
packet_transmit_response(result, remote, response);
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -791,7 +928,7 @@ DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet) {
|
||||||
unsigned int *tmp;
|
unsigned int *tmp;
|
||||||
|
|
||||||
CaptureJob *j;
|
CaptureJob *j;
|
||||||
DWORD result,pcnt,bcnt,rcnt,i;
|
DWORD result,pcnt,rcnt,i;
|
||||||
DWORD thi, tlo;
|
DWORD thi, tlo;
|
||||||
|
|
||||||
check_pssdk();
|
check_pssdk();
|
||||||
|
@ -834,7 +971,6 @@ DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet) {
|
||||||
|
|
||||||
// Add basic stats
|
// Add basic stats
|
||||||
pcnt = 0;
|
pcnt = 0;
|
||||||
bcnt = 0;
|
|
||||||
rcnt = 0;
|
rcnt = 0;
|
||||||
|
|
||||||
mbuf = (1024*1024);
|
mbuf = (1024*1024);
|
||||||
|
@ -916,6 +1052,11 @@ Command customCommands[] =
|
||||||
{ request_sniffer_capture_stats, { 0 }, 0 },
|
{ request_sniffer_capture_stats, { 0 }, 0 },
|
||||||
{ EMPTY_DISPATCH_HANDLER },
|
{ EMPTY_DISPATCH_HANDLER },
|
||||||
},
|
},
|
||||||
|
// Release captured packets instead of downloading them
|
||||||
|
{ "sniffer_capture_release",
|
||||||
|
{ request_sniffer_capture_release, { 0 }, 0 },
|
||||||
|
{ EMPTY_DISPATCH_HANDLER },
|
||||||
|
},
|
||||||
// Sniffing packet dump
|
// Sniffing packet dump
|
||||||
{ "sniffer_capture_dump",
|
{ "sniffer_capture_dump",
|
||||||
{ request_sniffer_capture_dump, { 0 }, 0 },
|
{ request_sniffer_capture_dump, { 0 }, 0 },
|
||||||
|
|
|
@ -59,7 +59,11 @@ class Sniffer < Extension
|
||||||
def capture_stop(intf)
|
def capture_stop(intf)
|
||||||
request = Packet.create_request('sniffer_capture_stop')
|
request = Packet.create_request('sniffer_capture_stop')
|
||||||
request.add_tlv(TLV_TYPE_SNIFFER_INTERFACE_ID, intf.to_i)
|
request.add_tlv(TLV_TYPE_SNIFFER_INTERFACE_ID, intf.to_i)
|
||||||
response = client.send_request(request)
|
response = client.send_request(request)
|
||||||
|
{
|
||||||
|
:packets => response.get_tlv_value(TLV_TYPE_SNIFFER_PACKET_COUNT),
|
||||||
|
:bytes => response.get_tlv_value(TLV_TYPE_SNIFFER_BYTE_COUNT),
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
# Retrieve stats about a current capture
|
# Retrieve stats about a current capture
|
||||||
|
@ -72,6 +76,17 @@ class Sniffer < Extension
|
||||||
:bytes => response.get_tlv_value(TLV_TYPE_SNIFFER_BYTE_COUNT),
|
:bytes => response.get_tlv_value(TLV_TYPE_SNIFFER_BYTE_COUNT),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Release packets from a current capture
|
||||||
|
def capture_release(intf)
|
||||||
|
request = Packet.create_request('sniffer_capture_release')
|
||||||
|
request.add_tlv(TLV_TYPE_SNIFFER_INTERFACE_ID, intf.to_i)
|
||||||
|
response = client.send_request(request)
|
||||||
|
{
|
||||||
|
:packets => response.get_tlv_value(TLV_TYPE_SNIFFER_PACKET_COUNT),
|
||||||
|
:bytes => response.get_tlv_value(TLV_TYPE_SNIFFER_BYTE_COUNT),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
# Buffer the current capture to a readable buffer
|
# Buffer the current capture to a readable buffer
|
||||||
def capture_dump(intf)
|
def capture_dump(intf)
|
||||||
|
|
|
@ -33,6 +33,7 @@ class Console::CommandDispatcher::Sniffer
|
||||||
"sniffer_stop" => "Stop packet capture on a specific interface",
|
"sniffer_stop" => "Stop packet capture on a specific interface",
|
||||||
"sniffer_stats" => "View statistics of an active capture",
|
"sniffer_stats" => "View statistics of an active capture",
|
||||||
"sniffer_dump" => "Retrieve captured packet data to PCAP file",
|
"sniffer_dump" => "Retrieve captured packet data to PCAP file",
|
||||||
|
"sniffer_release" => "Free captured packets on a specific interface instead of downloading them",
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -70,19 +71,21 @@ class Console::CommandDispatcher::Sniffer
|
||||||
end
|
end
|
||||||
|
|
||||||
def cmd_sniffer_stop(*args)
|
def cmd_sniffer_stop(*args)
|
||||||
intf = args[0].to_i
|
intf = args[0].to_i
|
||||||
if (intf == 0)
|
if (intf == 0)
|
||||||
print_error("Usage: sniffer_stop [interface-id]")
|
print_error("Usage: sniffer_stop [interface-id]")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
client.sniffer.capture_stop(intf)
|
res = client.sniffer.capture_stop(intf)
|
||||||
print_status("Capture stopped on interface #{intf}")
|
print_status("Capture stopped on interface #{intf}")
|
||||||
|
print_status("There are #{res[:packets]} packets (#{res[:bytes]} bytes) remaining")
|
||||||
|
print_status("Download or release them using 'sniffer_dump' or 'sniffer_release'")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
def cmd_sniffer_stats(*args)
|
def cmd_sniffer_stats(*args)
|
||||||
intf = args[0].to_i
|
intf = args[0].to_i
|
||||||
if (intf == 0)
|
if (intf == 0)
|
||||||
print_error("Usage: sniffer_stats [interface-id]")
|
print_error("Usage: sniffer_stats [interface-id]")
|
||||||
return
|
return
|
||||||
|
@ -96,9 +99,22 @@ class Console::CommandDispatcher::Sniffer
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def cmd_sniffer_release(*args)
|
||||||
|
intf = args[0].to_i
|
||||||
|
if (intf == 0)
|
||||||
|
print_error("Usage: sniffer_stats [interface-id]")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
res = client.sniffer.capture_release(intf)
|
||||||
|
print_status("Flushed #{res[:packets]} packets (#{res[:bytes]} bytes) from interface #{intf}")
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
def cmd_sniffer_dump(*args)
|
def cmd_sniffer_dump(*args)
|
||||||
intf = args[0].to_i
|
intf = args[0].to_i
|
||||||
if (intf == 0 or not args[1])
|
if (intf == 0 or not args[1])
|
||||||
print_error("Usage: sniffer_dump [interface-id] [pcap-file]")
|
print_error("Usage: sniffer_dump [interface-id] [pcap-file]")
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue