Click to See Complete Forum and Search --> : Get Names and IP's on local network.


Nedals
February 13th, 2006, 05:56 PM
I am attempting to get a list of names and ip addresses of all devices connected to my local network. Well actually I'm looking for just one ipaddress whose name is known. The network is using DHCP for most devices.

The code below will return the name and IP of my computer (the one on which this program is running), but I cannot figure out how to get the other devices. The network is linked together with a number of 5 port workgroup switches. My computer and the device I'm looking for are on the same switch, if that makes a difference.

I relatively new to C++ and networking. This code has been assembled from Micro$ and Google searches and, to be honest, I don't fully understand it - especially.... BufferSize/sizeof(NETRESOURCE).

Any help would be appreciated.


// function run in 'main'
void Library::Get_IPs() {

struct hostent *host;
char szHostName[200];

DWORD dwScope = RESOURCE_GLOBALNET; //RESOURCE_CONTEXT;
DWORD dwUsage = RESOURCEUSAGE_CONTAINER;
DWORD dwType = RESOURCETYPE_ANY;

NETRESOURCE *NetResource = NULL;
HANDLE hEnum;

WNetOpenEnum(dwScope, NULL, NULL, NULL, &hEnum);
WSADATA wsaData;
WSAStartup(MAKEWORD(1,1),&wsaData);

if (hEnum) {
DWORD Count = 0xFFFFFFFF;
DWORD BufferSize = 2048;
LPVOID Buffer = new char[2048];

WNetEnumResource(hEnum, &Count, Buffer, &BufferSize);
NetResource = (NETRESOURCE*)Buffer;

for (int i=0; i<BufferSize/sizeof(NETRESOURCE); i++, NetResource++) {
if (NetResource->dwUsage == dwUsage && NetResource->dwType == dwType) {
gethostname(szHostName, strlen(szHostName));
host = gethostbyname(NetResource->lpRemoteName);

printf("My Host name : %s\n", host->h_name );
printf("My Host addr : %s\n", inet_ntoa( *( in_addr *)host->h_addr) );
}
}

delete Buffer;
WNetCloseEnum( hEnum );
}
WSACleanup();
}

Jean-Guy2000
February 14th, 2006, 11:24 AM
To convert an host name into IP address check this out...

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/getnameinfo_2.asp

OR

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/gethostbyaddr_2.asp

depending on if the socket is connected or not. It sounds like you want to list these without connecting to them.

Nedals
February 15th, 2006, 01:33 AM
Thanks for the response.
To convert an IP address into host name check this out...Converting IP to name is not the problem. host->h_name and inet_ntoa( *( in_addr *)host->h_addr) already give me that information.
The code I posted does work, just not the way I want it to.
It sounds like you want to list these without connecting to them.That is correct...
I have a LAN with a number of devices connected to it. I need to get the ACTUAL IP of one device, connected via DHCP, whose name is known. I was under the impression the 'WNetEnumResource' could be used to get that. I have since learned that this function will not work with Win98.

Are there any alternative methods?

Jean-Guy2000
February 15th, 2006, 08:50 AM
Ok so you want to obtain a list of machines currently connected on your network without the C++ application having a list hostnames OR ip address of each machine (read DCHP leases).

Jean-Guy2000
February 15th, 2006, 12:25 PM
Here you go...


#include <windows.h>
#include <assert.h>
#include <stdio.h>
#pragma comment(lib,"mpr")
#pragma comment(lib,"wsock32")

void main()
{
NETRESOURCE *pNetResource;
HANDLE hEnum;
DWORD dwResult;
DWORD dwSize = 16386;
DWORD dwNum;
struct hostent* host = NULL;

WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
{
printf("Failed to start Winsock 2.2\n");
return;
}
dwResult = WNetOpenEnum(RESOURCE_CONTEXT,RESOURCETYPE_ANY,0,NULL,&hEnum);
if(dwResult != 0)
{
printf("WNetOpenEnum failed.\n");
return;
}
pNetResource=(LPNETRESOURCE)GlobalAlloc(GPTR, dwSize);
dwNum=-1;
dwResult = WNetEnumResource( hEnum, &dwNum,pNetResource, &dwSize);
for (DWORD i=0; i < dwNum; i++)
{
if (pNetResource[i].lpRemoteName==NULL)
continue;

char pszGroupName[255];
int iLen = strlen(pNetResource[i].lpRemoteName);
memset(&pszGroupName, 0, sizeof(pszGroupName));
// Remove the "\\" prefix to make it a real hostname.
memcpy(pszGroupName, pNetResource[i].lpRemoteName + 2, iLen - 2);
host = gethostbyname(pszGroupName);
if(host != NULL)
{
printf("%s - %s\n", host->h_name, inet_ntoa( *( in_addr *)host->h_addr) );
}
}
GlobalFree(pNetResource);
WNetCloseEnum(hEnum);
WSACleanup();
}
}

Nedals
February 16th, 2006, 01:08 PM
Jean-Guy2000,
Thanks for the response, but alas it did not work. It compiled and, by adding the following change, I was able to get the script to return my computer's ID and name. So the program is running correctly, just not picking up any other IP's.

if (pNetResource[i].lpRemoteName==NULL) {

// added for testing
char szHostName[200];
gethostname( szHostName, strlen( szHostName ) );
host = gethostbyname(pNetResource->lpRemoteName); //strFullName);
printf("Host name : %s\n", host->h_name );
printf("Host addr : %s\n", inet_ntoa( *( in_addr *)host->h_addr) );
//

continue;
}

As noted in my earlier post, I am running this on a Win98 OS. In the Micro$ site, it mentions that 'WNetOpenEnum' function is NOT supported in Win98, or that was my interpetation. If that is indeed the case, is there some other method.

Jean-Guy2000
February 16th, 2006, 01:44 PM
It must be the case, I tested it on Windows 2000/XP and with computers on a domain controller and running workgroup and it works 100%. I do not have any Win98/ME boxes to test with.

Win98 is difficult to work with network stuff because most of the networking products where not mature at the time Win98 was developed and a lot of API is NT only.

Nedals
February 16th, 2006, 02:07 PM
Thanks again...

If you, or anyone else, happen by a Win98 version, any code would be greatly appreciated.

MikeAThon
February 16th, 2006, 03:56 PM
...As noted in my earlier post, I am running this on a Win98 OS. In the Micro$ site, it mentions that 'WNetOpenEnum' function is NOT supported in Win98, or that was my interpetation...
I am not familiar with these WNet functions, but in the docs for WNetOpenEnum (at http://msdn.microsoft.com/library/en-us/wnet/wnet/wnetopenenum.asp ) it very clearly states that Win98 is supported. Why do you say that it's not?

There's also a link to sample code that "enumerates all resources on the network", at http://msdn.microsoft.com/library/en-us/wnet/wnet/enumerating_network_resources.asp . Does the sample give you any insights?

The sample states that the "code" is not supported under Win98. I don't know what that means, since the functions themselves seem to be supported. My only thought is that in a unicode build there might be problems (for which MSLU might be needed), or that you must call the specifically targetted functions such as WNetOpenEnumW or WNetOpenEnumA.

Incidentally, the code Jean Guy posted uses the RESOURCE_CONTEXT scope, which is supposed to retrieve resources that you can see in an ordinary "Network Neighborhood" view. Can you see the target in Network Neighborhood ? Maybe network topology is the real culprit in your problems.

Mike

Nedals
February 16th, 2006, 06:26 PM
The sample states that the "code" is not supported under Win98. That's where I got the 'NOT supported' comment.
Incidentally, the code Jean Guy posted uses the RESOURCE_CONTEXT scope, which is supposed to retrieve resources that you can see in an ordinary "Network Neighborhood" view. Can you see the target in Network Neighborhood ? Maybe network topology is the real culprit in your problems.Now you are taking me outside my comfort zone. That may be the problem. I CANNOT see the target in Network Neighorhood. In fact, when I click on 'Network' I get back a window with 'Entire Network' and that's it. Clicking on that gives me an error message... 'Unable to browse the network'.

That said, I want to accomplish the task-at-hand (get the IP of the device on the network) without a user having to do any setup. It's highly possible the 'Enumeration' method is the wrong way to go. As I mentioned earlier, I am a novice when it comes to Networking. I learned a few buzz-words but that's where my expertise ends.