Mega Code Archive

 
Categories / Delphi / LAN Web TCP
 

How to display all IP connections

Title: How to display all IP connections Question: I don't know, what is the meaning of the SNMP identifiers, no list found ??? Answer: //------------------------------------------------------------------------ // NetStat.C // 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 // Original from MS C++ [(C) 1998 Mark Russinovich www.SystemsInternals,com] // #include "SNMP.h" from MS C++ or Borland CPP // Translate to Delphi 2001 by Manfred Ssens //------------------------------------------------------------------------- unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, winsock; type // ************ declaration of Snmp types ***************** PAsnObjectIdentifier = ^AsnObjectIdentifier; AsnObjectIdentifier = record idLength: Cardinal; // number of integers in object ids: ^Cardinal; // pointer to integer stream end; AsnOctetString = record _stream: ^BYTE; // pointer to octet stream length: Cardinal; // number of octets in stream _dynamic: BOOL; // true if octets must be freed end; TAsnValue = (number, _string, _object, sequence, address, counter, gauge, ticks, arbitrary); TAsnValueUnion = record // translation of C++ Union case TAsnValue of number :(number :Longint); //..integer tag. %ld(long) _string :(_string :AsnOctetString); //..octet string tag. putchar _object :(_object :AsnObjectIdentifier);//..object identifier tag. .1.2.3.4 sequence :(sequence :AsnOctetString); //..ASN sequence variable. ASN_OCTET STRING address :(address :AsnOctetString); //..IP address variable. 157.578.160 counter :(counter :DWORD); //..counter variable. %lu (unsigned log) gauge :(gauge :DWORD); //..gauge variable. %lu (unsigned log) ticks :(ticks :DWORD); //..timeticks variable. %lu (unsigned log) arbitrary:(arbitrary:AsnOctetString); //..opaque variable. 0x5 ox3 ox end; AsnAny = record asnType: BYTE; // Indicates a ... (look at top) asnValue: TAsnValueUnion; // Contains the variable's value. end; RFC1157VarBind = record name: AsnObjectIdentifier; // variable's object identifer value: AsnAny; // variable's value (in asn terms) end; PRFC1157VarBindList = ^RFC1157VarBindList; RFC1157VarBindList = record list: ^RFC1157VarBind; // array of variable bindings len: Cardinal; // number of bindings in array end; PAsnInteger = ^Longint; TData = record // return Data of Snmp for Print Protocol :String; LocalIP :Cardinal; LocalPort :Cardinal; RemoteIP :Cardinal; RemotePort :UINT; State :String; end; TCardinalArray = Array of Cardinal; TCardinal = ^Cardinal; TForm1 = class(TForm) //turn to "ViewStyle=vsReport" and add 4 Columns: // Protocol, Local Address:Port, Remote Address:Port, State ListView1: TListView; Button1: TButton; CheckBoxResolve: TCheckBox; procedure Button1Click(Sender: TObject); procedure ListView1ColumnClick(Sender: TObject; Column: TListColumn); procedure ListView1Compare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); private ColumnToSort: Integer; end; function GetIpHostName(resolve:Boolean;ipaddr:Cardinal;remote:Boolean):String; function GetPortName(resolve:Boolean;port:Cardinal;proto:String; ipaddr:Cardinal;remote:Boolean):String; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); const ASN_CONSTRUCTOR = $20; ASN_CONTEXTSPECIFIC = $80; ASN_RFC1157_GETNEXTREQUEST = ASN_CONTEXTSPECIFIC OR ASN_CONSTRUCTOR OR $01; tcpidentifiers: array [0..9] of Cardinal = (1,3,6,1,2,1,6,13,1,1); udpidentifiers: array [0..9] of Cardinal = (1,3,6,1,2,1,7, 5,1,1); //I don't know, what is the meaning of the identifiers, no list found ??? TcpState: array [0..11] of String = ('???','CLOSED','LISTENING','SYN_SENT', 'SEN_RECEIVED','ESTABLISHED','FIN_WAIT','FIN_WAIT2','CLOSE_WAIT', 'CLOSING','LAST_ACK','TIME_WAIT'); var pSnmpExtensionInit:function (dwTimeZeroReference:DWORD; hPollForTrapEvent:PHandle; supportedView:PAsnObjectIdentifier):Boolean; stdcall; pSnmpExtensionQuery:function (requestType:Byte; variableBindings:PRFC1157VarBindList; errorStatus:PAsnInteger; errorIndex:PAsnInteger):Boolean; stdcall; wVersionRequested : WORD; //Version of WinSock field hInetLib : THandle; //Library (inetmib1.dll) address _wsaData : WSADATA; //data structure WinSock implementation hTrapEvent : THandle; //Handle to event object hIdentifier : AsnObjectIdentifier; //ASN Object errorStatus, errorIndex : Longint; bindList : RFC1157VarBindList; //connection List bindEntry : RFC1157VarBind; //connection ActualDataType : Cardinal; //delivered Datatype of query function Data : Array of TData; //collecting data DataPointer : Integer; //pointer to actual data field ListItem : TListItem; n : Integer; begin // Initialize winsock //The MAKEWORD macro creates an unsigned 16-bit integer by concatenating two // given unsigned character values. wVersionRequested:=MAKEWORD( 1, 1 ); //The Windows Sockets WSAStartup function initiates use of the Windows // Sockets DLL by a process. if Boolean(WSAStartup(wVersionRequested,_wsaData )) then begin ShowMessage('Could not initialize Winsock.'); exit; end; // Locate and initialize INETMIB1 hInetLib:=LoadLibrary('inetmib1.dll'); if hInetLib=0 then begin ShowMessage('Could not load extension DLL "inetmib1.dll".'); exit; end else begin @pSnmpExtensionInit:=GetProcAddress(hInetLib,'SnmpExtensionInit'); if @pSnmpExtensionInit=nil then begin ShowMessage('Could not load extension DLL "inetmib1.dll".'); exit; end else begin @pSnmpExtensionQuery:=GetProcAddress(hInetLib,'SnmpExtensionQuery'); if @pSnmpExtensionQuery=nil then begin ShowMessage('Could not load extension DLL "inetmib1.dll".'); exit; end; end; end; //The CreateEvent function creates a named or unnamed event object. hTrapEvent:=CreateEvent(nil, TRUE, FALSE,nil); //The extensible agent calls the SnmpExtensionInit function in the extension // agent DLL to perform bilateral initialization of both the extension and // the extensible agents. if not pSnmpExtensionInit(GetTickCount,@hTrapEvent,@hIdentifier) then begin ShowMessage('Could not initialize extension DLL "inetmib1.dll".'); exit; end; //********************** TCP ******************************************** // Initialize the query structure once bindEntry.name.idLength := 10; bindEntry.name.ids := @tcpidentifiers; //In the .List field is the address of the actual List with the return Data bindList.list := @bindEntry; bindList.len := 1; //Roll through TCP connections ActualDataType := 1; //look at the case option DataPointer := 0; //Points to the actual Data in Array while 1=1 do begin if NOT pSnmpExtensionQuery( ASN_RFC1157_GETNEXTREQUEST, @bindList, @errorStatus, @errorIndex ) then begin ShowMessage('Fault in query bind list...exit'); exit; end; // Terminate when we are no longer seeing TCP information if bindEntry.name.idLength // Go back to start of table if we're reading info about the next byte if ActualDataType TCardinalArray(bindEntry.name.ids)[9] then begin ActualDataType:=TCardinalArray(bindEntry.name.ids)[9]; DataPointer:=0; end; // Build our TCP information table case TCardinalArray(bindEntry.name.ids)[9] of 1:begin // Add new Data to Array State of connection SetLength(Data,length(Data)+1); Data[DataPointer].Protocol:='TCP'; Data[DataPointer].State:=TcpState[bindEntry.value.asnValue.number]; end; 2:Data[DataPointer].LocalIP:= //Local IP-address TCardinal(bindEntry.value.asnValue.address._stream)^; 3:Data[DataPointer].LocalPort:= //Local Port bindEntry.value.asnValue.number; 4:Data[DataPointer].RemoteIP:= //Remote IP-address TCardinal(bindEntry.value.asnValue.address._stream)^; 5:Data[DataPointer].RemotePort:= //Remote Port bindEntry.value.asnValue.number; end; DataPointer:=DataPointer+1; end; // Now print the TCP connection information for n:= 0 to Length(Data)-1 do begin with ListView1 do begin ListItem := Items.Add; ListItem.Caption := Data[n].Protocol; ListItem.SubItems.Add( GetIpHostName(CheckBoxResolve.Checked,Data[n].LocalIP,false)+ ':'+ GetPortName(CheckBoxResolve.Checked,Data[n].LocalPort,'tcp', Data[n].LocalIP,false)); ListItem.SubItems.Add( GetIpHostName(CheckBoxResolve.Checked,Data[n].RemoteIP,true)+ ':'+ GetPortName(CheckBoxResolve.Checked,Data[n].RemotePort,'tcp', Data[n].RemoteIP,true)); ListItem.SubItems.Add(Data[n].State); end; Application.ProcessMessages; end; Finalize(Data); //********************** UDP ******************************************** // Initialize the query structure once bindEntry.name.idLength := 10; bindEntry.name.ids := @udpidentifiers; //In the .List field is the address of the actual List with the return Data bindList.list := @bindEntry; bindList.len := 1; //Roll through TCP connections ActualDataType := 1; //look at the case option DataPointer := 0; //Points to the actual Data in Array while 1=1 do begin if NOT pSnmpExtensionQuery( ASN_RFC1157_GETNEXTREQUEST, @bindList, @errorStatus, @errorIndex ) then begin ShowMessage('Fault in query bind list...exit'); exit; end; // Terminate when we are no longer seeing TCP information if bindEntry.name.idLength // Go back to start of table if we're reading info about the next byte if ActualDataType TCardinalArray(bindEntry.name.ids)[9] then begin ActualDataType:=TCardinalArray(bindEntry.name.ids)[9]; DataPointer:=0; end; // Build our UDP information table case TCardinalArray(bindEntry.name.ids)[9] of 1:begin // Add new Data to Array State of connection SetLength(Data,length(Data)+1); Data[DataPointer].Protocol:='UDP'; Data[DataPointer].LocalIP:= TCardinal(bindEntry.value.asnValue.address._stream)^; end; 2:Data[DataPointer].LocalPort:= //Local Port bindEntry.value.asnValue.number; end; DataPointer:=DataPointer+1; end; // Now print the UDP connection information for n:= 0 to Length(Data)-1 do begin with ListView1 do begin ListItem := Items.Add; ListItem.Caption := Data[n].Protocol; ListItem.SubItems.Add( GetIpHostName(CheckBoxResolve.Checked,Data[n].LocalIP,false)+ ':'+ GetPortName(CheckBoxResolve.Checked,Data[n].LocalPort,'udp', Data[n].LocalIP,false)); ListItem.SubItems.Add('*.*.*.*:*'); ListItem.SubItems.Add(''); end; Application.ProcessMessages; end; Finalize(Data); end; //------------------------------------------------------------------------- // GetIpHostName // Translate IP addresses into their name-resolved form if possible. // Translate from C [(C) 1998 Mark Russinovich Systems Internals] to Delphi //------------------------------------------------------------------------- function GetIpHostName(resolve:Boolean;ipaddr:Cardinal;remote:Boolean):String; var P_hostent:PHostent; nipaddr:Cardinal; Buffer: Array [0..255] of char; begin nipaddr:=htonl(ipaddr); //change right bytes to left if NOT resolve OR (remote AND NOT Boolean(nipaddr)) then result:=format('%d.%d.%d.%d', [(nipaddr shr 24) AND $FF, (nipaddr shr 16) AND $FF, (nipaddr shr 8) AND $FF, (nipaddr ) AND $FF]) else if not Boolean(nipaddr) then begin //0.0.0.0 ??? //The Windows Sockets gethostname function returns the standard host // name for the local machine GetHostName(Buffer,SizeOf(Buffer)); result:=StrPas(Buffer); end else if nipaddr = $7f000001 then begin //127.0.0.1 ??? GetHostName(Buffer,SizeOf(Buffer)); result:=StrPas(Buffer); end else begin //The Windows Sockets gethostbyaddr function gets host information // corresponding to an address P_hostent:=GetHostByAddr(PChar(@ipaddr),Sizeof(nipaddr), PF_INET); if P_hostentnil then result:=StrPas(P_hostent.h_name) else result:=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; //------------------------------------------------------------------------- // GetPortName // Translate port numbers into their text equivalent if there is one // Translate from C [(C) 1998 Mark Russinovich Systems Internals] to Delphi //------------------------------------------------------------------------- function GetPortName(resolve:Boolean;port:Cardinal;proto:String; ipaddr:Cardinal;remote:Boolean):String; var psrvent:PServEnt; begin if remote AND NOT Boolean(ipaddr) then result:='0' else if resolve then begin //The Windows Sockets getservbyport function gets service information // corresponding to a port and protocol psrvent:=GetServByPort( htons(port),PChar(proto)); if psrventnil then result:=StrPas(psrvent.s_name) else result:=format('%d',[port]); end else result:=format('%d',[port]); end; procedure TForm1.ListView1ColumnClick(Sender: TObject; Column: TListColumn); begin ColumnToSort := Column.Index; (Sender as TCustomListView).AlphaSort; end; procedure TForm1.ListView1Compare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); var ix: Integer; begin if ColumnToSort = 0 then Compare := CompareText(Item1.Caption,Item2.Caption) else begin ix := ColumnToSort - 1; Compare := CompareText(Item1.SubItems[ix],Item2.SubItems[ix]); end; end; end.