Programming/C/C++

내 네트워크상의 모든 컴퓨터 이름 목록과 IP 주소 출력

acidpop 2012. 12. 20. 15:06
반응형

c 코딩으로 만든 내 네트워크 상의 모든 컴퓨터 목록 또는 Local Network 목록을 가져오고

 

그 이름을 가지고 IP 주소까지 얻어오는 코드이다.


#ifndef UNICODE 
#define UNICODE 
#endif 
#pragma comment(lib, "netapi32.lib") 
#include 
#include 
#include 
#include 
#include 
#pragma comment(lib, "ws2_32.lib") // 해당 컴퓨터의 플랫폼 이름 
char* PrintPlatform(DWORD dwPlatformId) 
{ 
	switch(dwPlatformId) 
	{ 
	case PLATFORM_ID_DOS:				return "The MS-DOS platform";
	case PLATFORM_ID_OS2:				return "The OS/2 platform";
	case PLATFORM_ID_NT:				return "The Windows NT platform";
	case PLATFORM_ID_OSF:				return "The OSF lpatform";
	case PLATFORM_ID_VMS:				return "The VMS platform";
	default:							return "Unknown Platform";
	} 
} 

// MSDN 을 참조하였으나 일치 하는 코드가 없는것 같다.
char* Printsv101Type(DWORD dwType) 
{ 
	switch(dwType) 
	{ 
	case SV_TYPE_WORKSTATION:			return "A workstation.";
	case SV_TYPE_SERVER:				return "A server.";
	case SV_TYPE_SQLSERVER:				return "A server running with Microsoft SQL Server.";
	case SV_TYPE_DOMAIN_CTRL:			return "A primary domain controller.";
	case SV_TYPE_DOMAIN_BAKCTRL:		return "A backup domain controller.";
	case SV_TYPE_TIME_SOURCE:			return "A server running the Timesource service.";
	case SV_TYPE_AFP:					return "A server running the Apple Filing Protocol (AFP) file service.";
	case SV_TYPE_NOVELL:				return "A Novell server.";
	case SV_TYPE_DOMAIN_MEMBER:			return "A LAN Manager 2.x domain member.";
	case SV_TYPE_PRINTQ_SERVER:			return "A server that shares a print queue.";
	case SV_TYPE_DIALIN_SERVER:			return "A server that runs a dial-in service.";
	case SV_TYPE_XENIX_SERVER:			return "A Xenix or Unix server.";
	case SV_TYPE_NT:					return "A workstation or server.";
	case SV_TYPE_WFW:					return "A computer that runs Windows for Workgroups.";
	case SV_TYPE_SERVER_MFPN:			return "A server that runs the Microsoft File and Print for NetWare service.";
	case SV_TYPE_SERVER_NT:				return "Any server that is not a domain controller.";
	case SV_TYPE_POTENTIAL_BROWSER:		return "A computer that can run the browser service.";
	case SV_TYPE_BACKUP_BROWSER:		return "A server running a browser service as backup.";
	case SV_TYPE_MASTER_BROWSER:		return "A server running the master browser service.";
	case SV_TYPE_DOMAIN_MASTER:			return "A server running the domain master browser.";
	case SV_TYPE_SERVER_OSF:			return "A computer that runs OSF.";
	case SV_TYPE_SERVER_VMS:			return "A computer that runs VMS.";
	case SV_TYPE_WINDOWS:				return "A computer that runs Windows.";
	case SV_TYPE_DFS:					return "A server that is the root of a DFS tree.";
	case SV_TYPE_CLUSTER_NT:			return "A server cluster available in the domain.";
	case SV_TYPE_TERMINALSERVER:		return "A server that runs the Terminal Server service.";
	case SV_TYPE_CLUSTER_VS_NT:			return "Cluster virtual servers available in the domain.";
	case SV_TYPE_DCE:					return "A server that runs the DCE Directory and Security Services or equivalent.";
	case SV_TYPE_ALTERNATE_XPORT:		return "A server that is returned by an alternate transport.";
	case SV_TYPE_LOCAL_LIST_ONLY:		return "A server that is maintained by the browser.";
	case SV_TYPE_DOMAIN_ENUM:			return "A primary domain.";
	default:							return "Unknown Type";
	} 
} // Write : Acidpop 


void PrintHostIP(wchar_t* szName) 
{ 
	char** pptr = NULL;
	struct hostent *host_entry = NULL;
	char lServerName[256] = "";
	char szIpAddr[256] = "";
	struct in_addr addr; 

	// Acidpop, wchar_t 를 char 형태로 바꾼다. 
	WideCharToMultiByte(CP_ACP, 0, szName, -1, lServerName, 255, NULL, NULL); 

	// struct hostent 를 얻어온다. 
	host_entry = gethostbyname(lServerName); 

	if( host_entry != NULL) 
	{ 
		// 해당 컴퓨터가 n개의 랜카드를 가질 수 있으므로.. 
		for(int i=0 ; host_entry->h_addr_list[i] ; i++) 
		{ 
			// struct in_addr type을 복사하여 IP 주소로 변환한다. 
			memcpy(&addr, host_entry->h_addr_list[i], sizeof(struct in_addr));
			printf("\tIP: %s\n", inet_ntoa(addr));
		} 
	} 
} 


int wmain(int argc, wchar_t * argv[]) 
{
	LPSERVER_INFO_101 pBuf = NULL;
	LPSERVER_INFO_101 pTmpBuf;
	DWORD dwLevel = 101;
	DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
	DWORD dwEntriesRead = 0;
	DWORD dwTotalEntries = 0;
	DWORD dwTotalCount = 0;
	DWORD dwServerType = SV_TYPE_SERVER;
	// all servers 
	DWORD dwResumeHandle = 0;
	NET_API_STATUS nStatus;
	LPWSTR pszServerName = NULL;
	LPWSTR pszDomainName = NULL;
	DWORD i;
	if (argc > 2) 
	{ 
		fwprintf(stderr, L"Usage: %s [DomainName]\n", argv[0]);
		exit(1);
	} // The request is not for the primary domain. // 
	if (argc == 2) 
		pszDomainName = argv[1];
	WSAData wsaData;
	if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) 
	{
		return 255;
	} // 
	// Call the NetServerEnum function to retrieve information 


	// for all servers, specifying information level 101. 
	nStatus = NetServerEnum(pszServerName, dwLevel, (LPBYTE *) & pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries, dwServerType, pszDomainName, &dwResumeHandle);

	// 
	// If the call succeeds, 
	if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA)) 
	{ 
		if ((pTmpBuf = pBuf) != NULL) 
		{ 
			// 
			// Loop through the entries and 
			// print the data for all server types. 
			for (i = 0;i < dwEntriesRead; i++) 
			{ 
				assert(pTmpBuf != NULL);
				if (pTmpBuf == NULL) 
				{ 
					fprintf(stderr, "An access violation has occurred\n");
					break;
				} 
				printf("\tPlatform: %s(%d)\n", PrintPlatform(pTmpBuf->sv101_platform_id), pTmpBuf->sv101_platform_id );
				wprintf(L"\tName: %s\n", pTmpBuf->sv101_name);
				printf("\tVersion: %d.%d\n", pTmpBuf->sv101_version_major, pTmpBuf->sv101_version_minor);
				printf("\tType: %s(%d)\n", Printsv101Type(pTmpBuf->sv101_type), pTmpBuf->sv101_type);
				PrintHostIP(pTmpBuf->sv101_name);

				// Check to see if the server is a domain controller;
				// if so, identify it as a PDC or a BDC. 
				if (pTmpBuf->sv101_type & SV_TYPE_DOMAIN_CTRL) 
					wprintf(L" (PDC)");
				else if (pTmpBuf->sv101_type & SV_TYPE_DOMAIN_BAKCTRL) 
					wprintf(L" (BDC)"); printf("\n"); 


				// Also print the comment associated with the server. 
				wprintf(L"\tComment: %s\n\n", pTmpBuf->sv101_comment); 
				pTmpBuf++; 
				dwTotalCount++; 
			} 

			// Display a warning if all available entries were 
			// not enumerated, print the number actually 
			// enumerated, and the total number available. 
			if (nStatus == ERROR_MORE_DATA) 
			{ 
				fprintf(stderr, "\nMore entries available!!!\n"); fprintf(stderr, "Total entries: %d", dwTotalEntries); 
			} 

			printf("\nEntries enumerated: %d\n", dwTotalCount); 
		} 
		else 
		{ 
			printf("No servers were found\n"); 
			printf("The buffer (bufptr) returned was NULL\n"); 
			printf(" entriesread: %d\n", dwEntriesRead); 
			printf(" totalentries: %d\n", dwEntriesRead); 
		} 
	} 
	else 
		fprintf(stderr, "NetServerEnum failed with error: %d\n", nStatus); 

	// Free the allocated buffer. 
	if (pBuf != NULL) 
		NetApiBufferFree(pBuf); 


	WSACleanup(); 

	return 0;
} 

코드 참조는 MSDN 의 샘플코드를 토대로 IP 부분만 추가한 소스인다.

 

참고 MSDN : ( http://msdn.microsoft.com/en-us/library/windows/desktop/aa370623(v=vs.85).aspx )