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

📄 read.c

📁 一个简单的sniffer,下载后请用winrar
💻 C
字号:
// read.c - PacketAllocatePacketBuffer, PacketRead, PacketReceiveIndicate,
//          PacketTransferDataComplete, PacketReceiveComplete

// 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 <debug.h>
#include <ndis.h>
#include <vwin32.h>

#include "packet.h"
#include "ntddpack.h"

#pragma VxD_LOCKED_CODE_SEG
#pragma VxD_LOCKED_DATA_SEG

//--------------------------------------------------------------------
//
//  PacketAllocatePacketBuffer - allocate a buffer for reading/writing
//
//--------------------------------------------------------------------

VOID PacketAllocatePacketBuffer(PNDIS_STATUS    pStatus,
                                POPEN_INSTANCE  pOpen,
                                PNDIS_PACKET    *ppPacket,
                                PDIOCPARAMETERS pDiocParms,
                                DWORD           FunctionCode )
{
    PNDIS_BUFFER pNdisBuffer;
    PNDIS_PACKET pPacket;
    
    //
    //  Try to get a packet from our list of free ones
    //

    NdisAllocatePacket(pStatus, ppPacket, pOpen->PacketPool);

    if (*pStatus != NDIS_STATUS_SUCCESS) {
Debug_Out("PacketAllocatePacketBuffer: ERROR: no packet buffer\n");
		*(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
		return;
    }
    
    pPacket = *ppPacket;

    //
	// Buffers used asynchronously must be page locked
	//

    switch (FunctionCode) {
        case IOCTL_PROTOCOL_READ:
            RESERVED(pPacket)->lpBuffer = (PVOID)PacketPageLock((PVOID) pDiocParms->lpvOutBuffer, pDiocParms->cbOutBuffer);
            RESERVED(pPacket)->cbBuffer = pDiocParms->cbOutBuffer;
            break;

        case IOCTL_PROTOCOL_WRITE:
            RESERVED(pPacket)->lpBuffer = (PVOID)PacketPageLock(pDiocParms->lpvInBuffer, pDiocParms->cbInBuffer);
            RESERVED(pPacket)->cbBuffer = pDiocParms->cbInBuffer;
            break;

        default:
Debug_Out("PacketAllocatePacketBuffer: ERROR: Bad FunctionCode\n");
            // recycle the packet
            NdisReinitializePacket(pPacket);
            
            // Put the packet on the free queue
            NdisFreePacket(pPacket);
	
            *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
            *pStatus = NDIS_STATUS_NOT_ACCEPTED;
            return;
	}
	
    RESERVED(pPacket)->lpcbBytesReturned = (PVOID)PacketPageLock((PVOID) pDiocParms->lpcbBytesReturned, sizeof(DWORD));
    RESERVED(pPacket)->lpoOverlapped     = (PVOID)PacketPageLock((PVOID) pDiocParms->lpoOverlapped, sizeof(OVERLAPPED));
    RESERVED(pPacket)->hDevice           = pDiocParms->hDevice;
    RESERVED(pPacket)->tagProcess        = pDiocParms->tagProcess;

    switch (FunctionCode) {
        case IOCTL_PROTOCOL_READ:
            NdisAllocateBuffer(pStatus, 
                               &pNdisBuffer, 
                               pOpen->BufferPool, 
                (PVOID)(RESERVED(pPacket)->lpBuffer + ETHERNET_HEADER_LENGTH),
                               pDiocParms->cbOutBuffer);
            break;

        case IOCTL_PROTOCOL_WRITE:
            NdisAllocateBuffer(pStatus, 
                           &pNdisBuffer, 
                           pOpen->BufferPool, 
                           (PVOID)RESERVED(pPacket)->lpBuffer,
                           pDiocParms->cbInBuffer);
            break;
    }

    if (*pStatus != NDIS_STATUS_SUCCESS) {
Debug_Out("PacketAllocatePacketBuffer: ERROR: no buffer descriptor\n");

        // recycle the packet

        NdisReinitializePacket(pPacket);

        // Put the packet on the free queue

        NdisFreePacket(pPacket);
	
		*(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
        return;
	}

	// Attach buffer to Packet

    NdisChainBufferAtFront(pPacket, pNdisBuffer);

	return;
}

//--------------------------------------------------------------------
//
//  PacketRead - read a packet
//
//--------------------------------------------------------------------

DWORD PacketRead(POPEN_INSTANCE     Open,
                 DWORD              dwDDB,
                 DWORD              hDevice,
                 PDIOCPARAMETERS    pDiocParms)

{
    NDIS_STATUS     Status;
    PNDIS_PACKET    pPacket;

    //
    //  Check that the buffer can hold a max length Ethernet packet
    //

    if (pDiocParms->cbOutBuffer < ETHERNET_PACKET_LENGTH) {
        // Need bigger buffer       
		*(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
Debug_Out("Debug_Out: PacketRead: ERROR: buffer length not 1514 bytes\n"); 
        return NDIS_STATUS_SUCCESS;
    }

    PacketAllocatePacketBuffer(&Status, Open, &pPacket, pDiocParms, IOCTL_PROTOCOL_READ);

    if (Status == NDIS_STATUS_SUCCESS) {
        //
        //  Put this packet in a list of pending reads.
        //  The receive indication handler will attempt to remove packets
        //  from this list for use in transfer data calls
        //
        NdisAcquireSpinLock(&Open->RcvQSpinLock); // fixed 6.11.97

        InsertTailList(&Open->RcvList, &RESERVED(pPacket)->ListElement);

        NdisReleaseSpinLock(&Open->RcvQSpinLock);
    }
else Debug_Out("PacketRead: ERROR: allocate packet buffer failed\n");
    return -1;  // This will make DeviceIOControl return ERROR_IO_PENDING
}

//--------------------------------------------------------------------
//
//  PacketReceiveIndicate - upcall on packet arrival
//
//--------------------------------------------------------------------

NDIS_STATUS NDIS_API PacketReceiveIndicate(
    IN NDIS_HANDLE ProtocolBindingContext,
    IN NDIS_HANDLE MacReceiveContext,
    IN PVOID       HeaderBuffer,
    IN UINT        HeaderBufferSize,
    IN PVOID       LookaheadBuffer,
    IN UINT        LookaheadBufferSize,
    IN UINT        PacketSize)

{
    POPEN_INSTANCE      Open;
    PLIST_ENTRY         PacketListEntry;
    PNDIS_PACKET        pPacket;
    NDIS_STATUS         Status;
    UINT                BytesTransfered = 0;
    ULONG               BufferLength;
    PPACKET_RESERVED    pReserved;
//    UINT                flags;
        
    if (HeaderBufferSize != ETHERNET_HEADER_LENGTH) {
Debug_Out("PacketReceiveIndicate: ERROR: bad HeaderBufferSize\n");
        return NDIS_STATUS_NOT_ACCEPTED;
    }

    Open = (POPEN_INSTANCE) ProtocolBindingContext;

    //
    //  See if there are any pending reads that we can satisfy
    //
    
    NdisAcquireSpinLock(&Open->RcvQSpinLock); // fixed 6.11.97

    if (IsListEmpty(&Open->RcvList)) { 
        NdisReleaseSpinLock(&Open->RcvQSpinLock);
Debug_Out("PacketReceiveIndicate: ERROR: RcvList empty\n");
        return NDIS_STATUS_NOT_ACCEPTED;
	}
    else {
        PacketListEntry = RemoveHeadList(&Open->RcvList);
        NdisReleaseSpinLock(&Open->RcvQSpinLock);
    }

    pReserved = CONTAINING_RECORD(PacketListEntry, PACKET_RESERVED, ListElement);
    pPacket  =  CONTAINING_RECORD(pReserved, NDIS_PACKET, ProtocolReserved);

    //
    // Copy the MAC header
    //

    NdisMoveMemory(RESERVED(pPacket)->lpBuffer, HeaderBuffer, HeaderBufferSize);
//NdisQuerySendFlags(pPacket, &flags);
//NdisMoveMemory(RESERVED(pPacket)->lpBuffer, &flags, 4);        
    //
    //  Call the Mac to transfer the data portion of the packet
    //

    NdisTransferData(&Status, Open->AdapterHandle, MacReceiveContext, 
                     0, PacketSize, pPacket, &BytesTransfered);

    if (Status == NDIS_STATUS_PENDING) {
Debug_Out("PacketReceiveIndicate: NdisTransfer pending\n");
        return NDIS_STATUS_SUCCESS;
    } 
    if (Status == NDIS_STATUS_SUCCESS) {
Debug_Out("PacketReceiveIndicate: NdisTransfer complete\n");
        PacketTransferDataComplete(Open, pPacket, Status, BytesTransfered);
        return NDIS_STATUS_SUCCESS;
    } 
Debug_Out("PacketReceiveIndicate: ERROR: NdisTransfer\n");
    PacketTransferDataComplete(Open, pPacket, Status, 0);
    return NDIS_STATUS_SUCCESS;
}

//--------------------------------------------------------------------
//
//  PacketTransferDataComplete - upcall when no more data available
//
//--------------------------------------------------------------------

VOID NDIS_API PacketTransferDataComplete(
                IN NDIS_HANDLE  ProtocolBindingContext,
                IN PNDIS_PACKET pPacket,
                IN NDIS_STATUS  Status,
                IN UINT         BytesTransfered)
{
    POPEN_INSTANCE      Open;
    PPACKET_RESERVED    pReserved;
	OVERLAPPED*			pOverlap;
	PNDIS_BUFFER		pNdisBuffer;

    Open        = (POPEN_INSTANCE) ProtocolBindingContext;
    pReserved   = ((PPACKET_RESERVED) (pPacket->ProtocolReserved));
    pOverlap    = ((OVERLAPPED *) (pReserved->lpoOverlapped));

    //
	// free buffer descriptor
	//

    NdisUnchainBufferAtFront(pPacket, &pNdisBuffer);
	
    if (pNdisBuffer)
        NdisFreeBuffer(pNdisBuffer);

	//
	// set total bytes returned
	//

    BytesTransfered += ETHERNET_HEADER_LENGTH;
    *(pReserved->lpcbBytesReturned) += BytesTransfered;

    pOverlap->O_InternalHigh        = *(pReserved->lpcbBytesReturned);

	//
    // The internal member of overlapped structure contains
    // a pointer to the event structure that will be signalled,
    // resuming the execution of the waitng GetOverlappedResult
    // call.
    //
    
    VWIN32_DIOCCompletionRoutine(pOverlap->O_Internal);


    // Unlock buffers   

    PacketPageUnlock(pReserved->lpBuffer, pReserved->cbBuffer);
    PacketPageUnlock(pReserved->lpcbBytesReturned, sizeof(DWORD));
    PacketPageUnlock(pReserved->lpoOverlapped, sizeof(OVERLAPPED));

    // recycle the packet

    NdisReinitializePacket(pPacket);

    // Put the packet on the free queue

    NdisFreePacket(pPacket);
    return;
}

//--------------------------------------------------------------------
//
//  PacketReceiveComplete - upcall when receive complete
//
//--------------------------------------------------------------------


VOID NDIS_API PacketReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext)
{
    return;
}

⌨️ 快捷键说明

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