Tuesday, 11 August 2009

Implementación del NetStat con Delphi

En éste artículo os mostraré una pequeña aplicación para visualizar la tabla de conexiones activas de nuestro equipo, al igual que utilizando el comando netstat en el intérprete de comandos. No os habéis preguntado como poder visualizar ésta tabla en una aplicación?, pues bien, eso es sencillo si echamos un vistazo a la librería de windows MSDN (Microsoft Developer Network). Para ésta aplicación, utilizaremos una librería que trae el sistema llamada IP Helper 'iphlpapi.dll' y que se encuentra en la ruta C:\WINDOWS\system32. Ésta librería, contiene un sinfín de funciones que nos permitirán obtener la tabla TCP y UDP de nuestra máquina. Si observamos las referencias de su API, en la web oficial de MSDN, podemos observar todos los métodos que podemos utilizar e incluso ejemplos escritos en la web (en C).
Pues bien, la aplicación tan sencilla que os propongo, utilizará la API del IP Helper mediante Delphi, y lo que haremos será conectarnos a la DLL, y apuntar a sus métodos de la siguiente forma:

initialization
    //Initialization of C:\windows\system32\iphlpapi.dll
    GetTcpTable := nil;
    GetExtendedTcpTable := nil;
    GetOwnerModuleFromTcpEntry := nil;
    Lib := LoadLibrary('iphlpapi.dll');
    if Lib <> 0 then
    begin
        GetTcpTable := GetProcAddress(Lib, 'GetTcpTable');
        GetExtendedTcpTable := GetProcAddress(Lib, 'GetExtendedTcpTable');
        GetOwnerModuleFromTcpEntry := GetProcAddress(Lib, 'GetOwnerModuleFromTcpEntry');
        GetUdpTable := GetProcAddress(Lib, 'GetUdpTable');
        GetExtendedUdpTable := GetProcAddress(Lib, 'GetExtendedUdpTable');
        GetOwnerModuleFromUdpEntry := GetProcAddress(Lib, 'GetOwnerModuleFromUdpEntry');
    end;
    Cache := nil;
    Cache := TStringList.Create;
finalization
    GetTcpTable := nil;
    GetExtendedTcpTable := nil;
    GetOwnerModuleFromTcpEntry := nil;
    GetUdpTable := nil;
    if Lib <> 0 then
        FreeLibrary(Lib);
    FreeAndNil(Cache);
end.

Una vez tenemos configurada la parte de la librería, solo tenemos que pensar en como representar los datos y luego hacer con ellos lo que queramos. Si os fijáis en la siguiente imagen, trata de una de mis aplicaciones Thundax Netstat, que la verdad es que la hice hace tiempo y ahora os la pongo aquí para que podáis comprobar que os aparece la misma tabla que al hacer netstat desde el cmd.


Mi intención ahora, es continuar con la aplicación y crear un avisador de conexiones. Ya lo hice en su día hace un par de años con VB.NET, y lo que hacía era escanear la tabla de conexiones y cuando aparecía una nueva conexión, es decir alguien se conectaba a nuestro equipo, te aparecía un popup indicando que alguien intentaba conectarse. Intentaré buscar ese código para ver lo que hice en su día!.

Aquí os dejo la aplicación ThundaxNetStat, para que la ejecutéis y comprobéis si funciona correctamente.

Un ejemplo de la carga de la tabla IP:

procedure TForm1.LoadTCPTable;
var
    TcpTable: PMIB_TCPTABLE;
    Size, i: DWORD;
    List: TObjectList;
begin
    List := TObjectList.Create();
    if TcpTableExists then
    begin
        GetMem(TcpTable, sizeof(MIB_TCPTABLE));
        Size := 0;
        if GetTcpTable(TcpTable, Size, TRUE) = ERROR_INSUFFICIENT_BUFFER then
        begin
            FreeMem(TcpTable);
            GetMem(TcpTable, Size);
        end;
        try
            if (GetTcpTable(TcpTable, Size, TRUE) = NO_ERROR) then
                for i := 0 to TcpTable.dwNumEntries - 1 do
                    if (TcpTable.table[i].dwState <> 2) or mnuListen.Checked then
                    begin
                        List.add('TCP');
                        List.add(IPToStr(TcpTable.table[i].dwLocalAddr) + ' : ' + IntToStr(htons(TcpTable.table[i].dwLocalPort)));
                        if TcpTable.table[i].dwState <> 2 then
                            List.add(IPToStr(TcpTable.table[i].dwRemoteAddr) + ' : ' + IntToStr(htons(TcpTable.table[i].dwRemotePort)))
                        else
                            List.add('- : -');
                        List.add(StateToStr(TcpTable.table[i].dwState));
                    end;
        finally
            FreeMem(TcpTable);
        end;
    end;
end;

Espero que os sirva de ayuda.

  • Enlaces de Interés:
xNestat Profesional.
Netstat VB.

2 comments:

  1. Hello...

    Thanks for this info it's dificult to find info on it over the web...

    Any way i am making a little tool for me under delphi to monitor some applications connections.

    as i am a newbie it's difficult for me to reproduce your "Thundax Netstat" could you please help me by providing me the sources ?

    intikaa@hotmail.com

    Thanks a lot !!!!!!!!

    ReplyDelete
  2. any way very good work !

    ReplyDelete