Solved

Netstat

Posted on 1998-09-27
8
1,120 Views
Last Modified: 2010-05-18
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
Comment
Question by:aluiken
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 2
8 Comments
 
LVL 5

Expert Comment

by:inter
ID: 1340982
You should use SNMP agent api (default for NT). I try to covert a C source by Mark Russonovich.
igor
0
 
LVL 5

Expert Comment

by:inter
ID: 1340983
//---------------------------------------------------------------------
//   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
 
LVL 5

Expert Comment

by:inter
ID: 1340984
Sorry it is too bad, give your email address and I'll post it...
igor
0
[Live Webinar] The Cloud Skills Gap

As Cloud technologies come of age, business leaders grapple with the impact it has on their team's skills and the gap associated with the use of a cloud platform.

Join experts from 451 Research and Concerto Cloud Services on July 27th where we will examine fact and fiction.

 
LVL 1

Author Comment

by:aluiken
ID: 1340985
Ok my email = aluiken@amgen.com
0
 
LVL 5

Accepted Solution

by:
inter earned 200 total points
ID: 1340986
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
 
LVL 1

Author Comment

by:aluiken
ID: 1340987
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
 
LVL 5

Expert Comment

by:inter
ID: 1340988
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
 
LVL 5

Expert Comment

by:mbormann
ID: 2297940
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

Get HTML5 Certified

Want to be a web developer? You'll need to know HTML. Prepare for HTML5 certification by enrolling in July's Course of the Month! It's free for Premium Members, Team Accounts, and Qualified Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
Suggested Courses
Course of the Month6 days, 11 hours left to enroll

623 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question