#define NL_MAX_DNS_LABEL_LENGTH 63 #include #include #include #include #include #include #include #include #include #include #include #define MAX_PRINTF_LEN 1024 // Arbitrary. VOID NlPrintRoutine( IN DWORD DebugFlag, IN LPSTR Format, ... ) { va_list arglist; char OutputBuffer[MAX_PRINTF_LEN]; // // Put a the information requested by the caller onto the line // va_start(arglist, Format); (VOID) vsprintf(OutputBuffer, Format, arglist); va_end(arglist); printf( "%s", OutputBuffer ); return; UNREFERENCED_PARAMETER( DebugFlag ); } VOID NlAssertFailed( IN PVOID FailedAssertion, IN PVOID FileName, IN ULONG LineNumber, IN PCHAR Message OPTIONAL ) { printf( "\n*** Assertion failed: %s%s\n*** Source File: %s, line %ld\n\n", Message ? Message : "", FailedAssertion, FileName, LineNumber ); } NTSTATUS NlBrowserSendDatagram( IN PVOID ContextDomainInfo, IN ULONG IpAddress, IN LPWSTR UnicodeDestinationName, IN DGRECEIVER_NAME_TYPE NameType, IN LPWSTR TransportName, IN LPSTR OemMailslotName, IN PVOID Buffer, IN ULONG BufferSize ) /*++ Routine Description: Send the specified mailslot message to the specified mailslot on the specified server on the specified transport.. Arguments: DomainInfo - Hosted domain sending the datagram IpAddress - IpAddress of the machine to send the pind to. If zero, UnicodeDestinationName must be specified. UnicodeDestinationName -- Name of the server to send to. NameType -- Type of name represented by UnicodeDestinationName. TransportName -- Name of the transport to send on. Use NULL to send on all transports. OemMailslotName -- Name of the mailslot to send to. Buffer -- Specifies a pointer to the mailslot message to send. BufferSize -- Size in bytes of the mailslot message Return Value: Status of the operation. --*/ { return STATUS_INTERNAL_ERROR; // If this routine is ever needed, copy it from logonsrv\client\getdcnam.c UNREFERENCED_PARAMETER(ContextDomainInfo); UNREFERENCED_PARAMETER(IpAddress); UNREFERENCED_PARAMETER(UnicodeDestinationName); UNREFERENCED_PARAMETER(NameType); UNREFERENCED_PARAMETER(TransportName); UNREFERENCED_PARAMETER(OemMailslotName); UNREFERENCED_PARAMETER(Buffer); UNREFERENCED_PARAMETER(BufferSize); } NET_API_STATUS NlGetLocalPingResponse( IN LPCWSTR NetbiosDomainName OPTIONAL, IN LPCWSTR DnsDomainName OPTIONAL, IN GUID *DomainGuid OPTIONAL, IN PSID DomainSid OPTIONAL, IN BOOL PdcOnly, IN LPCWSTR UnicodeComputerName, IN LPCWSTR UnicodeUserName OPTIONAL, IN ULONG AllowableAccountControlBits, IN ULONG NtVersion, IN ULONG NtVersionFlags, OUT PSOCKET_ADDRESS *ResponseDcAddress, OUT PVOID *Message, OUT PULONG MessageSize ) /*++ Routine Description: Build the message to ping a DC to see if it exists. Arguments: NetbiosDomainName - Netbios Domain Name of the domain to query. DnsDomainName - DNS Domain Name of the domain to query. PdcOnly - True if only the PDC should respond. UnicodeComputerName - Netbios computer name of the machine to respond to. UnicodeUserName - Account name of the user being pinged. If NULL, DC will always respond affirmatively. AllowableAccountControlBits - Mask of allowable account types for UnicodeUserName. NtVersion - Version of the message NtVersionFlags - Version of the message. 0: For backward compatibility. NETLOGON_NT_VERSION_5: for NT 5.0 message. Message - Returns the message to be sent to the DC in question. Buffer must be free using NetpMemoryFree(). MessageSize - Returns the size (in bytes) of the returned message Return Value: NO_ERROR - Operation completed successfully; ERROR_NO_SUCH_DOMAIN - If the machine isn't a DC for the requested domain. ERROR_NOT_ENOUGH_MEMORY - The message could not be allocated. --*/ { // This stub routine simply does nothing harmful return ERROR_NO_SUCH_DOMAIN; UNREFERENCED_PARAMETER( NetbiosDomainName ); UNREFERENCED_PARAMETER( DnsDomainName ); UNREFERENCED_PARAMETER( DomainGuid ); UNREFERENCED_PARAMETER( DomainSid ); UNREFERENCED_PARAMETER( PdcOnly ); UNREFERENCED_PARAMETER( UnicodeComputerName ); UNREFERENCED_PARAMETER( UnicodeUserName ); UNREFERENCED_PARAMETER( AllowableAccountControlBits ); UNREFERENCED_PARAMETER( NtVersion ); UNREFERENCED_PARAMETER( NtVersionFlags ); UNREFERENCED_PARAMETER( ResponseDcAddress ); UNREFERENCED_PARAMETER( Message ); UNREFERENCED_PARAMETER( MessageSize ); } VOID NlpDumpBuffer( IN DWORD DebugFlag, PVOID Buffer, DWORD BufferSize ) /*++ Routine Description: Dumps the buffer content on to the debugger output. Arguments: DebugFlag: Debug flag to pass on to NlPrintRoutine Buffer: buffer pointer. BufferSize: size of the buffer. Return Value: none --*/ { #define NUM_CHARS 16 DWORD i, limit; CHAR TextBuffer[NUM_CHARS + 1]; LPBYTE BufferPtr = Buffer; // // Hex dump of the bytes // limit = ((BufferSize - 1) / NUM_CHARS + 1) * NUM_CHARS; for (i = 0; i < limit; i++) { if (i < BufferSize) { printf("%02x ", BufferPtr[i]); if (BufferPtr[i] < 31 ) { TextBuffer[i % NUM_CHARS] = '.'; } else if (BufferPtr[i] == '\0') { TextBuffer[i % NUM_CHARS] = ' '; } else { TextBuffer[i % NUM_CHARS] = (CHAR) BufferPtr[i]; } } else { printf(0," "); TextBuffer[i % NUM_CHARS] = ' '; } if ((i + 1) % NUM_CHARS == 0) { TextBuffer[NUM_CHARS] = 0; printf(" %s\n", TextBuffer); } } UNREFERENCED_PARAMETER( DebugFlag ); } VOID DoAdd( IN LPWSTR SubnetName, IN LPWSTR SiteName ) { ULONG SubnetAddress; ULONG SubnetMask; BYTE SubnetBitCount; NET_API_STATUS NetStatus; NetStatus = NlParseSubnetString( SubnetName, &SubnetAddress, &SubnetMask, &SubnetBitCount ); if ( NetStatus != NO_ERROR ) { return; } printf( "Doing %ws %8.8lX %8.8lX %ld\n", SubnetName, SubnetAddress, SubnetMask, SubnetBitCount ); NetStatus = NlSitesAddSubnet( SiteName, SubnetName ); if ( NetStatus != NO_ERROR ) { printf("Cannot add site %ws %ws %ld\n", SiteName, SubnetName, NetStatus ); return; } } VOID DoLook( IN LPWSTR IpAddress ) { INT WsaStatus; SOCKADDR SockAddr; INT SockAddrSize; PNL_SITE_ENTRY SiteEntry; // // Convert the address to a sockaddr // SockAddrSize = sizeof(SockAddr); WsaStatus = WSAStringToAddressW( IpAddress, AF_INET, NULL, (PSOCKADDR)&SockAddr, &SockAddrSize ); if ( WsaStatus != 0 ) { WsaStatus = WSAGetLastError(); printf("DoLook: %ws: Wsa Error %ld\n", IpAddress, WsaStatus ); return; } if ( SockAddr.sa_family != AF_INET ) { printf("DoLook: %ws: address not AF_INET\n", IpAddress ); return; } SiteEntry = NlFindSiteEntryBySockAddr( &SockAddr ); if ( SiteEntry == NULL ) { printf("DoLook: %ws: address cannot be found\n", IpAddress ); return; } printf("%ws is in site %ws\n", IpAddress, SiteEntry->SiteName ); NlDerefSiteEntry( SiteEntry ); } __cdecl main (int argc, char *argv[]) { NET_API_STATUS NetStatus; PNL_SITE_ENTRY Site1; PNL_SITE_ENTRY Site2; PNL_SITE_ENTRY Site3; WORD wVersionRequested; WSADATA wsaData; int err; // // Initialize winsock. // wVersionRequested = MAKEWORD( 1, 1 ); NetStatus = WSAStartup( wVersionRequested, &wsaData ); if ( NetStatus != 0 ) { printf( "NETAPI32.DLL: Cannot initialize winsock %ld.\n", NetStatus ); return NetStatus; } if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) { WSACleanup(); printf( "NETAPI32.DLL: Wrong winsock version %ld.\n", wsaData.wVersion ); return WSANOTINITIALISED; } // // Init NetStatus = NlSiteInitialize(); if ( NetStatus != NO_ERROR ) { printf( "Cannot NlSiteInitialize %ld\n", NetStatus ); return 1; } #ifdef notdef // // Add some sites. // Site1 = NlFindSiteEntry( L"Site 1" ); if ( Site1 == NULL ) { printf( "Cannot Create Site1\n"); return 1; } printf( "%lx: %ws\n", Site1, Site1->SiteName ); Site2 = NlFindSiteEntry( L"Site 1" ); if ( Site2 == NULL ) { printf( "Cannot Create Site2\n"); return 2; } printf( "%lx: %ws\n", Site2, Site2->SiteName ); Site3 = NlFindSiteEntry( L"Site 3" ); if ( Site3 == NULL ) { printf( "Cannot Create Site3\n"); return 3; } printf( "%lx: %ws\n", Site3, Site3->SiteName ); NlDerefSiteEntry( Site1 ); NlDerefSiteEntry( Site2 ); NlDerefSiteEntry( Site3 ); #endif // notdef // // Test invalid subnet strings // #ifdef notdef DoAdd( L"999.0.0.0/1", L"Site 1" ); DoAdd( L"1.0.0.0/0", L"Site 1" ); DoAdd( L"1.0.0.0/1", L"Site 1" ); DoAdd( L"1.0.0.0/33", L"Site 1" ); DoAdd( L"1.0.0.0/1p", L"Site 1" ); DoAdd( L"1.0.0.0", L"Site 1" ); DoAdd( L"128.0.0.0/1", L"Site 1" ); DoAdd( L"128.0.0.0/2", L"Site 1" ); DoAdd( L"128.0.0.0/3", L"Site 1" ); DoAdd( L"128.0.0.0/4", L"Site 1" ); DoAdd( L"128.0.0.0/5", L"Site 1" ); DoAdd( L"128.0.0.0/6", L"Site 1" ); DoAdd( L"128.0.0.0/7", L"Site 1" ); DoAdd( L"128.0.0.0/8", L"Site 1" ); DoAdd( L"128.0.0.0/9", L"Site 1" ); DoAdd( L"128.0.0.0/10", L"Site 1" ); DoAdd( L"128.0.0.0/11", L"Site 1" ); DoAdd( L"128.0.0.0/12", L"Site 1" ); DoAdd( L"128.0.0.0/13", L"Site 1" ); DoAdd( L"128.0.0.0/14", L"Site 1" ); DoAdd( L"128.0.0.0/15", L"Site 1" ); DoAdd( L"128.0.0.0/16", L"Site 1" ); DoAdd( L"128.0.0.0/17", L"Site 1" ); DoAdd( L"128.0.0.0/18", L"Site 1" ); DoAdd( L"128.0.0.0/19", L"Site 1" ); DoAdd( L"128.0.0.0/20", L"Site 1" ); DoAdd( L"128.0.0.0/21", L"Site 1" ); DoAdd( L"128.0.0.0/22", L"Site 1" ); DoAdd( L"128.0.0.0/23", L"Site 1" ); DoAdd( L"128.0.0.0/24", L"Site 1" ); DoAdd( L"128.0.0.0/25", L"Site 1" ); DoAdd( L"128.0.0.0/26", L"Site 1" ); DoAdd( L"128.0.0.0/27", L"Site 1" ); DoAdd( L"128.0.0.0/28", L"Site 1" ); DoAdd( L"128.0.0.0/29", L"Site 1" ); DoAdd( L"128.0.0.0/30", L"Site 1" ); DoAdd( L"128.0.0.0/31", L"Site 1" ); DoAdd( L"128.0.0.0/32", L"Site 1" ); #endif // notdef { ULONG i; for ( i=0; i<2; i++ ) { DoAdd( L"128.0.0.0/8", L"Site 1" ); DoAdd( L"128.0.0.0/7", L"Site 2" ); DoAdd( L"128.0.0.0/8", L"Site 3" ); // DoAdd( L"128.0.0.0/1", L"Site 4" ); DoAdd( L"157.55.0.0/16", L"Site 5" ); DoAdd( L"157.55.80.0/20", L"Site 6" ); NlSitesEndSubnetEnum(); } } DoLook( L"157.55.95.68" ); DoLook( L"157.55.24.68" ); #ifdef notdef DoAdd( L"157.55.0.0/16", L"Site 1" ); DoAdd( L"157.55.240.0/20", L"Site 1" ); DoAdd( L"128.0.0.0/1", L"Site 1" ); #endif // notdef // // Done. // NlSiteTerminate(); printf( "Done\n" ); return 0; }