Esempio n. 1
0
char *get_interface_name_by_index(unsigned int fidx)
{
	unsigned int i, idx;
	char errbuf[PCAP_ERRBUF_SIZE+4];
	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;

	interfaces = int_iter = NULL;
	ifaces = NULL;
	idx = 1;

	memset(device_name, 0, sizeof(device_name));

	if(pcap_findalldevs(&interfaces, errbuf) == -1)
	{
		dprintf("pcap_findalldevs failed, trying netlink_get_interfaces, errbuf was : %s", errbuf);
		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)
		{
			if(fidx == idx++)
			{
				strncpy(device_name, int_iter->name, sizeof(device_name)-1);
				break;
			}
		}
	}

	if(interfaces)
	{
		pcap_freealldevs(interfaces);
	}

	if (ifaces)
	{
		free(ifaces);
	}

	return device_name[0] ? device_name : NULL;

}
Esempio n. 2
0
#include "precomp.h"

#ifdef _WIN32
#include <iptypes.h>
#include <ws2ipdef.h>
#endif

#ifdef _WIN32
DWORD get_interfaces_windows_mib(Remote *remote, Packet *response)
{
	DWORD result = ERROR_SUCCESS;
	DWORD tlv_cnt;

	Tlv entries[6];
	PMIB_IPADDRTABLE table = NULL;
	DWORD tableSize = sizeof(MIB_IPADDRROW) * 33;
	DWORD index;
	DWORD mtu_bigendian;
	DWORD interface_index_bigendian;
	MIB_IFROW iface;

	do
	{
		// Allocate memory for reading addresses into
		if (!(table = (PMIB_IPADDRTABLE)malloc(tableSize)))
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}

		// Get the IP address table
		if (GetIpAddrTable(table, &tableSize, TRUE) != NO_ERROR)
		{
			result = GetLastError();
			break;
		}

		// Enumerate the entries
		for (index = 0; index < table->dwNumEntries; index++)
		{
			tlv_cnt = 0;

			interface_index_bigendian = htonl(table->table[index].dwIndex);
			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_INDEX;
			entries[tlv_cnt].buffer = (PUCHAR)&interface_index_bigendian;
			tlv_cnt++;

			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type = TLV_TYPE_IP;
			entries[tlv_cnt].buffer = (PUCHAR)&table->table[index].dwAddr;
			tlv_cnt++;

			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type = TLV_TYPE_NETMASK;
			entries[tlv_cnt].buffer = (PUCHAR)&table->table[index].dwMask;
			tlv_cnt++;

			iface.dwIndex = table->table[index].dwIndex;

			// If interface information can get gotten, use it.
			if (GetIfEntry(&iface) == NO_ERROR)
			{
				entries[tlv_cnt].header.length = iface.dwPhysAddrLen;
				entries[tlv_cnt].header.type = TLV_TYPE_MAC_ADDR;
				entries[tlv_cnt].buffer = (PUCHAR)iface.bPhysAddr;
				tlv_cnt++;

				mtu_bigendian = htonl(iface.dwMtu);
				entries[tlv_cnt].header.length = sizeof(DWORD);
				entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_MTU;
				entries[tlv_cnt].buffer = (PUCHAR)&mtu_bigendian;
				tlv_cnt++;

				if (iface.bDescr)
				{
					entries[tlv_cnt].header.length = iface.dwDescrLen + 1;
					entries[tlv_cnt].header.type = TLV_TYPE_MAC_NAME;
					entries[tlv_cnt].buffer = (PUCHAR)iface.bDescr;
					tlv_cnt++;
				}
			}

			// Add the interface group
			packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
			entries, tlv_cnt);
		}

	} while (0);

	if (table)
		free(table);

	return result;
}


DWORD get_interfaces_windows(Remote *remote, Packet *response) {
	DWORD result = ERROR_SUCCESS;
	DWORD tlv_cnt;
	// Most of the time we'll need:
	//   index, name (description), MAC addr, mtu, flags, IP addr, netmask, maybe scope id
	// In some cases, the interface will have multiple addresses, so we'll realloc
	// this when necessary, but this will cover the common case.
	DWORD allocd_entries = 20;
	Tlv *entries = (Tlv *)malloc(sizeof(Tlv) * 20);
	int prefixes[30];
	int prefixes_cnt = 0;

	DWORD mtu_bigendian;
	DWORD interface_index_bigendian;

	ULONG flags = GAA_FLAG_INCLUDE_PREFIX
		| GAA_FLAG_SKIP_DNS_SERVER
		| GAA_FLAG_SKIP_MULTICAST
		| GAA_FLAG_SKIP_ANYCAST;

	LPSOCKADDR sockaddr;

	ULONG family = AF_UNSPEC;
	IP_ADAPTER_ADDRESSES *pAdapters = NULL;
	IP_ADAPTER_ADDRESSES *pCurr = NULL;
	ULONG outBufLen = 0;
	DWORD (WINAPI *gaa)(DWORD, DWORD, void *, void *, void *);

	// Use the newer version so we're guaranteed to have a large enough struct.
	// Unfortunately, using these probably means it won't compile on older
	// versions of Visual Studio.  =(
	IP_ADAPTER_UNICAST_ADDRESS_LH *pAddr = NULL;
	IP_ADAPTER_UNICAST_ADDRESS_LH *pPref = NULL;
	// IP_ADAPTER_PREFIX is only defined if NTDDI_VERSION > NTDDI_WINXP
	// Since we request older versions of things, we have to be explicit
	// when using newer structs.
	IP_ADAPTER_PREFIX_XP *pPrefix = NULL;

	do
	{
		gaa = (DWORD (WINAPI *)(DWORD,DWORD,void*,void*,void*))GetProcAddress(
				GetModuleHandle("iphlpapi"), "GetAdaptersAddresses"
			);
		if (!gaa) {
			result = get_interfaces_windows_mib(remote, response);
			break;
		}

		gaa(family, flags, NULL, pAdapters, &outBufLen);
		if (!(pAdapters = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen)))
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}
		if (gaa(family, flags, NULL, pAdapters, &outBufLen))
		{
			result = GetLastError();
			break;
		}

		// Enumerate the entries
		for (pCurr = pAdapters; pCurr; pCurr = pCurr->Next)
		{
			tlv_cnt = 0;

			interface_index_bigendian = htonl(pCurr->IfIndex);
			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type   = TLV_TYPE_INTERFACE_INDEX;
			entries[tlv_cnt].buffer        = (PUCHAR)&interface_index_bigendian;
			tlv_cnt++;

			entries[tlv_cnt].header.length = pCurr->PhysicalAddressLength;
			entries[tlv_cnt].header.type   = TLV_TYPE_MAC_ADDR;
			entries[tlv_cnt].buffer        = (PUCHAR)pCurr->PhysicalAddress;
			tlv_cnt++;

			entries[tlv_cnt].header.length = wcslen(pCurr->Description)*2 + 1;
			entries[tlv_cnt].header.type   = TLV_TYPE_MAC_NAME;
			entries[tlv_cnt].buffer        = (PUCHAR)pCurr->Description;
			tlv_cnt++;

			mtu_bigendian            = htonl(pCurr->Mtu);
			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type   = TLV_TYPE_INTERFACE_MTU;
			entries[tlv_cnt].buffer        = (PUCHAR)&mtu_bigendian;
			tlv_cnt++;

			if (pCurr->Length > 68) {
				// Then this is a Longhorn struct version and it contains the
				// FirstPrefix member, save it for later in case we don't have
				// an OnLinkPrefixLength
				pPrefix = pCurr->FirstPrefix;
			}

			for (pAddr = (void*)pCurr->FirstUnicastAddress; pAddr; pAddr = (void*)pAddr->Next)
			{
				sockaddr = pAddr->Address.lpSockaddr;
				if (AF_INET != sockaddr->sa_family && AF_INET6 != sockaddr->sa_family) {
					// Skip interfaces that aren't IP
					continue;
				}

				// This loop can add up to three Tlv's - one for address, one
				// for scope_id, one for netmask.  Go ahead and allocate enough
				// room for all of them.
				if (allocd_entries < tlv_cnt+3) {
					entries = realloc(entries, sizeof(Tlv) * (tlv_cnt+3));
					allocd_entries += 3;
				}

				if (pAddr->Length > 44) {
					// Then this is Vista+ and the OnLinkPrefixLength member
					// will be populated
					prefixes[prefixes_cnt] = htonl(pAddr->OnLinkPrefixLength);
				}
				if (pPrefix && 0 == prefixes[prefixes_cnt]) {
					// Otherwise, we have to walk the FirstPrefix linked list
					prefixes[prefixes_cnt] = htonl(pPrefix->PrefixLength);
					pPrefix = pPrefix->Next;
				} else {
					// This is XP SP0 and as far as I can tell, we have no way
					// of determining the netmask short of bailing on
					// this method and falling back to MIB, which doesn't
					// return IPv6 addresses. Older versions (e.g. NT4, 2k)
					// don't have GetAdapterAddresses, so they will have fallen
					// through earlier to the MIB implementation.
					free(entries);
					free(pAdapters);
					return get_interfaces_windows_mib(remote, response);
				}

				if (prefixes[prefixes_cnt]) {
					entries[tlv_cnt].header.length = 4;
					entries[tlv_cnt].header.type = TLV_TYPE_IP_PREFIX;
					entries[tlv_cnt].buffer = (PUCHAR)&prefixes[prefixes_cnt];
					tlv_cnt++;
					prefixes_cnt++;
				}

				if (sockaddr->sa_family == AF_INET) {
					entries[tlv_cnt].header.length = 4;
					entries[tlv_cnt].header.type = TLV_TYPE_IP;
					entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in *)sockaddr)->sin_addr);
					tlv_cnt++;

				} else {
					entries[tlv_cnt].header.length = 16;
					entries[tlv_cnt].header.type = TLV_TYPE_IP;
					entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr);
					tlv_cnt++;

					entries[tlv_cnt].header.length = sizeof(DWORD);
					entries[tlv_cnt].header.type = TLV_TYPE_IP6_SCOPE;
					entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_scope_id);
					tlv_cnt++;
				}

			}
			// Add the interface group
			packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
					entries, tlv_cnt);
		}
	} while (0);

	if (entries)
		free(entries);
	if (pAdapters)
		free(pAdapters);

	return result;
}

#else /* _WIN32 */
int get_interfaces_linux(Remote *remote, Packet *response) {
	struct ifaces_list *ifaces = NULL;
	int i;
	int result;
	uint32_t interface_index_bigendian, mtu_bigendian;
	DWORD allocd_entries = 10;
	Tlv *entries = (Tlv *)malloc(sizeof(Tlv) * 10);

	dprintf("Grabbing interfaces");
	result = netlink_get_interfaces(&ifaces);
	dprintf("Got 'em");

	if (!result) {
		for (i = 0; i < ifaces->entries; i++) {
			int tlv_cnt = 0;
			int j = 0;
			dprintf("Building TLV for iface %d", i);

			entries[tlv_cnt].header.length = strlen(ifaces->ifaces[i].name)+1;
			entries[tlv_cnt].header.type   = TLV_TYPE_MAC_NAME;
			entries[tlv_cnt].buffer        = (PUCHAR)ifaces->ifaces[i].name;
			tlv_cnt++;

			entries[tlv_cnt].header.length = 6;
			entries[tlv_cnt].header.type   = TLV_TYPE_MAC_ADDR;
			entries[tlv_cnt].buffer        = (PUCHAR)ifaces->ifaces[i].hwaddr;
			tlv_cnt++;

			mtu_bigendian            = htonl(ifaces->ifaces[i].mtu);
			entries[tlv_cnt].header.length = sizeof(uint32_t);
			entries[tlv_cnt].header.type   = TLV_TYPE_INTERFACE_MTU;
			entries[tlv_cnt].buffer        = (PUCHAR)&mtu_bigendian;
			tlv_cnt++;

			entries[tlv_cnt].header.length = strlen(ifaces->ifaces[i].flags)+1;
			entries[tlv_cnt].header.type   = TLV_TYPE_INTERFACE_FLAGS;
			entries[tlv_cnt].buffer        = (PUCHAR)ifaces->ifaces[i].flags;
			tlv_cnt++;

			interface_index_bigendian = htonl(ifaces->ifaces[i].index);
			entries[tlv_cnt].header.length = sizeof(uint32_t);
			entries[tlv_cnt].header.type   = TLV_TYPE_INTERFACE_INDEX;
			entries[tlv_cnt].buffer        = (PUCHAR)&interface_index_bigendian;
			tlv_cnt++;

			for (j = 0; j < ifaces->ifaces[i].addr_count; j++) {
				if (allocd_entries < tlv_cnt+3) {
					entries = realloc(entries, sizeof(Tlv) * (tlv_cnt+3));
					allocd_entries += 3;
				}
				if (ifaces->ifaces[i].addr_list[j].family == AF_INET) {
					dprintf("ip addr for %s", ifaces->ifaces[i].name);
					entries[tlv_cnt].header.length = sizeof(__u32);
					entries[tlv_cnt].header.type   = TLV_TYPE_IP;
					entries[tlv_cnt].buffer        = (PUCHAR)&ifaces->ifaces[i].addr_list[j].ip.addr;
					tlv_cnt++;

					//dprintf("netmask for %s", ifaces->ifaces[i].name);
					entries[tlv_cnt].header.length = sizeof(__u32);
					entries[tlv_cnt].header.type   = TLV_TYPE_NETMASK;
					entries[tlv_cnt].buffer        = (PUCHAR)&ifaces->ifaces[i].addr_list[j].nm.netmask;
					tlv_cnt++;
				} else {
					dprintf("-- ip six addr for %s", ifaces->ifaces[i].name);
					entries[tlv_cnt].header.length = sizeof(__u128);
					entries[tlv_cnt].header.type   = TLV_TYPE_IP;
					entries[tlv_cnt].buffer        = (PUCHAR)&ifaces->ifaces[i].addr_list[j].ip.addr6;
					tlv_cnt++;

					//dprintf("netmask6 for %s", ifaces->ifaces[i].name);
					entries[tlv_cnt].header.length = sizeof(__u128);
					entries[tlv_cnt].header.type   = TLV_TYPE_NETMASK;
					entries[tlv_cnt].buffer        = (PUCHAR)&ifaces->ifaces[i].addr_list[j].nm.netmask6;
					tlv_cnt++;
				}
			}

			dprintf("Adding TLV to group");
			packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE, entries, tlv_cnt);
			dprintf("done Adding TLV to group");
		}
	}

	if (ifaces)
		free(ifaces);
	if (entries)
		free(entries);


	return result;
}
Esempio n. 3
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?
		*/
	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;
}