Ejemplo n.º 1
0
static u_int
pcap_sendqueue_transmit_win32(pcap_t *p, pcap_send_queue *queue, int sync)
{
	struct pcap_win *pw = p->priv;
	u_int res;
	char errbuf[PCAP_ERRBUF_SIZE+1];

	if (pw->adapter==NULL) {
		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "Cannot transmit a queue to an offline capture or to a TurboCap port");
		return (0);
	}

	res = PacketSendPackets(pw->adapter,
		queue->buffer,
		queue->len,
		(BOOLEAN)sync);

	if(res != queue->len){
		pcap_win32_err_to_str(GetLastError(), errbuf);
		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "Error opening adapter: %s", errbuf);
	}

	return (res);
}
Ejemplo n.º 2
0
/*
 * Win32-only routine for getting statistics.
 *
 * This way is definitely safer than passing the pcap_stat * from the userland.
 * In fact, there could happen than the user allocates a variable which is not
 * big enough for the new structure, and the library will write in a zone
 * which is not allocated to this variable.
 *
 * In this way, we're pretty sure we are writing on memory allocated to this
 * variable.
 *
 * XXX - but this is the wrong way to handle statistics.  Instead, we should
 * have an API that returns data in a form like the Options section of a
 * pcapng Interface Statistics Block:
 *
 *    http://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://raw.githubusercontent.com/pcapng/pcapng/master/draft-tuexen-opsawg-pcapng.xml&modeAsFormat=html/ascii&type=ascii#rfc.section.4.6
 *
 * which would let us add new statistics straightforwardly and indicate which
 * statistics we are and are *not* providing, rather than having to provide
 * possibly-bogus values for statistics we can't provide.
 */
struct pcap_stat *
pcap_stats_ex_win32(pcap_t *p, int *pcap_stat_size)
{
	struct pcap_win *pw = p->priv;
	struct bpf_stat bstats;
	char errbuf[PCAP_ERRBUF_SIZE+1];

	*pcap_stat_size = sizeof (p->stat);

	/*
	 * Try to get statistics.
	 *
	 * (Please note - "struct pcap_stat" is *not* the same as
	 * WinPcap's "struct bpf_stat". It might currently have the
	 * same layout, but let's not cheat.)
	 */
	if (!PacketGetStatsEx(pw->adapter, &bstats)) {
		pcap_win32_err_to_str(GetLastError(), errbuf);
		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "PacketGetStatsEx error: %s", errbuf);
		return (NULL);
	}
	p->stat.ps_recv = bstats.bs_recv;
	p->stat.ps_drop = bstats.bs_drop;
	p->stat.ps_ifdrop = bstats.ps_ifdrop;
#ifdef ENABLE_REMOTE
	p->stat.ps_capt = bstats.bs_capt;
#endif
	return (&p->stat);
}
Ejemplo n.º 3
0
static int
pcap_oid_get_request_win32(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp)
{
	struct pcap_win *pw = p->priv;
	PACKET_OID_DATA *oid_data_arg;
	char errbuf[PCAP_ERRBUF_SIZE+1];

	/*
	 * Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
	 * It should be big enough to hold "*lenp" bytes of data; it
	 * will actually be slightly larger, as PACKET_OID_DATA has a
	 * 1-byte data array at the end, standing in for the variable-length
	 * data that's actually there.
	 */
	oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
	if (oid_data_arg == NULL) {
		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "Couldn't allocate argument buffer for PacketRequest");
		return (PCAP_ERROR);
	}

	/*
	 * No need to copy the data - we're doing a fetch.
	 */
	oid_data_arg->Oid = oid;
	oid_data_arg->Length = (ULONG)(*lenp);	/* XXX - check for ridiculously large value? */
	if (!PacketRequest(pw->adapter, FALSE, oid_data_arg)) {
		pcap_win32_err_to_str(GetLastError(), errbuf);
		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "Error calling PacketRequest: %s", errbuf);
		free(oid_data_arg);
		return (PCAP_ERROR);
	}

	/*
	 * Get the length actually supplied.
	 */
	*lenp = oid_data_arg->Length;

	/*
	 * Copy back the data we fetched.
	 */
	memcpy(data, oid_data_arg->Data, *lenp);
	free(oid_data_arg);
	return (0);
}
Ejemplo n.º 4
0
static int
pcap_stats_win32(pcap_t *p, struct pcap_stat *ps)
{
	struct pcap_win *pw = p->priv;
	struct bpf_stat bstats;
	char errbuf[PCAP_ERRBUF_SIZE+1];

	/*
	 * Try to get statistics.
	 *
	 * (Please note - "struct pcap_stat" is *not* the same as
	 * WinPcap's "struct bpf_stat". It might currently have the
	 * same layout, but let's not cheat.
	 *
	 * Note also that we don't fill in ps_capt, as we might have
	 * been called by code compiled against an earlier version of
	 * WinPcap that didn't have ps_capt, in which case filling it
	 * in would stomp on whatever comes after the structure passed
	 * to us.
	 */
	if (!PacketGetStats(pw->adapter, &bstats)) {
		pcap_win32_err_to_str(GetLastError(), errbuf);
		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "PacketGetStats error: %s", errbuf);
		return (-1);
	}
	ps->ps_recv = bstats.bs_recv;
	ps->ps_drop = bstats.bs_drop;

	/*
	 * XXX - PacketGetStats() doesn't fill this in, so we just
	 * return 0.
	 */
#if 0
	ps->ps_ifdrop = bstats.ps_ifdrop;
#else
	ps->ps_ifdrop = 0;
#endif

	return (0);
}
Ejemplo n.º 5
0
/*
 * Get a list of all interfaces that are up and that we can open.
 * Returns -1 on error, 0 otherwise.
 * The list, as returned through "alldevsp", may be null if no interfaces
 * were up and could be opened.
 *
 * Win32 implementation, based on WinPcap
 */
int
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
{
	pcap_if_t *devlist = NULL;
	int ret = 0;
	const char *desc;
	char *AdaptersName;
	ULONG NameLength;
	char *name;
	char our_errbuf[PCAP_ERRBUF_SIZE+1];

	/*
	 * Find out how big a buffer we need.
	 *
	 * This call should always return FALSE; if the error is
	 * ERROR_INSUFFICIENT_BUFFER, NameLength will be set to
	 * the size of the buffer we need, otherwise there's a
	 * problem, and NameLength should be set to 0.
	 *
	 * It shouldn't require NameLength to be set, but,
	 * at least as of WinPcap 4.1.3, it checks whether
	 * NameLength is big enough before it checks for a
	 * NULL buffer argument, so, while it'll still do
	 * the right thing if NameLength is uninitialized and
	 * whatever junk happens to be there is big enough
	 * (because the pointer argument will be null), it's
	 * still reading an uninitialized variable.
	 */
	NameLength = 0;
	if (!PacketGetAdapterNames(NULL, &NameLength))
	{
		DWORD last_error = GetLastError();

		if (last_error != ERROR_INSUFFICIENT_BUFFER)
		{
			pcap_win32_err_to_str(last_error, our_errbuf);
			pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
			    "PacketGetAdapterNames: %s", our_errbuf);
			return (-1);
		}
	}

	if (NameLength > 0)
		AdaptersName = (char*) malloc(NameLength);
	else
	{
		*alldevsp = NULL;
		return 0;
	}
	if (AdaptersName == NULL)
	{
		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters.");
		return (-1);
	}

	if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
		pcap_win32_err_to_str(GetLastError(), our_errbuf);
		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "PacketGetAdapterNames: %s",
		    our_errbuf);
		free(AdaptersName);
		return (-1);
	}

	/*
	 * "PacketGetAdapterNames()" returned a list of
	 * null-terminated ASCII interface name strings,
	 * terminated by a null string, followed by a list
	 * of null-terminated ASCII interface description
	 * strings, terminated by a null string.
	 * This means there are two ASCII nulls at the end
	 * of the first list.
	 *
	 * Find the end of the first list; that's the
	 * beginning of the second list.
	 */
	desc = &AdaptersName[0];
	while (*desc != '\0' || *(desc + 1) != '\0')
		desc++;

	/*
 	 * Found it - "desc" points to the first of the two
	 * nulls at the end of the list of names, so the
	 * first byte of the list of descriptions is two bytes
	 * after it.
	 */
	desc += 2;

	/*
	 * Loop over the elements in the first list.
	 */
	name = &AdaptersName[0];
	while (*name != '\0') {
		/*
		 * Add an entry for this interface.
		 */
		if (pcap_add_if_win32(&devlist, name, desc, errbuf) == -1) {
			/*
			 * Failure.
			 */
			ret = -1;
			break;
		}
		name += strlen(name) + 1;
		desc += strlen(desc) + 1;
	}

	if (ret != -1) {
		/*
		 * We haven't had any errors yet; do any platform-specific
		 * operations to add devices.
		 */
		if (pcap_platform_finddevs(&devlist, errbuf) < 0)
			ret = -1;
	}

	if (ret == -1) {
		/*
		 * We had an error; free the list we've been constructing.
		 */
		if (devlist != NULL) {
			pcap_freealldevs(devlist);
			devlist = NULL;
		}
	}

	*alldevsp = devlist;
	free(AdaptersName);
	return (ret);
}