TDI_STATUS InfoTdiSetRoute(PIP_INTERFACE IF, PVOID Buffer, UINT BufferSize) { IP_ADDRESS Address, Netmask, Router; PIPROUTE_ENTRY Route = Buffer; AddrInitIPv4( &Address, Route->Dest ); AddrInitIPv4( &Netmask, Route->Mask ); AddrInitIPv4( &Router, Route->Gw ); if (!Buffer || BufferSize < sizeof(IPROUTE_ENTRY)) return TDI_INVALID_PARAMETER; if (IF == Loopback) { DbgPrint("Failing attempt to add route to loopback adapter\n"); return TDI_INVALID_PARAMETER; } if( Route->Type == IP_ROUTE_TYPE_ADD ) { /* Add the route */ TI_DbgPrint(DEBUG_INFO,("Adding route (%s)\n", A2S(&Address))); if (!RouterCreateRoute( &Address, &Netmask, &Router, IF, Route->Metric1)) return TDI_NO_RESOURCES; return TDI_SUCCESS; } else if( Route->Type == IP_ROUTE_TYPE_DEL ) { TI_DbgPrint(DEBUG_INFO,("Removing route (%s)\n", A2S(&Address))); if (NT_SUCCESS(RouterRemoveRoute( &Address, &Router ))) return TDI_SUCCESS; else return TDI_INVALID_PARAMETER; } return TDI_INVALID_REQUEST; }
NTSTATUS RouterRemoveRoute(PIP_ADDRESS Target, PIP_ADDRESS Router) /* * FUNCTION: Removes a route from the Forward Information Base (FIB) * ARGUMENTS: * Target: The machine or network targeted by the route * Router: The router used to pass the packet to the destination * * Searches the FIB and removes a route matching the indicated parameters. */ { KIRQL OldIrql; PLIST_ENTRY CurrentEntry; PLIST_ENTRY NextEntry; PFIB_ENTRY Current; BOOLEAN Found = FALSE; PNEIGHBOR_CACHE_ENTRY NCE; TI_DbgPrint(DEBUG_ROUTER, ("Called\n")); TI_DbgPrint(DEBUG_ROUTER, ("Deleting Route From: %s\n", A2S(Router))); TI_DbgPrint(DEBUG_ROUTER, (" To: %s\n", A2S(Target))); TcpipAcquireSpinLock(&FIBLock, &OldIrql); RouterDumpRoutes(); CurrentEntry = FIBListHead.Flink; while (CurrentEntry != &FIBListHead) { NextEntry = CurrentEntry->Flink; Current = CONTAINING_RECORD(CurrentEntry, FIB_ENTRY, ListEntry); NCE = Current->Router; if( AddrIsEqual( &Current->NetworkAddress, Target ) && AddrIsEqual( &NCE->Address, Router ) ) { Found = TRUE; break; } Current = NULL; CurrentEntry = NextEntry; } if( Found ) { TI_DbgPrint(DEBUG_ROUTER, ("Deleting route\n")); DestroyFIBE( Current ); } RouterDumpRoutes(); TcpipReleaseSpinLock(&FIBLock, OldIrql); TI_DbgPrint(DEBUG_ROUTER, ("Leaving\n")); return Found ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; }
PFIB_ENTRY RouterAddRoute( PIP_ADDRESS NetworkAddress, PIP_ADDRESS Netmask, PNEIGHBOR_CACHE_ENTRY Router, UINT Metric) /* * FUNCTION: Adds a route to the Forward Information Base (FIB) * ARGUMENTS: * NetworkAddress = Pointer to address of network * Netmask = Pointer to netmask of network * Router = Pointer to NCE of router to use * Metric = Cost of this route * RETURNS: * Pointer to FIB entry if the route was added, NULL if not * NOTES: * The FIB entry references the NetworkAddress, Netmask and * the NCE of the router. The caller is responsible for providing * these references */ { PFIB_ENTRY FIBE; TI_DbgPrint(DEBUG_ROUTER, ("Called. NetworkAddress (0x%X) Netmask (0x%X) " "Router (0x%X) Metric (%d).\n", NetworkAddress, Netmask, Router, Metric)); TI_DbgPrint(DEBUG_ROUTER, ("NetworkAddress (%s) Netmask (%s) Router (%s).\n", A2S(NetworkAddress), A2S(Netmask), A2S(&Router->Address))); FIBE = ExAllocatePoolWithTag(NonPagedPool, sizeof(FIB_ENTRY), FIB_TAG); if (!FIBE) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NULL; } RtlCopyMemory( &FIBE->NetworkAddress, NetworkAddress, sizeof(FIBE->NetworkAddress) ); RtlCopyMemory( &FIBE->Netmask, Netmask, sizeof(FIBE->Netmask) ); FIBE->Router = Router; FIBE->Metric = Metric; /* Add FIB to the forward information base */ TcpipInterlockedInsertTailList(&FIBListHead, &FIBE->ListEntry, &FIBLock); return FIBE; }
VOID NBResetNeighborTimeout(PIP_ADDRESS Address) { KIRQL OldIrql; UINT HashValue; PNEIGHBOR_CACHE_ENTRY NCE; TI_DbgPrint(DEBUG_NCACHE, ("Resetting NCE timout for 0x%s\n", A2S(Address))); HashValue = *(PULONG)(&Address->Address); HashValue ^= HashValue >> 16; HashValue ^= HashValue >> 8; HashValue ^= HashValue >> 4; HashValue &= NB_HASHMASK; TcpipAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql); for (NCE = NeighborCache[HashValue].Cache; NCE != NULL; NCE = NCE->Next) { if (AddrIsEqual(Address, &NCE->Address)) { NCE->EventCount = 0; break; } } TcpipReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql); }
static afs_status_t DoesAPartitionExist(BOOL& bExists) { g_LogFile.Write("Does a partition exist on this machine: "); bExists = FALSE; afs_status_t nStatus; int nResult = ReadPartitionTable(&nStatus); if (!nResult) return nStatus; int nNumPartitions = 0; cfg_partitionEntry_t *pTable = GetPartitionTable(nNumPartitions); bExists = nNumPartitions > 0; if (bExists) { g_CfgData.chDeviceName = pTable->deviceName[0]; lstrcpy(g_CfgData.szPartitionName, ((TCHAR *)A2S(pTable->partitionName)) + lstrlen(TEXT("/vicep"))); } g_LogFile.WriteBoolResult(bExists); return 0; }
/* * NOTE: This function has an important side effect. If this machine * is not the first in a new cell, then this function will get the * cell name from the config info. The cell name may be needed in * config calls that come later, and so this function must be called * before they are. */ static int IsConfigInfoValid(BOOL& bValid, afs_status_t& nStatus) { if (bCancel) return FALSE; afs_status_t configStatus; char *pszCellName = 0; NextStep(IDS_CHECK_CONFIG_INFO); bValid = FALSE; g_LogFile.Write("Is there valid configuration information on this machine: "); int nResult = cfg_HostQueryStatus(GetHostnameA(), &configStatus, &pszCellName, &nStatus); if (!nResult) return FALSE; g_LogFile.WriteBoolResult((configStatus == 0)); if (configStatus == 0) lstrncpy(g_CfgData.szCellName, A2S(pszCellName), MAX_CELL_NAME_LEN); else g_LogFile.WriteError("The configuration information on this host is not valid", configStatus); bValid = (BOOL)(configStatus == 0); return TRUE; }
PFIB_ENTRY RouterCreateRoute( PIP_ADDRESS NetworkAddress, PIP_ADDRESS Netmask, PIP_ADDRESS RouterAddress, PIP_INTERFACE Interface, UINT Metric) /* * FUNCTION: Creates a route with IPv4 addresses as parameters * ARGUMENTS: * NetworkAddress = Address of network * Netmask = Netmask of network * RouterAddress = Address of router to use * NTE = Pointer to NTE to use * Metric = Cost of this route * RETURNS: * Pointer to FIB entry if the route was created, NULL if not. * The FIB entry references the NTE. The caller is responsible * for providing this reference */ { KIRQL OldIrql; PLIST_ENTRY CurrentEntry; PLIST_ENTRY NextEntry; PFIB_ENTRY Current; PNEIGHBOR_CACHE_ENTRY NCE; TcpipAcquireSpinLock(&FIBLock, &OldIrql); CurrentEntry = FIBListHead.Flink; while (CurrentEntry != &FIBListHead) { NextEntry = CurrentEntry->Flink; Current = CONTAINING_RECORD(CurrentEntry, FIB_ENTRY, ListEntry); NCE = Current->Router; if( AddrIsEqual(NetworkAddress, &Current->NetworkAddress) && AddrIsEqual(Netmask, &Current->Netmask) ) { TI_DbgPrint(DEBUG_ROUTER,("Attempting to add duplicate route to %s\n", A2S(NetworkAddress))); TcpipReleaseSpinLock(&FIBLock, OldIrql); return NULL; } CurrentEntry = NextEntry; } TcpipReleaseSpinLock(&FIBLock, OldIrql); /* The NCE references RouterAddress. The NCE is referenced for us */ NCE = NBFindOrCreateNeighbor(Interface, RouterAddress); if (!NCE) { /* Not enough free resources */ return NULL; } return RouterAddRoute(NetworkAddress, Netmask, NCE, Metric); }
void RouterDumpRoutes() { PLIST_ENTRY CurrentEntry; PLIST_ENTRY NextEntry; PFIB_ENTRY Current; PNEIGHBOR_CACHE_ENTRY NCE; TI_DbgPrint(DEBUG_ROUTER,("Dumping Routes\n")); CurrentEntry = FIBListHead.Flink; while (CurrentEntry != &FIBListHead) { NextEntry = CurrentEntry->Flink; Current = CONTAINING_RECORD(CurrentEntry, FIB_ENTRY, ListEntry); NCE = Current->Router; TI_DbgPrint(DEBUG_ROUTER,("Examining FIBE %x\n", Current)); TI_DbgPrint(DEBUG_ROUTER,("... NetworkAddress %s\n", A2S(&Current->NetworkAddress))); TI_DbgPrint(DEBUG_ROUTER,("... NCE->Address . %s\n", A2S(&NCE->Address))); CurrentEntry = NextEntry; } TI_DbgPrint(DEBUG_ROUTER,("Dumping Routes ... Done\n")); }
PNEIGHBOR_CACHE_ENTRY RouteGetRouteToDestination(PIP_ADDRESS Destination) /* * FUNCTION: Locates an RCN describing a route to a destination address * ARGUMENTS: * Destination = Pointer to destination address to find route to * RCN = Address of pointer to an RCN * RETURNS: * Status of operation * NOTES: * The RCN is referenced for the caller. The caller is responsible * for dereferencing it after use */ { PNEIGHBOR_CACHE_ENTRY NCE = NULL; PIP_INTERFACE Interface; TI_DbgPrint(DEBUG_RCACHE, ("Called. Destination (0x%X)\n", Destination)); TI_DbgPrint(DEBUG_RCACHE, ("Destination (%s)\n", A2S(Destination))); #if 0 TI_DbgPrint(MIN_TRACE, ("Displaying tree (before).\n")); PrintTree(RouteCache); #endif /* Check if the destination is on-link */ Interface = FindOnLinkInterface(Destination); if (Interface) { /* The destination address is on-link. Check our neighbor cache */ NCE = NBFindOrCreateNeighbor(Interface, Destination); } else { /* Destination is not on any subnets we're on. Find a router to use */ NCE = RouterGetRoute(Destination); } if( NCE ) TI_DbgPrint(DEBUG_ROUTER,("Interface->MTU: %d\n", NCE->Interface->MTU)); return NCE; }
PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor( PIP_INTERFACE Interface, PIP_ADDRESS Address, BOOLEAN NoTimeout) /* * FUNCTION: Tries to find a neighbor and if unsuccesful, creates a new NCE * ARGUMENTS: * Interface = Pointer to interface to use (in case NCE is not found) * Address = Pointer to IP address * RETURNS: * Pointer to NCE, NULL if there is not enough free resources * NOTES: * The NCE is referenced if found or created. The caller is * responsible for dereferencing it again after use */ { PNEIGHBOR_CACHE_ENTRY NCE; TI_DbgPrint(DEBUG_NCACHE, ("Called. Interface (0x%X) Address (0x%X).\n", Interface, Address)); NCE = NBLocateNeighbor(Address, Interface); if (NCE == NULL) { TI_DbgPrint(MID_TRACE,("BCAST: %s\n", A2S(&Interface->Broadcast))); if( AddrIsEqual(Address, &Interface->Broadcast) || AddrIsUnspecified(Address) ) { TI_DbgPrint(MID_TRACE,("Packet targeted at broadcast addr\n")); NCE = NBAddNeighbor(Interface, Address, NULL, Interface->AddressLength, NUD_PERMANENT, 0); } else { NCE = NBAddNeighbor(Interface, Address, NULL, Interface->AddressLength, NUD_INCOMPLETE, NoTimeout ? 0 : ARP_INCOMPLETE_TIMEOUT); if (!NCE) return NULL; NBSendSolicit(NCE); } } return NCE; }
static BOOL AreWeLastDBServer(BOOL& bLast, afs_status_t& nStatus) { ASSERT(g_CfgData.szHostname[0]); char *pszCellname = 0; char *pszCellServDB = 0; bLast = FALSE; g_LogFile.Write("Checking if this machine is the last DB server in the cell.\r\n"); g_LogFile.Write("Getting CellServDB from host %s.\r\n", GetHostnameA()); int nResult = cfg_CellServDbEnumerate(GetHostnameA(), &pszCellname, &pszCellServDB, &nStatus); if (!nResult) return FALSE; if (!pszCellServDB) { g_LogFile.Write("There are no DB servers in CellServDB!!!!!"); ASSERT(FALSE); // This should not be possible return FALSE; } char *psz = pszCellServDB; int i; for (i = 0; *psz; psz += strlen(psz) + 1) i++; if (i == 1) { ASSERT(lstrcmp(g_CfgData.szHostname, A2S(pszCellServDB)) == 0); g_LogFile.Write("This machine IS the last DB server in the cell.\r\n"); bLast = TRUE; } else g_LogFile.Write("This machine is NOT the last DB server in the cell.\r\n"); return TRUE; }
static BOOL IsClientConfigured(BOOL& bConfigured, afs_status_t& nStatus) { if (bCancel) return FALSE; bConfigured = FALSE; NextStep(IDS_CHECK_AFS_CLIENT); short isInstalled; afs_status_t configStatus; char *pszCellName = 0; g_LogFile.Write("Is the AFS Client installed on this machine: "); if (!cfg_ClientQueryStatus(GetHostnameA(), &isInstalled, &g_CfgData.nClientVersion, &configStatus, &pszCellName, &nStatus)) { ImmediateErrorDialog(nStatus, IDS_ERROR_AFS_CLIENT_CHECK); return FALSE; } g_LogFile.WriteBoolResult((BOOL)isInstalled); bConfigured = (BOOL)(configStatus == 0); if (bConfigured) lstrncpy(g_CfgData.szClientCellName, A2S(pszCellName), MAX_CELL_NAME_LEN); else g_LogFile.WriteError("The client configuration information on this host is not valid", configStatus); if (!isInstalled) { g_LogFile.Write("ERROR: AFS Client is not installed. The AFS Server requires the AFS Client.\r\n"); ImmediateErrorDialog(0, IDS_ERROR_AFS_CLIENT_NOT_INSTALLED); nStatus = -1; // Just need something nonzero return FALSE; } return TRUE; }
/* * Event Handler Functions _________________________________________________________________ * */ static void OnInitDialog(HWND hwndDlg) { hDlg = hwndDlg; bAdvanced = TRUE; TCHAR szNumProcesses[32]; _itot(DEFAULT_NUM_PROCESSES, szNumProcesses, 10); SetWndText(hDlg, IDC_NUM_PROCESSES, szNumProcesses); SetCheck(hDlg, IDC_NUM_PROCESSES_CHECKBOX); SetWndText(hDlg, IDC_LOG_FILE, A2S(DEFAULT_LOG_FILE)); // If a partition name isn't selected, then only allow the salvage server option if (szPartitionName[0] == 0) { SetEnable(hDlg, IDC_PARTITION, ES_DISABLE); SetEnable(hDlg, IDC_VOLUME, ES_DISABLE); SetCheck(hDlg, IDC_SERVER); } else SetCheck(hDlg, IDC_PARTITION); // Close the Advanced portion of the dialog OnAdvanced(); }
/* * FUNCTION: Open an address file object * ARGUMENTS: * Request = Pointer to TDI request structure for this request * Address = Pointer to address to be opened * Protocol = Protocol on which to open the address * Shared = Specifies if the address is opened for shared access * Options = Pointer to option buffer * RETURNS: * Status of operation */ NTSTATUS FileOpenAddress( PTDI_REQUEST Request, PTA_IP_ADDRESS Address, USHORT Protocol, BOOLEAN Shared, PVOID Options) { PADDRESS_FILE AddrFile; TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol)); /* If it's shared and has a port specified, look for a match */ if ((Shared != FALSE) && (Address->Address[0].Address[0].sin_port != 0)) { AddrFile = AddrFindShared(NULL, Address->Address[0].Address[0].sin_port, Protocol); if (AddrFile != NULL) { Request->Handle.AddressHandle = AddrFile; return STATUS_SUCCESS; } } AddrFile = ExAllocatePoolWithTag(NonPagedPool, sizeof(ADDRESS_FILE), ADDR_FILE_TAG); if (!AddrFile) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(AddrFile, sizeof(ADDRESS_FILE)); AddrFile->RefCount = 1; AddrFile->Free = AddrFileFree; AddrFile->Sharers = 1; /* Set our default options */ AddrFile->TTL = 128; AddrFile->DF = 0; AddrFile->BCast = 1; AddrFile->HeaderIncl = 1; /* Make sure address is a local unicast address or 0 */ /* FIXME: IPv4 only */ AddrFile->Family = Address->Address[0].AddressType; AddrFile->Address.Address.IPv4Address = Address->Address[0].Address[0].in_addr; AddrFile->Address.Type = IP_ADDRESS_V4; if (!AddrIsUnspecified(&AddrFile->Address) && !AddrLocateInterface(&AddrFile->Address)) { TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", A2S(&AddrFile->Address))); ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); return STATUS_INVALID_ADDRESS; } TI_DbgPrint(MID_TRACE, ("Opening address %s for communication (P=%d U=%d).\n", A2S(&AddrFile->Address), Protocol, IPPROTO_UDP)); /* Protocol specific handling */ switch (Protocol) { case IPPROTO_TCP: if (Address->Address[0].Address[0].sin_port) { /* The client specified an explicit port so we force a bind to this */ AddrFile->Port = TCPAllocatePort(Address->Address[0].Address[0].sin_port); /* Check for bind success */ if (AddrFile->Port == 0xffff) { ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); return STATUS_ADDRESS_ALREADY_EXISTS; } /* Sanity check */ ASSERT(Address->Address[0].Address[0].sin_port == AddrFile->Port); } else if (!AddrIsUnspecified(&AddrFile->Address)) { /* The client is trying to bind to a local address so allocate a port now too */ AddrFile->Port = TCPAllocatePort(0); /* Check for bind success */ if (AddrFile->Port == 0xffff) { ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); return STATUS_ADDRESS_ALREADY_EXISTS; } } else { /* The client wants an unspecified port with an unspecified address so we wait to see what the TCP library gives us */ AddrFile->Port = 0; } AddEntity(CO_TL_ENTITY, AddrFile, CO_TL_TCP); AddrFile->Send = NULL; /* TCPSendData */ break; case IPPROTO_UDP: TI_DbgPrint(MID_TRACE,("Allocating udp port\n")); AddrFile->Port = UDPAllocatePort(Address->Address[0].Address[0].sin_port); if ((Address->Address[0].Address[0].sin_port && AddrFile->Port != Address->Address[0].Address[0].sin_port) || AddrFile->Port == 0xffff) { ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); return STATUS_ADDRESS_ALREADY_EXISTS; } TI_DbgPrint(MID_TRACE,("Setting port %d (wanted %d)\n", AddrFile->Port, Address->Address[0].Address[0].sin_port)); AddEntity(CL_TL_ENTITY, AddrFile, CL_TL_UDP); AddrFile->Send = UDPSendDatagram; break; case IPPROTO_ICMP: AddrFile->Port = 0; AddrFile->Send = ICMPSendDatagram; /* FIXME: Verify this */ AddEntity(ER_ENTITY, AddrFile, ER_ICMP); break; default: /* Use raw IP for all other protocols */ AddrFile->Port = 0; AddrFile->Send = RawIPSendDatagram; /* FIXME: Verify this */ AddEntity(CL_TL_ENTITY, AddrFile, 0); break; } TI_DbgPrint(MID_TRACE, ("IP protocol number for address file object is %d.\n", Protocol)); TI_DbgPrint(MID_TRACE, ("Port number for address file object is %d.\n", WN2H(AddrFile->Port))); /* Set protocol */ AddrFile->Protocol = Protocol; /* Initialize receive and transmit queues */ InitializeListHead(&AddrFile->ReceiveQueue); InitializeListHead(&AddrFile->TransmitQueue); /* Initialize spin lock that protects the address file object */ KeInitializeSpinLock(&AddrFile->Lock); /* Return address file object */ Request->Handle.AddressHandle = AddrFile; /* Add address file to global list */ ExInterlockedInsertTailList( &AddressFileListHead, &AddrFile->ListEntry, &AddressFileListLock); TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); return STATUS_SUCCESS; }
/* * FUNCTION: Searches through address file entries to find next match * ARGUMENTS: * SearchContext = Pointer to search context * RETURNS: * Pointer to referenced address file, NULL if none was found */ PADDRESS_FILE AddrSearchNext( PAF_SEARCH SearchContext) { PLIST_ENTRY CurrentEntry; PIP_ADDRESS IPAddress; KIRQL OldIrql; PADDRESS_FILE Current = NULL; BOOLEAN Found = FALSE; PADDRESS_FILE StartingAddrFile; TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql); if (SearchContext->Next == &AddressFileListHead) { TcpipReleaseSpinLock(&AddressFileListLock, OldIrql); return NULL; } /* Save this pointer so we can dereference it later */ StartingAddrFile = CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry); CurrentEntry = SearchContext->Next; while (CurrentEntry != &AddressFileListHead) { Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_FILE, ListEntry); IPAddress = &Current->Address; TI_DbgPrint(DEBUG_ADDRFILE, ("Comparing: ((%d, %d, %s), (%d, %d, %s)).\n", WN2H(Current->Port), Current->Protocol, A2S(IPAddress), WN2H(SearchContext->Port), SearchContext->Protocol, A2S(SearchContext->Address))); /* See if this address matches the search criteria */ if ((Current->Port == SearchContext->Port) && (Current->Protocol == SearchContext->Protocol) && (AddrReceiveMatch(IPAddress, SearchContext->Address))) { /* We've found a match */ Found = TRUE; break; } CurrentEntry = CurrentEntry->Flink; } if (Found) { SearchContext->Next = CurrentEntry->Flink; if (SearchContext->Next != &AddressFileListHead) { /* Reference the next address file to prevent the link from disappearing behind our back */ ReferenceObject(CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry)); } /* Reference the returned address file before dereferencing the starting * address file because it may be that Current == StartingAddrFile */ ReferenceObject(Current); } else Current = NULL; DereferenceObject(StartingAddrFile); TcpipReleaseSpinLock(&AddressFileListLock, OldIrql); return Current; }
VOID LogActiveObjects(VOID) { #ifdef LOG_OBJECTS PLIST_ENTRY CurrentEntry; KIRQL OldIrql; PADDRESS_FILE AddrFile; PCONNECTION_ENDPOINT Conn; DbgPrint("----------- TCP/IP Active Object Dump -------------\n"); TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql); CurrentEntry = AddressFileListHead.Flink; while (CurrentEntry != &AddressFileListHead) { AddrFile = CONTAINING_RECORD(CurrentEntry, ADDRESS_FILE, ListEntry); DbgPrint("Address File (%s, %d, %d) @ 0x%p | Ref count: %d | Sharers: %d\n", A2S(&AddrFile->Address), WN2H(AddrFile->Port), AddrFile->Protocol, AddrFile, AddrFile->RefCount, AddrFile->Sharers); DbgPrint("\tListener: "); if (AddrFile->Listener == NULL) DbgPrint("<None>\n"); else DbgPrint("0x%p\n", AddrFile->Listener); DbgPrint("\tAssociated endpoints: "); if (AddrFile->Connection == NULL) DbgPrint("<None>\n"); else { Conn = AddrFile->Connection; while (Conn) { DbgPrint("0x%p ", Conn); Conn = Conn->Next; } DbgPrint("\n"); } CurrentEntry = CurrentEntry->Flink; } TcpipReleaseSpinLock(&AddressFileListLock, OldIrql); TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); CurrentEntry = ConnectionEndpointListHead.Flink; while (CurrentEntry != &ConnectionEndpointListHead) { Conn = CONTAINING_RECORD(CurrentEntry, CONNECTION_ENDPOINT, ListEntry); DbgPrint("Connection @ 0x%p | Ref count: %d\n", Conn, Conn->RefCount); DbgPrint("\tPCB: "); if (Conn->SocketContext == NULL) DbgPrint("<None>\n"); else { DbgPrint("0x%p\n", Conn->SocketContext); LibTCPDumpPcb(Conn->SocketContext); } DbgPrint("\tPacket queue status: %s\n", IsListEmpty(&Conn->PacketQueue) ? "Empty" : "Not Empty"); DbgPrint("\tRequest lists: Connect: %s | Recv: %s | Send: %s | Shutdown: %s | Listen: %s\n", IsListEmpty(&Conn->ConnectRequest) ? "Empty" : "Not Empty", IsListEmpty(&Conn->ReceiveRequest) ? "Empty" : "Not Empty", IsListEmpty(&Conn->SendRequest) ? "Empty" : "Not Empty", IsListEmpty(&Conn->ShutdownRequest) ? "Empty" : "Not Empty", IsListEmpty(&Conn->ListenRequest) ? "Empty" : "Not Empty"); DbgPrint("\tSend shutdown: %s\n", Conn->SendShutdown ? "Yes" : "No"); DbgPrint("\tReceive shutdown: %s\n", Conn->ReceiveShutdown ? "Yes" : "No"); if (Conn->ReceiveShutdown) DbgPrint("\tReceive shutdown status: 0x%x\n", Conn->ReceiveShutdownStatus); DbgPrint("\tClosing: %s\n", Conn->Closing ? "Yes" : "No"); CurrentEntry = CurrentEntry->Flink; } TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); DbgPrint("---------------------------------------------------\n"); #endif }
PNEIGHBOR_CACHE_ENTRY RouterGetRoute(PIP_ADDRESS Destination) /* * FUNCTION: Finds a router to use to get to Destination * ARGUMENTS: * Destination = Pointer to destination address (NULL means don't care) * RETURNS: * Pointer to NCE for router, NULL if none was found * NOTES: * If found the NCE is referenced */ { KIRQL OldIrql; PLIST_ENTRY CurrentEntry; PLIST_ENTRY NextEntry; PFIB_ENTRY Current; UCHAR State, BestState = 0; UINT Length, BestLength = 0, MaskLength; PNEIGHBOR_CACHE_ENTRY NCE, BestNCE = NULL; TI_DbgPrint(DEBUG_ROUTER, ("Called. Destination (0x%X)\n", Destination)); TI_DbgPrint(DEBUG_ROUTER, ("Destination (%s)\n", A2S(Destination))); TcpipAcquireSpinLock(&FIBLock, &OldIrql); CurrentEntry = FIBListHead.Flink; while (CurrentEntry != &FIBListHead) { NextEntry = CurrentEntry->Flink; Current = CONTAINING_RECORD(CurrentEntry, FIB_ENTRY, ListEntry); NCE = Current->Router; State = NCE->State; Length = CommonPrefixLength(Destination, &Current->NetworkAddress); MaskLength = AddrCountPrefixBits(&Current->Netmask); TI_DbgPrint(DEBUG_ROUTER,("This-Route: %s (Sharing %d bits)\n", A2S(&NCE->Address), Length)); if(Length >= MaskLength && (Length > BestLength || !BestNCE) && (!(State & NUD_STALE) || !BestNCE)) { /* This seems to be a better router */ BestNCE = NCE; BestLength = Length; BestState = State; TI_DbgPrint(DEBUG_ROUTER,("Route selected\n")); } CurrentEntry = NextEntry; } TcpipReleaseSpinLock(&FIBLock, OldIrql); if( BestNCE ) { TI_DbgPrint(DEBUG_ROUTER,("Routing to %s\n", A2S(&BestNCE->Address))); } else { TI_DbgPrint(DEBUG_ROUTER,("Packet won't be routed\n")); } return BestNCE; }