LAN Ip Scanner

January 26, 2009

Recently I came across a useful network API provided by Microsoft: Ipapi – IP Helper API. I’ve wrote a small application using it and I’ve explain here what is the purpose of Ipapi. 

 

What is Ipapi?

Ipapi is an API provided by Microsoft for network programming. The official page on MSDN is:

http://msdn.microsoft.com/en-us/library/aa366073(VS.85).aspx

It is destinated for C/C++ programmers. Ipapi provides the neccesary functions, procedures and structures to get information about the network configurations and change them. There are available several types of operations:

  • retrieving information about network configuration
  • managing network adapters, interfaces and IPs
  • using ARP
  • using ICMP
  • routing
  • get  notification for network events
  • get information about TCP and UDP

 

Example 1: get information about network adapters I’ve used some functions provided by Ipapi to list all of my network interfaces and, based on user option, to scan a LAN and detect used IPs.

Ipapi works with some specific structures. One of them is called IP_ADAPTER_INFO. This structure contains information discribing a network adapter. The full description of the structure is avaialble here: 

http://msdn.microsoft.com/en-us/library/aa366062.aspx

To get information about the local network interfaces Ipapi has the function GetAdaptersInfo, witch return a IP_ADAPTER_INFO, witch will point to another adapter, if the local machine has more than one adapter. The code for getting information about an adapter is presented bellow:

PIP_ADAPTER_INFO pAdapterInfo = NULL;
PIP_ADAPTER_INFO pAdapter = NULL;
DWORD dwRetVal = 0;
ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
// Allocate memory for the adapter info structure
pAdapterInfo = (IP_ADAPTER_INFO *) malloc(sizeof (IP_ADAPTER_INFO));
if (pAdapterInfo == NULL) {
	printf("Error allocating memory needed to call GetAdaptersinfo\n");
	return 1;
}

// Test if method is available and get buffer size
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
	free(pAdapterInfo);
	pAdapterInfo = (IP_ADAPTER_INFO *) malloc(ulOutBufLen);
	if (pAdapterInfo == NULL) {
		printf("Error allocating memory needed to call GetAdaptersinfo\n");
		return 1;
	}
}

// Get adapters info and iterate them
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
        pAdapter = pAdapterInfo;
        while (pAdapter) {
			// Do printing stuff
			.....
            pAdapter = pAdapter->Next;
        }
} else {
	printf("GetAdaptersInfo failed with error: %d\n", dwRetVal);
}

 

Example 2: scan IPs from LAN

Assuming that the network adapters info was revealed, one might be interested to know witch ips are used in one’s LAN. A simple method for doing this would be to compute all possible IPs inside the land and, for each IPs, send an ARP request. If the IP is used, then the corresponding machine will issue an ARP response.
In order to perform a scan, we must know the network mask and the network address. Ussing the previous example, we can find out the netmask and the local IP:

char *pMask = pAdapter->IpAddressList.IpMask.String;
char *pIp = pAdapter->IpAddressList.IpAddress.String

By converting these strings to numerical values and then applying bit-level operation, we can find out the LAN address. Using the netmask and the LAN address, we can iterate all possible IPs from the LAN and send arp requests. In order to do so, we can use a method provided by Ipapi: SendArp, like in the following sample code:

 // Input data:
IPAddr DestIp, IPAddr SrcIp;

DWORD dwRetVal =0;
ULONG MacAddr[2];
ULONG PhysAddrLen = 6;
BYTE *bPhysAddr = NULL;
UINT i = 0;

// Clear the memory zone for the MAC address
memset(&MacAddr, 0xff, sizeof (MacAddr));
// Send the ARP request for the DestIp IP, from the SrcIp. If the Ip is used, then
// the corresponding MAC address will be stored in MacAddr and the size of
// the MAC in PhysAddLen
dwRetVal = SendARP(DestIp, SrcIp, &MacAddr, &PhysAddrLen);

// If the function SendARP is successful - that is if the IP is used, then print the MAC address
if (dwRetVal == NO_ERROR) {
	// The destination IP is used - print the corresponding MAC address
	bPhysAddr = (BYTE *) & MacAddr;
	if (PhysAddrLen) {
		for (i = 0; i < (int) PhysAddrLen; i++) {
			if (i == (PhysAddrLen - 1))
				printf("\t%.2X\n", (int) bPhysAddr[i]);
			else
				printf("\t%.2X-", (int) bPhysAddr[i]);
		}
	}
}

Entry Filed under: Recommandation, Software. .

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


Blogroll

Recent Posts

Categories