Not getting correct port number by GetExtendedTcpTable in delphi 7
I have implemented the following code for getting TCP information by the Function getTCPExtendedTable :
const
ANY_SIZE = 1;
iphlpapi = 'iphlpapi.dll'; //For using the DLL
TCP_TABLE_OWNER_PID_ALL = 5;
{States of the Connections}
MIB_TCP_STATE:
array[1..12] of string = ('CLOSED', 'LISTEN', 'SYN-SENT ','SYN-RECEIVED', 'ESTABLISHED', 'FIN-WAIT-1',
'FIN-WAIT-2', 'CLOSE-WAIT', 'CLOSING','LAST-ACK', 'TIME- WAIT', 'delete TCB');
{record of type MIB_TCPROW:
typedef struct _MIB_TCPROW
{
DWORD dwState;
DWORD dwLocalAddr;
DWORD dwLocalPort;
DWORD dwRemoteAddr;
DWORD dwRemotePort;
}//MIB_TCPROW, *PMIB_TCPROW;
type
{The type of the TCP table structure to retrieve.
This parameter can be one of the values from the TCP_TABLE_CLASS enumeration. }
TCP_TABLE_CLASS = Integer;
PMibTcpRowOwnerPid = ^TMibTcpRowOwnerPid;
TMibTcpRowOwnerPid = packed record
dwState : DWORD;
dwLocalAddr : DWORD;
dwLocalPort : DWORD;
dwRemoteAddr: DWORD;
dwRemotePort: DWORD;
dwOwningPid : DWORD;
end;
{record of type MIB_TCPTABLE:
typedef struct _MIB_TCPTABLE
{
DWORD dwNumEntries;
MIB_TCPROW table[ANY_SIZE];
} //MIB_TCPTABLE, *PMIB_TCPTABLE
PMIB_TCPTABLE_OWNER_PID = ^MIB_TCPTABLE_OWNER_PID;
MIB_TCPTABLE_OWNER_PID = packed record
dwNumEntries: DWord;
table: array [0..ANY_SIZE - 1] OF TMibTcpRowOwnerPid;
end;
//Defintion
GetExtendedTcpTable:function (pTcpTable: Pointer; dwSize: PDWORD; bOrder: BOOL; lAf: ULONG; TableClass: TCP_TABLE_CLASS; Reserved: ULONG): DWord; stdcall;
procedure TFmainViewTCP.ShowCurrent开发者_高级运维TCPConnections;
var
Error : DWORD;
TableSize : DWORD;
i : integer;
IpAddress : in_addr;
RemoteIp : string;
LocalIp : string;
ProcName:string;
FExtendedTcpTable : PMIB_TCPTABLE_OWNER_PID;
begin
i:=0;
TableSize := 0;
Error := GetExtendedTcpTable(nil, @TableSize, False,AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
if Error <> ERROR_INSUFFICIENT_BUFFER then
Exit;
GetMem(FExtendedTcpTable, TableSize);
try
if GetExtendedTcpTable(FExtendedTcpTable, @TableSize, TRUE,AF_INET,TCP_TABLE_OWNER_PID_ALL, 0) = NO_ERROR then
begin
for i := 0 to FExtendedTcpTable.dwNumEntries - 1 do
begin
IpAddress.s_addr := FExtendedTcpTable.Table[i].dwRemoteAddr;
RemoteIp := string(inet_ntoa(IpAddress));
IpAddress.s_addr := FExtendedTcpTable.Table[i].dwLocalAddr;
LocalIp := string(inet_ntoa(IpAddress));
Memo1.Lines.Add(IntToStr(FExtendedTcpTable.Table[i].dwOwningPid));
Memo1.Lines.Add(IntToStr(Lo(FExtendedTcpTable.Table[i].dwLocalPort)));
end; //for
end; //if
finally
FreeMem(FExtendedTcpTable);
end;
end;
the problem is that the port numbers displayed are like '34560' whereas the real port number is something like '135' as seen through netstat. What changes are needed to see the correct port number?
I read that we should only display the lower 16 bytes of dwLocalPort. I did it with Lo() function. I got answers like '0','8' etc. Please Help.
Thanks in Advance
The port numbers are given in network byte order. Network byte order is big endian and so you have to reverse the order of the bytes to make sense of it.
The documentation for MIB_TCPROW_OWNER_PID
contains this important point.
The dwLocalPort, and dwRemotePort members are in network byte order. In order to use the dwLocalPort or dwRemotePort members, the ntohs or inet_ntoa functions in Windows Sockets or similar functions may be needed.
Simply pass the port numbers through ntohs()
and they will make sense to you again. For example:
Memo1.Lines.Add(IntToStr(ntohs(FExtendedTcpTable.Table[i].dwLocalPort)));
The function returns Raw port numbers which need to be converted to Real Port Numbers, This can be done by
function ConvertRawPortToRealPort(RawPort : DWORD) : DWORD;
begin
Result := (RawPort div 256) + (RawPort mod 256) * 256;
end;
This should give the correct output
精彩评论