📄 read.c
字号:
/*
* NtSniff by Davide Libenzi ( To rebuild NtSniff You need Microsoft SDK & DDK )
* Copyright (C) 1999 Davide Libenzi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Davide Libenzi <davidel@maticad.it>
*
*/
#include "stdarg.h"
#include "ntddk.h"
#include "ntiologc.h"
#include "ndis.h"
#include "debug.h"
#include "packet.h"
NTSTATUS
PacketRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
/*++ MS say
Routine Description:
This is the dispatch routine for create/open and close requests.
These requests complete successfully.
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
Status is returned.
--*/
{
POPEN_INSTANCE Open;
PIO_STACK_LOCATION IrpSp;
PNDIS_PACKET pPacket;
PMDL pMdl;
NDIS_STATUS Status;
IF_LOUD(DbgPrint("Packet: Read\n"));
IrpSp = IoGetCurrentIrpStackLocation(Irp);
Open = IrpSp->FileObject->FsContext;
//
// See if the buffer is atleast big enough to hold the
// ethernet header
//
if (IrpSp->Parameters.Read.Length < ETHERNET_HEADER_LENGTH)
{
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
return STATUS_UNSUCCESSFUL;
}
//
// Allocate an MDL to map the portion of the buffer following the
// header
//
pMdl = IoAllocateMdl(MmGetMdlVirtualAddress(Irp->MdlAddress),
MmGetMdlByteCount(Irp->MdlAddress), FALSE, FALSE, NULL);
if (pMdl == NULL)
{
IF_LOUD(DbgPrint("Packet: Read-Failed to allocate Mdl\n"));
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
return STATUS_UNSUCCESSFUL;
}
//
// Build the mdl to point to the the portion of the buffer followin
// the header
//
IoBuildPartialMdl(Irp->MdlAddress, pMdl,
((PUCHAR) MmGetMdlVirtualAddress(Irp->MdlAddress)) + ETHERNET_HEADER_LENGTH, 0);
//
// Clear the next link in the new MDL
//
pMdl->Next = NULL;
//
// Try to get a packet from our list of free ones
//
NdisAllocatePacket(&Status, &pPacket, Open->PacketPool);
if (Status != NDIS_STATUS_SUCCESS)
{
IF_LOUD(DbgPrint("Packet: Read- No free packets\n"));
IoFreeMdl(pMdl);
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
return STATUS_UNSUCCESSFUL;
}
//
// Get a pointer to the packet itself
//
RESERVED(pPacket)->Irp = Irp;
RESERVED(pPacket)->pMdl = pMdl;
IoMarkIrpPending(Irp);
Irp->IoStatus.Status = STATUS_PENDING;
//
// Attach our new MDL to the packet
//
NdisChainBufferAtFront(pPacket, pMdl);
//
// Put this packet in a list of pending reads.
// The receive indication handler will attemp to remove packets
// from this list for use in transfer data calls
//
ExInterlockedInsertTailList(&Open->RcvList, &RESERVED(pPacket)->ListElement,
&Open->RcvQSpinLock);
return (STATUS_PENDING);
}
NDIS_STATUS
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;
PIO_STACK_LOCATION IrpSp;
PIRP Irp;
PLIST_ENTRY PacketListEntry;
PNDIS_PACKET pPacket;
ULONG SizeToTransfer;
NDIS_STATUS Status;
UINT BytesTransfered;
ULONG BufferLength;
PPACKET_RESERVED Reserved;
IF_LOUD(DbgPrint("Packet: ReceiveIndicate\n"));
Open = (POPEN_INSTANCE) ProtocolBindingContext;
if (HeaderBufferSize > ETHERNET_HEADER_LENGTH)
return NDIS_STATUS_SUCCESS;
//
// See if there are any pending read that we can satisfy
//
PacketListEntry = ExInterlockedRemoveHeadList(&Open->RcvList, &Open->RcvQSpinLock);
if (PacketListEntry == NULL)
return NDIS_STATUS_SUCCESS;
Reserved = CONTAINING_RECORD(PacketListEntry, PACKET_RESERVED, ListElement);
pPacket = CONTAINING_RECORD(Reserved, NDIS_PACKET, ProtocolReserved);
Irp = RESERVED(pPacket)->Irp;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
//
// This is the length of our partial MDL
//
BufferLength = IrpSp->Parameters.Read.Length - ETHERNET_HEADER_LENGTH;
//
// Find out how much to transfer
//
SizeToTransfer = (PacketSize < BufferLength) ? PacketSize : BufferLength;
//
// copy the ethernet header into the actual readbuffer
//
NdisMoveMappedMemory(MmGetSystemAddressForMdl(Irp->MdlAddress), HeaderBuffer,
HeaderBufferSize);
//
// Call the Mac to transfer the packet
//
NdisTransferData(&Status, Open->AdapterHandle, MacReceiveContext,
0, SizeToTransfer, pPacket, &BytesTransfered);
if (Status != NDIS_STATUS_PENDING)
{
//
// If it didn't pend, call the completeion routine now
//
PacketTransferDataComplete(Open, pPacket, Status, BytesTransfered);
}
return NDIS_STATUS_SUCCESS;
}
VOID
PacketTransferDataComplete(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pPacket,
IN NDIS_STATUS Status, IN UINT BytesTransfered)
{
PIO_STACK_LOCATION IrpSp;
POPEN_INSTANCE Open;
PIRP Irp;
PMDL pMdl;
IF_LOUD(DbgPrint("Packet: TransferDataComplete\n"));
Open = (POPEN_INSTANCE) ProtocolBindingContext;
Irp = RESERVED(pPacket)->Irp;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
pMdl = RESERVED(pPacket)->pMdl;
//
// Free the MDL that we allocated
//
IoFreeMdl(pMdl);
//
// recylcle the packet
//
NdisReinitializePacket(pPacket);
//
// Put the packet on the free queue
//
NdisFreePacket(pPacket);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = BytesTransfered + ETHERNET_HEADER_LENGTH;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
VOID
PacketReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext)
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -