DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	unsigned int ifid;
	CaptureJob *j;
	DWORD result;

	check_pssdk();
	dprintf("sniffer>> stop_capture()");

	ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
	dprintf("sniffer>> stop_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)
#else
		if (!j->pcap)
#endif
		{
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		lock_acquire(snifferm);

		j->active = 0;
#ifdef _WIN32
		AdpSetMacFilter(j->adp, 0);
		AdpCloseAdapter(j->adp);
		AdpDestroy(j->adp);
#else
		thread_sigterm(j->thread);
		thread_join(j->thread);		// should take less than 1 second :p
#endif

		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);

		lock_release(snifferm);

		dprintf("sniffer>> stop_capture() interface %d processed %d packets/%d bytes", j->intf, j->cur_pkts, j->cur_bytes);
	} while (0);

	packet_transmit_response(result, remote, response);
	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;
}
Exemple #3
0
DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet) {
	Packet *response = packet_create_response(packet);
	unsigned int ifid,i;
	CaptureJob *j;
	DWORD result;

	check_pssdk();
	dprintf("sniffer>> stop_capture()");

	ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID);
	dprintf("sniffer>> stop_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
		if(! j->adp) {
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		
		EnterCriticalSection(&sniffercs);

		j->active = 0;
		AdpSetMacFilter(j->adp, 0);
		AdpCloseAdapter(j->adp);
		AdpDestroy(j->adp);
		
		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));
		
		LeaveCriticalSection(&sniffercs);

		dprintf("sniffer>> stop_capture() interface %d processed %d packets/%d bytes", j->intf, j->cur_pkts, j->cur_bytes); 
	} while(0);
	
	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}
Exemple #4
0
static DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet) {
	Packet *response = packet_create_response(packet);
	unsigned int ifid;
	unsigned int bcnt;
	CaptureJob *j;
	DWORD result;

	check_pssdk();
	dprintf("sniffer>> capture_dump_read()");

	ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID);
	bcnt = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_BYTE_COUNT);
	bcnt = min(bcnt, 32*1024*1024);

	dprintf("sniffer>> capture_dump_read(0x%.8x, %d)", ifid, bcnt);

	result = ERROR_SUCCESS;

	do {
		// the interface is invalid
		if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) {
			packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
			break;
		}
		
		j = &open_captures[ifid];
		if(! j->dbuf) {
			packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
			break;
		}
		
		if(j->didx + bcnt > j->dlen) {
			bcnt = j->dlen - j->didx;
		}

		packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, bcnt);
		packet_add_tlv_raw(response, TLV_TYPE_SNIFFER_PACKET, (unsigned char *)j->dbuf+j->didx, bcnt);
		j->didx += bcnt;
	} while(0);
	
	// Free memory if the read is complete
	if(j->didx >= j->dlen-1) {
		free(j->dbuf);
		j->dbuf = NULL;
		j->didx = 0;
		j->dlen = 0;
	}

	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}
DWORD request_sniffer_capture_stats(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	unsigned int ifid;
	CaptureJob *j;
	DWORD result;

	check_pssdk();
	dprintf("sniffer>> capture_stats()");

	ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
	dprintf("sniffer>> capture_stats(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 was not captured
#ifdef _WIN32
		if(! j->adp)
#else
		if (!j->pcap)
#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);
		lock_release(snifferm);
	} while (0);

	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}
Exemple #6
0
DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	Tlv entries[8];

	/*
		0: Index
		1: Name
		2: Description
		3: Type
		4: MTU
		5: Wireless?
		6: Accessible?
		7: DHCP?
	*/
	unsigned int idx = 1;
	HANDLE hCfg;
	
	check_pssdk();

	hCfg = MgrGetFirstAdapterCfg(hMgr);

	do
	{
		unsigned char *aname = (unsigned char *)AdpCfgGetAdapterNameA(hCfg);
		unsigned char *adesc = (unsigned char *)AdpCfgGetAdapterDescriptionA(hCfg);
		unsigned int ahand = htonl((unsigned int)hCfg); 
		unsigned int atype = htonl(AdpCfgGetAdapterType(hCfg));
		unsigned int amtu  = htonl(AdpCfgGetMaxPacketSize(hCfg));
		unsigned int aidx  = htonl(idx);

		BOOL awireless = AdpCfgIsWireless(hCfg);
		BOOL ausable   = AdpCfgGetAccessibleState(hCfg);
		BOOL adhcp     = AdpCfgGetDhcpState(hCfg);

		memset(entries, 0, sizeof(entries));

		dprintf("sniffer>> interface %d - %s - %s", idx, aname, adesc);

		entries[0].header.type   = TLV_TYPE_UINT;
		entries[0].header.length = sizeof(unsigned int);
		entries[0].buffer        = (PUCHAR)&aidx;

		entries[1].header.type   = TLV_TYPE_STRING;
		entries[1].header.length = strlen(aname)+1;
		entries[1].buffer        = aname;

		entries[2].header.type   = TLV_TYPE_STRING;
		entries[2].header.length = strlen(adesc)+1;
		entries[2].buffer        = adesc;

		entries[3].header.type   = TLV_TYPE_UINT;
		entries[3].header.length = sizeof(unsigned int);
		entries[3].buffer        = (PUCHAR)&atype;

		entries[4].header.type   = TLV_TYPE_UINT;
		entries[4].header.length = sizeof(unsigned int);
		entries[4].buffer        = (PUCHAR)&amtu;

		entries[5].header.type   = TLV_TYPE_BOOL;
		entries[5].header.length = sizeof(BOOL);
		entries[5].buffer        = (PUCHAR)&awireless;

		entries[6].header.type   = TLV_TYPE_BOOL;
		entries[6].header.length = sizeof(BOOL);
		entries[6].buffer        = (PUCHAR)&ausable;

		entries[7].header.type   = TLV_TYPE_BOOL;
		entries[7].header.length = sizeof(BOOL);
		entries[7].buffer        = (PUCHAR)&adhcp;

		packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8);

		idx++;
	}while((hCfg = MgrGetNextAdapterCfg(hMgr,hCfg)) != NULL);

	packet_transmit_response(ERROR_SUCCESS, remote, response);
	return ERROR_SUCCESS;
}
Exemple #7
0
DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet) {
	Packet *response = packet_create_response(packet);
	unsigned int ifid;
	unsigned int rbuf,mbuf;
	unsigned int *tmp;

	CaptureJob *j;
	DWORD result,pcnt,bcnt,rcnt,i;
	DWORD thi, tlo;

	check_pssdk();
	dprintf("sniffer>> capture_dump()");

	ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID);
	dprintf("sniffer>> capture_dump(0x%.8x)", ifid);

	result = ERROR_SUCCESS;

	EnterCriticalSection(&sniffercs);

	do {
		// the interface is invalid
		if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) {
			result = ERROR_INVALID_PARAMETER;
			break;
		}
		
		j = &open_captures[ifid];

		// the interface was not captured
		if(! j->adp) {
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		// Free any existing packet buffer
		if(j->dbuf) {
			free(j->dbuf);
			j->dbuf = NULL;
			j->dlen = 0;
			j->didx = 0;
		}

		// Add basic stats
		pcnt = 0;
		bcnt = 0;
		rcnt = 0;

		mbuf = (1024*1024);
		j->dbuf = malloc(mbuf);
		rbuf = 0;

		for(i=0; i<j->max_pkts; i++) {
			if(!j->pkts[i]) break;

			rbuf += (8 + 8 + 4 + PktGetPacketSize(j->pkts[i]));
			if(mbuf < rbuf) {
				mbuf += (1024*1024);
				j->dbuf = realloc(j->dbuf, mbuf);
			
				if(!j->dbuf) {
					dprintf("sniffer>> realloc of %d bytes failed!", rbuf);
					result = ERROR_NOT_ENOUGH_MEMORY;
					break;
				}
			}

			tmp = (unsigned int *)( j->dbuf + rcnt );
			tlo = PktGetId(j->pkts[i], &thi);
			*tmp = htonl(thi); tmp++;
			*tmp = htonl(tlo); tmp++;

			tlo = PktGetTimeStamp(j->pkts[i], &thi);
			*tmp = htonl(thi); tmp++;
			*tmp = htonl(tlo); tmp++;

			tlo = PktGetPacketSize(j->pkts[i]);
			*tmp = htonl(tlo); tmp++;

			memcpy(j->dbuf+rcnt+20, PktGetPacketData(j->pkts[i]), tlo);
			
			rcnt += 20 + tlo;
			pcnt++;

			PktDestroy(j->pkts[i]);
			j->pkts[i] = NULL;
		}

		j->dlen = rcnt;

		packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, pcnt);
		packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, rcnt);

		dprintf("sniffer>> finished processing packets");

		j->cur_bytes = 0;
		j->cur_pkts  = 0;
		j->idx_pkts  = 0;
	} while(0);

	LeaveCriticalSection(&sniffercs);
	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}
Exemple #8
0
DWORD request_sniffer_capture_start(Remote *remote, Packet *packet) {
	Packet *response = packet_create_response(packet);
	unsigned int ifid;
	unsigned int maxp;
	CaptureJob *j;
	DWORD result;
	HANDLE ifh;

	check_pssdk();
	dprintf("sniffer>> start_capture()");

	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 = min(maxp, 200000);
	maxp = max(maxp, 1);

	result = ERROR_SUCCESS;

	do {
		// the interface is invalid
		if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) {
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		ifh = pktsdk_interface_by_index(ifid);
		if(ifh == NULL) {
			result = ERROR_INVALID_PARAMETER;
			break;		
		}

		j = &open_captures[ifid];

		// the interface is already being captured
		if(j->active) {
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		j->adp = AdpCreate();
		dprintf("sniffer>> capture_start() AdpCreate: 0x%.8x", j->adp);

		AdpSetConfig(j->adp,ifh);
		hErr = AdpOpenAdapter(j->adp);
		dprintf("sniffer>> capture_start() AdpOpenAdapter: 0x%.8x", hErr);
		if (hErr != HNERR_OK) { 
			AdpDestroy(j->adp);
			result = hErr;
			break;
		}
		
		j->pkts = calloc(maxp, sizeof(HANDLE));
		if(j->pkts == NULL) {
			AdpCloseAdapter(j->adp);
			AdpDestroy(j->adp);
			result = ERROR_ACCESS_DENIED;
			break;
		}

		j->active   = 1;
		j->intf     = ifid;
		j->max_pkts = maxp;
		j->cur_pkts = 0;
		j->mtu      = AdpCfgGetMaxPacketSize(AdpGetConfig(j->adp));

		AdpSetOnPacketRecv(j->adp, (FARPROC) sniffer_receive, (DWORD_PTR)j);
		AdpSetMacFilter(j->adp, mfAll);
	} while(0);
	
	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}
DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	unsigned int ifid, i;
	unsigned int bcnt;
	CaptureJob *j;
	DWORD result;

	check_pssdk();
	dprintf("sniffer>> capture_dump_read()");

	ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
	bcnt = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_BYTE_COUNT);
	bcnt = min(bcnt, 32 * 1024 * 1024);

	dprintf("sniffer>> capture_dump_read(0x%.8x, %d)", ifid, bcnt);

	result = ERROR_SUCCESS;

	do
	{
		// the interface is invalid
		if (ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES)
		{
			packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
			goto fail;
		}

		j = &open_captures[ifid];

		if (!j->dbuf)
		{
			packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
			goto fail;
		}

		if (j->didx + bcnt > j->dlen)
		{
			bcnt = j->dlen - j->didx;
		}

		packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, bcnt);
		packet_add_tlv_raw(response, TLV_TYPE_SNIFFER_PACKET, (unsigned char *)j->dbuf + j->didx, bcnt);
		j->didx += bcnt;
	} while (0);

	// Free memory if the read is complete
	if (j->didx >= j->dlen - 1)
	{
		free(j->dbuf);
		j->dbuf = NULL;
		j->didx = 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);
	return ERROR_SUCCESS;
}
DWORD request_sniffer_capture_start(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	unsigned int ifid;
	unsigned int maxp;
	CaptureJob *j;
	DWORD result;
	HANDLE ifh;

#ifndef _WIN32
	char errbuf[PCAP_ERRBUF_SIZE+4];
	char *name;
#endif

	check_pssdk();
	dprintf("sniffer>> start_capture()");

	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 = min(maxp, SNIFFER_MAX_QUEUE);
	maxp = max(maxp, 1);

	result = ERROR_SUCCESS;

	do
	{
		// the interface is invalid
		if (ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES)
		{
			result = ERROR_INVALID_PARAMETER;
			break;
		}

#ifdef _WIN32
		ifh = pktsdk_interface_by_index(ifid);
		if (ifh == NULL)
		{
			result = ERROR_INVALID_PARAMETER;
			break;
		}
#else
		ifh = ifid;
#endif

		j = &open_captures[ifid];

		// the interface is already being captured
		if (j->active)
		{
			result = ERROR_INVALID_PARAMETER;
			break;
		}

#ifdef _WIN32
		j->adp = AdpCreate();
		dprintf("sniffer>> capture_start() AdpCreate: 0x%.8x", j->adp);

		AdpSetConfig(j->adp, ifh);
		hErr = AdpOpenAdapter(j->adp);
		dprintf("sniffer>> capture_start() AdpOpenAdapter: 0x%.8x", hErr);

		if (hErr != HNERR_OK)
		{
			AdpDestroy(j->adp);
			result = hErr;
			break;
		}

		j->capture_linktype = 1; //  LINKTYPE_ETHERNET forced on windows
#else
		name = get_interface_name_by_index(ifh);

		if(!name)
		{
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		j->pcap = pcap_open_live(name, 65535, 1, 1000, errbuf);
		if(!j->pcap)
		{
			result = EACCES;
			break;
		}

		j->capture_linktype = dlt_to_linktype(pcap_datalink(j->pcap)); // get the datalink associated with the capture, needed when saving pcap file
		if (-1 == j->capture_linktype)
		{
			j->capture_linktype = 1; // force to LINKTYPE_ETHERNET in case of error
		}

		if(packet_filter)
		{
			struct bpf_program bpf;
			char *add_filter;
			char *real_filter = NULL;
			int rc;

			dprintf("handling packet_filter");

			add_filter = packet_get_tlv_value_string(packet, TLV_TYPE_SNIFFER_ADDITIONAL_FILTER);

			dprintf("add_filter = %p (%s)", add_filter, add_filter ? add_filter : "");

			if(add_filter)
			{
				asprintf(&real_filter, "%s and (%s)", packet_filter, add_filter);
			}
			else
			{
				real_filter = strdup(packet_filter);
			}

			dprintf("the real filter string we'll be using is '%s'", real_filter);

			rc = pcap_compile(j->pcap, &bpf, real_filter, 1, 0);
			free(real_filter);

			if(rc == -1)
			{
				dprintf("pcap compile reckons '%s' is a failure because of '%s'",
					real_filter, pcap_geterr(j->pcap));

				result = ERROR_INVALID_PARAMETER;
				break;
			}

			dprintf("compiled filter, now setfilter()'ing");

			rc = pcap_setfilter(j->pcap, &bpf);
			pcap_freecode(&bpf);

			if(rc == -1)
			{
				dprintf("can't set filter because '%s'", pcap_geterr(j->pcap));

				result = ERROR_INVALID_PARAMETER;
				break;
			}

			dprintf("filter applied successfully");
		}

		j->thread = thread_create((THREADFUNK) sniffer_thread, j, NULL, NULL);

		if(! j->thread)
		{
			pcap_close(j->pcap);
			break;
		}

#endif

		j->pkts = calloc(maxp, sizeof(*(j->pkts)));
		if (j->pkts == NULL) {
#ifdef _WIN32
			AdpCloseAdapter(j->adp);
			AdpDestroy(j->adp);
#else
			pcap_close(j->pcap);
#endif
			result = ERROR_ACCESS_DENIED;
			break;
		}

		j->active = 1;
		j->intf = ifid;
		j->max_pkts = maxp;
		j->cur_pkts = 0;
		j->mtu = AdpCfgGetMaxPacketSize(AdpGetConfig(j->adp));

#ifdef _WIN32
		AdpSetOnPacketRecv(j->adp, (FARPROC)sniffer_receive, (DWORD_PTR)j);
		AdpSetMacFilter(j->adp, mfAll);
#else
		thread_run(j->thread);
#endif

	} while (0);

	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}
DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	Tlv entries[8];

	/*
		0: Index
		1: Name
		2: Description
		3: Type
		4: MTU
		5: Wireless?
		6: Accessible?
		7: DHCP?
		*/
	DWORD result = ERROR_SUCCESS;

#ifdef _WIN32
	HANDLE hCfg;
	unsigned int idx = 1;

	check_pssdk();

	hCfg = MgrGetFirstAdapterCfg(hMgr);

	do
	{
		unsigned char *aname = (unsigned char *)AdpCfgGetAdapterNameA(hCfg);
		unsigned char *adesc = (unsigned char *)AdpCfgGetAdapterDescriptionA(hCfg);
		unsigned int ahand = htonl((unsigned int)hCfg);
		unsigned int atype = htonl(AdpCfgGetAdapterType(hCfg));
		unsigned int amtu = htonl(AdpCfgGetMaxPacketSize(hCfg));
		unsigned int aidx = htonl(idx);

		BOOL awireless = AdpCfgIsWireless(hCfg);
		BOOL ausable = AdpCfgGetAccessibleState(hCfg);
		BOOL adhcp = AdpCfgGetDhcpState(hCfg);

		memset(entries, 0, sizeof(entries));

		dprintf("sniffer>> interface %d - %s - %s", idx, aname, adesc);

		entries[0].header.type = TLV_TYPE_UINT;
		entries[0].header.length = sizeof(unsigned int);
		entries[0].buffer = (PUCHAR)&aidx;

		entries[1].header.type = TLV_TYPE_STRING;
		entries[1].header.length = (DWORD)strlen(aname) + 1;
		entries[1].buffer = aname;

		entries[2].header.type = TLV_TYPE_STRING;
		entries[2].header.length = (DWORD)strlen(adesc) + 1;
		entries[2].buffer = adesc;

		entries[3].header.type = TLV_TYPE_UINT;
		entries[3].header.length = sizeof(unsigned int);
		entries[3].buffer = (PUCHAR)&atype;

		entries[4].header.type = TLV_TYPE_UINT;
		entries[4].header.length = sizeof(unsigned int);
		entries[4].buffer = (PUCHAR)&amtu;

		entries[5].header.type = TLV_TYPE_BOOL;
		entries[5].header.length = sizeof(BOOL);
		entries[5].buffer = (PUCHAR)&awireless;

		entries[6].header.type = TLV_TYPE_BOOL;
		entries[6].header.length = sizeof(BOOL);
		entries[6].buffer = (PUCHAR)&ausable;

		entries[7].header.type = TLV_TYPE_BOOL;
		entries[7].header.length = sizeof(BOOL);
		entries[7].buffer = (PUCHAR)&adhcp;

		packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8);

		idx++;
	} while ((hCfg = MgrGetNextAdapterCfg(hMgr, hCfg)) != NULL);

#else
	char errbuf[PCAP_ERRBUF_SIZE+4];
	int aidx = htonl(1);				// :~(
	struct ifaces_list *ifaces;
	uint32_t i;
	int aidx_bigendian;
	int mtu_bigendian;

	int yes_int = htonl(1);
	int no_int = 0;
	int mtu_int = htonl(1514);

	pcap_if_t *interfaces, *int_iter;

	interfaces = int_iter = NULL;
	ifaces = NULL;

	do
	{
		result = pcap_findalldevs(&interfaces, errbuf);

		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].buffer        = (PUCHAR)&aidx;

				entries[1].header.type   = TLV_TYPE_STRING;
				entries[1].header.length = strlen(int_iter->name)+1;
				entries[1].buffer        = (PUCHAR)int_iter->name;

				entries[2].header.type   = TLV_TYPE_STRING;
				entries[2].header.length = strlen(int_iter->name)+1;
				entries[2].buffer        = (PUCHAR)int_iter->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?

				entries[4].header.type   = TLV_TYPE_UINT;
				entries[4].header.length = sizeof(unsigned int);
				entries[4].buffer        = (PUCHAR)&mtu_int;		// PKS :-(

				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);
				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);

	if(ifaces)
	{
		free(ifaces);
	}

	if (interfaces)
	{
		pcap_freealldevs(interfaces);
	}

#endif

	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}
DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	unsigned int ifid;
	unsigned int rbuf, mbuf;
	unsigned int *tmp;

	CaptureJob *j;
	DWORD result, pcnt, rcnt, i;
#ifdef _WIN64
	ULONGLONG thilo;
#endif
	DWORD thi, tlo;

	check_pssdk();
	dprintf("sniffer>> capture_dump()");

	ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
	dprintf("sniffer>> capture_dump(0x%.8x)", ifid);

	result = ERROR_SUCCESS;

	lock_acquire(snifferm);

	do
	{
		// the interface is invalid
		if (ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES)
		{
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		j = &open_captures[ifid];

		// the interface was not captured
#ifdef _WIN32
		if (!j->adp)
#else
		if(! j->pcap)
#endif
		{
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		// Free any existing packet buffer
		if (j->dbuf)
		{
			free(j->dbuf);
			j->dbuf = NULL;
			j->dlen = 0;
			j->didx = 0;
		}

		// Add basic stats
		pcnt = 0;
		rcnt = 0;

		mbuf = (1024 * 1024);
		j->dbuf = malloc(mbuf);
		rbuf = 0;

		for (i = 0; i < j->max_pkts; i++)
		{
			if (!j->pkts[i]) break;

			rbuf += (8 + 8 + 4 + PktGetPacketSize(j->pkts[i]));
			if (mbuf < rbuf)
			{
				mbuf += (1024 * 1024);
				j->dbuf = realloc(j->dbuf, mbuf);

				if (!j->dbuf)
				{
					dprintf("sniffer>> realloc of %d bytes failed!", rbuf);
					result = ERROR_NOT_ENOUGH_MEMORY;
					break;
				}
			}

			tmp = (unsigned int *)(j->dbuf + rcnt);
#ifdef _WIN64
			thilo = PktGetId(j->pkts[i]);
			thi = (DWORD)(thilo >> 32);
			tlo = (DWORD)(thilo & 0xFFFFFFFF);
#else
			tlo = PktGetId(j->pkts[i], &thi);
#endif
			*tmp = htonl(thi); tmp++;
			*tmp = htonl(tlo); tmp++;

#ifdef _WIN64
			thilo = PktGetTimeStamp(j->pkts[i]);
			thi = (DWORD)(thilo >> 32);
			tlo = (DWORD)(thilo & 0xFFFFFFFF);
#else
			tlo = PktGetTimeStamp(j->pkts[i], &thi);
#endif
			*tmp = htonl(thi); tmp++;
			*tmp = htonl(tlo); tmp++;

			tlo = PktGetPacketSize(j->pkts[i]);
			*tmp = htonl(tlo); tmp++;

			memcpy(j->dbuf + rcnt + 20, PktGetPacketData(j->pkts[i]), tlo);

			rcnt += 20 + tlo;
			pcnt++;

			PktDestroy(j->pkts[i]);
			j->pkts[i] = NULL;
		}

		j->dlen = rcnt;

		packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, pcnt);
		packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, rcnt);
		// add capture datalink, needed when saving capture file, use TLV_TYPE_SNIFFER_INTERFACE_ID not to create a new TLV type
		packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_INTERFACE_ID, j->capture_linktype);

		dprintf("sniffer>> finished processing packets");

		j->cur_bytes = 0;
		j->cur_pkts = 0;
		j->idx_pkts = 0;
	} while (0);

	lock_release(snifferm);
	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}