Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1129
  • Last Modified:

Netstat

Hi there,

I want to make a gui version of netstat. But how can i read wich connections are open ? api ?

If someone has some examples for me i would appericiate it,

Kind regards,
Arijan
0
aluiken
Asked:
aluiken
  • 5
  • 2
1 Solution
 
interCommented:
You should use SNMP agent api (default for NT). I try to covert a C source by Mark Russonovich.
igor
0
 
interCommented:
//---------------------------------------------------------------------
//   NETSTAT translation with permission of the  Mark Russonovich
//   from www.ntinternals.com
//   simply add this unit to your uses clause and call it as
//     NetStat(listbox1.items)
//   you can see the details below
//---------------------------------------------------------------------
unit snmp;
interface
uses
  Classes,Windows, WinSock, SysUtils, Dialogs;
// export to other units
function NetStat(const T : TStrings):boolean;
// ---------------------
type
  LONG = longint;
  PIntArray = ^TIntArray;
  TIntArray = array[0..16384] of UINT;
// --------------
// PARTIAL SNMP.H TRANSLATION REQUIRED HERE
const
  ASN_CONSTRUCTOR = $20;
  ASN_CONTEXTSPECIFIC = $80;
  ASN_RFC1157_GETNEXTREQUEST = (ASN_CONTEXTSPECIFIC or ASN_CONSTRUCTOR or $01);
type
  AsnObjectIdentifier = packed record
    idLength : UINT;            // number of integers in oid
    ids      : ^UINT;                 // pointer to integer stream
  end;
  AsnOctetString = packed record
      stream : ^BYTE;     // pointer to octet stream in original BUT I allocate 4 bytes for it
      length : UINT;        // number of octets in stream
      _dynamic : BOOL;        // true if octets must be freed
    end;
  AsnInteger = LONG;
  AsnCounter = DWORD;
  AsnGauge = DWORD;
  AsnTimeticks = DWORD;
  AsnSequence = AsnOctetString;
  AsnImplicitSequence = AsnOctetString;
  AsnIPAddress = AsnOctetString;
  AsnDisplayString = AsnOctetString;
  AsnOpaque = AsnOctetString;
  AsnObjectName = AsnObjectIdentifier;
  AsnNetworkAddress = AsnIPAddress;
  AsnAny = record
      asnType : BYTE;
      asnValue : packed record
          case Integer of
            1 : (                number : AsnInteger              );
            2 : (                _string : AsnOctetString             );
            3 : (                _object : AsnObjectIdentifier             );
            4 : (                sequence : AsnSequence           );
            5 : (   address : AsnIPAddress      );
            6 : (   counter : AsnCounter       );
            7 : (    gauge : AsnGauge        );
            8 : (   ticks : AsnTimeticks   );
            9 : ( arbitrary : AsnOpaque );
      end;
    end;
  AsnObjectSyntax = AsnAny;
  RFC1157VarBind = packed record
    name : AsnObjectName;      // variable's object identifer
    value: AsnObjectSyntax;     // variable's value (in asn terms)
  end;
  RFC1157VarBindList = packed record
    list : ^RFC1157VarBind;      // array of variable bindings
    len  : UINT;        // number of bindings in array
  end;
// SNMP DEFS END
// ----------------
const
  HOSTNAMELEN = 256;
  PORTNAMELEN = 256;
  ADDRESSLEN  = HOSTNAMELEN+PORTNAMELEN;
type
  PTCPINFO = ^TTCPINFO;
  TTCPINFO = packed record
      prev, next : PTCPINFO;
      state,
      localip,
      localport,
      remoteip,
      remoteport : UINT;
  end;
type
  TSnmpExtensionInit = function (
    dwTimeZeroReference : DWORD;
    var hPollForTrapEvent : THandle;
    var supportedView : AsnObjectIdentifier ) : BOOL; stdcall;
  TSnmpExtensionQuery = function (
    requestType : byte;
    var variableBindings : RFC1157VarBindList;
    var errorStatus : AsnInteger;
    var errorIndex : AsnInteger) : BOOL; stdcall;
//
// Possible TCP endpoint states
//
const
  TcpState : array[0..11] of string = (
      '???',
      'CLOSED',
      'LISTENING',
      'SYN_SENT',
      'SEN_RECEIVED',
      'ESTABLISHED',
      'FIN_WAIT',
      'FIN_WAIT2',
      'CLOSE_WAIT',
      'CLOSING',
      'LAST_ACK',
      'TIME_WAIT');
//
// Lists of endpoints
//
var
  TcpInfoTable,
  UdpInfoTable : TTCPINFO;
  SnmpExtensionInit : TSnmpExtensionInit;
  SnmpExtensionQuery: TSnmpExtensionQuery;
implementation
//------------------------------------------------------------
//
// GetPortName
//
// Translate port numbers into their text equivalent if
// there is one
//
//------------------------------------------------------------
function GetPortName( port : UINT; proto, name : PChar; namelen :integer): PChar;
var
 psrvent : Pservent;
begin
  psrvent := getservbyport( htons(port), proto );
      if ( psrvent <> nil) then
           StrCopy( name, psrvent^.s_name )
      else
           StrCopy( name , PChar(Format('%d', [port])));
  Result := name;
end;
//------------------------------------------------------------
//
// GetIpHostName
//
// Translate IP addresses into their name-resolved form
// if possible.
//
//------------------------------------------------------------
function GetIpHostName( local : BOOL; ipaddr : UINT; name :PChar;namelen :integer):PChar;
var
  _phostent : PHostEnt;
  nipaddr  : UINT;
begin
  nipaddr := htonl( ipaddr );
  if( ipaddr <> 0 ) then
  begin
            if( local ) then
                begin
                  StrCopy( name , PChar( Format('%d.%d.%d.%d',[
                        (nipaddr shr 24) and $FF,
                        (nipaddr shr 16) and $FF,
                        (nipaddr shr 8) and $FF,
                        (nipaddr) and $FF])));
            end
                else
                begin
                  gethostname(name, namelen);
            end
      end else if( ipaddr = $0100007f ) then
        begin
            if( local ) then
                begin
                  gethostname(name, namelen);
            end
                else
                begin
                  StrCopy(  name, 'localhost' );
            end
      end else begin
          _phostent := gethostbyaddr( @ipaddr, sizeof( nipaddr ), PF_INET );
          if( _phostent <> nil) then
          begin
            strcopy( name, _phostent^.h_name );
        end else
          begin
            StrCopy( name , PChar(Format('%d.%d.%d.%d',[
                  (nipaddr shr 24) and $FF,
                  (nipaddr shr 16) and $FF,
                  (nipaddr shr 8) and $FF,
                  (nipaddr) and $FF])));
          end
        end;
      Result := name;
end;
//------------------------------------------------------------
//
// LoadInetMibEntryPoints
//
// Load the TCP/IP SNMP extension DLL and locate the entry
// points we will use.
//
//------------------------------------------------------------
function LoadInetMibEntryPoints:boolean;
var
  hInetLib : THandle;
begin
  hInetLib := LoadLibrary( 'inetmib1.dll' );
      if( hInetLib = 0) then
        begin
        Result := FALSE;
          Exit;
      end;
        @SnmpExtensionInit := GetProcAddress( hInetLib,'SnmpExtensionInit' );
      if( @SnmpExtensionInit = nil ) then
        begin
        Result := FALSE;
          Exit;
      end;
        @SnmpExtensionQuery := GetProcAddress( hInetLib,'SnmpExtensionQuery' );
      if( @SnmpExtensionQuery = nil ) then
        begin
        Result := FALSE;
          Exit;
      end;
      Result := true;
end;
//------------------------------------------------------------
//
// Main
//
// Do it all. Load and initialize the SNMP extension DLL and
// then build a table of TCP endpoints and UDP endpoints. After
// each table is built resolve addresses to names and print
// out the information
//
//------------------------------------------------------------
function NetStat(const T : TStrings):boolean;
var
      hTrapEvent : THandle;
      hIdentifier : AsnObjectIdentifier;
      bindList : RFC1157VarBindList;
      bindEntry : RFC1157VarBind;
      errorStatus, errorIndex : AsnInteger;
      currentEntry, newEntry : PTCPINFO;
      currentIndex : UINT;
      wVersionRequested :WORD;
      wsaData: TWSADATA;
      localname, remotename : array[0..HOSTNAMELEN] of char;
      remoteport, localport : array[0..PORTNAMELEN] of char;
      localaddr, remoteaddr : array[0..ADDRESSLEN] of char;
const
      tcpidentifiers: array[0..9] of UINT = (1,3,6,1,2,1,6,13,1,1);
      udpidentifiers: array[0..9] of UINT= (1,3,6,1,2,1,7,5,1,1);
begin
        Result := false;
        FillChar(bindEntry, sizeof(bindEntry),0);
        try
      //
      // Initialize winsock
      //
      wVersionRequested := $0101;
      if( WSAStartup(  wVersionRequested, wsaData ) <> 0) then
        begin
        ShowMessage('Could not initialize Winsock.');
          Exit;
      end;
      //
      // Locate and initialize INETMIB1
      //
      if( not LoadInetMibEntryPoints) then
        begin
            ShowMessage('Could not load extension DLL.');
            Exit;
      end;
      if( not SnmpExtensionInit( GetCurrentTime, hTrapEvent, hIdentifier )) then
        begin
            ShowMessage('Could not initialize extension DLL.');
            Exit;
      end;
      //
      // Initialize the query structure once
      //
      bindEntry.name.idLength := $A;
      bindEntry.name.ids := @tcpidentifiers[0];
      bindList.list := @bindEntry;
      bindList.len  := 1;
      TcpInfoTable.prev := @TcpInfoTable;
      TcpInfoTable.next := @TcpInfoTable;
      //
      // Roll through TCP connections
      //
      currentIndex := 1;
      currentEntry := @TcpInfoTable;
      while(true) do
        begin
            if( not SnmpExtensionQuery( ASN_RFC1157_GETNEXTREQUEST,
                  bindList, errorStatus, errorIndex )) then
                begin
                        Exit;
            end;
            //
            // Terminate when we're no longer seeing TCP information
            //
            if( bindEntry.name.idLength < $A ) then break;
            //
            // Go back to start of table if we're reading info
            // about the next byte
            //
            if( currentIndex <>  PIntArray(bindEntry.name.ids)^[9] ) then
                begin
                  currentEntry := TcpInfoTable.next;
                  currentIndex := PIntArray(bindEntry.name.ids)^[9];
            end;
            //
            // Build our TCP information table
            //
            case  PIntArray(bindEntry.name.ids)^[9] of
              1:    begin
                  //
                  // Always allocate a new structure
                  //
                  new(newEntry);
                  newEntry^.prev := currentEntry;
                  newEntry^.next := @TcpInfoTable;
                  currentEntry^.next := newEntry;
                  currentEntry := newEntry;
                  currentEntry^.state := bindEntry.value.asnValue.number;
                  end;
              2:    begin
                  currentEntry^.localip :=
                        PIntArray(bindEntry.value.asnValue.address.stream)^[0];
                  currentEntry := currentEntry^.next;
                  end;
              3:    begin
                  currentEntry^.localport :=
                        bindEntry.value.asnValue.number;
                  currentEntry := currentEntry^.next;
                  end;
              4:    begin
                  currentEntry^.remoteip :=
                        PIntArray(@bindEntry.value.asnValue.address.stream)^[0];
                  currentEntry := currentEntry^.next;
                  end;
              5:    begin
                  currentEntry^.remoteport :=
                        bindEntry.value.asnValue.number;
                  currentEntry := currentEntry^.next;
                  end;
            end;
      end;
      //
      // Now print the connection information
      //
      T.Add(Format('%7s %-30s %-30s %s', ['Proto', 'Local', 'Remote', 'State'] ));
      currentEntry := TcpInfoTable.next;
      while( currentEntry <>  @TcpInfoTable ) do
        begin
            StrCopy(localaddr, PChar(Format('%s:%s',[
                    GetIpHostName( TRUE, currentEntry^.localip, localname, HOSTNAMELEN),
                    GetPortName( currentEntry^.localport, 'tcp', localport, PORTNAMELEN )])));
                if currentEntry^.remoteip = 0 then
                  remoteport := '0'
                else
                  GetPortName( currentEntry^.remoteport, 'tcp', remoteport, PORTNAMELEN );
            StrCopy( remoteaddr , PChar(Format('%s:%s',[
                  GetIpHostName( FALSE, currentEntry^.remoteip, remotename, HOSTNAMELEN),
                        remoteport])));
            T.Add(Format('%7s %-30s %-30s %d', ['TCP',
                  localaddr, remoteaddr,
//                  TcpState[currentEntry^.state]]));
                  currentEntry^.state]));
            currentEntry := currentEntry^.next;
      end;
      //
      // Initialize the query structure once
      //
      bindEntry.name.idLength := $A;
      bindEntry.name.ids := @udpidentifiers;
      bindList.list := @bindEntry;
      bindList.len  := 1;
      UdpInfoTable.prev := @UdpInfoTable;
      UdpInfoTable.next := @UdpInfoTable;
      //
      // Roll through UDP endpoints
      //
      currentIndex := 1;
      currentEntry := @UdpInfoTable;
      while(true) do
        begin
            if not SnmpExtensionQuery( ASN_RFC1157_GETNEXTREQUEST,
                  bindList, errorStatus, errorIndex ) then
                begin
                        Exit;
            end;
            //
            // Terminate when we're no longer seeing TCP information
            //
            if( bindEntry.name.idLength < $A ) then break;
            //
            // Go back to start of table if we're reading info
            // about the next byte
            //
            if( currentIndex <>  PIntArray(bindEntry.name.ids)^[9] ) then
                begin
                  currentEntry := UdpInfoTable.next;
                  currentIndex := PIntArray(bindEntry.name.ids)^[9];
            end;
            //
            // Build our TCP information table
            //
            case PIntArray(bindEntry.name.ids)^[9] of
              1: begin
                  //
                  // Always allocate a new structure
                  //
                  new(newEntry);
                  newEntry^.prev := currentEntry;
                  newEntry^.next := @UdpInfoTable;
                  currentEntry^.next := newEntry;
                  currentEntry := newEntry;
                  currentEntry^.localip :=
                        PIntArray(@bindEntry.value.asnValue.address.stream)^[0];
                  end;
              2: begin
                  currentEntry^.localport :=
                        bindEntry.value.asnValue.number;
                  currentEntry := currentEntry^.next;
                  end;
            end;
      end;
      //
      // Now print the connection information
      //
      currentEntry := UdpInfoTable.next;
      while( currentEntry <>  @UdpInfoTable ) do
        begin
            T.Add(Format('%7s %s:%s', ['UDP',
                        GetIpHostName( TRUE, currentEntry^.localip, localname, HOSTNAMELEN),
                        GetPortName( currentEntry^.localport, 'udp', localport, PORTNAMELEN )] ));
            currentEntry := currentEntry^.next;
      end;
      Result := true;
        finally
          WSACleanup;
        end;
end;
end.

Regards, Igor (sorry I should squeezz the code...)
0
 
interCommented:
Sorry it is too bad, give your email address and I'll post it...
igor
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
aluikenAuthor Commented:
Ok my email = aluiken@amgen.com
0
 
interCommented:
Hi,
So the code of the previous answer is the answer to this question. Just change the
T.Add(Format('%7s %-30s %-30s %d', ['TCP',
      localaddr, remoteaddr,
      // TcpState[currentEntry^.state]]));
      currentEntry^.state]));
to
T.Add(Format('%7s %-30s %-30s %d', ['TCP',
      localaddr, remoteaddr,
      TcpState[currentEntry^.state]]));

regards, igor (may everthing is ok)
0
 
aluikenAuthor Commented:
Hi, i checked out the code but somehow it does not work, but i have got an idea now how to fix it.

Thanks.
0
 
interCommented:
What is do not work? I can help you...The code should comile without any modification. I am using Delphi 3 and test the program several times...
0
 
mbormannCommented:
hello igor,inter

CAn u pls send me the C source code for netstat?
My Email is amitkulz@hotmail.com ,
thanks very much!
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now