📄 filterrtns.cpp
字号:
/**************************************************************************************************/
/* */
/* Copyright (C) 2003, James Antognini, antognini@mindspring.com. */
/* */
/**************************************************************************************************/
#ifdef __cplusplus // C++ conversion
extern "C"
{
#endif
#include <ndis.h>
#include "passthru.h"
#include "PktHdr.h"
#include "WMIFunc.h"
#ifdef __cplusplus // C++ conversion
}
#endif
#define JADrvNm "JApassthru"
#define JADrvRtnsName "FilterRtns"
#define JADrvRtnsVer "1.01"
#pragma comment(exestr, /* ja, 04.10.2003. */ \
JADrvNm " " JADrvRtnsName " v" JADrvRtnsVer " compiled on " __DATE__ " at " __TIME__)
/**************************************************************************************************/
/* */
/**************************************************************************************************/
extern "C"
NDIS_STATUS
FilterPacket(
PADAPT pAdapt, // Address of adapter structure.
PNDIS_PACKET pPktDesc, // Address of NDIS_PACKET, if available. NULL if not.
PUCHAR pPayload, // Address of packet payload if NDIS_PACKET is NULL. Must contain at least the ethernet header and,
// if the type is IP, the IP header or, if the type is ARP or RARP, the ARP or RARP structure.
BOOLEAN bSend, // TRUE if Send, FALSE if Receive.
PBOOLEAN pBDecision // Address of boolean variable, whose value will be: TRUE => drop packet and FALSE => do not drop.
// But this is meaningful only if returned status is NDIS_STATUS_SUCCESS.
)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
#define szPayloadCopy ETH_MAX_PACKET_SIZE
UCHAR PayloadCopy[szPayloadCopy]; // Area to receive packet payload if NDIS_PACKET provided.
pEthHdr pETH;
pIPHdr pIPH;
ULONG const LoopLim = 5;
ULONG i,
ulUsed,
IPAddr,
ulOrigPayload;
int lowIdx,
highIdx,
midPt;
PPassthruIPAddrArray pAddrArr;
BOOLEAN bGotStorage = FALSE;
#define szLclStorage 256
union // Area in stack to receive IP-address array, if the latter can be accommodated.
{
PassthruIPAddrArray lclIPArray;
char stuff[szLclStorage]; // EnsurelclIPArray is padded out to szLclStorage.
};
*pBDecision = FALSE; // Default action is not to drop the packet.
do // Big 'do' group.
{
if (NULL!=pPktDesc) // NDIS_PACKET provided?
GetPktPayload(pPktDesc, // Copy payload
PayloadCopy, // to area.
szPayloadCopy, // Amount of space in area.
&ulOrigPayload // Return number of bytes in packet.
);
else
NdisMoveMemory(PayloadCopy, // An IP packet (on ethernet) comprises the ethernet header + the IP header/body. An ARP or RARP packet
pPayload, // similarly comprises the ethernet header and the ARP or RARP body. Since the mapped IP header is 20
sizeof(EthHdr)+sizeof(IPHdr) // bytes and an ARP or RARP is 28 bytes, an amount = sizeof(EthHdr)+sizeof(IPHdr) is safely copied.
);
pETH = (pEthHdr)PayloadCopy; // Point to ethernet header.
if (EthHTypeIP!=RtlUshortByteSwap(pETH->Type)) // No IP header?
break; // Leave big 'do' group and do nothing more.
pIPH = (pIPHdr)(PayloadCopy + sizeof(EthHdr)); // Point to IP header in copy of payload.
if (TRUE==bSend) // Send operation?
IPAddr = pIPH->DestinationAddress; // Use destination IP address.
else
IPAddr = pIPH->SourceAddress; // Use source IP address.
for (i = 0; i < LoopLim; i ++) // Try several times to get current IP-address array, with ever-increasing amounts of working storage.
{
if (0==i) // First try?
{ // Use storage on the stack.
ulUsed = szLclStorage;
pAddrArr = (PPassthruIPAddrArray)&lclIPArray;
}
else
{ // Use dynamically obtained storage.
ulUsed *= 2; // Double size from first iteration or size previously indicated as needed.
status = // Get working storage.
NdisAllocateMemoryWithTag((PVOID*)&pAddrArr, ulUsed, TAG);
if (NDIS_STATUS_FAILURE==status) // A problem?
{
DBGPRINT(("FilterPacket(): Failed to get memory for IP address array for adapter at 0x%08x!\n", pAdapt));
status = NDIS_STATUS_RESOURCES;
goto done;
}
bGotStorage = TRUE; // Remember got working storage.
}
status = PassthruWMIGetAddrArray( // (Try to) get copy of IP-address array.
pAdapt,
&ulUsed, // Variable with size of provided area. Will be updated with size actually used or size needed.
pAddrArr // Area to receive IP-address array structure.
);
if (NDIS_STATUS_SUCCESS==status) // Success?
break; // Leave 'for' group.
if (i+1==LoopLim) // At loop limit?
{
DBGPRINT(("FilterPacket(): Failed to get array last time, status 0x%08x!\n", status));
status = NDIS_STATUS_FAILURE;
goto done;
}
if (TRUE==bGotStorage) // Got working storage?
{
NdisFreeMemory(pAddrArr, ulUsed, 0);
bGotStorage = FALSE;
}
} // End 'for' try to get current IP-address array.
// PUCHAR pC = (PUCHAR)&IPAddr;
// DBGPRINT(("FilterPacket(): IP address = %d.%d.%d.%d\n", *pC, *(pC+1), *(pC+2), *(pC+3)));
// DumpMem((char*)PayloadCopy, ulOrigPayload>=64 ? 64: ulOrigPayload, FALSE, 1);
for ( // Go through the IP addresses in a binary search.
lowIdx = 0,
highIdx = pAddrArr->NumberElements - 1;
lowIdx <= highIdx;
/* No iteration action. */
)
{
midPt = (lowIdx + highIdx)/2; // Calculate mid-point.
if (IPAddr==pAddrArr->IPAddrArray[midPt]) // A hit?
{
*pBDecision = TRUE; // Indicate packet to be dropped.
break;
}
if (IPAddr<pAddrArr->IPAddrArray[midPt]) // Is the target less than the mid-point?
highIdx = midPt - 1; // Yes, adjust "right boundary."
else
lowIdx = midPt + 1; // No, adjust "left boundary."
} // End 'for' binary search.
} while(0); // End big 'do' group.
done:
if (TRUE==bGotStorage) // Got working storage?
NdisFreeMemory(pAddrArr, ulUsed, 0);
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -