2020-09-30 17:12:29 +02:00

536 lines
11 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
packet.c
Abstract:
This module contains code to copy from ndis packets to ndis packets,
and also to copy from ndis packets to a buffer.
Author:
Anthony V. Ercolano (Tonye) 12-Sept-1990
Environment:
Works in kernal mode, but is not important that it does.
Revision History:
--*/
#include <ntos.h>
#include <ndis.h>
#include <filter.h>
#include <pc586hrd.h>
#include <pc586sft.h>
extern
VOID
Pc586CopyFromPacketToBuffer(
IN PNDIS_PACKET Packet,
IN UINT Offset,
IN UINT BytesToCopy,
OUT PCHAR Buffer,
OUT PUINT BytesCopied
)
/*++
Routine Description:
Copy from an ndis packet into a buffer.
Arguments:
Packet - The packet to copy from.
Offset - The offset from which to start the copy.
BytesToCopy - The number of bytes to copy from the packet.
Buffer - The destination of the copy.
BytesCopied - The number of bytes actually copied. Can be less then
BytesToCopy if the packet is shorter than BytesToCopy.
Return Value:
None
--*/
{
//
// Holds the number of ndis buffers comprising the packet.
//
UINT NdisBufferCount;
//
// Points to the buffer from which we are extracting data.
//
PNDIS_BUFFER CurrentBuffer;
//
// Holds the virtual address of the current buffer.
//
PVOID VirtualAddress;
//
// Holds the length of the current buffer of the packet.
//
UINT CurrentLength;
//
// Keep a local variable of BytesCopied so we aren't referencing
// through a pointer.
//
UINT LocalBytesCopied = 0;
//
// Take care of boundary condition of zero length copy.
//
*BytesCopied = 0;
if (!BytesToCopy) return;
//
// Get the first buffer.
//
NdisQueryPacket(
Packet,
NULL,
&NdisBufferCount,
&CurrentBuffer,
NULL
);
//
// Could have a null packet.
//
if (!NdisBufferCount) return;
NdisQueryBuffer(
CurrentBuffer,
NULL,
&VirtualAddress,
&CurrentLength
);
while (LocalBytesCopied < BytesToCopy) {
if (!CurrentLength) {
NdisGetNextBuffer(
CurrentBuffer,
&CurrentBuffer
);
//
// We've reached the end of the packet. We return
// with what we've done so far. (Which must be shorter
// than requested.
//
if (!CurrentBuffer) break;
NdisQueryBuffer(
CurrentBuffer,
NULL,
&VirtualAddress,
&CurrentLength
);
continue;
}
//
// Try to get us up to the point to start the copy.
//
if (Offset) {
if (Offset > CurrentLength) {
//
// What we want isn't in this buffer.
//
Offset -= CurrentLength;
CurrentLength = 0;
continue;
} else {
VirtualAddress = (PCHAR)VirtualAddress + Offset;
CurrentLength -= Offset;
Offset = 0;
}
}
//
// Copy the data.
//
{
//
// Holds the amount of data to move.
//
UINT AmountToMove;
AmountToMove =
((CurrentLength <= (BytesToCopy - LocalBytesCopied))?
(CurrentLength):(BytesToCopy - LocalBytesCopied));
PC586_MOVE_MEMORY(
Buffer,
VirtualAddress,
AmountToMove
);
Buffer = (PCHAR)Buffer + AmountToMove;
VirtualAddress = (PCHAR)VirtualAddress + AmountToMove;
LocalBytesCopied += AmountToMove;
CurrentLength -= AmountToMove;
}
}
*BytesCopied = LocalBytesCopied;
}
extern
VOID
Pc586CopyFromPacketToPacket(
IN PNDIS_PACKET Destination,
IN UINT DestinationOffset,
IN UINT BytesToCopy,
IN PNDIS_PACKET Source,
IN UINT SourceOffset,
OUT PUINT BytesCopied
)
/*++
Routine Description:
Copy from an ndis packet to an ndis packet.
Arguments:
Destination - The packet should be copied in to.
DestinationOffset - The offset from the beginning of the packet
into which the data should start being placed.
BytesToCopy - The number of bytes to copy from the source packet.
Source - The ndis packet from which to copy data.
SourceOffset - The offset from the start of the packet from which
to start copying data.
BytesCopied - The number of bytes actually copied from the source
packet. This can be less than BytesToCopy if the source or destination
packet is too short.
Return Value:
None
--*/
{
//
// Holds the count of the number of ndis buffers comprising the
// destination packet.
//
UINT DestinationBufferCount;
//
// Holds the count of the number of ndis buffers comprising the
// source packet.
//
UINT SourceBufferCount;
//
// Points to the buffer into which we are putting data.
//
PNDIS_BUFFER DestinationCurrentBuffer;
//
// Points to the buffer from which we are extracting data.
//
PNDIS_BUFFER SourceCurrentBuffer;
//
// Holds the virtual address of the current destination buffer.
//
PVOID DestinationVirtualAddress;
//
// Holds the virtual address of the current source buffer.
//
PVOID SourceVirtualAddress;
//
// Holds the length of the current destination buffer.
//
UINT DestinationCurrentLength;
//
// Holds the length of the current source buffer.
//
UINT SourceCurrentLength;
//
// Keep a local variable of BytesCopied so we aren't referencing
// through a pointer.
//
UINT LocalBytesCopied = 0;
//
// Take care of boundary condition of zero length copy.
//
*BytesCopied = 0;
if (!BytesToCopy) return;
//
// Get the first buffer of the destination.
//
NdisQueryPacket(
Destination,
NULL,
&DestinationBufferCount,
&DestinationCurrentBuffer,
NULL
);
//
// Could have a null packet.
//
if (!DestinationBufferCount) return;
NdisQueryBuffer(
DestinationCurrentBuffer,
NULL,
&DestinationVirtualAddress,
&DestinationCurrentLength
);
//
// Get the first buffer of the source.
//
NdisQueryPacket(
Source,
NULL,
&SourceBufferCount,
&SourceCurrentBuffer,
NULL
);
//
// Could have a null packet.
//
if (!SourceBufferCount) return;
NdisQueryBuffer(
SourceCurrentBuffer,
NULL,
&SourceVirtualAddress,
&SourceCurrentLength
);
while (LocalBytesCopied < BytesToCopy) {
//
// Check to see whether we've exhausted the current destination
// buffer. If so, move onto the next one.
//
if (!DestinationCurrentLength) {
NdisGetNextBuffer(
DestinationCurrentBuffer,
&DestinationCurrentBuffer
);
if (!DestinationCurrentBuffer) {
//
// We've reached the end of the packet. We return
// with what we've done so far. (Which must be shorter
// than requested.)
//
break;
}
NdisQueryBuffer(
DestinationCurrentBuffer,
NULL,
&DestinationVirtualAddress,
&DestinationCurrentLength
);
continue;
}
//
// Check to see whether we've exhausted the current source
// buffer. If so, move onto the next one.
//
if (!SourceCurrentLength) {
NdisGetNextBuffer(
SourceCurrentBuffer,
&SourceCurrentBuffer
);
if (!SourceCurrentBuffer) {
//
// We've reached the end of the packet. We return
// with what we've done so far. (Which must be shorter
// than requested.)
//
break;
}
NdisQueryBuffer(
SourceCurrentBuffer,
NULL,
&SourceVirtualAddress,
&SourceCurrentLength
);
continue;
}
//
// Try to get us up to the point to start the copy.
//
if (DestinationOffset) {
if (DestinationOffset > DestinationCurrentLength) {
//
// What we want isn't in this buffer.
//
DestinationOffset -= DestinationCurrentLength;
DestinationCurrentLength = 0;
continue;
} else {
DestinationVirtualAddress = (PCHAR)DestinationVirtualAddress
+ DestinationOffset;
DestinationCurrentLength -= DestinationOffset;
DestinationOffset = 0;
}
}
//
// Try to get us up to the point to start the copy.
//
if (SourceOffset) {
if (SourceOffset > SourceCurrentLength) {
//
// What we want isn't in this buffer.
//
SourceOffset -= SourceCurrentLength;
SourceCurrentLength = 0;
continue;
} else {
SourceVirtualAddress = (PCHAR)SourceVirtualAddress
+ SourceOffset;
SourceCurrentLength -= SourceOffset;
SourceOffset = 0;
}
}
//
// Copy the data.
//
{
//
// Holds the amount of data to move.
//
UINT AmountToMove;
//
// Holds the amount desired remaining.
//
UINT Remaining = BytesToCopy - LocalBytesCopied;
AmountToMove =
((SourceCurrentLength <= DestinationCurrentLength)?
(SourceCurrentLength):(DestinationCurrentLength));
AmountToMove = ((Remaining < AmountToMove)?
(Remaining):(AmountToMove));
PC586_MOVE_MEMORY(
DestinationVirtualAddress,
SourceVirtualAddress,
AmountToMove
);
DestinationVirtualAddress =
(PCHAR)DestinationVirtualAddress + AmountToMove;
SourceVirtualAddress =
(PCHAR)SourceVirtualAddress + AmountToMove;
LocalBytesCopied += AmountToMove;
SourceCurrentLength -= AmountToMove;
DestinationCurrentLength -= AmountToMove;
}
}
*BytesCopied = LocalBytesCopied;
}