You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1423 lines
42 KiB
1423 lines
42 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
afds.c
|
|
|
|
Abstract:
|
|
|
|
Implements tcpip commands
|
|
|
|
Author:
|
|
|
|
Vadim Eydelman, October 2001
|
|
|
|
Environment:
|
|
|
|
User Mode.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#include "afdkdp.h"
|
|
#pragma hdrstop
|
|
|
|
VOID
|
|
DumpTCBBrief (
|
|
ULONG64 Address
|
|
);
|
|
VOID
|
|
DumpSynTCBBrief (
|
|
ULONG64 Address
|
|
);
|
|
VOID
|
|
DumpTWTCBBrief (
|
|
ULONG64 Address
|
|
);
|
|
|
|
ULONG
|
|
TCBListCallback (
|
|
PFIELD_INFO pField,
|
|
PVOID UserContext
|
|
);
|
|
ULONG
|
|
SynTCBListCallback (
|
|
PFIELD_INFO pField,
|
|
PVOID UserContext
|
|
);
|
|
ULONG
|
|
TWTCBQueueCallback (
|
|
PFIELD_INFO pField,
|
|
PVOID UserContext
|
|
);
|
|
|
|
LONG64 TCBTable,SynTCBTable,TWQueue;
|
|
ULONG TCBTableSize, TCBTablePartitions;
|
|
USHORT TWTCBDelta;
|
|
ULONG SynTCBListLinkOffset, TWTCBQueueLinkOffset;
|
|
|
|
DECLARE_API (tcb)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dump TCP/IP TCB.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ULONG result,i;
|
|
PCHAR argp;
|
|
LONG64 address;
|
|
CHAR expr[MAX_ADDRESS_EXPRESSION];
|
|
|
|
gClient = pClient;
|
|
|
|
if (!CheckKmGlobals (
|
|
)) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
argp = ProcessOptions ((PCHAR)args);
|
|
if (argp==NULL)
|
|
return E_INVALIDARG;
|
|
Options |= AFDKD_BRIEF_DISPLAY;
|
|
|
|
dprintf (AFDKD_BRIEF_TCB_DISPLAY_HEADER);
|
|
|
|
if (argp[0]==0) {
|
|
union {
|
|
struct {
|
|
LONG64 next;
|
|
LONG64 prev;
|
|
} *q64;
|
|
struct {
|
|
LONG32 next;
|
|
LONG32 prev;
|
|
} *q32;
|
|
LONG64 *p64;
|
|
LONG32 *p32;
|
|
} table;
|
|
ULONG64 count;
|
|
ULONG size;
|
|
|
|
result = GetFieldValue (0, "TCPIP!MaxHashTableSize", NULL, count);
|
|
if (result!=0) {
|
|
if (TCBTableSize==0) {
|
|
dprintf ("\ntcb: Could not read TCPIP!MaxHashTableSize, err: %ld\n", result);
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
else if (count==0) {
|
|
dprintf ("\ntcb: TCPIP!MaxHashTableSize is 0!!!\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
else {
|
|
TCBTableSize = (ULONG)count;
|
|
}
|
|
|
|
if (Options & AFDKD_SYNTCB_DISPLAY) {
|
|
result = GetFieldValue (0, "TCPIP!SYNTCBTable", NULL, address);
|
|
if (result!=0) {
|
|
if (SynTCBTable==0) {
|
|
dprintf ("\ntcb: Could not read TCPIP!SYNTCBTable, err: %ld\n", result);
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
else if (address==0) {
|
|
dprintf ("\ntcb: TCPIP!SYNTCBTable is NULL!!!\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
else
|
|
SynTCBTable = address;
|
|
|
|
size = (IsPtr64 ()
|
|
? sizeof(table.q64[0])
|
|
: sizeof (table.q32[0]))*TCBTableSize;
|
|
|
|
table.p64 = RtlAllocateHeap (RtlProcessHeap (), 0, size);
|
|
if (table.p64==NULL) {
|
|
dprintf ("\ntcb: Failed to allocate SYNTCBTable, size: %ld\n", size);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
|
|
if (!ReadMemory (SynTCBTable, table.p64, size, &result)) {
|
|
RtlFreeHeap (RtlProcessHeap (), 0, table.p64);
|
|
dprintf ("\ntcb: Failed to read TCPIP!SYNTCBTable\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
result = GetFieldOffset ("TCPIP!SYNTCB", "syntcb_link", &SynTCBListLinkOffset);
|
|
if (result!=0) {
|
|
RtlFreeHeap (RtlProcessHeap (), 0, table.p64);
|
|
dprintf ("\ntcb: Failed to get syntcb_link offset in TCPIP!SYNTCB, err: %ld\n", result);
|
|
return E_INVALIDARG;
|
|
}
|
|
for (i=0; i<TCBTableSize; i++) {
|
|
LONG64 address2 = SynTCBTable+i*(IsPtr64()
|
|
? sizeof(table.q64[i])
|
|
: sizeof(table.q32[i]));
|
|
if( CheckControlC() ) {
|
|
break;
|
|
}
|
|
address = IsPtr64() ? table.q64[i].next : table.q32[i].next;
|
|
if (address!=address2) {
|
|
ListType (
|
|
"TCPIP!Queue", // Type
|
|
address, // Address
|
|
0, // ListByFieldAddress
|
|
"q_next", // NextPointer
|
|
&address2, // Context
|
|
SynTCBListCallback);
|
|
}
|
|
}
|
|
}
|
|
else if (Options & AFDKD_TWTCB_DISPLAY) {
|
|
result = GetFieldValue (0, "TCPIP!NumTcbTablePartitions", NULL, count);
|
|
if (result!=0) {
|
|
if (TCBTablePartitions==0) {
|
|
dprintf ("\ntcb: Could not read TCPIP!NumTcbTablePartitions, err: %ld\n", result);
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
else if (count==0) {
|
|
dprintf ("\ntcb: TCPIP!NumTcbTablePartitions is 0!!!\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
else {
|
|
TCBTablePartitions = (ULONG)count;
|
|
}
|
|
|
|
result = GetFieldValue (0, "TCPIP!TWQueue", NULL, address);
|
|
if (result!=0) {
|
|
if (TWQueue==0) {
|
|
dprintf ("\ntcb: Could not read TCPIP!TWQueue, err: %ld\n", result);
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
else if (address==0) {
|
|
dprintf ("\ntcb: TCPIP!TWQueue is NULL!!!\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
else
|
|
TWQueue = address;
|
|
|
|
size = (IsPtr64 ()
|
|
? sizeof(table.q64[0])
|
|
: sizeof(table.q32[0])) * TCBTablePartitions;
|
|
|
|
table.p64 = RtlAllocateHeap (RtlProcessHeap (), 0, size);
|
|
if (table.p64==NULL) {
|
|
dprintf ("\ntcb: Failed to allocate TWQueue, size: %ld\n", size);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if (!ReadMemory (TWQueue, table.p64, size, &result)) {
|
|
RtlFreeHeap (RtlProcessHeap (), 0, table.p64);
|
|
dprintf ("\ntcb: Failed to read TCPIP!TWQueue\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
result = GetFieldOffset ("TCPIP!TWTCB", "twtcb_TWQueue", &TWTCBQueueLinkOffset);
|
|
if (result!=0) {
|
|
RtlFreeHeap (RtlProcessHeap (), 0, table.p64);
|
|
dprintf ("\ntcb: Failed to get twtcb_TWQueue offset in TCPIP!TWTCB, err: %ld\n", result);
|
|
return E_INVALIDARG;
|
|
}
|
|
for (i=0; i<TCBTablePartitions; i++) {
|
|
LONG64 address2 = TWQueue+i*(IsPtr64()
|
|
? sizeof(table.q64[i])
|
|
: sizeof(table.q32[i]));
|
|
if( CheckControlC() ) {
|
|
break;
|
|
}
|
|
address = IsPtr64() ? table.q64[i].next : table.q32[i].next;
|
|
if (address!=address2 ) {
|
|
TWTCBDelta = 0;
|
|
ListType (
|
|
"TCPIP!Queue", // Type
|
|
address, // Address
|
|
0, // ListByFieldAddress
|
|
"q_next", // NextPointer
|
|
&address2, // Context
|
|
TWTCBQueueCallback);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
result = GetFieldValue (0, "TCPIP!TCBTable", NULL, address);
|
|
if (result!=0) {
|
|
if (TCBTable==0) {
|
|
dprintf ("\ntcb: Could not read TCPIP!TCBTable, err: %ld\n", result);
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
else if (address==0) {
|
|
dprintf ("\ntcb: TCPIP!TCBTable is NULL!!!\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
else
|
|
TCBTable = address;
|
|
|
|
size = (IsPtr64 ()
|
|
? sizeof(table.p64[0])
|
|
: sizeof(table.p32[0]))*TCBTableSize;
|
|
|
|
table.p64 = RtlAllocateHeap (RtlProcessHeap (), 0, size);
|
|
if (table.p64==NULL) {
|
|
dprintf ("\ntcb: Failed to allocate SYNTCBTable, size: %ld\n", size);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if (!ReadMemory (TCBTable, table.p64, size, &result)) {
|
|
RtlFreeHeap (RtlProcessHeap (), 0, table.p64);
|
|
dprintf ("\ntcb: Failed to read TCPIP!TCBTable\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
for (i=0; i<TCBTableSize; i++) {
|
|
if( CheckControlC() ) {
|
|
break;
|
|
}
|
|
address = IsPtr64() ? table.p64[i] : table.p32[i];
|
|
if (address!=0) {
|
|
ListType (
|
|
"TCPIP!TCB", // Type
|
|
address, // Address
|
|
0, // ListByFieldAddress
|
|
"tcb_next", // NextPointer
|
|
argp, // Context
|
|
TCBListCallback);
|
|
}
|
|
}
|
|
}
|
|
RtlFreeHeap (RtlProcessHeap (), 0, table.p64);
|
|
}
|
|
else {
|
|
|
|
//
|
|
// Snag the address from the command line.
|
|
//
|
|
while (sscanf( argp, "%s%n", expr, &i )==1) {
|
|
if( CheckControlC() ) {
|
|
break;
|
|
}
|
|
|
|
argp+=i;
|
|
address = GetExpression (expr);
|
|
|
|
result = (ULONG)InitTypeRead (address, TCPIP!TCB);
|
|
if (result!=0) {
|
|
dprintf ("\nendp: Could not read TCB @ %p, err: %d\n",
|
|
address, result);
|
|
break;
|
|
}
|
|
|
|
DumpTCBBrief (address);
|
|
if (Options & AFDKD_FIELD_DISPLAY) {
|
|
ProcessFieldOutput (address, "TCPIP!TCB");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
dprintf (AFDKD_BRIEF_TCB_DISPLAY_TRAILER);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
ULONG
|
|
TCBListCallback (
|
|
PFIELD_INFO pField,
|
|
PVOID UserContext
|
|
)
|
|
{
|
|
ULONG result;
|
|
|
|
if (pField->address==0)
|
|
return 1;
|
|
|
|
if (!(Options & AFDKD_CONDITIONAL) ||
|
|
CheckConditional (pField->address, "TCPIP!TCB")) {
|
|
result = (ULONG)InitTypeRead (pField->address, TCPIP!TCB);
|
|
if (result!=0) {
|
|
dprintf ("\nTCBListCallback: Could not read TCPIP!TCB @ %p, err: %d\n",
|
|
pField->address, result);
|
|
}
|
|
DumpTCBBrief (pField->address);
|
|
if (Options & AFDKD_FIELD_DISPLAY) {
|
|
ProcessFieldOutput (pField->address, "TCPIP!TCB");
|
|
}
|
|
}
|
|
else {
|
|
dprintf (".");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
ULONG
|
|
SynTCBListCallback (
|
|
PFIELD_INFO pField,
|
|
PVOID UserContext
|
|
)
|
|
{
|
|
ULONG result;
|
|
ULONG64 address;
|
|
|
|
if (pField->address==0)
|
|
return 1;
|
|
else if (pField->address==*(LONG64 *)UserContext)
|
|
return 1;
|
|
|
|
address = pField->address-SynTCBListLinkOffset;
|
|
|
|
if (!(Options & AFDKD_CONDITIONAL) ||
|
|
CheckConditional (address, "TCPIP!SYNTCB")) {
|
|
result = (ULONG)InitTypeRead (address, TCPIP!SYNTCB);
|
|
if (result!=0) {
|
|
dprintf ("\nSynTCBListCallback: Could not read TCPIP!SYNTCB @ %p, err: %d\n",
|
|
address, result);
|
|
}
|
|
DumpSynTCBBrief (address);
|
|
if (Options & AFDKD_FIELD_DISPLAY) {
|
|
ProcessFieldOutput (pField->address, "TCPIP!SYNTCB");
|
|
}
|
|
}
|
|
else {
|
|
dprintf (".");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
ULONG
|
|
TWTCBQueueCallback (
|
|
PFIELD_INFO pField,
|
|
PVOID UserContext
|
|
)
|
|
{
|
|
ULONG result;
|
|
ULONG64 address;
|
|
ULONG64 delta;
|
|
|
|
if (pField->address==0)
|
|
return 1;
|
|
else if (pField->address==*(LONG64 *)UserContext)
|
|
return 1;
|
|
|
|
address = pField->address-TWTCBQueueLinkOffset;
|
|
result = GetFieldValue (address, "TCPIP!TWTCB", "twtcb_rexmittimer", delta);
|
|
if (result!=0) {
|
|
dprintf ("\nTWTCBQueueCallback: Could not read twtcb_rexmittimer of TCPIP!TWTCB @ %p, err: %d\n",
|
|
address, result);
|
|
return 1;
|
|
}
|
|
TWTCBDelta += (USHORT)delta;
|
|
|
|
if (!(Options & AFDKD_CONDITIONAL) ||
|
|
CheckConditional (address, "TCPIP!TWTCB")) {
|
|
result = (ULONG)InitTypeRead (address, TCPIP!TWTCB);
|
|
if (result!=0) {
|
|
dprintf ("\nTCBListCallback: Could not read TCPIP!TWTCB @ %p, err: %d\n",
|
|
address, result);
|
|
return 1;
|
|
}
|
|
DumpTWTCBBrief (address);
|
|
if (Options & AFDKD_FIELD_DISPLAY) {
|
|
ProcessFieldOutput (address, "TCPIP!TWTCB");
|
|
}
|
|
}
|
|
else {
|
|
dprintf (".");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
CHAR *TCBStateStrings [] = {
|
|
"Cd",
|
|
"Li",
|
|
"SS",
|
|
"SR",
|
|
"Es",
|
|
"F1",
|
|
"F2",
|
|
"CW",
|
|
"Ci",
|
|
"LA",
|
|
"TW"
|
|
};
|
|
#define MAX_TCB_STATE (sizeof(TCBStateStrings)/sizeof (TCBStateStrings[0]))
|
|
|
|
VOID
|
|
DumpTCBBrief (
|
|
ULONG64 Address
|
|
)
|
|
{
|
|
TA_IP_ADDRESS address;
|
|
CHAR src[MAX_ADDRESS_STRING], dst[MAX_ADDRESS_STRING];
|
|
CHAR symbol[MAX_FIELD_CHARS];
|
|
ULONG64 offset;
|
|
UCHAR state;
|
|
ULONG flags;
|
|
ULONG64 conn,pid,ctx;
|
|
|
|
state = (UCHAR)ReadField (tcb_state);
|
|
flags = (ULONG)ReadField(tcb_flags);
|
|
GetSymbol (ReadField (tcb_rcvind), symbol, &offset);
|
|
address.TAAddressCount = 1;
|
|
address.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
|
|
address.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
|
|
address.Address[0].Address[0].in_addr = (ULONG)ReadField (tcb_saddr);
|
|
address.Address[0].Address[0].sin_port = (USHORT)ReadField (tcb_sport);
|
|
strncpy (src, TransportAddressToString ((PTRANSPORT_ADDRESS)&address, 0), sizeof (src)-1);
|
|
src[sizeof(src)-1] = 0;
|
|
|
|
address.Address[0].Address[0].in_addr = (ULONG)ReadField (tcb_daddr);
|
|
address.Address[0].Address[0].sin_port = (USHORT)ReadField (tcb_dport);
|
|
strncpy (dst, TransportAddressToString ((PTRANSPORT_ADDRESS)&address, 0), sizeof (dst)-1);
|
|
dst[sizeof(dst)-1] = 0;
|
|
ctx = ReadField (tcb_conncontext);
|
|
if (SavedMinorVersion>=2219) {
|
|
if (GetFieldValue (Address, "TCPIP!TCB", "tcb_conn", conn)!=0 ||
|
|
GetFieldValue (conn, "TCPIP!TCPConn", "tc_owningpid", pid)!=0) {
|
|
pid = 0;
|
|
}
|
|
}
|
|
else {
|
|
pid = 0;
|
|
}
|
|
|
|
/* TCB State Flags Client ConnCtx PID Src Addr Dst Addr*/
|
|
dprintf (
|
|
IsPtr64 ()
|
|
? "\n%011.011p %-2.2s %8.8x %-6.8s %011.011p %4.4x %-19s %-s"
|
|
: "\n%008.008p %-2.2s %8.8x %-6.8s %008.008p %4.4x %-19s %-s",
|
|
DISP_PTR (Address),
|
|
state<MAX_TCB_STATE ? TCBStateStrings[state] : "??",
|
|
flags,
|
|
strtok (symbol, "!"),
|
|
DISP_PTR(ctx),
|
|
(ULONG)pid,
|
|
src,
|
|
dst);
|
|
|
|
}
|
|
|
|
VOID
|
|
DumpSynTCBBrief (
|
|
ULONG64 Address
|
|
)
|
|
{
|
|
TA_IP_ADDRESS address;
|
|
CHAR src[MAX_ADDRESS_STRING], dst[MAX_ADDRESS_STRING];
|
|
UCHAR state;
|
|
ULONG flags;
|
|
|
|
state = (UCHAR)ReadField (syntcb_state);
|
|
flags = (ULONG)ReadField(syntcb_flags);
|
|
address.TAAddressCount = 1;
|
|
address.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
|
|
address.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
|
|
address.Address[0].Address[0].in_addr = (ULONG)ReadField (syntcb_saddr);
|
|
address.Address[0].Address[0].sin_port = (USHORT)ReadField (syntcb_sport);
|
|
strncpy (src, TransportAddressToString ((PTRANSPORT_ADDRESS)&address, 0), sizeof (src)-1);
|
|
src[sizeof(src)-1] = 0;
|
|
|
|
address.Address[0].Address[0].in_addr = (ULONG)ReadField (syntcb_daddr);
|
|
address.Address[0].Address[0].sin_port = (USHORT)ReadField (syntcb_dport);
|
|
strncpy (dst, TransportAddressToString ((PTRANSPORT_ADDRESS)&address, 0), sizeof (dst)-1);
|
|
dst[sizeof(dst)-1] = 0;
|
|
|
|
/* TCB State Flags Client ConnCtx PID Src Addr Dst Addr*/
|
|
dprintf (
|
|
IsPtr64 ()
|
|
? "\n%011.011p %-2.2s %8.8x %-19s %-s"
|
|
: "\n%008.008p %-2.2s %8.8x %-19s %-s",
|
|
DISP_PTR (Address),
|
|
state<MAX_TCB_STATE ? TCBStateStrings[state] : "??",
|
|
flags,
|
|
src,
|
|
dst);
|
|
|
|
}
|
|
|
|
VOID
|
|
DumpTWTCBBrief (
|
|
ULONG64 Address
|
|
)
|
|
{
|
|
TA_IP_ADDRESS address;
|
|
CHAR src[MAX_ADDRESS_STRING], dst[MAX_ADDRESS_STRING];
|
|
|
|
address.TAAddressCount = 1;
|
|
address.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
|
|
address.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
|
|
address.Address[0].Address[0].in_addr = (ULONG)ReadField (twtcb_saddr);
|
|
address.Address[0].Address[0].sin_port = (USHORT)ReadField (twtcb_sport);
|
|
strncpy (src, TransportAddressToString ((PTRANSPORT_ADDRESS)&address, 0), sizeof (src)-1);
|
|
src[sizeof(src)-1] = 0;
|
|
|
|
address.Address[0].Address[0].in_addr = (ULONG)ReadField (twtcb_daddr);
|
|
address.Address[0].Address[0].sin_port = (USHORT)ReadField (twtcb_dport);
|
|
strncpy (dst, TransportAddressToString ((PTRANSPORT_ADDRESS)&address, 0), sizeof (dst)-1);
|
|
dst[sizeof(dst)-1] = 0;
|
|
|
|
/* TCB St Flags Client ConnCtx PID Src Addr Dst Addr*/
|
|
dprintf (
|
|
IsPtr64 ()
|
|
? "\n%011.011p TW expires in %5d ticks %-19s %-s"
|
|
: "\n%008.008p TW expires in %5d ticks %-19s %-s",
|
|
DISP_PTR (Address),
|
|
TWTCBDelta,
|
|
src,
|
|
dst);
|
|
|
|
}
|
|
|
|
VOID
|
|
DumpTCB6Brief (
|
|
ULONG64 Address
|
|
);
|
|
|
|
ULONG
|
|
TCB6ListCallback (
|
|
PFIELD_INFO pField,
|
|
PVOID UserContext
|
|
);
|
|
|
|
ULONG64 TCB6Table;
|
|
ULONG TCB6TableSize;
|
|
|
|
DECLARE_API (tcb6)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dump TCP/IP TCB.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ULONG result,i;
|
|
PCHAR argp;
|
|
ULONG64 address;
|
|
CHAR expr[MAX_ADDRESS_EXPRESSION];
|
|
|
|
gClient = pClient;
|
|
|
|
if (!CheckKmGlobals ()) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
argp = ProcessOptions ((PCHAR)args);
|
|
if (argp==NULL)
|
|
return E_INVALIDARG;
|
|
Options |= AFDKD_BRIEF_DISPLAY;
|
|
|
|
dprintf (AFDKD_BRIEF_TCB6_DISPLAY_HEADER);
|
|
if (argp[0]==0) {
|
|
union {
|
|
ULONG64 *p64;
|
|
ULONG *p32;
|
|
} table;
|
|
ULONG64 count;
|
|
ULONG size;
|
|
|
|
result = GetFieldValue (0, "TCPIP6!TCBTable", NULL, address);
|
|
if (result!=0) {
|
|
if (TCB6Table==0) {
|
|
dprintf ("\ntcb6: Could not read TCPIP6!TCBTable, err: %ld\n", result);
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
else if (address==0) {
|
|
dprintf ("\ntcb6: TCPIP6!TCBTable is NULL!!!\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
else
|
|
TCB6Table = address;
|
|
|
|
result = GetFieldValue (0, "TCPIP6!TcbTableSize", NULL, count);
|
|
if (result!=0) {
|
|
if (TCB6TableSize==0) {
|
|
dprintf ("\ntcb6: Could not read TCPIP6!TcbTableSize, err: %ld\n", result);
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
else if (count==0) {
|
|
dprintf ("\ntcb6: TCPIP6!TcbTableSize is 0!!!\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
else {
|
|
TCB6TableSize = (ULONG)count;
|
|
}
|
|
|
|
size = (IsPtr64 () ? sizeof (ULONG64) : sizeof (ULONG))*TCB6TableSize;
|
|
table.p64 = RtlAllocateHeap (RtlProcessHeap (), 0, size);
|
|
if (table.p64==NULL) {
|
|
dprintf ("\ntcb: Failed to allocate TCBTable, size: %ld\n", size);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if (!ReadMemory (TCB6Table, table.p64, size, &result)) {
|
|
RtlFreeHeap (RtlProcessHeap (), 0, table.p64);
|
|
dprintf ("\ntcb: Failed to read TCBTable\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
for (i=0; i<TCB6TableSize; i++) {
|
|
if( CheckControlC() ) {
|
|
break;
|
|
}
|
|
address = IsPtr64() ? table.p64[i] : table.p32[i];
|
|
if (address!=0) {
|
|
ListType (
|
|
"TCPIP6!TCB", // Type
|
|
address, // Address
|
|
0, // ListByFieldAddress
|
|
"tcb_next", // NextPointer
|
|
argp, // Context
|
|
TCB6ListCallback);
|
|
}
|
|
}
|
|
RtlFreeHeap (RtlProcessHeap (), 0, table.p64);
|
|
}
|
|
else {
|
|
|
|
//
|
|
// Snag the address from the command line.
|
|
//
|
|
while (sscanf( argp, "%s%n", expr, &i )==1) {
|
|
if( CheckControlC() ) {
|
|
break;
|
|
}
|
|
|
|
argp+=i;
|
|
address = GetExpression (expr);
|
|
|
|
result = (ULONG)InitTypeRead (address, TCPIP6!TCB);
|
|
if (result!=0) {
|
|
dprintf ("\nendp: Could not read TCB @ %p, err: %d\n",
|
|
address, result);
|
|
break;
|
|
}
|
|
|
|
DumpTCBBrief (address);
|
|
if (Options & AFDKD_FIELD_DISPLAY) {
|
|
ProcessFieldOutput (address, "TCPIP6!TCB");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
dprintf (AFDKD_BRIEF_TCB6_DISPLAY_TRAILER);
|
|
return S_OK;
|
|
}
|
|
|
|
ULONG
|
|
TCB6ListCallback (
|
|
PFIELD_INFO pField,
|
|
PVOID UserContext
|
|
)
|
|
{
|
|
ULONG result;
|
|
|
|
if (pField->address==0)
|
|
return 0;
|
|
|
|
if (!(Options & AFDKD_CONDITIONAL) ||
|
|
CheckConditional (pField->address, "TCPIP6!TCB")) {
|
|
result = (ULONG)InitTypeRead (pField->address, TCPIP6!TCB);
|
|
if (result!=0) {
|
|
dprintf ("\nTCBListCallback: Could not read TCB @ %p, err: %d\n",
|
|
pField->address, result);
|
|
}
|
|
DumpTCB6Brief (pField->address);
|
|
if (Options & AFDKD_FIELD_DISPLAY) {
|
|
ProcessFieldOutput (pField->address, "TCPIP6!TCB");
|
|
}
|
|
}
|
|
else {
|
|
dprintf (".");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
VOID
|
|
DumpTCB6Brief (
|
|
ULONG64 Address
|
|
)
|
|
{
|
|
TA_IP6_ADDRESS address;
|
|
CHAR src[MAX_ADDRESS_STRING], dst[MAX_ADDRESS_STRING];
|
|
CHAR symbol[MAX_FIELD_CHARS];
|
|
ULONG64 offset;
|
|
UCHAR state;
|
|
ULONG flags;
|
|
ULONG64 conn,pid,ctx;
|
|
|
|
state = (UCHAR)ReadField (tcb_state);
|
|
flags = (ULONG)ReadField (tcb_flags);
|
|
GetSymbol (ReadField (tcb_rcvind), symbol, &offset);
|
|
address.TAAddressCount = 1;
|
|
address.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP6;
|
|
address.Address[0].AddressType = TDI_ADDRESS_TYPE_IP6;
|
|
GetFieldValue (Address, "TCPIP6!TCB", "tcb_saddr", address.Address[0].Address[0].sin6_addr);
|
|
address.Address[0].Address[0].sin6_port = (USHORT)ReadField (tcb_sport);
|
|
address.Address[0].Address[0].sin6_scope_id = (ULONG)ReadField(tcb_sscope_id);
|
|
strncpy (src, TransportAddressToString ((PTRANSPORT_ADDRESS)&address, 0), sizeof (src)-1);
|
|
src[sizeof(src)-1] = 0;
|
|
|
|
GetFieldValue (Address, "TCPIP6!TCB", "tcb_daddr", address.Address[0].Address[0].sin6_addr);
|
|
address.Address[0].Address[0].sin6_port = (USHORT)ReadField (tcb_dport);
|
|
address.Address[0].Address[0].sin6_scope_id = (ULONG)ReadField(tcb_dscope_id);
|
|
strncpy (dst, TransportAddressToString ((PTRANSPORT_ADDRESS)&address, 0), sizeof (dst)-1);
|
|
dst[sizeof(dst)-1] = 0;
|
|
ctx = ReadField (tcb_conncontext);
|
|
if (SavedMinorVersion>=2471) {
|
|
if (GetFieldValue (Address, "TCPIP6!TCB", "tcb_conn", conn)!=0 ||
|
|
GetFieldValue (conn, "TCPIP6!TCPConn", "tc_owningpid", pid)!=0) {
|
|
pid = 0;
|
|
}
|
|
}
|
|
else {
|
|
pid = 0;
|
|
}
|
|
|
|
/* TCB State Flags Client ConnCtx PID Src Dst*/
|
|
dprintf (
|
|
IsPtr64 ()
|
|
? "\n%011.011p %-2.2s %8.8x %-6.8s %011.011p %4.4x %-s\n"
|
|
" %-s"
|
|
: "\n%008.008p %-2.2s %8.8x %-6.8s %008.008p %4.4x %-s\n"
|
|
" %-s",
|
|
DISP_PTR (Address),
|
|
state<MAX_TCB_STATE ? TCBStateStrings[state] : "??",
|
|
flags,
|
|
strtok (symbol, "!"),
|
|
DISP_PTR(ctx),
|
|
(ULONG)pid,
|
|
src,
|
|
dst);
|
|
|
|
}
|
|
|
|
VOID
|
|
DumpTAOBrief (
|
|
ULONG64 Address
|
|
);
|
|
ULONG
|
|
TAOListCallback (
|
|
PFIELD_INFO pField,
|
|
PVOID UserContext
|
|
);
|
|
|
|
ULONG64 AOTable;
|
|
ULONG AOTableSize;
|
|
DECLARE_API (tao)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dump TCP/IP Address Objects.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ULONG result,i;
|
|
PCHAR argp;
|
|
ULONG64 address;
|
|
CHAR expr[MAX_ADDRESS_EXPRESSION];
|
|
|
|
gClient = pClient;
|
|
|
|
if (!CheckKmGlobals ()) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
argp = ProcessOptions ((PCHAR)args);
|
|
if (argp==NULL)
|
|
return E_INVALIDARG;
|
|
Options |= AFDKD_BRIEF_DISPLAY;
|
|
|
|
dprintf (AFDKD_BRIEF_TAO_DISPLAY_HEADER);
|
|
if (argp[0]==0) {
|
|
union {
|
|
ULONG64 *p64;
|
|
ULONG *p32;
|
|
} table;
|
|
ULONG64 count;
|
|
ULONG size;
|
|
|
|
result = GetFieldValue (0, "TCPIP!AddrObjTable", NULL, address);
|
|
if (result!=0) {
|
|
if (AOTable==0) {
|
|
dprintf ("\ntao: Could not read TCPIP!AddrObjTable, err: %ld\n", result);
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
else if (address==0) {
|
|
dprintf ("\ntao: TCPIP!AddrObjTable is NULL!!!\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
else
|
|
AOTable = address;
|
|
|
|
result = GetFieldValue (0, "TCPIP!AddrObjTableSize", NULL, count);
|
|
if (result!=0) {
|
|
if (AOTableSize==0) {
|
|
dprintf ("\ntao: Could not read TCPIP!AddrObjTableSize, err: %ld\n", result);
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
else if (count==0) {
|
|
dprintf ("\ntao: TCPIP!AddrObjTableSize is 0!!!\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
else {
|
|
AOTableSize = (ULONG)count;
|
|
}
|
|
|
|
size = (IsPtr64 () ? sizeof (ULONG64) : sizeof (ULONG))*AOTableSize;
|
|
table.p64 = RtlAllocateHeap (RtlProcessHeap (), 0, size);
|
|
if (table.p64==NULL) {
|
|
dprintf ("\ntcb: Failed to allocate AOTable, size: %ld\n", size);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if (!ReadMemory (AOTable, table.p64, size, &result)) {
|
|
RtlFreeHeap (RtlProcessHeap (), 0, table.p64);
|
|
dprintf ("\ntcb: Failed to read AOTable\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
for (i=0; i<AOTableSize; i++) {
|
|
if( CheckControlC() ) {
|
|
break;
|
|
}
|
|
address = IsPtr64() ? table.p64[i] : table.p32[i];
|
|
if (address!=0) {
|
|
ListType (
|
|
"TCPIP!AddrObj", // Type
|
|
address, // Address
|
|
0, // ListByFieldAddress
|
|
"ao_next", // NextPointer
|
|
argp, // Context
|
|
TAOListCallback);
|
|
}
|
|
}
|
|
RtlFreeHeap (RtlProcessHeap (), 0, table.p64);
|
|
|
|
}
|
|
else {
|
|
//
|
|
// Snag the address from the command line.
|
|
//
|
|
while (sscanf( argp, "%s%n", expr, &i )==1) {
|
|
if( CheckControlC() ) {
|
|
break;
|
|
}
|
|
|
|
argp+=i;
|
|
address = GetExpression (expr);
|
|
|
|
result = (ULONG)InitTypeRead (address, TCPIP!AddrObj);
|
|
if (result!=0) {
|
|
dprintf ("\ntao: Could not read AddrObj @ %p, err: %d\n",
|
|
address, result);
|
|
break;
|
|
}
|
|
|
|
DumpTAOBrief (address);
|
|
if (Options & AFDKD_FIELD_DISPLAY) {
|
|
ProcessFieldOutput (address, "TCPIP!AddrObj");
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dprintf (AFDKD_BRIEF_TAO_DISPLAY_TRAILER);
|
|
return S_OK;
|
|
}
|
|
|
|
ULONG
|
|
TAOListCallback (
|
|
PFIELD_INFO pField,
|
|
PVOID UserContext
|
|
)
|
|
{
|
|
ULONG result;
|
|
|
|
if (pField->address==0)
|
|
return 0;
|
|
|
|
if (!(Options & AFDKD_CONDITIONAL) ||
|
|
CheckConditional (pField->address, "TCPIP!AddrObj")) {
|
|
result = (ULONG)InitTypeRead (pField->address, TCPIP!AddrObj);
|
|
if (result!=0) {
|
|
dprintf ("\nAOListCallback: Could not read AddrObj @ %p, err: %d\n",
|
|
pField->address, result);
|
|
}
|
|
DumpTAOBrief (pField->address);
|
|
if (Options & AFDKD_FIELD_DISPLAY) {
|
|
ProcessFieldOutput (pField->address, "TCPIP!AddrObj");
|
|
}
|
|
}
|
|
else {
|
|
dprintf (".");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
VOID
|
|
DumpTAOBrief (
|
|
ULONG64 Address
|
|
)
|
|
{
|
|
TA_IP_ADDRESS address;
|
|
CHAR src[MAX_ADDRESS_STRING], dst[MAX_ADDRESS_STRING];
|
|
CHAR symbol[MAX_FIELD_CHARS];
|
|
ULONG64 offset;
|
|
ULONG64 pid, ctx = 0;
|
|
ULONG result;
|
|
USHORT prot;
|
|
ULONG flags, ifidx;
|
|
|
|
address.TAAddressCount = 1;
|
|
address.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
|
|
address.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
|
|
address.Address[0].Address[0].in_addr = (ULONG)ReadField (ao_addr);
|
|
address.Address[0].Address[0].sin_port = (USHORT)ReadField (ao_port);
|
|
ifidx = (ULONG)ReadField (ao_bindindex);
|
|
if (ifidx==0 || (address.Address[0].Address[0].in_addr!=0)) {
|
|
strncpy (src, TransportAddressToString ((PTRANSPORT_ADDRESS)&address, 0), sizeof (src)-1);
|
|
}
|
|
else {
|
|
_snprintf (src, sizeof (src)-1, "%%%d:%d", ifidx, NTOHS (address.Address[0].Address[0].sin_port));
|
|
}
|
|
src[sizeof(src)-1] = 0;
|
|
|
|
prot = (USHORT)ReadField (ao_prot);
|
|
flags = (ULONG)ReadField (ao_flags);
|
|
|
|
if ((offset=ReadField (ao_connect))!=0) {
|
|
ctx = ReadField (ao_conncontext);
|
|
}
|
|
else if ((offset=ReadField (ao_rcvdg))!=0) {
|
|
ctx = ReadField (ao_rcvdgcontext);
|
|
}
|
|
else if ((offset=ReadField (ao_disconnect))!=0) {
|
|
ctx = ReadField (ao_disconncontext);
|
|
}
|
|
else if ((offset=ReadField (ao_error))!=0) {
|
|
ctx = ReadField (ao_errcontext);
|
|
}
|
|
else if ((offset=ReadField (ao_rcv))!=0) {
|
|
ctx = ReadField (ao_rcvcontext);
|
|
}
|
|
else if ((offset=ReadField (ao_errorex))!=0) {
|
|
ctx = ReadField (ao_errorexcontext);
|
|
}
|
|
else if ((offset=ReadField (ao_chainedrcv))!=0) {
|
|
ctx = ReadField (ao_chainedrcvcontext);
|
|
}
|
|
else if ((offset=ReadField (ao_exprcv))!=0) {
|
|
ctx = ReadField (ao_exprcvcontext);
|
|
}
|
|
|
|
if (offset!=0) {
|
|
GetSymbol (offset, symbol, &offset);
|
|
}
|
|
else {
|
|
strncpy (symbol, "???", sizeof (symbol)-1);
|
|
symbol[sizeof(symbol)-1] = 0;
|
|
}
|
|
|
|
if (SavedMinorVersion>=2219) {
|
|
pid = ReadField (ao_owningpid);
|
|
}
|
|
else {
|
|
pid = 0;
|
|
}
|
|
|
|
offset = ReadField (ao_RemoteAddress);
|
|
if (offset!=0) {
|
|
if (ReadMemory (offset, &address, sizeof (address), &result)) {
|
|
strncpy (dst, TransportAddressToString ((PTRANSPORT_ADDRESS)&address, offset), sizeof (dst)-1);
|
|
|
|
}
|
|
else {
|
|
_snprintf (dst, sizeof (dst)-1, "Read err @ %I64X", offset);
|
|
}
|
|
dst[sizeof(dst)-1] = 0;
|
|
}
|
|
else {
|
|
INT n;
|
|
ULONG fldoff;
|
|
n = _snprintf (dst, sizeof (dst)-1, "%3.3x", (ULONG)ReadField (ao_listencnt));
|
|
result = GetFieldOffset ("TCPIP!AddrObj", "ao_activeq", &fldoff);
|
|
if (result==0) {
|
|
if (Options & AFDKD_LIST_COUNT) {
|
|
n+= _snprintf (&dst[n], sizeof (dst)-1-n, " %3.3x",
|
|
CountListEntries (Address+fldoff));
|
|
}
|
|
else {
|
|
n+= _snprintf (&dst[n], sizeof (dst)-1-n, " %3.3s",
|
|
ListCountEstimate (Address+fldoff));
|
|
}
|
|
}
|
|
result = GetFieldOffset ("TCPIP!AddrObj", "ao_idleq", &fldoff);
|
|
if (result==0) {
|
|
if (Options & AFDKD_LIST_COUNT) {
|
|
n+= _snprintf (&dst[n], sizeof (dst)-1-n, " %3.3x",
|
|
CountListEntries (Address+fldoff));
|
|
}
|
|
else {
|
|
n+= _snprintf (&dst[n], sizeof (dst)-1-n, " %3.3s",
|
|
ListCountEstimate (Address+fldoff));
|
|
}
|
|
}
|
|
dst[sizeof(dst)-1] = 0;
|
|
}
|
|
/* TCB Prot Flags Client ConnCtx PID Address Remote Address*/
|
|
dprintf (
|
|
IsPtr64 ()
|
|
? "\n%011.011p %4d %5.5x %-6.8s %011.011p %4.4x %-19s %-s"
|
|
: "\n%008.008p %4d %5.5x %-6.8s %008.008p %4.4x %-19s %-s",
|
|
DISP_PTR (Address),
|
|
prot,
|
|
flags,
|
|
strtok (symbol, "!"),
|
|
DISP_PTR(ctx),
|
|
(ULONG)pid,
|
|
src,
|
|
dst);
|
|
|
|
}
|
|
|
|
VOID
|
|
DumpTAO6Brief (
|
|
ULONG64 Address
|
|
);
|
|
ULONG
|
|
TAO6ListCallback (
|
|
PFIELD_INFO pField,
|
|
PVOID UserContext
|
|
);
|
|
|
|
ULONG64 AO6Table;
|
|
ULONG AO6TableSize;
|
|
DECLARE_API (tao6)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dump TCP/IPv6 Address Objects.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ULONG result,i;
|
|
PCHAR argp;
|
|
ULONG64 address;
|
|
CHAR expr[MAX_ADDRESS_EXPRESSION];
|
|
|
|
gClient = pClient;
|
|
|
|
if (!CheckKmGlobals ()) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
argp = ProcessOptions ((PCHAR)args);
|
|
if (argp==NULL)
|
|
return E_INVALIDARG;
|
|
|
|
Options |= AFDKD_BRIEF_DISPLAY;
|
|
|
|
dprintf (AFDKD_BRIEF_TAO6_DISPLAY_HEADER);
|
|
if (argp[0]==0) {
|
|
union {
|
|
ULONG64 *p64;
|
|
ULONG *p32;
|
|
} table;
|
|
ULONG64 count;
|
|
ULONG size;
|
|
|
|
result = GetFieldValue (0, "TCPIP6!AddrObjTable", NULL, address);
|
|
if (result!=0) {
|
|
if (AO6Table==0) {
|
|
dprintf ("\ntao6: Could not read TCPIP6!AddrObjTable, err: %ld\n", result);
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
else if (address==0) {
|
|
dprintf ("\ntao6: TCPIP6!AddrObjTable is NULL!!!\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
else
|
|
AO6Table = address;
|
|
|
|
result = GetFieldValue (0, "TCPIP6!AddrObjTableSize", NULL, count);
|
|
if (result!=0) {
|
|
if (AO6TableSize==0) {
|
|
dprintf ("\ntao6: Could not read TCPIP6!AddrObjTableSize, err: %ld\n", result);
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
else if (count==0) {
|
|
dprintf ("\ntao6: TCPIP6!AddrObjTableSize is 0!!!\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
else {
|
|
AO6TableSize = (ULONG)count;
|
|
}
|
|
|
|
size = (IsPtr64 () ? sizeof (ULONG64) : sizeof (ULONG))*AO6TableSize;
|
|
table.p64 = RtlAllocateHeap (RtlProcessHeap (), 0, size);
|
|
if (table.p64==NULL) {
|
|
dprintf ("\ntcb: Failed to allocate AOTable, size: %ld\n", size);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if (!ReadMemory (AO6Table, table.p64, size, &result)) {
|
|
RtlFreeHeap (RtlProcessHeap (), 0, table.p64);
|
|
dprintf ("\ntao6: Failed to read AOTable\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
for (i=0; i<AO6TableSize; i++) {
|
|
if( CheckControlC() ) {
|
|
break;
|
|
}
|
|
address = IsPtr64() ? table.p64[i] : table.p32[i];
|
|
if (address!=0) {
|
|
ListType (
|
|
"TCPIP6!AddrObj", // Type
|
|
address, // Address
|
|
0, // ListByFieldAddress
|
|
"ao_next", // NextPointer
|
|
argp, // Context
|
|
TAO6ListCallback);
|
|
}
|
|
}
|
|
RtlFreeHeap (RtlProcessHeap (), 0, table.p64);
|
|
|
|
}
|
|
else {
|
|
//
|
|
// Snag the address from the command line.
|
|
//
|
|
while (sscanf( argp, "%s%n", expr, &i )==1) {
|
|
if( CheckControlC() ) {
|
|
break;
|
|
}
|
|
|
|
argp+=i;
|
|
address = GetExpression (expr);
|
|
|
|
result = (ULONG)InitTypeRead (address, TCPIP6!AddrObj);
|
|
if (result!=0) {
|
|
dprintf ("\ntao6: Could not read AddrObj @ %p, err: %d\n",
|
|
address, result);
|
|
break;
|
|
}
|
|
|
|
DumpTAO6Brief (address);
|
|
if (Options & AFDKD_FIELD_DISPLAY) {
|
|
ProcessFieldOutput (address, "TCPIP6!AddrObj");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
dprintf (AFDKD_BRIEF_TAO6_DISPLAY_TRAILER);
|
|
return S_OK;
|
|
}
|
|
|
|
ULONG
|
|
TAO6ListCallback (
|
|
PFIELD_INFO pField,
|
|
PVOID UserContext
|
|
)
|
|
{
|
|
ULONG result;
|
|
|
|
if (pField->address==0)
|
|
return 0;
|
|
|
|
if (!(Options & AFDKD_CONDITIONAL) ||
|
|
CheckConditional (pField->address, "TCPIP6!AddrObj")) {
|
|
result = (ULONG)InitTypeRead (pField->address, TCPIP6!AddrObj);
|
|
if (result!=0) {
|
|
dprintf ("\nTAO6ListCallback: Could not read AddrObj @ %p, err: %d\n",
|
|
pField->address, result);
|
|
}
|
|
DumpTAO6Brief (pField->address);
|
|
if (Options & AFDKD_FIELD_DISPLAY) {
|
|
ProcessFieldOutput (pField->address, "TCPIP6!AddrObj");
|
|
}
|
|
}
|
|
else {
|
|
dprintf (".");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
VOID
|
|
DumpTAO6Brief (
|
|
ULONG64 Address
|
|
)
|
|
{
|
|
TA_IP6_ADDRESS address;
|
|
CHAR src[MAX_ADDRESS_STRING];
|
|
CHAR symbol[MAX_FIELD_CHARS];
|
|
ULONG64 offset;
|
|
ULONG64 pid, ctx = 0;
|
|
USHORT prot;
|
|
ULONG flags;
|
|
|
|
address.TAAddressCount = 1;
|
|
address.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP6;
|
|
address.Address[0].AddressType = TDI_ADDRESS_TYPE_IP6;
|
|
GetFieldValue (Address, "TCPIP6!AddrObj", "ao_addr", address.Address[0].Address[0].sin6_addr);
|
|
address.Address[0].Address[0].sin6_port = (USHORT)ReadField (ao_port);
|
|
address.Address[0].Address[0].sin6_scope_id = (ULONG)ReadField (ao_scope_id);
|
|
strncpy (src, TransportAddressToString ((PTRANSPORT_ADDRESS)&address, 0), sizeof (src)-1);
|
|
src[sizeof(src)-1] = 0;
|
|
|
|
prot = (USHORT)ReadField (ao_prot);
|
|
flags = (ULONG)ReadField (ao_flags);
|
|
|
|
if ((offset=ReadField (ao_connect))!=0) {
|
|
ctx = ReadField (ao_conncontext);
|
|
}
|
|
else if ((offset=ReadField (ao_rcvdg))!=0) {
|
|
ctx = ReadField (ao_rcvdgcontext);
|
|
}
|
|
else if ((offset=ReadField (ao_disconnect))!=0) {
|
|
ctx = ReadField (ao_disconncontext);
|
|
}
|
|
else if ((offset=ReadField (ao_error))!=0) {
|
|
ctx = ReadField (ao_errcontext);
|
|
}
|
|
else if ((offset=ReadField (ao_rcv))!=0) {
|
|
ctx = ReadField (ao_rcvcontext);
|
|
}
|
|
else if ((offset=ReadField (ao_errorex))!=0) {
|
|
ctx = ReadField (ao_errorexcontext);
|
|
}
|
|
#if 0
|
|
else if ((offset=ReadField (ao_chainedrcv))!=0) {
|
|
ctx = ReadField (ao_chainedrcvcontext);
|
|
}
|
|
#endif
|
|
else if ((offset=ReadField (ao_exprcv))!=0) {
|
|
ctx = ReadField (ao_exprcvcontext);
|
|
}
|
|
|
|
if (offset!=0) {
|
|
GetSymbol (offset, symbol, &offset);
|
|
}
|
|
else {
|
|
strncpy (symbol, "???", sizeof (symbol)-1);
|
|
symbol[sizeof (symbol)-1] = 0;
|
|
}
|
|
|
|
if (SavedMinorVersion>=2471) {
|
|
pid = ReadField (ao_owningpid);
|
|
}
|
|
else {
|
|
pid = 0;
|
|
}
|
|
|
|
#if 0
|
|
offset = ReadField (ao_RemoteAddress);
|
|
if (offset!=0) {
|
|
if (ReadMemory (offset, &address, sizeof (address), &result)) {
|
|
strncpy (dst, TransportAddressToString ((PTRANSPORT_ADDRESS)&address, offset), sizeof (dst)-1);
|
|
}
|
|
else {
|
|
_snprintf (dst, sizeof (dst), "Read err @ %I64X", offset);
|
|
}
|
|
dst[sizeof(dst)-1] = 0;
|
|
}
|
|
else {
|
|
dst[0] = 0;
|
|
}
|
|
#endif
|
|
/* TCB Prot Flags Client ConnCtx PID Addr*/
|
|
dprintf (
|
|
IsPtr64 ()
|
|
? "\n%011.011p %4d %4.4x %-6.8s %011.011p %4.4x %-s"
|
|
: "\n%008.008p %4d %4.4x %-6.8s %008.008p %4.4x %-s",
|
|
DISP_PTR (Address),
|
|
prot,
|
|
flags,
|
|
strtok (symbol, "!"),
|
|
DISP_PTR(ctx),
|
|
(ULONG)pid,
|
|
src);
|
|
|
|
}
|
|
|
|
|
|
ULONG
|
|
GetRemoteAddressFromTcp (
|
|
ULONG64 FoAddress,
|
|
PVOID AddressBuffer,
|
|
SIZE_T AddressBufferLength
|
|
)
|
|
{
|
|
ULONG result;
|
|
ULONG64 fsContext=0, tcpConn=0, tcb=0, u64=0;
|
|
PTA_IP_ADDRESS ipAddress = AddressBuffer;
|
|
|
|
if ((result=GetFieldValue (FoAddress, "NT!_FILE_OBJECT", "FsContext", fsContext))==0 &&
|
|
(result=GetFieldValue (fsContext, "TCPIP!_TCP_CONTEXT", "Conn", tcpConn))==0 &&
|
|
(result=GetFieldValue (tcpConn, "TCPIP!TCPConn", "tc_tcb", tcb))==0 &&
|
|
(result=GetFieldValue (tcb, "TCPIP!TCB", "tcb_daddr", u64))==0 ) {
|
|
|
|
ipAddress->TAAddressCount = 1;
|
|
ipAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
|
|
ipAddress->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
|
|
ipAddress->Address[0].Address[0].in_addr = (ULONG)u64;
|
|
GetFieldValue (tcb, "TCPIP!TCB", "tcb_dport", u64);
|
|
ipAddress->Address[0].Address[0].sin_port = (USHORT)u64;
|
|
ZeroMemory (&ipAddress->Address[0].Address[0].sin_zero,
|
|
sizeof (ipAddress->Address[0].Address[0].sin_zero));
|
|
}
|
|
|
|
return result;
|
|
}
|