NTSTATUS LpxTdiGetAddressList_LSTrans( IN PTA_LSTRANS_ADDRESS AddressList ) { SOCKETLPX_ADDRESS_LIST socketLpxAddressList; NTSTATUS status; LONG idx_addr; status = LpxTdiGetAddressList(&socketLpxAddressList); if(!NT_SUCCESS(status)) goto error_out; // // translate LPX address list into LSTrans address list. // AddressList->TAAddressCount = socketLpxAddressList.iAddressCount; for(idx_addr= 0; idx_addr < socketLpxAddressList.iAddressCount; idx_addr ++) { AddressList->Address[idx_addr].AddressType = TDI_ADDRESS_TYPE_LPX; AddressList->Address[idx_addr].AddressLength = TDI_ADDRESS_LENGTH_LPX; RtlCopyMemory(AddressList->Address[idx_addr].Address, &socketLpxAddressList.SocketLpx[idx_addr], TDI_ADDRESS_LENGTH_LPX); } error_out: return status; }
// // compare addresses to see if the address is local. // BOOLEAN LfsIsFromLocal( PLPX_ADDRESS Addr ) { NTSTATUS ntStatus; SOCKETLPX_ADDRESS_LIST socketLpxAddressList; LONG idx_addr ; SPY_LOG_PRINT( LFS_DEBUG_TABLE_NOISE, ( "[LFS] LfsIsFromLocal: Entered with Addr:%02x:%02x:%02x:%02x:%02x:%02x\n", Addr->Node[0], Addr->Node[1], Addr->Node[2], Addr->Node[3], Addr->Node[4], Addr->Node[5] )); // // get addresses from LPX // socketLpxAddressList.iAddressCount = 0 ; ntStatus = LpxTdiGetAddressList( &socketLpxAddressList ) ; if(!NT_SUCCESS(ntStatus)) { SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] LfsIsFromLocal: LpxTdiGetAddressList() failed.\n")) ; return FALSE ; } if(0 == socketLpxAddressList.iAddressCount) { SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] LfsIsFromLocal: No NICs in the host.\n")) ; return FALSE ; } for(idx_addr = 0 ; idx_addr < socketLpxAddressList.iAddressCount ; idx_addr ++ ) { // // BUG FIX for LPX: skip SocketLpxDevice // if( (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[0]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[1]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[2]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[3]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[4]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[5]) ) { SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] LfsIsFromLocal: We don't use SocketLpx device.\n") ); continue ; } if( RtlCompareMemory(Addr->Node, socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node, ETHER_ADDR_LENGTH) == ETHER_ADDR_LENGTH ) { SPY_LOG_PRINT( LFS_DEBUG_TABLE_NOISE, ( "[LFS] LfsIsFromLocal: found a address matching.\n")) ; return TRUE ; } } return FALSE ; }
NTSTATUS LpxTdiGetAddressList_LSTrans( IN ULONG AddressListLen, IN PTA_LSTRANS_ADDRESS AddressList, OUT PULONG OutLength ) { SOCKETLPX_ADDRESS_LIST socketLpxAddressList; NTSTATUS status; LONG idx_addr; ULONG length; status = LpxTdiGetAddressList(&socketLpxAddressList); if(!NT_SUCCESS(status)) goto error_out; length = FIELD_OFFSET(TA_LSTRANS_ADDRESS, Address) + sizeof(struct _AddrLstrans) * socketLpxAddressList.iAddressCount; if(AddressListLen < length) { if(OutLength) { *OutLength = length; } return STATUS_INSUFFICIENT_RESOURCES; } // // translate LPX address list into LSTrans address list. // AddressList->TAAddressCount = socketLpxAddressList.iAddressCount; for(idx_addr = 0; idx_addr < socketLpxAddressList.iAddressCount; idx_addr ++) { AddressList->Address[idx_addr].AddressType = TDI_ADDRESS_TYPE_LPX; AddressList->Address[idx_addr].AddressLength = TDI_ADDRESS_LENGTH_LPX; RtlCopyMemory(&AddressList->Address[idx_addr].Address, &socketLpxAddressList.SocketLpx[idx_addr].LpxAddress, TDI_ADDRESS_LENGTH_LPX); } if(OutLength) { *OutLength = length; } error_out: return status; }
NTSTATUS BindListenSockets( IN PPRIMARY Primary ) { NTSTATUS ntStatus; PSOCKETLPX_ADDRESS_LIST socketLpxAddressList; LONG idx_addr; SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ("BindListenSockets: Entered\n")); Primary->Agent.ActiveListenSocketCount = 0; socketLpxAddressList = &Primary->Agent.SocketLpxAddressList; ntStatus = LpxTdiGetAddressList( socketLpxAddressList ); if(!NT_SUCCESS(ntStatus)) { //ASSERT(LPX_BUG); return ntStatus; } if(socketLpxAddressList->iAddressCount <= 0) { SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ( "BindListenSockets: No NICs in the host.\n") ); return STATUS_UNSUCCESSFUL; } if(socketLpxAddressList->iAddressCount > MAX_SOCKETLPX_INTERFACE) socketLpxAddressList->iAddressCount = MAX_SOCKETLPX_INTERFACE; for(idx_addr = 0; idx_addr < socketLpxAddressList->iAddressCount; idx_addr ++) { LPX_ADDRESS NICAddr; HANDLE addressFileHandle = NULL; PFILE_OBJECT addressFileObject = NULL; HANDLE listenFileHandle = NULL; PFILE_OBJECT listenFileObject = NULL; Primary->Agent.ListenSocket[idx_addr].Active = FALSE; if( (0 == socketLpxAddressList->SocketLpx[idx_addr].LpxAddress.Node[0]) && (0 == socketLpxAddressList->SocketLpx[idx_addr].LpxAddress.Node[1]) && (0 == socketLpxAddressList->SocketLpx[idx_addr].LpxAddress.Node[2]) && (0 == socketLpxAddressList->SocketLpx[idx_addr].LpxAddress.Node[3]) && (0 == socketLpxAddressList->SocketLpx[idx_addr].LpxAddress.Node[4]) && (0 == socketLpxAddressList->SocketLpx[idx_addr].LpxAddress.Node[5]) ) { SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ( "BindListenSockets: We don't use SocketLpx device.\n")); continue; } RtlCopyMemory( &Primary->Agent.ListenSocket[idx_addr].NICAddress, &socketLpxAddressList->SocketLpx[idx_addr].LpxAddress, sizeof(LPX_ADDRESS) ); RtlCopyMemory( &NICAddr, &socketLpxAddressList->SocketLpx[idx_addr].LpxAddress, sizeof(LPX_ADDRESS) ); NICAddr.Port = HTONS(Primary->Agent.ListenPort); // // open a address. // ntStatus = LpxTdiOpenAddress( &addressFileHandle, &addressFileObject, &NICAddr ); if(!NT_SUCCESS(ntStatus)) { ASSERT(LPX_BUG); continue; } Primary->Agent.ListenSocket[idx_addr].Active = TRUE; KeInitializeEvent(&Primary->Agent.ListenSocket[idx_addr].TdiListenContext.CompletionEvent, NotificationEvent, FALSE); Primary->Agent.ListenSocket[idx_addr].AddressFileHandle = addressFileHandle; Primary->Agent.ListenSocket[idx_addr].AddressFileObject = addressFileObject; Primary->Agent.ActiveListenSocketCount ++; ntStatus = MakeConnectionObject(addressFileHandle, addressFileObject, &listenFileHandle, &listenFileObject); if(!NT_SUCCESS(ntStatus)) { ASSERT(LPX_BUG); LpxTdiCloseAddress (addressFileHandle, addressFileObject); Primary->Agent.ListenSocket[idx_addr].Active = FALSE; Primary->Agent.ActiveListenSocketCount --; continue; } Primary->Agent.ListenSocket[idx_addr].ListenFileHandle = listenFileHandle; Primary->Agent.ListenSocket[idx_addr].ListenFileObject = listenFileObject; SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ( "BindListenSockets: opened a address:'%02X:%02X:%02X:%02X:%02X:%02X 0x%04X'\n", NICAddr.Node[0],NICAddr.Node[1],NICAddr.Node[2], NICAddr.Node[3],NICAddr.Node[4],NICAddr.Node[5], NTOHS(NICAddr.Port) ) ); Primary->Agent.ListenSocket[idx_addr].Flags = TDI_QUERY_ACCEPT; ntStatus = LpxTdiListenWithCompletionEvent( Primary->Agent.ListenSocket[idx_addr].ListenFileObject, &Primary->Agent.ListenSocket[idx_addr].TdiListenContext, &Primary->Agent.ListenSocket[idx_addr].Flags ); if(!NT_SUCCESS(ntStatus)) { ASSERT(LPX_BUG); LpxTdiDisassociateAddress(listenFileObject); LpxTdiCloseConnection(listenFileHandle, listenFileObject); LpxTdiCloseAddress (addressFileHandle, addressFileObject); Primary->Agent.ListenSocket[idx_addr].Active = FALSE; Primary->Agent.ActiveListenSocketCount --; continue; } } return STATUS_SUCCESS; }
// // Wait for incoming request to any arbiter on this host. // VOID DraidListenerThreadProc( PVOID Param ) { PDRAID_GLOBALS DraidGlobals = (PDRAID_GLOBALS)Param; NTSTATUS status; PLIST_ENTRY listEntry; PDRAID_LISTEN_CONTEXT ListenContext; KIRQL oldIrql; INT32 MaxEventCount = 0; PKEVENT *events = NULL; PKWAIT_BLOCK WaitBlocks = NULL; INT32 eventCount; NTSTATUS waitStatus; SOCKETLPX_ADDRESS_LIST socketLpxAddressList; INT32 i; KDPrintM(DBG_LURN_INFO, ("Starting\n")); MaxEventCount = DraidReallocEventArray(&events, &WaitBlocks, MaxEventCount); status = LpxTdiGetAddressList( &socketLpxAddressList ); if (!NT_SUCCESS(status)) { KDPrintM(DBG_LURN_INFO, ("Failed to get address list\n")); goto out; } for(i=0;i<socketLpxAddressList.iAddressCount;i++) { ListenContext = DraidCreateListenContext(DraidGlobals, &socketLpxAddressList.SocketLpx[i].LpxAddress); if (ListenContext) { status = DraidStartListenAddress(DraidGlobals, ListenContext); if (!NT_SUCCESS(status)) { DraidStopListenAddress(DraidGlobals, ListenContext); } } } while(TRUE) { restart: if (events == NULL || WaitBlocks == NULL) { KDPrintM(DBG_LURN_INFO, ("Insufficient memory\n")); break; } eventCount = 0; // // Wait exit event, net change event, connect request. // events[0] = &DraidGlobals->DraidExitEvent; eventCount++; events[1] = &DraidGlobals->NetChangedEvent; eventCount++; // // Add listening event // ACQUIRE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, &oldIrql); for (listEntry = DraidGlobals->ListenContextList.Flink; listEntry != &DraidGlobals->ListenContextList; listEntry = listEntry->Flink) { ListenContext = CONTAINING_RECORD (listEntry, DRAID_LISTEN_CONTEXT, Link); if (!ListenContext->Destroy) { if (MaxEventCount < eventCount+1) { RELEASE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, oldIrql); MaxEventCount = DraidReallocEventArray(&events, &WaitBlocks, MaxEventCount); goto restart; } events[eventCount] = &ListenContext->TdiListenContext.CompletionEvent; eventCount++; } } RELEASE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, oldIrql); waitStatus = KeWaitForMultipleObjects( eventCount, events, WaitAny, Executive, KernelMode, TRUE, NULL, //&TimeOut, WaitBlocks); if (KeReadStateEvent(&DraidGlobals->DraidExitEvent)) { KDPrintM(DBG_LURN_INFO, ("Exit requested\n")); break; } if (KeReadStateEvent(&DraidGlobals->NetChangedEvent)) { KDPrintM(DBG_LURN_INFO, ("NIC status has changed\n")); KeClearEvent(&DraidGlobals->NetChangedEvent); // // Start if not listening and stop if destorying request is on. // ACQUIRE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, &oldIrql); for (listEntry = DraidGlobals->ListenContextList.Flink; listEntry != &DraidGlobals->ListenContextList; listEntry = listEntry->Flink) { ListenContext = CONTAINING_RECORD (listEntry, DRAID_LISTEN_CONTEXT, Link); status = STATUS_SUCCESS; if (!ListenContext->Started) { RELEASE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, oldIrql); status = DraidStartListenAddress(DraidGlobals, ListenContext); ACQUIRE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, &oldIrql); } if (!NT_SUCCESS(status) || ListenContext->Destroy) { listEntry = listEntry->Blink; // // Move to next entry. There may be multiple interface is down. RemoveEntryList(&ListenContext->Link); RELEASE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, oldIrql); DraidStopListenAddress(DraidGlobals, ListenContext); ACQUIRE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, &oldIrql); } } RELEASE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, oldIrql); continue; // Reset listen event. } // Check whether listen event has been signaled. for(i=2;i<eventCount;i++) { if (KeReadStateEvent(events[i])) { BOOLEAN Found; KeClearEvent(events[i]); // Find listencontext related to this event. ACQUIRE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, &oldIrql); Found = FALSE; for (listEntry = DraidGlobals->ListenContextList.Flink; listEntry != &DraidGlobals->ListenContextList; listEntry = listEntry->Flink) { ListenContext = CONTAINING_RECORD (listEntry, DRAID_LISTEN_CONTEXT, Link); if (&ListenContext->TdiListenContext.CompletionEvent == events[i]) { Found = TRUE; break; } } RELEASE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, oldIrql); if (Found) { DraidAcceptConnection(DraidGlobals, ListenContext); } else { ASSERT(FALSE); } } } } out: // // to do: clean-up pending client // // // Close and free pending listen contexts // while(listEntry = ExInterlockedRemoveHeadList(&DraidGlobals->ListenContextList, &DraidGlobals->ListenContextSpinlock)) { ListenContext = CONTAINING_RECORD (listEntry, DRAID_LISTEN_CONTEXT, Link); DraidStopListenAddress(DraidGlobals, ListenContext); } DraidFreeEventArray(events, WaitBlocks); KDPrint(1,("Exiting.\n")); PsTerminateSystemThread(STATUS_SUCCESS); }
// // compare addresses to see if the address is local. // BOOLEAN xixfs_IsFromLocal( PLPX_ADDRESS Addr ) { NTSTATUS ntStatus; SOCKETLPX_ADDRESS_LIST socketLpxAddressList; LONG idx_addr ; PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_HOSTCOM, ("Enter xixfs_IsFromLocal \n")); DebugTrace(DEBUG_LEVEL_INFO, DEBUG_TARGET_HOSTCOM, ( "[LFS] xixfs_IsFromLocal: Entered with Addr:%02x:%02x:%02x:%02x:%02x:%02x\n", Addr->Node[0], Addr->Node[1], Addr->Node[2], Addr->Node[3], Addr->Node[4], Addr->Node[5] )); // // get addresses from LPX // socketLpxAddressList.iAddressCount = 0 ; ntStatus = LpxTdiGetAddressList( &socketLpxAddressList ) ; if(!NT_SUCCESS(ntStatus)) { DebugTrace( DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ( "[LFS] xixfs_IsFromLocal: LpxTdiGetAddressList() failed.\n")) ; return FALSE ; } if(0 == socketLpxAddressList.iAddressCount) { DebugTrace( DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ( "[LFS] xixfs_IsFromLocal: No NICs in the host.\n")) ; return FALSE ; } for(idx_addr = 0 ; idx_addr < socketLpxAddressList.iAddressCount ; idx_addr ++ ) { // // BUG FIX for LPX: skip SocketLpxDevice // if( (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[0]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[1]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[2]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[3]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[4]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[5]) ) { DebugTrace(DEBUG_LEVEL_INFO, DEBUG_TARGET_HOSTCOM, ( "[LFS] xixfs_IsFromLocal: We don't use SocketLpx device.\n") ); continue ; } if( RtlCompareMemory(Addr->Node, socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node, ETHER_ADDR_LENGTH) == ETHER_ADDR_LENGTH ) { DebugTrace(DEBUG_LEVEL_INFO, DEBUG_TARGET_HOSTCOM, ( "[LFS] xixfs_IsFromLocal: found a address matching.\n")) ; return TRUE ; } } DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_HOSTCOM, ("Exit xixfs_IsFromLocal \n")); return FALSE ; }
// // open a datagram socket // NTSTATUS xixfs_OpenDGSocket( OUT PLFSDG_Socket Socket, IN USHORT PortNo ) { HANDLE addressFileHandle = NULL; HANDLE connectionFileHandle = NULL; PFILE_OBJECT addressFileObject = NULL; PFILE_OBJECT connectionFileObject = NULL; NTSTATUS ntStatus ; SOCKETLPX_ADDRESS_LIST socketLpxAddressList; LONG idx_addr ; ULONG open_addr ; LPX_ADDRESS NICAddr ; PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_HOSTCOM, ("Enter xixfs_OpenDGSocket \n")); Socket->SocketCnt = 0 ; // // get addresses from LPX // ntStatus = LpxTdiGetAddressList( &socketLpxAddressList ) ; if(!NT_SUCCESS(ntStatus)) { return ntStatus; } if(0 == socketLpxAddressList.iAddressCount) { return STATUS_INSUFFICIENT_RESOURCES; } // // open a port for each NIC. // open_addr = 0 ; for(idx_addr = 0 ; idx_addr < socketLpxAddressList.iAddressCount; idx_addr ++) { if( (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[0]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[1]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[2]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[3]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[4]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[5]) ) { continue ; } RtlCopyMemory(&NICAddr, &socketLpxAddressList.SocketLpx[idx_addr].LpxAddress, sizeof(LPX_ADDRESS)) ; NICAddr.Port = HTONS(PortNo) ; // // open a connection and address. // if this calling for a datagram server, don't create a connection. // ntStatus = LpxTdiOpenAddress( &addressFileHandle, &addressFileObject, &NICAddr ); if(!NT_SUCCESS(ntStatus)) { DebugTrace( DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ( "[LFS] xixfs_OpenDGSocket: couldn't open a address %d:'%02X:%02X:%02X:%02X:%02X:%02X/%d'\n", idx_addr, NICAddr.Node[0],NICAddr.Node[1],NICAddr.Node[2], NICAddr.Node[3],NICAddr.Node[4],NICAddr.Node[5], (int)NTOHS(NICAddr.Port) ) ); continue ; } DebugTrace(DEBUG_LEVEL_INFO, DEBUG_TARGET_HOSTCOM, ( "[LFS] xixfs_OpenDGSocket: opened a address:'%02X:%02X:%02X:%02X:%02X:%02X/%d'\n", NICAddr.Node[0],NICAddr.Node[1],NICAddr.Node[2], NICAddr.Node[3],NICAddr.Node[4],NICAddr.Node[5], (int)NTOHS(NICAddr.Port) ) ); // // return values // close handles, but leave objects // Socket->Sockets[open_addr].AddressFile = addressFileObject ; Socket->Sockets[open_addr].AddressFileHandle = addressFileHandle ; RtlCopyMemory(&Socket->Sockets[open_addr].NICAddr, &NICAddr, sizeof(LPX_ADDRESS)) ; open_addr ++ ; } Socket->SocketCnt = (USHORT)open_addr ; DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_HOSTCOM, ("Exit xixfs_OpenDGSocket \n")); return ntStatus ; }
static VOID xixfs_NetEventDetectorProc( PVOID lpParameter // thread data ) { PNETEVTCTX NetEvtCtx = (PNETEVTCTX)lpParameter; NTSTATUS ntStatus ; SOCKETLPX_ADDRESS_LIST addressList ; LARGE_INTEGER TimeOut ; LONG idx_callbacks ; PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_HOSTCOM, ("Enter xixfs_NetEventDetectorProc \n")); DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_HOSTCOM, ("[LFS] xixfs_NetEventDetectorProc: Initializing Networking event detector...\n")) ; // // get the address list // ntStatus = LpxTdiGetAddressList( &NetEvtCtx->AddressList ); if(!NT_SUCCESS(ntStatus)) { DebugTrace( DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ( "[LFS] xixfs_NetEventDetectorProc: LpxTdiGetAddressList() failed. NTSTATUS:%lu\n", ntStatus)); // goto termination ; } DebugTrace(DEBUG_LEVEL_INFO, DEBUG_TARGET_HOSTCOM, ("[LFS] xixfs_NetEventDetectorProc: Networking event detector started...\n")) ; // Main loop... while(1) { TimeOut.QuadPart = - NETEVT_FREQ ; ntStatus = KeWaitForSingleObject( &NetEvtCtx->ShutdownEvent, Executive, KernelMode, FALSE, &TimeOut ); DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_HOSTCOM, ( "[LFS] xixfs_NetEventDetectorProc: NTSTATUS:%lu\n", ntStatus)); if(0 == ntStatus) { DebugTrace(DEBUG_LEVEL_INFO, DEBUG_TARGET_HOSTCOM, ( "[COM] xixfs_NetEventDetectorProc: ShutDown event received. NTSTATUS:%lu\n", ntStatus)); break ; } else if(STATUS_TIMEOUT == ntStatus) { // // Time Out. // DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_HOSTCOM, ( "[COM] xixfs_NetEventDetectorProc: Time out. Go ahead and check changes. NTSTATUS:%lu\n", ntStatus)); } else { DebugTrace(DEBUG_LEVEL_INFO, DEBUG_TARGET_HOSTCOM, ( "[COM] xixfs_NetEventDetectorProc: KeWaitForSingleObject() failed. NTSTATUS:%lu\n", ntStatus)); break ; } // // check changes // ntStatus = LpxTdiGetAddressList( &addressList ); if(!NT_SUCCESS(ntStatus)) { DebugTrace( DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ( "[LFS] xixfs_NetEventDetectorProc: LpxTdiGetAddressList() failed. NTSTATUS:%lu\n", ntStatus)); continue ; } xixfs_FindOutChanges( &NetEvtCtx->AddressList, &addressList, &NetEvtCtx->DisabledAddressList, &NetEvtCtx->EnabledAddressList ); // // call back // if( NetEvtCtx->DisabledAddressList.iAddressCount == 0 && NetEvtCtx->EnabledAddressList.iAddressCount == 0 ) { continue ; } DebugTrace(DEBUG_LEVEL_INFO, DEBUG_TARGET_HOSTCOM, ( "[LFS] xixfs_NetEventDetectorProc: Networking event detected.\n")); // // call callbacks and update address list. // for(idx_callbacks = 0 ; idx_callbacks < NetEvtCtx->CallbackCnt ; idx_callbacks ++ ) { if(NetEvtCtx->Callbacks[idx_callbacks]) { NetEvtCtx->Callbacks[idx_callbacks]( &NetEvtCtx->AddressList, &addressList, &NetEvtCtx->DisabledAddressList, &NetEvtCtx->EnabledAddressList, NetEvtCtx->CallbackContext[idx_callbacks] ) ; } else { DebugTrace(DEBUG_LEVEL_INFO, DEBUG_TARGET_HOSTCOM, ("[LFS] xixfs_NetEventDetectorProc: Callback #%d is NULL.\n", idx_callbacks)) ; } } RtlCopyMemory(&NetEvtCtx->AddressList, &addressList, sizeof(SOCKETLPX_ADDRESS_LIST)) ; } //termination: DebugTrace(DEBUG_LEVEL_INFO, DEBUG_TARGET_HOSTCOM, ("[LFS] Networking event detector terminated.\n")) ; DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_HOSTCOM, ("Exit xixfs_NetEventDetectorProc \n")); PsTerminateSystemThread(0) ; }
// // open a datagram socket // NTSTATUS LfsOpenDGSocket( OUT PLFSDG_Socket Socket, IN USHORT PortNo ) { HANDLE addressFileHandle = NULL; HANDLE connectionFileHandle = NULL; PFILE_OBJECT addressFileObject = NULL; PFILE_OBJECT connectionFileObject = NULL; NTSTATUS ntStatus ; SOCKETLPX_ADDRESS_LIST socketLpxAddressList; LONG idx_addr ; ULONG open_addr ; LPX_ADDRESS NICAddr ; SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] LfsOpenDGSocket: Entered\n")); Socket->SocketCnt = 0 ; // // get addresses from LPX // ntStatus = LpxTdiGetAddressList( &socketLpxAddressList ) ; if(!NT_SUCCESS(ntStatus)) { SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] LfsOpenDGSocket: LpxTdiGetAddressList() failed.\n")) ; return ntStatus; } if(0 == socketLpxAddressList.iAddressCount) { SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] LfsOpenDGSocket: No NICs in the host.\n") ); return STATUS_INSUFFICIENT_RESOURCES; } // // open a port for each NIC. // open_addr = 0 ; for(idx_addr = 0 ; idx_addr < socketLpxAddressList.iAddressCount; idx_addr ++) { if( (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[0]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[1]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[2]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[3]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[4]) && (0 == socketLpxAddressList.SocketLpx[idx_addr].LpxAddress.Node[5]) ) { SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] LfsOpenDGSocket: We don't use SocketLpx device.\n")) ; continue ; } RtlCopyMemory(&NICAddr, &socketLpxAddressList.SocketLpx[idx_addr].LpxAddress, sizeof(LPX_ADDRESS)) ; NICAddr.Port = HTONS(PortNo) ; // // open a connection and address. // if this calling for a datagram server, don't create a connection. // ntStatus = LpxTdiOpenAddress( &addressFileHandle, &addressFileObject, &NICAddr ); if(!NT_SUCCESS(ntStatus)) { SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] LfsOpenDGSocket: couldn't open a address %d:'%02X:%02X:%02X:%02X:%02X:%02X/%d'\n", idx_addr, NICAddr.Node[0],NICAddr.Node[1],NICAddr.Node[2], NICAddr.Node[3],NICAddr.Node[4],NICAddr.Node[5], (int)NTOHS(NICAddr.Port) ) ); continue ; } SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] LfsOpenDGSocket: opened a address:'%02X:%02X:%02X:%02X:%02X:%02X/%d'\n", NICAddr.Node[0],NICAddr.Node[1],NICAddr.Node[2], NICAddr.Node[3],NICAddr.Node[4],NICAddr.Node[5], (int)NTOHS(NICAddr.Port) ) ); // // return values // close handles, but leave objects // Socket->Sockets[open_addr].AddressFile = addressFileObject ; Socket->Sockets[open_addr].AddressFileHandle = addressFileHandle ; RtlCopyMemory(&Socket->Sockets[open_addr].NICAddr, &NICAddr, sizeof(LPX_ADDRESS)) ; open_addr ++ ; } Socket->SocketCnt = (USHORT)open_addr ; return ntStatus ; }
static VOID NetEventDetectorProc( PVOID lpParameter // thread data ) { PNETEVTCTX NetEvtCtx = (PNETEVTCTX)lpParameter; NTSTATUS ntStatus ; SOCKETLPX_ADDRESS_LIST addressList ; LARGE_INTEGER TimeOut ; LONG idx_callbacks ; LONG AgeCount; // Force refreshing of open socket. This is temporary fix. SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ("[LFS] NetEventDetectorProc: Initializing Networking event detector...\n")) ; // // get the address list // ntStatus = LpxTdiGetAddressList( &NetEvtCtx->AddressList ); if(!NT_SUCCESS(ntStatus)) { SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] NetEventDetectorProc: LpxTdiGetAddressList() failed. NTSTATUS:%lu\n", ntStatus)); // goto termination ; } SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ("[LFS] NetEventDetectorProc: Networking event detector started...\n")) ; AgeCount = 0; // Main loop... while(1) { TimeOut.QuadPart = - NETEVT_FREQ ; ntStatus = KeWaitForSingleObject( &NetEvtCtx->ShutdownEvent, Executive, KernelMode, FALSE, &TimeOut ); SPY_LOG_PRINT( LFS_DEBUG_TABLE_NOISE, ( "[LFS] NetEventDetectorProc: NTSTATUS:%lu\n", ntStatus)); if(0 == ntStatus) { SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] NetEventDetectorProc: ShutDown event received. NTSTATUS:%lu\n", ntStatus)); break ; } else if(STATUS_TIMEOUT == ntStatus) { // // Time Out. // SPY_LOG_PRINT( LFS_DEBUG_TABLE_NOISE, ( "[LFS] NetEventDetectorProc: Time out. Go ahead and check changes. NTSTATUS:%lu\n", ntStatus)); AgeCount++; } else { SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] NetEventDetectorProc: KeWaitForSingleObject() failed. NTSTATUS:%lu\n", ntStatus)); break ; } // // check changes // ntStatus = LpxTdiGetAddressList( &addressList ); if(!NT_SUCCESS(ntStatus)) { SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] NetEventDetectorProc: LpxTdiGetAddressList() failed. NTSTATUS:%lu\n", ntStatus)); continue ; } FindOutChanges( &NetEvtCtx->AddressList, &addressList, &NetEvtCtx->DisabledAddressList, &NetEvtCtx->EnabledAddressList ); // // call back // if( NetEvtCtx->DisabledAddressList.iAddressCount == 0 && NetEvtCtx->EnabledAddressList.iAddressCount == 0 && AgeCount <= 10 ) { continue ; } SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ( "[LFS] NetEventDetectorProc: Networking event detected.\n")); AgeCount = 0; // // call callbacks and update address list. // for(idx_callbacks = 0 ; idx_callbacks < NetEvtCtx->CallbackCnt ; idx_callbacks ++ ) { if(NetEvtCtx->Callbacks[idx_callbacks]) { NetEvtCtx->Callbacks[idx_callbacks]( &NetEvtCtx->AddressList, &addressList, &NetEvtCtx->DisabledAddressList, &NetEvtCtx->EnabledAddressList, NetEvtCtx->CallbackContext[idx_callbacks] ) ; } else { SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ("[LFS] NetEventDetectorProc: Callback #%d is NULL.\n", idx_callbacks)) ; } } RtlCopyMemory(&NetEvtCtx->AddressList, &addressList, sizeof(SOCKETLPX_ADDRESS_LIST)) ; } //termination: SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ("[LFS] Networking event detector terminated.\n")) ; PsTerminateSystemThread(0) ; }