for rllibby ( close ports )

for mods:

i have seperated out this suggestion from q
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21194414.html
because it is not a solution for this q, but a very valueable suggestion

for rllibby:

thanks for your time and knowledge.

-------------- the suggestion

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21194414.html#12567693


Meikl,

I'm sure that you could have worked the code to fit yuor situation, but I figured I would save you the time. Here is a re-coding of the tcp table handling so its a little more generic, and can be used as a set of function calls. There are only a few functions, so the learning curve is pretty low

function     TcpOpenEnum(var TcpTable: PTcpTable): DWORD;
procedure  TcpCloseEnum(TcpTable: PTcpTable);
function     TcpPortFromLong(Port: LongWord): Word;
function     TcpAddrFromLong(Address: LongWord): String;
function     TcpStateDescription(State: LongWord): String;
function     TcpDeleteRow(TcpRow: PTcpRow): DWORD;

An example of using all functions:

var  lpTable:       PTcpTable;
     dwCount:       Integer;
begin

  // Retrieve the table of tcp entries
  if (TCPOpenEnum(lpTable) = ERROR_SUCCESS) then
  begin
     // Resource protection
     try
        // Walk the table entries
        for dwCount:=0 to Pred(lpTable^.dwNumEntries) do
        begin
           // Write out
           // -  the local port (in common format, vs network order)
           // -  the local address (in string format)
           // -  the descriptive state of the tcp entry
           WriteLn(TcpPortFromLong(lpTable^.Table[dwCount].dwLocalPort),
                   ' , ',
                   TcpAddrFromLong(lpTable^.Table[dwCount].dwLocalAddr),
                   ' , ',
                   TcpStateDescription(lpTable^.Table[dwCount].dwState));

           // Example of closing a tcp port/connection
           // - check for a connection to a remote port 80 (http) and close it
           if (TcpPortFromLong(lpTable^.Table[dwCount].dwRemotePort) = 80) then
              TcpDeleteRow(@lpTable^.Table[dwCount]);
        end;
     finally
        // Free the memory allocated by the open enum function
        TCPCloseEnum(lpTable);
     end;
  end;

end;

And finally, the source for it all.

Let me know if you run into questions/problems,
Russell

--------

unit TcpApi;
////////////////////////////////////////////////////////////////////////////////
//
//   Unit           :  TCPAPI
//   Date           :  Original -  05.25.2004
//                     Updated  -  11.12.2004
//   Author         :  rllibby
//
//   Description    :  Set of TCP enumeration and helper routines.
//
////////////////////////////////////////////////////////////////////////////////
interface

////////////////////////////////////////////////////////////////////////////////
//   Include units
////////////////////////////////////////////////////////////////////////////////
uses
  Windows,
  SysUtils;

////////////////////////////////////////////////////////////////////////////////
//   General constants
////////////////////////////////////////////////////////////////////////////////
const
  ALLOC_SIZE        =  4096;

////////////////////////////////////////////////////////////////////////////////
//   Data structures
////////////////////////////////////////////////////////////////////////////////
type
  PMIB_TCPROW       =  ^MIB_TCPROW;
  MIB_TCPROW        =  packed record
     dwState:       LongWord;
     dwLocalAddr:   LongWord;
     dwLocalPort:   LongWord;
     dwRemoteAddr:  LongWord;
     dwRemotePort:  LongWord;
  end;
  TTcpRow           =  MIB_TCPROW;
  PTcpRow           =  ^TTcpRow;

  PMIB_TCPTABLE     =  ^MIB_TCPTABLE;
  MIB_TCPTABLE      =  packed record
     dwNumEntries:  LongWord;
     Table:         Array [0..MaxWord] of MIB_TCPROW;
  end;
  TTcpTable         =  MIB_TCPTABLE;
  PTcpTable         =  ^TTcpTable;

  PIP_BYTES         =  ^IP_BYTES;
  IP_BYTES          =  Array [0..3] of Byte;
  TIpBytes          =  IP_BYTES;
  PIpBytes          =  ^TIpBytes;

////////////////////////////////////////////////////////////////////////////////
//   Function definitions
////////////////////////////////////////////////////////////////////////////////
type
  TGetTcpTable      =  function(lpTcpTable: PTcpTable; lpdwSize: PDWORD; bOrder: BOOL): DWORD; stdcall;
  TSetTcpEntry      =  function(lpTcpRow: PTcpRow): DWORD; stdcall;

////////////////////////////////////////////////////////////////////////////////
//   TCP table entry state constants
////////////////////////////////////////////////////////////////////////////////
const
  MIB_TCP_STATE_CLOSED       =  1;
  MIB_TCP_STATE_LISTEN       =  2;
  MIB_TCP_STATE_SYN_SENT     =  3;
  MIB_TCP_STATE_SYN_RCVD     =  4;
  MIB_TCP_STATE_ESTAB        =  5;
  MIB_TCP_STATE_FIN_WAIT1    =  6;
  MIB_TCP_STATE_FIN_WAIT2    =  7;
  MIB_TCP_STATE_CLOSE_WAIT   =  8;
  MIB_TCP_STATE_CLOSING      =  9;
  MIB_TCP_STATE_LAST_ACK     =  10;
  MIB_TCP_STATE_TIME_WAIT    =  11;
  MIB_TCP_STATE_DELETE_TCB   =  12;

const
  MIB_TCP_STATES:            Array [0..12] of PChar =
                            ('Unknown',
                             'Closed',
                             'Listening',
                             'Syn Sent',
                             'Syn Received',
                             'Established',
                             'Fin Wait1',
                             'Fin Wait2',
                             'Close Wait',
                             'Closing',
                             'Last Ack',
                             'Time Wait',
                             'Deleted');

////////////////////////////////////////////////////////////////////////////////
//   Late bound function wrappers
////////////////////////////////////////////////////////////////////////////////
function   GetTcpTable(lpTcpTable: PTcpTable; lpdwSize: PDWORD; bOrder: BOOL): DWORD; stdcall;
function   SetTcpEntry(lpTcpRow: PTcpRow): DWORD; stdcall;

////////////////////////////////////////////////////////////////////////////////
//   TCP functions designed to be used by developers
////////////////////////////////////////////////////////////////////////////////
function   TcpOpenEnum(var TcpTable: PTcpTable): DWORD;
procedure  TcpCloseEnum(TcpTable: PTcpTable);
function   TcpPortFromLong(Port: LongWord): Word;
function   TcpAddrFromLong(Address: LongWord): String;
function   TcpStateDescription(State: LongWord): String;
function   TcpDeleteRow(TcpRow: PTcpRow): DWORD;

implementation

////////////////////////////////////////////////////////////////////////////////
//   Library and function name constants
////////////////////////////////////////////////////////////////////////////////
const
  LIB_IPHLPAPI            =  'iphlpapi.dll';
  FUNC_GETTCPTABLE        =  'GetTcpTable';
  FUNC_SETTCPENTRY_NAME   =  'SetTcpEntry';

////////////////////////////////////////////////////////////////////////////////
//   Protected variables
////////////////////////////////////////////////////////////////////////////////
var
  hIphlp:           HMODULE        =  0;
  _GetTcpTable:     TGetTcpTable   =  nil;
  _SetTcpEntry:     TSetTcpEntry   =  nil;

function TcpDeleteRow(TcpRow: PTcpRow): DWORD;
begin

  // Check assignment
  if Assigned(TcpRow) then
  begin
     // Set entry state
     TcpRow^.dwState:=MIB_TCP_STATE_DELETE_TCB;
     // Call SetTcpEntry
     result:=SetTcpEntry(TcpRow);
  end
  else
     // Invalid param
     result:=ERROR_INVALID_PARAMETER;

end;

function TcpStateDescription(State: LongWord): String;
begin

  // Handle state
  if State in [MIB_TCP_STATE_CLOSED..MIB_TCP_STATE_DELETE_TCB] then
     // Return state description
     result:=MIB_TCP_STATES[State]
  else
     // Unknown state
     result:=MIB_TCP_STATES[0];

end;

function TcpAddrFromLong(Address: LongWord): String;
var  lpBytes:    TIpBytes;
     dwIndex:    Integer;
begin

  // Move dword to byte array
  Move(Address, lpBytes, SizeOf(LongWord));

  // Set start of string
  result:=IntToStr(lpBytes[0]);

  // Walk remaining bytes
  for dwIndex:=Succ(Low(lpBytes)) to High(lpBytes) do result:=result+'.'+IntToStr(lpBytes[dwIndex]);

end;

function TcpPortFromLong(Port: LongWord): Word;
begin

  // Convert from network order to common port format
  result:=(Port div 256) + (Port mod 256) * 256;

end;

function TcpOpenEnum(var TcpTable: PTcpTable): DWORD;
var  dwSize:        DWORD;
begin

  // Set the default size, this is enough to hold appx 204 entries
  dwSize:=ALLOC_SIZE;

  // Allocate memory
  TcpTable:=AllocMem(dwSize);

  // Attempt to get the full tcp table
  result:=GetTcpTable(TcpTable, @dwSize, True);

  // Check for insuffecient buffer
  if (result = ERROR_INSUFFICIENT_BUFFER) then
  begin
     // Re-alloc the table
     ReAllocMem(TcpTable, dwSize);
     // Call the function again
     result:=GetTcpTable(TcpTable, @dwSize, True);
  end;

  // Check result
  if (result <> ERROR_SUCCESS) then
  begin
     // Failed to get table, cleanup allocated memory
     FreeMem(TcpTable);
     // Clear the table
     TcpTable:=nil;
  end;

end;

procedure TcpCloseEnum(TcpTable: PTcpTable);
begin

  // Need to free the memory allocated by a call to open enum
  if Assigned(TcpTable) then FreeMem(TcpTable);

end;

function GetTcpTable(lpTcpTable: PTcpTable; lpdwSize: PDWORD; bOrder: BOOL): DWORD;
begin

  // Make sure the api function was bound
  if Assigned(@_GetTcpTable) then
     // Call the function
     result:=_GetTcpTable(lpTcpTable, lpdwSize, bOrder)
  else
     // Function was not bound
     result:=ERROR_PROC_NOT_FOUND;

end;

function SetTcpEntry(lpTcpRow: PTcpRow): DWORD;
begin

  // Make sure the api function was bound
  if Assigned(@_SetTcpEntry) then
     // Call the function
     result:=_SetTcpEntry(lpTcpRow)
  else
     // Function was not bound
     result:=ERROR_PROC_NOT_FOUND;

end;

initialization

  // Load the ip helper api library
  hIphlp:=LoadLibrary(LIB_IPHLPAPI);

  // Attempt to get the function addresses
  if (hIphlp > 0) then
  begin
     // Bind both the get table and set entry functions
     @_GetTcpTable:=GetProcAddress(hIpHlp, FUNC_GETTCPTABLE);
     @_SetTcpEntry:=GetProcAddress(hIpHlp, FUNC_SETTCPENTRY_NAME);
  end;

finalization

  // Clear bound functions
  @_GetTcpTable:=nil;
  @_SetTcpEntry:=nil;

  // Free the ip helper api library
  if (hIphlp > 0) then FreeLibrary(hIphlp);

end.

--------------------------------------

many thanks

meikl ;-)
LVL 27
kretzschmarAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

tobjectpascalCommented:
Very interesting code, i tried it, all it does is disconnect the socket/connection i am right in thinking that's all it does, you can't close off a port completely or get proccess id of the application that's connected or is there more to it somewhere else?
0
kretzschmarAuthor Commented:
yep, usual it was thought to close a port
(my question header is not correct)

maybe rllibby can tell more

meikl ;-)

0
kretzschmarAuthor Commented:
question title corrected from block into close ;-))
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

Russell LibbySoftware Engineer, Advisory Commented:
Thanks for the points Meikl. I would have posted sooner but its the holiday season here, and I took a few days off....

Regarding the code; yes it closes ports, no it does not block a port.  In order to truly block a port / address, working with the lower layer of the tcp stack is required. Fortunately, this is made a little simpler through the use of the ip helper API's, which have been around since Win98. The downside though is the lack of documentation / examples for this api usage. Some code examples that I worked on for port/address blocking can be found here though:

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20829690.html

While the code does need some cleanup, it provides the basics for blocking.

Regards,
Russell
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
tobjectpascalCommented:
0
kretzschmarAuthor Commented:
thanks for your time, russell
0
tobjectpascalCommented:
program netblock;
{$APPTYPE CONSOLE}

uses
  Windows,
  GetIP,
  SysUtils,
  fltdefs,
  winsock;

// IP address as an array of 4 bytes
type
  PIpBytes       =  ^TIpBytes;
  TIpBytes       =  Array [0..3] of Byte;

// Enumerations
type
  TIpInOut       =  (ioIn, ioOut);
  TIpProtocol    =  (protoTcp, protoUdp, protoAny);

// Globals
var
  hIF:           INTERFACE_HANDLE;
  ipLocal:       TIpBytes;

// Convert string to ip

Function StrToIpBytes(IpStr: String): TipBytes;
Var
 N: Integer;
Begin
 N:=0;
 While Pos('.',IpStr)>0 Do
  Begin
    Result[N]:=StrToInt(Copy(IpStr,1,Pos('.',IpStr)-1));
    Delete(IpStr,1,Pos('.',IpStr));
    Inc(N);
  End;
End;

function StrToIp(lpszIP: PChar; lpipAddr: PIpBytes): PIpBytes;
var  lpszStr:    Array [0..63] of Char;
     dwPos:      Integer;
     lpPos:      PChar;
begin

  // Copy the IP string over
  StrLCopy(@lpszStr, lpszIP, SizeOf(lpszStr));
  lpszStr[Pred(SizeOf(lpszStr))]:=#0;

  // Clear output buffer
  ZeroMemory(lpipAddr, SizeOf(TIpBytes));

  // Parse into bytes
  dwPos:=Pred(SizeOf(TIpBytes));
  lpPos:=StrRScan(lpszStr, '.');
  while Assigned(lpPos) do
  begin
     lpPos^:=#0;
     Inc(lpPos);
     lpipAddr^[dwPos]:=StrToIntDef(lpPos, 0);
     Dec(dwPos);
     if (dwPos = 0) then break;
     lpPos:=StrRScan(lpszStr, '.');
  end;
  lpipAddr^[dwPos]:=StrToIntDef(lpszStr, 0);

  // Result is the pointer to buffer
  result:=lpipAddr;

end;

// Get the local ip address
function GetLocalIPAddr(lpipAddr: PIpBytes): Boolean;
var  lpszLocal:  Array [0..255] of Char;
     pheAddr:    PHostEnt;
begin

  // Get the host name
  if (gethostname(lpszLocal, SizeOf(lpszLocal)) = 0) then
  begin
     // Get the host ent structure
     pheAddr:=gethostbyname(lpszLocal);
     if Assigned(pheAddr) then
     begin
        // Get the ip address
        Move(pheAddr^.h_addr_list^^, lpipAddr^, 4);
        result:=True;
     end
     else
        result:=False;
  end
  else
     result:=False;

end;

// Add a filter
procedure AddFilter(ioType: TIpInOut; lpszRemote: PChar; protoType: TIpProtocol; lpszPort: PChar);
var  ipFlt:      PF_FILTER_DESCRIPTOR;
     dwPort:     Integer;
     ipDest:     TIpBytes;
     ipSrcMask:  TIpBytes;
     ipDstMask:  TIpBytes;
     dwRet:      DWORD;
begin

  // Clear the filter description buffer
  ZeroMemory(@ipFlt, SizeOf(ipFlt));

  // Set the static filtering flags
  ipFlt.dwFilterFlags:=FD_FLAGS_NOSYN;
  ipFlt.dwRule:=0;
  ipFlt.pfatType:=PF_IPV4;
  ipFlt.fLateBound:=0;

  // Set protocol filtering
  case protoType of
     protoTcp :  ipFlt.dwProtocol:=FILTER_PROTO_TCP;
     protoUdp :  ipFlt.dwProtocol:=FILTER_PROTO_UDP;
  else
     ipFlt.dwProtocol:=FILTER_PROTO_ANY;
  end;

  // If nil is passed for the port, set port type to any
  if Assigned(lpszPort) then
     dwPort:=StrToIntDef(lpszPort, FILTER_TCPUDP_PORT_ANY)
  else
     dwPort:=FILTER_TCPUDP_PORT_ANY;

  // Set port ranges
  case ioType of
     // Filter all inbound connections to specified port
     ioIn  :
     begin
        ipFlt.wDstPort:=FILTER_TCPUDP_PORT_ANY;
        ipFlt.wDstPortHighRange:=FILTER_TCPUDP_PORT_ANY;
        ipFlt.wSrcPort:=dwPort;
        ipFlt.wSrcPortHighRange:=dwPort;
     end;
     // Filter all outbound connections to specific port
     ioOut :
     begin
        ipFlt.wDstPort:=dwPort;
        ipFlt.wDstPortHighRange:=dwPort;
        ipFlt.wSrcPort:=FILTER_TCPUDP_PORT_ANY;
        ipFlt.wSrcPortHighRange:=FILTER_TCPUDP_PORT_ANY;
     end;
  end;

  // Create default subnet masks
  StrToIP('255.255.255.255', @ipSrcMask);
  StrToIP('255.255.255.255', @ipDstMask);

  // Check for input or output filter
  if (ioType = ioIn) then
  begin
     // Input filter
     if Assigned(lpszRemote) then
     begin
        ipFlt.SrcAddr:=PByteArray(StrToIp(lpszRemote, @ipDest));
        ipFlt.SrcMask:=@ipSrcMask;
     end
     else
     begin
        ipFlt.SrcAddr:=PByteArray(StrToIp('0.0.0.0', @ipDest));
        StrToIP('0.0.0.0', @ipSrcMask);
        ipFlt.SrcMask:=@ipSrcMask;
     end;
     ipFlt.DstAddr:=@ipLocal;
     ipFlt.DstMask:=@ipDstMask;
     PfAddFiltersToInterface(hIF, 1, @ipFlt, 0, nil, nil);
  end
  else
  begin
     // Output filter
     ipFlt.SrcAddr:=@ipLocal;
     ipFlt.SrcMask:=@ipSrcMask;
     if Assigned(lpszRemote) then
     begin
        ipFlt.DstAddr:=PByteArray(StrToIp(lpszRemote, @ipDest));
        ipFlt.DstMask:=@ipDstMask;
     end
     else
     begin
        ipFlt.DstAddr:=PByteArray(StrToIp('0.0.0.0', @ipDest));
        StrToIP('0.0.0.0', @ipDstMask);
        ipFlt.DstMask:=@ipDstMask;
     end;
     PfAddFiltersToInterface(hIF, 0, nil, 1, @ipFlt, nil);
  end;

end;


////////////////////////////////////////////////////////////////////////////////
// WinMain
////////////////////////////////////////////////////////////////////////////////
var
  wsaData:       TWSAData;
  MIP: String;
begin

  // Initialize winsock so we can get the local ip address
  if (WSAStartup(MakeWord(1, 1), wsaData) = 0) then
  begin

     // Get the local IP address (Network or Assigned ISP IP should it get? as it gets network)
     //192.168.0.1
     MIP:=GetIPAddress; //Get the real IP
     FillChar(IpLocal,4,#0);
     IpLocal:=StrToIpBytes(MIP); //convert it to the byte array
     If MIP<>'' Then
     begin
       // Create the interface
        PfCreateInterface(0, PF_ACTION_FORWARD, PF_ACTION_FORWARD, False, True, hIF);

        // Add some filters - these are just examples
        AddFilter(ioIn, '66.102.7.104', protoTcp, nil);
        AddFilter(ioOut, '66.102.7.104', protoTcp, '80');
        AddFilter(ioOut, '216.239.53.99', protoTcp, '80');
        AddFilter(ioIn, '66.218.70.48', protoUdp, '1024');

        // Example of blocking all outbound to web sites
        AddFilter(ioOut, nil, protoTcp, '80');

       //not working at all
        AddFilter(ioOut, '203.217.3.209', protoTcp, '80');
        AddFilter(ioOut,  Nil, protoTcp, '80');
       //..

        // Bind the interface to the local IP address
        PfBindInterfaceToIPAddress(hIF, PF_IPV4, @ipLocal);

        // Wait until enter is pressed
        WriteLn('Press [ENTER] to stop filtering');
        ReadLn;

        // Unbind and remove filter interface
        PfUnBindInterface(hIF);
        PfDeleteInterface(hIF);

     end
     else
        // Display the winsock error
        WriteLn(Format('WinSock error: %d', [WSAGetLastError]));

     // Cleanup
     WSACleanup;

  end
  else
     // Display the winsock error
     WriteLn(Format('WinSock error: %d', [WSAGetLastError]));

end.


Well that will do me fine, but feel free to make the modifications and take the points :)

0
tobjectpascalCommented:
eek

Function StrToIpBytes(IpStr: String): TipBytes;
Var
 N: Integer;
Begin
 N:=0;
 While Pos('.',IpStr)>0 Do
  Begin
    Result[N]:=StrToInt(Copy(IpStr,1,Pos('.',IpStr)-1));
    Delete(IpStr,1,Pos('.',IpStr));
    Inc(N);
  End;
 Result[N]:=StrToInt(IpStr);
End;


I was not finishing off the routine :D that will fix it
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.