182 lines
4.6 KiB
C
182 lines
4.6 KiB
C
|
/*++
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|