⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 openclos.c

📁 一个简单的sniffer,下载后请用winrar
💻 C
字号:
// openclos.c - PacketBindAdapter, PacketBindAdapterComplete,
//              PacketUnbindAdapter, PacketUnbindAdapterComplete,
//              PacketCleanUp, PacketReset, PacketResetComplete

// Original code by William Ingle (address unknown)
// debugged and extended by Chris Chlap (chrisc@fir.canberra.edu.au)

#include <basedef.h>
#include <vmm.h>
#include <ndis.h>
#include <vwin32.h>
#include <debug.h>

#include "packet.h"

#pragma VxD_LOCKED_CODE_SEG
#pragma VxD_LOCKED_DATA_SEG

//--------------------------------------------------------------------
//
//  PacketBindAdapter - bind this driver to a NIC
//
//--------------------------------------------------------------------

VOID NDIS_API PacketBindAdapter(OUT PNDIS_STATUS pStatus,
                                IN  NDIS_HANDLE  BindAdapterContext,
                                IN  PNDIS_STRING pAdapterName,
                                IN  PVOID        SystemSpecific1,
                                IN  PVOID        SystemSpecific2)

{
    PDEVICE_EXTENSION   pde;
    POPEN_INSTANCE      oiNew;
	NDIS_STATUS			ErrorStatus, AllocStatus;
    UINT                Medium;
    NDIS_MEDIUM         MediumArray=NdisMedium802_3;
//    NDIS_MEDIUM         MediumArray=NdisMediumWan;
    UINT                i;

    PWRAPPER_PROTOCOL_BLOCK         pWPBlock;
    PNDIS_PROTOCOL_CHARACTERISTICS  pNPChar;

    pde = GlobalDeviceExtension;

    //
    //  allocate some memory for the open structure
    //

    NdisAllocateMemory((PVOID *)&oiNew, sizeof( OPEN_INSTANCE ), 0, -1);

    if (oiNew == NULL) {
        // not enough memory
        *pStatus = NDIS_STATUS_RESOURCES;
        Debug_Out("PacketBindAdapter: ERROR: no memory for Open\n"); 
        return;
    }

    NdisZeroMemory((PVOID)oiNew, sizeof(OPEN_INSTANCE));

	// Save Binding Context
	oiNew->BindAdapterContext = BindAdapterContext;

    // Save the device handle
    
    oiNew->hDevice = (DWORD) SystemSpecific1;

    //
    // Allocate a packet pool for our xmit and receive packets
    //
    NdisAllocatePacketPool(&AllocStatus,
                           &(oiNew->PacketPool),
                           TRANSMIT_PACKETS,
                           sizeof(PACKET_RESERVED));

    if (AllocStatus != NDIS_STATUS_SUCCESS) {

        // not enough memory
        NdisFreeMemory( oiNew, sizeof(OPEN_INSTANCE),  0);
        *pStatus = NDIS_STATUS_RESOURCES;
        Debug_Out("PacketBindAdapter: ERROR: no memory for Packet Pool\n"); 
        return;
    }

	//
	// Allocate a buffer pool for our xmit and receive buffers
	//
    NdisAllocateBufferPool(&AllocStatus, &(oiNew->BufferPool), TRANSMIT_PACKETS);

    if (AllocStatus != NDIS_STATUS_SUCCESS) {

        // not enough memory

//BUG: free packet pool first

        NdisFreeMemory(oiNew, sizeof(OPEN_INSTANCE), 0);
        *pStatus = NDIS_STATUS_RESOURCES;
        Debug_Out("PacketBindAdapter: ERROR: no memory for Buffer Pool\n"); 
        return;
    }
    //
    //  list to hold irp's that want to reset the adapter
    //
    NdisAllocateSpinLock(&(oiNew->ResetSpinLock));
    InitializeListHead(&(oiNew->ResetIrpList));

    //
    //  Initialize list for holding pending read requests
    //
    NdisAllocateSpinLock(&(oiNew->RcvQSpinLock));
    InitializeListHead(&(oiNew->RcvList));

    //
    //  Initialize the request list
    //
    NdisAllocateSpinLock(&(oiNew->RequestSpinLock));
    InitializeListHead(&(oiNew->RequestList));

    //
    //  link up the request stored in our open block
    //
    for (i=0; i<MAX_REQUESTS; i++) {
        InsertTailList(&(oiNew->RequestList),
                       &(oiNew->Requests[i].Reserved.ListElement));
    }

    //
    //  Try to open the MAC
    //
    NdisOpenAdapter(pStatus, &ErrorStatus, &oiNew->AdapterHandle, &Medium,
                    &MediumArray, 1, pde->NdisProtocolHandle, oiNew,
                    pAdapterName, 0, NULL);

	//
	//  Test for protocol name and adapter name
	//
	pWPBlock = ((PWRAPPER_OPEN_BLOCK)(oiNew->AdapterHandle))->ProtocolHandle;
	pNPChar  = &pWPBlock->ProtocolCharacteristics;

	//
	//  Save the status returned by NdisOpenAdapter for completion routine
	//
    oiNew->Status = *pStatus;

    switch (*pStatus) {
        case NDIS_STATUS_PENDING:
    Debug_Out("PacketBindAdapter: NdisOpenAdapter: Status Pending\n");
                break;

        case NDIS_STATUS_SUCCESS:
                ErrorStatus = NDIS_STATUS_SUCCESS;

        // fall through to completion routine with oiNew->Status 
        // set to !NDIS_STATUS_PENDING

        default:
                PacketBindAdapterComplete(oiNew, *pStatus, ErrorStatus);
                break;
    }
    return;
}

//--------------------------------------------------------------------
//
//  PacketBindAdapterComplete - upcall on Bind completion
//
//--------------------------------------------------------------------

VOID NDIS_API PacketBindAdapterComplete(
                                    IN NDIS_HANDLE  ProtocolBindingContext,
                                    IN NDIS_STATUS  Status,
                                    IN NDIS_STATUS  OpenErrorStatus)

{
    POPEN_INSTANCE Open;

    Open = (POPEN_INSTANCE)ProtocolBindingContext;

	//
    // If the binding is unsuccessful then we deallocate data structures in 
    // preparation for unloading
	//
    if (Status != NDIS_STATUS_SUCCESS) {
        NdisFreeSpinLock(&Open->RequestSpinLock);
        NdisFreeSpinLock(&Open->RcvQSpinLock);

        NdisFreeBufferPool(Open->BufferPool);
        NdisFreePacketPool(Open->PacketPool);

        NdisFreeMemory(Open, sizeof(OPEN_INSTANCE), 0);

        
        Debug_Out("PacketBindAdapterComplete: ERROR: could not bind\n"); 
		return;
	}

	//
	// Insert New Adapter into list
	//
    
    InsertTailList(&GlobalDeviceExtension->OpenList, &Open->ListElement);

	//
    // If the Open->Status == NDIS_STATUS_PENDING 
    // then we must complete the pended binding
	//

// Apparently, it is safe to NOT call NdisCompleteBindAdapter, even if
// Open->Status == NDIS_STATUS_PENDING

//    if (Open->Status == NDIS_STATUS_PENDING) {
//        NdisCompleteBindAdapter(Open->BindAdapterContext, Status, 
//                                OpenErrorStatus);
//        Open->Status = NDIS_STATUS_SUCCESS;
//    }

    //
	// Initialize some media information
	//
	return;
}

//--------------------------------------------------------------------
//
//  PacketUnbindAdapter - detach protocol from the NIC
//
//--------------------------------------------------------------------

VOID NDIS_API
PacketUnbindAdapter(OUT PNDIS_STATUS    Status,
                    IN  POPEN_INSTANCE   Open,
                    IN  POPEN_INSTANCE   junk)

{
	//
	// clean up any pending I/O requests
	//

    PacketCleanUp(Status, Open);

    //
    // close the adapter
    //
Debug_Out("PacketUnbindAdapter: calling NdisCloseAdapter\n");

    NdisCloseAdapter(Status, Open->AdapterHandle);

Debug_Out("PacketUnbindAdapter: NdisCloseAdapter returned\n");

	//
	// Save status returned from NdisCloseAdapter for completion routine
	//
    
    Open->Status = *Status;

    if (*Status != NDIS_STATUS_PENDING) 
        PacketUnbindAdapterComplete(Open, *Status);

Debug_Out("PacketUnbindAdapter: done\n");

    return;
}

//--------------------------------------------------------------------
//
//  PacketUnbindAdapterComplete - upcall on NdisCloseAdapter completion
//
//--------------------------------------------------------------------

VOID NDIS_API
PacketUnbindAdapterComplete(IN POPEN_INSTANCE Open,
                            IN NDIS_STATUS Status)

{
Debug_Out("CloseAdapterComplete: entered\n");
	//
    // If Open->Status == NDIS_STATUS_PENDING   
    // then we must complete the pended unbinding
	//
    if (Open->Status == NDIS_STATUS_PENDING) {
        NdisCompleteUnbindAdapter(Open->BindAdapterContext, Status);
		Open->Status = NDIS_STATUS_SUCCESS;
	}

    if (Status == NDIS_STATUS_SUCCESS) {
        
		//
		// Remove Adapter from global list
		//
        RemoveEntryList(&Open->ListElement);

		//
		// Free Memory
		//
        NdisFreeSpinLock(&Open->RequestSpinLock);
        NdisFreeSpinLock(&Open->RcvQSpinLock);
        NdisFreeSpinLock(&Open->ResetSpinLock);

        NdisFreeBufferPool(Open->BufferPool);

        NdisFreePacketPool(Open->PacketPool);

        NdisFreeMemory(Open, sizeof(OPEN_INSTANCE), 0);
	}

    return;
}

//--------------------------------------------------------------------
//
//  PacketCleanUp - cleanup before closing
//
//--------------------------------------------------------------------

VOID PacketCleanUp(PNDIS_STATUS Status,
                   POPEN_INSTANCE Open)

{
    PLIST_ENTRY     PacketListEntry;
    PNDIS_PACKET    pPacket;

    //
    //  The open instance of the device is about to close
    //  We need to complete all pending I/O requests
    //  First we complete any pending read requests
    //
    NdisAcquireSpinLock(&Open->RcvQSpinLock);

    while (!IsListEmpty(&Open->RcvList)) {
        PacketListEntry = RemoveHeadList(&Open->RcvList);

        pPacket = CONTAINING_RECORD(PacketListEntry, NDIS_PACKET, ProtocolReserved);

        //
        //  complete normally
        //
        PacketTransferDataComplete(Open, pPacket, NDIS_STATUS_SUCCESS, 0);
    }

    NdisReleaseSpinLock(&Open->RcvQSpinLock);

//    PacketReset(Status, Open);

    return;
}

//--------------------------------------------------------------------
//
//  PacketReset - reset the protocol
//
//--------------------------------------------------------------------

VOID PacketReset(PNDIS_STATUS   pStatus,
                 POPEN_INSTANCE pOpen)
                 
{
	PLIST_ENTRY	ResetListEntry;

	//
	// Acquire request element from list
	//

    NdisAllocateSpinLock(&pOpen->RequestSpinLock);

    if (IsListEmpty(&pOpen->RequestList)) { 
        NdisReleaseSpinLock(&pOpen->RequestSpinLock);
        *pStatus = NDIS_STATUS_RESOURCES;
Debug_Out("PacketReset: ERROR: RequestList empty\n");
        return;
	}
    else {
        ResetListEntry = RemoveHeadList(&pOpen->RequestList);
        NdisReleaseSpinLock(&pOpen->RequestSpinLock);
    }

 	//
	// Insert Reset IRP into Request Queue
	//

    NdisAcquireSpinLock(&pOpen->ResetSpinLock);

    InsertTailList(&pOpen->ResetIrpList, ResetListEntry);

    NdisReleaseSpinLock(&pOpen->ResetSpinLock);


	//
	// Reset the adapter
	//

    NdisReset(pStatus, pOpen->AdapterHandle);

    if (*pStatus != NDIS_STATUS_PENDING) {
        PacketResetComplete(pOpen, *pStatus);
    }

	return;
}
	
//--------------------------------------------------------------------
//
//  PacketResetComplete - upcall on reset completion
//
//--------------------------------------------------------------------

VOID NDIS_API PacketResetComplete(IN NDIS_HANDLE ProtocolBindingContext,
                                  IN NDIS_STATUS Status)

{
    POPEN_INSTANCE   Open;
    PLIST_ENTRY      ResetListEntry;

    Open = (POPEN_INSTANCE)ProtocolBindingContext;

    //
    //  remove the reset request from the list
    //
   
    NdisAcquireSpinLock(&Open->ResetSpinLock);

    if (IsListEmpty(&Open->ResetIrpList)) { 
        NdisReleaseSpinLock(&Open->ResetSpinLock);
Debug_Out("PacketResetComplete: ERROR: ResetIrpList empty\n");
        return;
	}
    else {
        ResetListEntry = RemoveHeadList(&Open->ResetIrpList);
        NdisReleaseSpinLock(&Open->ResetSpinLock);
    }

	//
	// Acquire request element from list
	//
    
    NdisAcquireSpinLock(&Open->RequestSpinLock);

    InsertTailList(&Open->RequestList, ResetListEntry);

    NdisReleaseSpinLock(&Open->RequestSpinLock);

    return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -