Beispiel #1
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_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;
}