Exemple #1
0
VOID NBUpdateNeighbor(
    PNEIGHBOR_CACHE_ENTRY NCE,
    PVOID LinkAddress,
    UCHAR State)
/*
 * FUNCTION: Update link address information in NCE
 * ARGUMENTS:
 *   NCE         = Pointer to NCE to update
 *   LinkAddress = Pointer to link address
 *   State       = State of NCE
 * NOTES:
 *   The link address and state is updated. Any waiting packets are sent
 */
{
    KIRQL OldIrql;
    UINT HashValue;

    TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X)  LinkAddress (0x%X)  State (0x%X).\n", NCE, LinkAddress, State));

    HashValue  = *(PULONG)(&NCE->Address.Address);
    HashValue ^= HashValue >> 16;
    HashValue ^= HashValue >> 8;
    HashValue ^= HashValue >> 4;
    HashValue &= NB_HASHMASK;

    TcpipAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);

    RtlCopyMemory(NCE->LinkAddress, LinkAddress, NCE->LinkAddressLength);
    NCE->State = State;
    NCE->EventCount = 0;

    TcpipReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);

    if( !(NCE->State & NUD_INCOMPLETE) )
    {
        if (NCE->EventTimer) NCE->EventTimer = ARP_COMPLETE_TIMEOUT;
        NBSendPackets( NCE );
    }
}
Exemple #2
0
ULONG NBCopyNeighbors
(PIP_INTERFACE Interface,
 PIPARP_ENTRY ArpTable)
{
  PNEIGHBOR_CACHE_ENTRY CurNCE;
  KIRQL OldIrql;
  UINT Size = 0, i;

  for (i = 0; i <= NB_HASHMASK; i++) {
      TcpipAcquireSpinLock(&NeighborCache[i].Lock, &OldIrql);
      for( CurNCE = NeighborCache[i].Cache;
	   CurNCE;
	   CurNCE = CurNCE->Next ) {
	  if( CurNCE->Interface == Interface &&
              !AddrIsEqual( &CurNCE->Address, &CurNCE->Interface->Unicast ) ) {
	      if( ArpTable ) {
		  ArpTable[Size].Index = Interface->Index;
		  ArpTable[Size].AddrSize = CurNCE->LinkAddressLength;
		  RtlCopyMemory
		      (ArpTable[Size].PhysAddr, 
		       CurNCE->LinkAddress,
		       CurNCE->LinkAddressLength);
		  ArpTable[Size].LogAddr = CurNCE->Address.Address.IPv4Address;
		  if( CurNCE->State & NUD_PERMANENT )
		      ArpTable[Size].Type = ARP_ENTRY_STATIC;
		  else if( CurNCE->State & NUD_INCOMPLETE )
		      ArpTable[Size].Type = ARP_ENTRY_INVALID;
		  else
		      ArpTable[Size].Type = ARP_ENTRY_DYNAMIC;
	      }
	      Size++;
	  }
      }
      TcpipReleaseSpinLock(&NeighborCache[i].Lock, OldIrql);
  }
  
  return Size;
}
Exemple #3
0
/*
 * FUNCTION: Searches through address file entries to find the first match
 * ARGUMENTS:
 *     Address       = IP address
 *     Port          = Port number
 *     Protocol      = Protocol number
 *     SearchContext = Pointer to search context
 * RETURNS:
 *     Pointer to address file, NULL if none was found
 */
PADDRESS_FILE AddrSearchFirst(
    PIP_ADDRESS Address,
    USHORT Port,
    USHORT Protocol,
    PAF_SEARCH SearchContext)
{
    KIRQL OldIrql;
    
    SearchContext->Address  = Address;
    SearchContext->Port     = Port;
    SearchContext->Protocol = Protocol;

    TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);

    SearchContext->Next = AddressFileListHead.Flink;

    if (!IsListEmpty(&AddressFileListHead))
        ReferenceObject(CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry));

    TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);

    return AddrSearchNext(SearchContext);
}
Exemple #4
0
TDI_STATUS InfoTdiQueryListEntities(PNDIS_BUFFER Buffer,
				    PUINT BufferSize)
{
    UINT Count, Size, BufSize = *BufferSize;
    KIRQL OldIrql;

    TI_DbgPrint(DEBUG_INFO,("About to copy %d TDIEntityIDs to user\n",
			   EntityCount));

    TcpipAcquireSpinLock(&EntityListLock, &OldIrql);

    Size = EntityCount * sizeof(TDIEntityID);
    *BufferSize = Size;

    TI_DbgPrint(DEBUG_INFO,("BufSize: %d, NeededSize: %d\n", BufSize, Size));

    if (BufSize < Size || !Buffer)
    {
	TcpipReleaseSpinLock( &EntityListLock, OldIrql );
	/* The buffer is too small to contain requested data, but we return
         * success anyway, as we did everything we wanted. */
	return TDI_SUCCESS;
    }

    /* Return entity list -- Copy only the TDIEntityID parts. */
    for( Count = 0; Count < EntityCount; Count++ ) {
	CopyBufferToBufferChain(Buffer,
				Count * sizeof(TDIEntityID),
				(PCHAR)&EntityList[Count],
				sizeof(TDIEntityID));
    }

    TcpipReleaseSpinLock(&EntityListLock, OldIrql);

    return TDI_SUCCESS;
}
Exemple #5
0
VOID NBShutdown(VOID)
/*
 * FUNCTION: Shuts down the neighbor cache
 */
{
  PNEIGHBOR_CACHE_ENTRY NextNCE;
  PNEIGHBOR_CACHE_ENTRY CurNCE;
  KIRQL OldIrql;
  UINT i;

  TI_DbgPrint(DEBUG_NCACHE, ("Called.\n"));

  /* Remove possible entries from the cache */
  for (i = 0; i <= NB_HASHMASK; i++)
    {
      TcpipAcquireSpinLock(&NeighborCache[i].Lock, &OldIrql);

      CurNCE = NeighborCache[i].Cache;
      while (CurNCE) {
          NextNCE = CurNCE->Next;

          /* Flush wait queue */
	  NBFlushPacketQueue( CurNCE, NDIS_STATUS_NOT_ACCEPTED );

          ExFreePoolWithTag(CurNCE, NCE_TAG);

	  CurNCE = NextNCE;
      }

    NeighborCache[i].Cache = NULL;

    TcpipReleaseSpinLock(&NeighborCache[i].Lock, OldIrql);
  }

  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
Exemple #6
0
/* Get IPRouteEntry s for each of the routes in the system */
TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUINT BufferSize ) {
    TDI_STATUS Status;
    KIRQL OldIrql;
    UINT RtCount = CountFIBs(IF);
    UINT Size = sizeof( IPROUTE_ENTRY ) * RtCount;
    PFIB_ENTRY RCache, RCacheCur;
    PIPROUTE_ENTRY RouteEntries, RtCurrent;
    UINT i;

    TI_DbgPrint(DEBUG_INFO, ("Called, routes = %d\n",
			    RtCount));
    
    if (RtCount == 0)
        return InfoCopyOut(NULL, 0, NULL, BufferSize);

    RouteEntries = ExAllocatePool( NonPagedPool, Size );
    RtCurrent = RouteEntries;

    RCache = ExAllocatePool( NonPagedPool, sizeof( FIB_ENTRY ) * RtCount );
    RCacheCur = RCache;

    if( !RCache || !RouteEntries ) {
	if( RCache ) ExFreePool( RCache );
	if( RouteEntries ) ExFreePool( RouteEntries );
	return TDI_NO_RESOURCES;
    }

    RtlZeroMemory( RouteEntries, Size );

    RtCount = CopyFIBs( IF, RCache );

    while( RtCurrent < RouteEntries + RtCount ) {
	ASSERT(RCacheCur->Router);

	RtlCopyMemory( &RtCurrent->Dest,
		       &RCacheCur->NetworkAddress.Address,
		       sizeof(RtCurrent->Dest) );
	RtlCopyMemory( &RtCurrent->Mask,
		       &RCacheCur->Netmask.Address,
		       sizeof(RtCurrent->Mask) );
	RtlCopyMemory( &RtCurrent->Gw,
		       &RCacheCur->Router->Address.Address,
		       sizeof(RtCurrent->Gw) );

	RtCurrent->Metric1 = RCacheCur->Metric;
	RtCurrent->Type = TDI_ADDRESS_TYPE_IP;

	TI_DbgPrint
	    (DEBUG_INFO,
	     ("%d: NA %08x NM %08x GW %08x MT %x\n",
	      RtCurrent - RouteEntries,
	      RtCurrent->Dest,
	      RtCurrent->Mask,
	      RtCurrent->Gw,
	      RtCurrent->Metric1 ));

	TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
	for (i = 0; i < EntityCount; i++)
             if (EntityList[i].context == IF)
                 break;

        if (i < EntityCount)
            RtCurrent->Index = EntityList[i].tei_instance;
        else
            RtCurrent->Index = 0;

	TcpipReleaseSpinLock(&EntityListLock, OldIrql);

	RtCurrent++; RCacheCur++;
    }

    Status = InfoCopyOut( (PCHAR)RouteEntries, Size, Buffer, BufferSize );

    ExFreePool( RouteEntries );
    ExFreePool( RCache );

    TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status));

    return Status;
}
Exemple #7
0
VOID AddrFileFree(
    PVOID Object)
/*
 * FUNCTION: Frees an address file object
 * ARGUMENTS:
 *     Object = Pointer to address file object to free
 */
{
  PADDRESS_FILE AddrFile = Object;
  KIRQL OldIrql;
  PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
  PDATAGRAM_SEND_REQUEST SendRequest;
  PLIST_ENTRY CurrentEntry;

  TI_DbgPrint(MID_TRACE, ("Called.\n"));

  /* We should not be associated with a connection here */
  ASSERT(!AddrFile->Connection);

  /* Remove address file from the global list */
  TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
  RemoveEntryList(&AddrFile->ListEntry);
  TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);

  /* FIXME: Kill TCP connections on this address file object */

  /* Return pending requests with error */

  TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile));

  /* Go through pending receive request list and cancel them all */
  while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) {
    ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
    (*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_CANCELLED, 0);
    /* ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); FIXME: WTF? */
  }

  TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile));

  /* Go through pending send request list and cancel them all */
  while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) {
    SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
    (*SendRequest->Complete)(SendRequest->Context, STATUS_CANCELLED, 0);
    ExFreePoolWithTag(SendRequest, DATAGRAM_SEND_TAG);
  }

  /* Protocol specific handling */
  switch (AddrFile->Protocol) {
  case IPPROTO_TCP:
    if (AddrFile->Port)
    {
        TCPFreePort(AddrFile->Port);
    }
    break;

  case IPPROTO_UDP:
    UDPFreePort( AddrFile->Port );
    break;
  }

  RemoveEntityByContext(AddrFile);

  ExFreePoolWithTag(Object, ADDR_FILE_TAG);
}
Exemple #8
0
/*
 * 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;
}
Exemple #9
0
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
}
Exemple #10
0
VOID NTAPI TiUnload(
  PDRIVER_OBJECT DriverObject)
/*
 * FUNCTION: Unloads the driver
 * ARGUMENTS:
 *     DriverObject = Pointer to driver object created by the system
 */
{


#if DBG
  KIRQL OldIrql;

  TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
  if (!IsListEmpty(&AddressFileListHead)) {
    TI_DbgPrint(MIN_TRACE, ("[TCPIP, TiUnload] Called. Open address file objects exists.\n"));
  }
  TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
#endif
  /* Cancel timer */
  KeCancelTimer(&IPTimer);

  /* Unregister loopback adapter */
  LoopUnregisterAdapter(NULL);

  /* Unregister protocol with NDIS */
  LANUnregisterProtocol();

  /* Shutdown transport level protocol subsystems */
  TCPShutdown();
  UDPShutdown();
  RawIPShutdown();
  ICMPShutdown();

  /* Shutdown network level protocol subsystem */
  IPShutdown();

  /* Free NDIS buffer descriptors */
  if (GlobalBufferPool)
    NdisFreeBufferPool(GlobalBufferPool);

  /* Free NDIS packet descriptors */
  if (GlobalPacketPool)
    NdisFreePacketPool(GlobalPacketPool);

  /* Release all device objects */

  if (TCPDeviceObject)
    IoDeleteDevice(TCPDeviceObject);

  if (UDPDeviceObject)
    IoDeleteDevice(UDPDeviceObject);

  if (RawIPDeviceObject)
    IoDeleteDevice(RawIPDeviceObject);

  if (IPDeviceObject) {
     ChewShutdown();
     IoDeleteDevice(IPDeviceObject);
  }

  if (EntityList)
    ExFreePoolWithTag(EntityList, TDI_ENTITY_TAG);

  TI_DbgPrint(MAX_TRACE, ("[TCPIP, TiUnload] Leaving.\n"));

}
Exemple #11
0
NTSTATUS NTAPI
TiDispatch(
  PDEVICE_OBJECT DeviceObject,
  PIRP Irp)
/*
 * FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests
 * ARGUMENTS:
 *     DeviceObject = Pointer to a device object for this driver
 *     Irp          = Pointer to a I/O request packet
 * RETURNS:
 *     Status of the operation
 */
{
  NTSTATUS Status;
  PIO_STACK_LOCATION IrpSp;

  IrpSp  = IoGetCurrentIrpStackLocation(Irp);

  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Called. IRP is at (0x%X).\n", Irp));

  Irp->IoStatus.Information = 0;

#if 0
  Status = TdiMapUserRequest(DeviceObject, Irp, IrpSp);
  if (NT_SUCCESS(Status)) {
    TiDispatchInternal(DeviceObject, Irp);
    Status = STATUS_PENDING;
  } else {
#else
  if (TRUE) {
#endif
    /* See if this request is TCP/IP specific */
    switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
    case IOCTL_TCP_QUERY_INFORMATION_EX:
      TI_DbgPrint(MIN_TRACE, ("TCP_QUERY_INFORMATION_EX\n"));
      Status = DispTdiQueryInformationEx(Irp, IrpSp);
      break;

    case IOCTL_TCP_SET_INFORMATION_EX:
      TI_DbgPrint(MIN_TRACE, ("TCP_SET_INFORMATION_EX\n"));
      Status = DispTdiSetInformationEx(Irp, IrpSp);
      break;

    case IOCTL_SET_IP_ADDRESS:
      TI_DbgPrint(MIN_TRACE, ("SET_IP_ADDRESS\n"));
      Status = DispTdiSetIPAddress(Irp, IrpSp);
      break;

    case IOCTL_DELETE_IP_ADDRESS:
      TI_DbgPrint(MIN_TRACE, ("DELETE_IP_ADDRESS\n"));
      Status = DispTdiDeleteIPAddress(Irp, IrpSp);
      break;

    case IOCTL_QUERY_IP_HW_ADDRESS:
      TI_DbgPrint(MIN_TRACE, ("QUERY_IP_HW_ADDRESS\n"));
      Status = DispTdiQueryIpHwAddress(DeviceObject, Irp, IrpSp);
      break;

    default:
      TI_DbgPrint(MIN_TRACE, ("Unknown IOCTL 0x%X\n",
          IrpSp->Parameters.DeviceIoControl.IoControlCode));
      Status = STATUS_NOT_IMPLEMENTED;
      break;
    }
  }

  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Leaving. Status = (0x%X).\n", Status));

  return IRPFinish( Irp, Status );
}


VOID NTAPI TiUnload(
  PDRIVER_OBJECT DriverObject)
/*
 * FUNCTION: Unloads the driver
 * ARGUMENTS:
 *     DriverObject = Pointer to driver object created by the system
 */
{
#if DBG
  KIRQL OldIrql;

  TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
  if (!IsListEmpty(&AddressFileListHead)) {
    TI_DbgPrint(MIN_TRACE, ("[TCPIP, TiUnload] Called. Open address file objects exists.\n"));
  }
  TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
#endif
  /* Cancel timer */
  KeCancelTimer(&IPTimer);

  /* Unregister loopback adapter */
  LoopUnregisterAdapter(NULL);

  /* Unregister protocol with NDIS */
  LANUnregisterProtocol();

  /* Shutdown transport level protocol subsystems */
  TCPShutdown();
  UDPShutdown();
  RawIPShutdown();
  ICMPShutdown();

  /* Shutdown network level protocol subsystem */
  IPShutdown();

  /* Free NDIS buffer descriptors */
  if (GlobalBufferPool)
    NdisFreeBufferPool(GlobalBufferPool);

  /* Free NDIS packet descriptors */
  if (GlobalPacketPool)
    NdisFreePacketPool(GlobalPacketPool);

  /* Release all device objects */

  if (TCPDeviceObject)
    IoDeleteDevice(TCPDeviceObject);

  if (UDPDeviceObject)
    IoDeleteDevice(UDPDeviceObject);

  if (RawIPDeviceObject)
    IoDeleteDevice(RawIPDeviceObject);

  if (IPDeviceObject) {
     ChewShutdown();
     IoDeleteDevice(IPDeviceObject);
  }

  if (EntityList)
    ExFreePoolWithTag(EntityList, TDI_ENTITY_TAG);

  TI_DbgPrint(MAX_TRACE, ("[TCPIP, TiUnload] Leaving.\n"));
}
Exemple #12
0
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;
}
Exemple #13
0
PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor(
  PIP_ADDRESS Address,
  PIP_INTERFACE Interface)
/*
 * FUNCTION: Locates a neighbor in the neighbor cache
 * ARGUMENTS:
 *   Address = Pointer to IP address
 *   Interface = Pointer to IP interface
 * RETURNS:
 *   Pointer to NCE, NULL if not found
 * NOTES:
 *   If the NCE is found, it is referenced. The caller is
 *   responsible for dereferencing it again after use
 */
{
  PNEIGHBOR_CACHE_ENTRY NCE;
  UINT HashValue;
  KIRQL OldIrql;
  PIP_INTERFACE FirstInterface;

  TI_DbgPrint(DEBUG_NCACHE, ("Called. Address (0x%X).\n", Address));

  HashValue = *(PULONG)&Address->Address;
  HashValue ^= HashValue >> 16;
  HashValue ^= HashValue >> 8;
  HashValue ^= HashValue >> 4;
  HashValue &= NB_HASHMASK;

  TcpipAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);

  /* If there's no adapter specified, we'll look for a match on
   * each one. */
  if (Interface == NULL)
  {
      FirstInterface = GetDefaultInterface();
      Interface = FirstInterface;
  }
  else
  {
      FirstInterface = NULL;
  }

  do
  {
      NCE = NeighborCache[HashValue].Cache;
      while (NCE != NULL)
      {
         if (NCE->Interface == Interface &&
             AddrIsEqual(Address, &NCE->Address))
         {
             break;
         }
 
         NCE = NCE->Next;
      }
      
      if (NCE != NULL)
          break;
  }
  while ((FirstInterface != NULL) &&
         ((Interface = GetDefaultInterface()) != FirstInterface));

  if ((NCE == NULL) && (FirstInterface != NULL))
  {
      /* This time we'll even match loopback NCEs */
      NCE = NeighborCache[HashValue].Cache;
      while (NCE != NULL)
      {
         if (AddrIsEqual(Address, &NCE->Address))
         {
             break;
         }

         NCE = NCE->Next;
      }
  }

  TcpipReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);

  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));

  return NCE;
}
Exemple #14
0
PNEIGHBOR_CACHE_ENTRY NBAddNeighbor(
  PIP_INTERFACE Interface,
  PIP_ADDRESS Address,
  PVOID LinkAddress,
  UINT LinkAddressLength,
  UCHAR State,
  UINT EventTimer)
/*
 * FUNCTION: Adds a neighbor to the neighbor cache
 * ARGUMENTS:
 *   Interface         = Pointer to interface
 *   Address           = Pointer to IP address
 *   LinkAddress       = Pointer to link address (may be NULL)
 *   LinkAddressLength = Length of link address
 *   State             = State of NCE
 * RETURNS:
 *   Pointer to NCE, NULL there is not enough free resources
 * NOTES:
 *   The NCE if referenced for the caller if created. The NCE retains
 *   a reference to the IP address if it is created, the caller is
 *   responsible for providing this reference
 */
{
  PNEIGHBOR_CACHE_ENTRY NCE;
  ULONG HashValue;
  KIRQL OldIrql;

  TI_DbgPrint
      (DEBUG_NCACHE,
       ("Called. Interface (0x%X)  Address (0x%X)  "
	"LinkAddress (0x%X)  LinkAddressLength (%d)  State (0x%X)\n",
	Interface, Address, LinkAddress, LinkAddressLength, State));

  NCE = ExAllocatePoolWithTag
      (NonPagedPool, sizeof(NEIGHBOR_CACHE_ENTRY) + LinkAddressLength,
       NCE_TAG);
  if (NCE == NULL)
    {
      TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
      return NULL;
    }

  NCE->Interface = Interface;
  NCE->Address = *Address;
  NCE->LinkAddressLength = LinkAddressLength;
  NCE->LinkAddress = (PVOID)&NCE[1];
  if( LinkAddress )
      RtlCopyMemory(NCE->LinkAddress, LinkAddress, LinkAddressLength);
  else
      memset(NCE->LinkAddress, 0xff, LinkAddressLength);
  NCE->State = State;
  NCE->EventTimer = EventTimer;
  NCE->EventCount = 0;
  InitializeListHead( &NCE->PacketQueue );

  TI_DbgPrint(MID_TRACE,("NCE: %x\n", NCE));

  HashValue = *(PULONG)&Address->Address;
  HashValue ^= HashValue >> 16;
  HashValue ^= HashValue >> 8;
  HashValue ^= HashValue >> 4;
  HashValue &= NB_HASHMASK;

  TcpipAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);

  NCE->Next = NeighborCache[HashValue].Cache;
  NeighborCache[HashValue].Cache = NCE;

  TcpipReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);

  return NCE;
}