Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi TCPTable liefert falschen Port (https://www.delphipraxis.net/25745-tcptable-liefert-falschen-port.html)

Luckie 11. Jul 2004 19:41


TCPTable liefert falschen Port
 
Liste der Anhänge anzeigen (Anzahl: 4)
Ich bin gerade dabei und überarbeite meinen IPMonitor. Dafür benutze ich die IPHlpAPI übersetzungen von Marcel van Brakel. Nur hab eich sie jetzt etwas modifiziert, sprich, ich habe mir nur das rausgezogen, was ich brauche. Die IPs stimmen auch alle, nur die Ports sind Mist.

Hier mal mein Code:
Delphi-Quellcode:
function IpAddressToString(Addr: DWORD): string;
var
  InAddr: TInAddr;
begin
  InAddr.S_addr := Addr;
  Result := inet_ntoa(InAddr);
end;

function TCPStateToStr(status: integer): string;
begin
  status := status - 1;
  case status of
    0: result := 'closed';
    1: result := 'listen';
    2: result := 'SYN_Sent';
    3: result := 'SYN_Rcvd';
    4: result := 'established';
    5: result := 'Fin wait 1';
    6: result := 'Fin wait 2';
    7: result := 'Close wait';
    8: result := 'closing';
    9: result := 'last Ack.';
    10: result := 'time wait';
    11: result := 'delete TCB';
  end;
end;

function GetIPInfos: IPInfo;
var
  TCPTable: PMibTcpTable;
  UDPTable: PMibUdptable;
  NumEntriesTCP: DWORD;
  NumEntriesUDP: DWORD;
  dwSizeTCP: DWORD;
  dwSizeUDP: DWORD;
  i: Integer;
begin
  Setlength(result, 0);
  VVGetTcpTable(TCPTable, dwSizeTCP, True);
  NumEntriesTCP := TCPTable.dwNumEntries;
  if TCPTable <> nil then
  begin
    SetLength(result, NumEntriesTCP);
    for i := 0 to NumEntriesTCP - 1 do
    begin
      result[i].Protokoll := 'TCP';
      result[i].localIP := IpAddressToString(TCPTable^.table[i].dwLocalAddr);
      result[i].localPort := IntToStr(TCPTable^.table[i].dwLocalPort);
      result[i].remoteIP := IpAddressToString(TCPTable^.table[i].dwRemoteAddr);
      result[i].remotePort := IntToStr(TCPTable^.table[i].dwRemotePort);
      result[i].Status := TCPTable^.table[i].dwState;
    end;
  end;
  FreeMem(TCPTable, dwSizeTCP);
  VVGetUdpTable(UDPTable, dwSizeUDP, True);
  if UDPTable <> nil then
  begin
    NumEntriesUDP := UDPTable.dwNumEntries;
    SetLength(result, NumEntriesTCP + NumEntriesUDP);
    for i := NumEntriesTCP to NumEntriesTCP + NumEntriesUDP - 1 do
    begin
      result[i].Protokoll := 'UDP';
      result[i].localIP := IpAddressToString(UDPTable^.table[i].dwLocalAddr);
      result[i].localPort := IntToStr(UDPTable^.table[i].dwLocalPort);
    end;
  end;
  FreeMem(UDPTable, dwSizeUDP);
end;
Und im Anhang meine Units. Irgendwo steckt da der Wurm drinne. Ich habe schon die original Units von Marcel genommen, da stimmen die Ports auch nicht. Bei UDP kommt übrigens nur Mist raus. :roll:

Chewie 11. Jul 2004 19:51

Re: TCPTable liefert falschen Port
 
Ist nur so ne Idee, aber versuch mal die Byte-Umkehrung (Host Order in Network Order) anzuwenden (MSDN-Library durchsuchenhtons)

Luckie 11. Jul 2004 19:56

Re: TCPTable liefert falschen Port
 
Die IP Adressen stimme ja - zumindest bei TCP.

Chewie 11. Jul 2004 20:22

Re: TCPTable liefert falschen Port
 
Bei der IP-Adresse hatte ich noch nie Probleme mit der Byte Order.

Luckie 11. Jul 2004 21:26

Re: TCPTable liefert falschen Port
 
So, ersteres Problem mit den Ports ist gelöst:
Code:
result[i].localPort := IntToStr([b]ntohs[/b](Word(TCPTable^.table[i].dwlocalPort)));
Die fehlerhaften IP Adressen bei UDP bleiben noch.

c113plpbr 12. Jul 2004 16:20

Re: TCPTable liefert falschen Port
 
beim port sollte dir htons weiterhelfen
den host musst kannst du warscheinlich mit GetHostByAddr rausfinden. Über den Hostnamen kannst du dann theoretisch die IP-rausfinden.

ciao, Philipp

shmia 12. Jul 2004 16:41

Re: TCPTable liefert falschen Port
 
Das Fehlerhandling in VVGetTcpTable & VVGetUdpTable erscheint mir noch etwas zu schwach.
Delphi-Quellcode:
procedure VVGetTcpTable(var pTcpTable: PMibTcpTable; var dwSize: DWORD;
  const bOrder: BOOL);
var
  Res: DWORD;
begin
  ....
    Res := GetTcpTable(pTcpTable, dwSize, bOrder);
  end;
  (* alt
  if Res <> NO_ERROR then
    exit;
  *)
  // neu
  case res of
     ERROR_NOT_SUPPORTED : raise EWin32Error.Create('GetTcpTable not supported');
     ERROR_INVALID_PARAMETER : raise EWin32Error.Create('GetTcpTable: invalid parameter');
  else
     raise EWin32Error.CreateResFmt(@SWin32Error, [Res, SysErrorMessage(Res)])
  end;
end;

Luckie 12. Jul 2004 17:05

Re: TCPTable liefert falschen Port
 
@shimia: Das war Absicht, da ich die SysUtils rausschmeißen wollte. Ganz befriedigt michmeine Lösung auch noch nicht. Im Original entspricht die Fehlerbehandlung in etwa deiner Version.

@c113plpbr: Ja, das könnte ich probieren mit htons. Aber wie soll ich die IP auflösen und wieder zurück, wenn ich nur Schrott bekomme?

Chewie 12. Jul 2004 17:13

Re: TCPTable liefert falschen Port
 
Zitat:

Zitat von Luckie
@c113plpbr: Ja, das könnte ich probieren mit htons. Aber wie soll ich die IP auflösen und wieder zurück, wenn ich nur Schrott bekomme?

Du benutzt ja schon htons bei dem Port, Luckie. htons und ntohs sind ja identisch: Beide Funktionen kehren die Byte-Order eines 16Bit-Wortes um. Die Unterscheidung dient nur der besseren Verständlichkeit. Network Order ist halt eine bestimmte Reihenfolge und Host Order die andere. Mehr Möglichkeiten gibt es nicht.
Das Pendant für 32Bit heißt htonl bzw. ntohl, versuch mal, das auf deine falsche IP-Adresse loszulassen. Warum du das tun musst, weiß ich auch nicht, aber vielleicht funktionierts ja...

Luckie 12. Jul 2004 17:46

Re: TCPTable liefert falschen Port
 
So richtig was gebracht hat das auch nicht.

c113plpbr 12. Jul 2004 19:19

Re: TCPTable liefert falschen Port
 
Für die lokale IP kannst du das hier verwenden um den rechnernamen herauszufinden:
Delphi-Quellcode:
GetServByPort(dwLocalPort, nil)
und für die remote IP das hier:
Delphi-Quellcode:
GetHostByAddr(PChar(@dwLocalAddr), SizeOf(DWORD), AF_INET)
versuchs einfach ... bei mir hats geklappt ... ^^ (setz einfach mal den 'schrott' da ein, und schau mal was rauskommt)

[edit]und falls es dann immer noch nicht geht: http://salvatoremeschini.cjb.net/ schau dir unter downloads netstat32 an[/edit]

Luckie 13. Jul 2004 01:16

Re: TCPTable liefert falschen Port
 
Ich willd ie IP ja nichjt auflösen. Ich will erstmal schon eine gescheite IP da stehen haben. Und ob mir der Lionk weiterhilft vage ich zu bezweifeln. Denn das verrückte ist ja, mein erstes Programm mit wietgehend identischen Code liefert keinen Schrott. Irgendwas mache ich anders, aber ich weiß eben nicht was. :evil:

Luckie 13. Jul 2004 03:22

Re: TCPTable liefert falschen Port
 
So, habe den Fehler gefunden:
Delphi-Quellcode:
function GetIPInfos: IPInfo;
var
  Error: DWORD;
  TCPTable: PMibTcpTable;
  UDPTable: PMibUdptable;
  NumEntriesTCP: DWORD;
  NumEntriesUDP: DWORD;
  dwSize: DWORD;
  i: Integer;
begin
  NumEntriesTCP := 0;
  Setlength(result, 0);
//  dwSize := 0;
//  Error := GetTcpTable(nil, dwSize, False);
//  if Error <> ERROR_INSUFFICIENT_BUFFER then
//    Exit;
//  GetMem(TCPTable, dwSize);
//  try
//    if GetTCPTable(TcpTable, dwSize, TRUE) = NO_ERROR then
//    begin
//      if TCPTable <> nil then
//      begin
//        NumEntriesTCP := TCPTable.dwNumEntries;
//        SetLength(result, NumEntriesTCP);
//        for i := 0 to NumEntriesTCP - 1 do
//        begin
//          result[i].Protocol := 'TCP';
//          result[i].localIP := TCPTable^.table[i].dwLocalAddr;
//          result[i].localPort := TCPTable^.table[i].dwlocalPort;
//          result[i].remoteIP := TCPTable^.table[i].dwRemoteAddr;
//          if TCPTable^.table[i].dwRemoteAddr = 0 then
//            TCPTable^.table[i].dwRemotePort := 0;
//          result[i].remotePort := TCPTable^.table[i].dwRemotePort;
//          result[i].Status := TCPTable^.table[i].dwState;
//        end;
//      end;
//    end;
//  finally
//    FreeMem(TCPTable, dwSize);
//  end;
  dwSize := 0;
  Error := GetUdpTable(nil, dwSize, False);
  if Error <> ERROR_INSUFFICIENT_BUFFER then
    exit;
  GetMem(UDPTable, dwSize);
  try
    if GetUdpTable(UDPTable, dwSize, TRUE) = NO_ERROR then
    begin
      if UDPTable <> nil then
      begin
        NumEntriesUDP := UDPTable.dwNumEntries;
        SetLength(result, NumEntriesUDP); {SetLength(result, NumEntriesTCP+NumEntriesUDP);}
        for i := 0 to NumEntriesUDP-1 do {for i := NumEntriesTCP to NumEntriesTCP+ NumEntriesUDP-1 do}
        begin
          result[i].Protocol := 'UDP';
          result[i].localIP := UDPTable^.table[i].dwLocalAddr;
          result[i].localPort := UDPTable^.table[i].dwLocalPort;
          result[i].remoteIP := 0;
          result[i].remotePort := 0;
          result[i].Status := 99;
        end;
      end;
    end;
  finally
    FreeMem(UDPTable, dwSize);
  end;
end;
Da geht irgendwo was schief mit dem Array füllen. Lasse ich den oberen Teil raus und fülle das Array nur mit den UDP Werten klappt alles wunderbar. Nehme ich den TCP Teil hinzu, stimmen sie nicht mehr. Was mache ich also falsch?

Luckie 13. Jul 2004 11:57

Re: TCPTable liefert falschen Port
 
Liste der Anhänge anzeigen (Anzahl: 1)
Um es noch mal deutlich zu machen. Das Array wird schon richtig verlängert, aber irgendwie stimmen die Werte dann nicht mehr, die dann da reingeschrieben werden.

Wer es selber noch mal testen will, dem habe ich das Projekt noch mal angehangen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:09 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz