Example #1
0
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;
}
Example #2
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;
}
Example #3
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;
}
Example #4
0
void __stdcall sniffer_receive(DWORD_PTR Param, DWORD_PTR ThParam, HANDLE hPacket, LPVOID pPacketData, DWORD IncPacketSize) {
	CaptureJob *j;
	HANDLE pkt;
	unsigned char *pktbuf;
	unsigned char *pktmax;
 	struct eth_hdr *eth;
 	struct ip_hdr *ip;
 	struct tcp_hdr *tcp;
//	struct udp_hdr *udp;


	j = (CaptureJob *)Param;
	pktbuf = (unsigned char *)pPacketData;
	pktmax = pktbuf + IncPacketSize;


	// Only process active jobs
	if(!j->active) return;

	// Traffic filtering goes here
	do {
		// Skip matching on short packets
		if(IncPacketSize < ETH_HDR_LEN + IP_HDR_LEN + TCP_HDR_LEN){
			dprintf("sniffer>> skipping exclusion because the packet is too small");
			break;
		}

		// Match IP packets
 		if(!peername4) {
			dprintf("sniffer>> skipping exclusion because peername4 is not defined");
			break;
		}

		// Skip non-IP packets
 		eth = (struct eth_hdr *) pktbuf;
 		if(ntohs(eth->eth_type) != ETH_TYPE_IP) {
			dprintf("sniffer>> skipping non-IP packet from filter");
			break;
		}

		// Skip non-TCP/UDP packets
 		ip = (struct ip_hdr *) &pktbuf[ETH_HDR_LEN];
 		if(ip->ip_p != IP_PROTO_TCP && ip->ip_p != IP_PROTO_UDP) {
 			dprintf("sniffer>> skipping non-TCP/UDP packet from filter: %d", ip->ip_p);
			break;
		}

 		if(ip->ip_p == IP_PROTO_TCP) {
 			tcp = (struct tcp_hdr *) &pktbuf[ETH_HDR_LEN + (ip->ip_hl * 4)];
 			if( (unsigned char *)tcp + TCP_HDR_LEN > pktmax) {
				dprintf("sniffer>> TCP packet is too short");
				break;
			}
			
			// Ignore our own control session's traffic
 			if ( (memcmp(&ip->ip_src,  &peername4->sin_addr, 4) == 0 && tcp->th_sport == peername4->sin_port) ||
 				 (memcmp(&ip->ip_dst, &peername4->sin_addr, 4) == 0 && tcp->th_dport == peername4->sin_port) ) {
				return;
			}
			// TODO: Scan through a list of included/excluded ports
		}

		// All done matching exclusions
	} while(0);


	// Thread-synchronized access to the queue
	EnterCriticalSection(&sniffercs);

	if(j->idx_pkts >= j->max_pkts) j->idx_pkts = 0;
	j->cur_pkts++;
	j->cur_bytes += IncPacketSize;
	
	pkt = PktCreate(j->mtu);
	PktCopyPacketToPacket(pkt, hPacket);
	if(j->pkts[j->idx_pkts])
			PktDestroy(j->pkts[j->idx_pkts]);
	j->pkts[j->idx_pkts] = pkt;
	j->idx_pkts++;

	LeaveCriticalSection(&sniffercs);
}
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_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;
}