182 lines
4.6 KiB
C
Raw Permalink Normal View History

2001-01-01 00:00:00 +01:00
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
dbgmon.c
Abstract:
Functions that are specific to the debug monitor stack
Revision History:
08/04/2000 davidx
Created it.
--*/
#include "precomp.h"
//
// Debug monitor related global variables
//
PRIVATE IPRECEIVEPROC IpReceivePacketProc;
PRIVATE FREEPKTPROC FreePacketProc;
PRIVATE IfEnet *IfpEnetShared;
VOID
DmExFreePool(
IN PVOID P
);
//
// Pass the received frame up to the IP layer
//
VOID IPRECEIVEPACKET(Packet* pkt) {
// If two stacks are present, we need to figure out
// who's supposed to get this packet.
if (IpReceivePacketProc) {
IpHeader* iphdr;
TcpHeader* tcphdr;
UdpHeader* udphdr;
UINT iphdrlen;
// We assume the packet data length >= IPHDRLEN
iphdr = GETPKTDATA(pkt, IpHeader);
iphdrlen = GETIPHDRLEN(iphdr);
tcphdr = (TcpHeader*) ((BYTE*) iphdr + iphdrlen);
udphdr = (UdpHeader*) ((BYTE*) iphdr + iphdrlen);
if (iphdrlen &&
(iphdr->protocol == IPPROTOCOL_TCP &&
iphdrlen+TCPHDRLEN <= pkt->datalen &&
tcphdr->dstport == HTONS(DEBUGGER_PORT)) ||
(iphdr->protocol == IPPROTOCOL_UDP &&
iphdrlen+UDPHDRLEN <= pkt->datalen &&
udphdr->dstport == HTONS(DEBUGGER_PORT))) {
IpReceivePacket(pkt);
} else {
IpReceivePacketProc(pkt);
}
} else {
IpReceivePacket(pkt);
}
}
//
// Dispose of a packet after transmission
//
VOID COMPLETEPACKET(Packet* pkt, NTSTATUS status) {
if (pkt->pktflags & PKTFLAG_DBGMON) {
XnetCompletePacket(pkt, status);
} else {
// This packet came from the regular net stack.
// We must use the callback function to dispose of it.
if (pkt->completionCallback) {
pkt->completionCallback(pkt, status);
#ifdef DVTSNOOPBUG
} else if (pkt->pktflags & PKTFLAG_UNCACHED) {
XnetUncachedFreeProc(pkt);
#endif
} else if (!(pkt->pktflags & PKTFLAG_NETPOOL)) {
// The packet memory came from the system pool
DmExFreePool(pkt);
} else if (FreePacketProc) {
// The packet memory came from the private pool
FreePacketProc(pkt);
}
}
}
//
// Cancel any pending transmissions that
// originated from the regular stack.
//
VOID DmCancelPendingPackets(PacketQueue* pktq) {
PacketQueue tmpq;
Packet* pkt;
INT dropped = 0;
PktQInit(&tmpq);
while (!PktQIsEmpty(pktq)) {
pkt = PktQRemoveHead(pktq);
if (pkt->pktflags & PKTFLAG_DBGMON) {
PktQInsertTail(&tmpq, pkt);
} else {
COMPLETEPACKET(pkt, NETERR_CANCELLED);
dropped++;
}
}
*pktq = tmpq;
if (dropped) {
WARNING_("Pending transmissions cancelled: %d", dropped);
}
}
//
// Check to see if we should delete the enet interface
//
VOID IFENET_DELETE_CHECK(IfEnet* ifp) {
ASSERT(ifp->refcount > 0);
if (--ifp->refcount > 0) {
//
// Cancel any pending transmissions that
// originated from the regular stack.
//
INT index;
DmCancelPendingPackets(&ifp->sendq);
NicWaitForXmitQEmpty(ifp);
for (index=0; index < ARP_CACHE_SIZE; index++) {
DmCancelPendingPackets(&ifp->arpCache[index].waitq);
}
IpReceivePacketProc = NULL;
FreePacketProc = NULL;
}
}
//
// Notify the debug monitor that regular netstack is starting up
//
PRIVATE IfEnet* EnetStartTitleStack(ENETINITPARAMS* initParams) {
// NOTE: Wait until we acquired an address
// before starting the title stack.
DhcpWaitForAddress((IfInfo*) IfpEnetShared);
IpReceivePacketProc = initParams->IpReceiveProc;
FreePacketProc = initParams->FreePktProc;
initParams->UncachedAllocProc = XnetUncachedAllocProc;
initParams->UncachedFreeProc = XnetUncachedFreeProc;
IfpEnetShared->refcount++;
return IfpEnetShared;
}
//
// Set the enet interface information in the process control block
//
VOID SET_DBGMON_ENETINFO(IfEnet* ifp) {
IfpEnetShared = ifp;
ASSERT(KeGetCurrentPrcb()->DmEnetFunc == 0);
#pragma warning(disable:4054)
KeGetCurrentPrcb()->DmEnetFunc = (VOID*) EnetStartTitleStack;
}
//
// Return the IP address of the Ethernet interface to the debugger
//
DWORD DmGetIpAddress(void) {
return IfpEnetShared ? HTONL(IfpEnetShared->ipaddr) : 0;
}