Solved

How to discover which network adapter is connected to internet?

Posted on 2004-09-29
14
1,658 Views
Last Modified: 2007-12-19
Hello.

I want to discover which network adpter is connected to the internet. For example: I have a LAN internet connection and a DialUP internet connection, I can navigate on internet using LAN or Modem (DialUp) and I want know which LAN or Modem is connected.

Using this code I can get type of my internet connection, but I don't know what adapter is connected to internet.

Uses wininet;

Function TfrmMSNListen.ConnectionKind :boolean;
var
  flags:dword;
begin
  Result:=InternetGetConnectedState(@flags,0);
  if Result then
  begin
    if (flags and INTERNET_CONNECTION_MODEM) = INTERNET_CONNECTION_MODEM then
    begin
      showmessage('Modem');
    end;
    if (flags and INTERNET_CONNECTION_LAN) = INTERNET_CONNECTION_LAN then
    begin
      showmessage('LAN');
    end;
    if (flags and INTERNET_CONNECTION_PROXY) = INTERNET_CONNECTION_PROXY then
    begin
      showmessage('Proxy');
    end;
    if (flags and INTERNET_CONNECTION_MODEM_BUSY)=INTERNET_CONNECTION_MODEM_BUSY then
    begin
      showmessage('Modem Busy');
    end;
  end;
end;


Please help me!

Thanks.
0
Comment
Question by:pepoclv
  • 8
  • 6
14 Comments
 
LVL 26

Expert Comment

by:Russell Libby
ID: 12181478

You could use the iphlpapi translation to get the adapter information (things like status, bytes send, etc). A quick example code that displays the adapters as well as some basic info is listed below. (but first, you will need to download the source for the ip helper stuff from the Jedi site). The download can be gotten here:

ftp://delphi-jedi.org/api/IPHlpAPI.zip

Hopefully this will give you some ideas as how to determine which is connected (between the 2). The one question I do have though, is what are you going to do if both adapters are connected?

Russell


program adapters;
////////////////////////////////////////////////////////////////////////////////
//
//   Example program that uses the iphlpapi translation from Jedi to list the
//   network adapters installed on the computer, and to display the stats for
//   each adapter
//
//   Translation can be found at:
//
//   ftp://delphi-jedi.org/api/IPHlpAPI.zip
//
////////////////////////////////////////////////////////////////////////////////

{$APPTYPE CONSOLE}

uses
  Windows,
  SysUtils,
  Winsock,
  IpExport,
  IpHlpApi,
  IpTypes,
  IpIfConst,
  IpRtrMib;

var
  dwSize:           ULONG;
  dwCount:          Integer;
  lpIntfTable:      PMibIfTable;
  lpRow:            PMibIfRow;

begin

  // Get the function to tell us how much memory we need to allocate
  dwSize:=0;
  if (GetIfTable(nil, dwSize, True) = ERROR_INSUFFICIENT_BUFFER) then
  begin
     // Allocate memory for the table
     lpIntfTable:=AllocMem(dwSize);
     try
        // Make the call again
        if (GetIfTable(lpIntfTable, dwSize, True) = NO_ERROR) then
        begin
           // Iterate the adapters
           for dwCount:=0 to Pred(lpIntfTable^.dwNumEntries) do
           begin
              // Get the row
              lpRow:=@lpIntfTable.Table[dwCount];
              // Skip the loopback
              if (lpRow^.dwType = MIB_IF_TYPE_LOOPBACK) then Continue;
              // Display description
              WriteLn(PChar(@lpRow^.bDescr));
              // Display adapter type
              case lpRow^.dwType of
                 MIB_IF_TYPE_OTHER       :  WriteLn(#9, 'Type  : Other');
                 MIB_IF_TYPE_ETHERNET    :  WriteLn(#9, 'Type  : Ethernet');
                 MIB_IF_TYPE_TOKENRING   :  WriteLn(#9, 'Type  : TokenRing');
                 MIB_IF_TYPE_FDDI        :  WriteLn(#9, 'Type  : FDDI');
                 MIB_IF_TYPE_PPP         :  WriteLn(#9, 'Type  : PPP');
                 MIB_IF_TYPE_SLIP        :  WriteLn(#9, 'Type  : Slip');
              end;
              // Display speed
              WriteLn(#9, 'Speed : ', lpRow^.dwSpeed);
              // Display status
              case lpRow^.dwOperStatus of
                 MIB_IF_OPER_STATUS_NON_OPERATIONAL  :  WriteLn(#9, 'Status: Non-operational');
                 MIB_IF_OPER_STATUS_UNREACHABLE      :  WriteLn(#9, 'Status: Unreachable');
                 MIB_IF_OPER_STATUS_DISCONNECTED     :  WriteLn(#9, 'Status: Disconnected');
                 MIB_IF_OPER_STATUS_CONNECTING       :  WriteLn(#9, 'Status: Connecting');
                 MIB_IF_OPER_STATUS_CONNECTED        :  WriteLn(#9, 'Status: Connected');
                 MIB_IF_OPER_STATUS_OPERATIONAL      :  WriteLn(#9, 'Status: Operational');
              end;
              // etc, etc, etc
              //
           end;
        end;
     finally
        FreeMem(lpIntfTable);
     end;
  end;

  // Pause
  WriteLn;
  WriteLn('Press enter to continue...');
  ReadLn;

end.
0
 

Author Comment

by:pepoclv
ID: 12181943
Your example should display PPP for a modem and ethernet for a network card, but it returns ethernet for both adapters.
0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 12182016

Strange...
What about the rest of the field attributes for the interface table row, are they displaying correct info? (Perhaps a copy/paste from the output would help as well.)

Russell
0
 

Author Comment

by:pepoclv
ID: 12182117
here is the output:

PPP Adapter.
      Type  : Ethernet
      Speed : 9600
      Status: Unreachable
Realtek 8139-series PCI NIC                                                      
      Type  : Ethernet
      Speed : 10000000
      Status: Unreachable

Press enter to continue...

NOTE: I'm using on Windows 98.
0
 

Author Comment

by:pepoclv
ID: 12182168
Your question:
"The one question I do have though, is what are you going to do if both adapters are connected?"

is that possible? both adapters connected to internet? If do, I don't know what to do.

I have a msn port listening, but I have to know what adapter is connected on the internet to listen tcp packets from it.
0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 12182189

The description looks good, as does the speed. Looks like the speed would be more reliable to you than the reported type. But i am not sure why the status of both reads "Unreachable" though. (i am assuming you are online if you are using EE)

Regarding the note; according to the docs, the ip helper library is supported on windows 98 .

Anyways, I will look into this some more for you and see what I can come up with

Russell
0
 

Author Comment

by:pepoclv
ID: 12182211
I just need to know the index or name of a adapter on my example that returns connection kind correctly.
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:pepoclv
ID: 12182225
I increased points. This question seems to be more difficult that I thought.
0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 12183766

Okay, perhaps we could clarify a few things...

Your question indicates that you are after the adapter that is connected to the internet, but above you indicated that you want to listen to tcp packets. Are you talking about the winsock listen(..) function, or some other tcp probing functionality? If you are talking about straight winsock, then you can easily bind (for listening) to all IP addresses on the local pc. So the question is; does this mean that you are after the IP address of the adapter, or just the name/index of the adapter? If not the IP address, what info do you need from the adapter?

Answering your question above, yes. It is possible for both the modem and the lan card to be connected to the internet at the same time. It is also possible that if you had 2 lan cards, a modem, and a wireless card, they could ALL be connected at the same time as well. Only difference in either case is that each device would have a unique IP address.

So, if you are mearly after a "name", then you could use the InternetGetConnectedStateEx function from wininet.

eg:

function InternetGetConnectedStateEx(lpdwFlags: LPDWORD; lpszConnectionName: PChar; dwNameLen, dwReserved: DWORD): BOOL; stdcall; external 'wininet.dll';

using it like:

var
  dwFlags:          DWORD;
  lpszName:         Array [0..MAX_PATH] of Char;
begin

  if InternetGetConnectedStateEx(@dwFlags, lpszName, MAX_PATH, 0)  then
  begin
     // etc....
  end;

end;

If you need the real network adapter info (including IP address), and want to determine the "best interface" (the one that your computer will use), then using the IP helper library should be able to provide what you want.

A good overview provided by Intel can be found here:
http://www.intel.com/cd/ids/developer/asmo-na/eng/downloads/60826.htm?page=4

And an excellent sample usage of the majority of the functions (wrapped in a nice demo) can be downloaded here:
http://www.codeproject.com/internet/IPHelper.asp

Regards,
Russell



0
 

Author Comment

by:pepoclv
ID: 12189998
Well, I have a promiscuous sniffer that listen to a port of an adapter. So I need to know the index of adapter that is connected to internet.

Using InternetGetConnectedStateEx it returns: Local network connection - when I use LAN to navigate on internet.

I just need to know the index of adapter that is connected to internet.

Example:

Index    Adapter
0         Motorola FAX/Modem
1         RealTek Network card

If I connected to internet by a LAN the function maybe returns 1
If I connected to internet by a MODEM the function maybe returns 0

Thanks for all help till now.


0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 12190969

You are welcome for the help, and hopefully I can finish this up for you today. Only 3 more things, and I should be able to put together the code to do what you need:

1.) Does your packet/port sniffer require the indexes of the adapters starting at zero (0), or starting at one (1)? (ip helper starts at one, and I also have to account for the loopback interface)
2.) Would you have an available ip address (either in dot format, or in name format; eg www.msn.com) that could be passed in to determine the best adpater should both devices be connected to the internet at the same time?
3.) Could you run the following modified code for me, and paste the results here. I realize that both interfaces return "ethernet", but I am curious as to what AddrLn returns. It WILL return 6 for the nic card, and I am hoping that it returns something else for the modem.

Thanks,
Russell


program adapters;
////////////////////////////////////////////////////////////////////////////////
//
//   Example program that uses the iphlpapi translation from Jedi to list the
//   network adapters installed on the computer, and to display the stats for
//   each adapter
//
//   Translation can be found at:
//
//   ftp://delphi-jedi.org/api/IPHlpAPI.zip
//
////////////////////////////////////////////////////////////////////////////////

{$APPTYPE CONSOLE}

uses
  Windows,
  SysUtils,
  Winsock,
  IpExport,
  IpHlpApi,
  IpTypes,
  IpIfConst,
  IpRtrMib;

var
  dwFlags:          DWORD;
  dwSize:           ULONG;
  dwCount:          Integer;
  lpIntfTable:      PMibIfTable;
  lpRow:            PMibIfRow;

begin

  // Get the function to tell us how much memory we need to allocate
  dwSize:=0;
  if (GetIfTable(nil, dwSize, True) = ERROR_INSUFFICIENT_BUFFER) then
  begin
     // Allocate memory for the table
     lpIntfTable:=AllocMem(dwSize);
     try
        // Make the call again
        if (GetIfTable(lpIntfTable, dwSize, True) = NO_ERROR) then
        begin
           // Iterate the adapters
           for dwCount:=0 to Pred(lpIntfTable^.dwNumEntries) do
           begin
              // Get the row
              lpRow:=@lpIntfTable.Table[dwCount];
              // Skip the loopback
              if (lpRow^.dwType = MIB_IF_TYPE_LOOPBACK) then Continue;
              // Display description
              WriteLn(PChar(@lpRow^.bDescr));
              // Display index of interface
              WriteLn(#9, 'Index : ', lpRow^.dwIndex);
              // Display adapter type
              case lpRow^.dwType of
                 MIB_IF_TYPE_OTHER       :  WriteLn(#9, 'Type  : Other');
                 MIB_IF_TYPE_ETHERNET    :  WriteLn(#9, 'Type  : Ethernet');
                 MIB_IF_TYPE_TOKENRING   :  WriteLn(#9, 'Type  : TokenRing');
                 MIB_IF_TYPE_FDDI        :  WriteLn(#9, 'Type  : FDDI');
                 MIB_IF_TYPE_PPP         :  WriteLn(#9, 'Type  : PPP');
                 MIB_IF_TYPE_SLIP        :  WriteLn(#9, 'Type  : Slip');
              end;
              // Display physical addr len
              WriteLn(#9, 'AddrLn: ', lpRow^.dwPhysAddrLen);
              // Display speed
              WriteLn(#9, 'Speed : ', lpRow^.dwSpeed);
              // Display status
              case lpRow^.dwOperStatus of
                 MIB_IF_OPER_STATUS_NON_OPERATIONAL  :  WriteLn(#9, 'Status: Non-operational');
                 MIB_IF_OPER_STATUS_UNREACHABLE      :  WriteLn(#9, 'Status: Unreachable');
                 MIB_IF_OPER_STATUS_DISCONNECTED     :  WriteLn(#9, 'Status: Disconnected');
                 MIB_IF_OPER_STATUS_CONNECTING       :  WriteLn(#9, 'Status: Connecting');
                 MIB_IF_OPER_STATUS_CONNECTED        :  WriteLn(#9, 'Status: Connected');
                 MIB_IF_OPER_STATUS_OPERATIONAL      :  WriteLn(#9, 'Status: Operational');
              end;
              WriteLn(#9, Format('In/Out: %d / %d', [lpRow^.dwInOctets, lpRow^.dwOutOctets]));
           end;
        end;
     finally
        FreeMem(lpIntfTable);
     end;
  end;

  // Pause
  WriteLn;
  WriteLn('Press enter to continue...');
  ReadLn;

end.
0
 

Author Comment

by:pepoclv
ID: 12192763
here is the answers:

1) It starts from 0 (zero)
2) If you mean something like a ping www.msn.com? Yes.
3) The output of adapters is:
PPP Adapter.
      Index : 16777218
      Type  : Ethernet
      AddrLn: 6
      Speed : 9600
      Status: Unreachable
      In/Out: 0 / 0

Realtek 8139-series PCI NIC                                                      
      Index : 33554435
      Type  : Ethernet
      AddrLn: 6
      Speed : 10000000
      Status: Unreachable
      In/Out: 4978 / 5888

Press enter to continue...

--------------------------------------------------------------------------
If you want to test my MSN listen project, download these files and run

http://200.201.133.13/mundo6br/listentomsn.zip
http://200.201.133.13/mundo6br/winpcap_3_1_beta_3.exe
http://200.201.133.13/mundo6br/snoop.zip

--------------------------------------------------------------------------
Note that on my project the adapter index starts from i:=0  to 5. Look the procedure below.
If I'm connected to internet on LAN that index is 1, and run my project it starts to capture on adapter index 0 because when I try to connect it returns true and I can't listen anything because the LAN is on internet not MODEM (index 0).
Did you understand me?

procedure TfrmMSNListen.StartCapture;
Var
  i:Integer;
  strIP:String;
begin
  Snoop1.Filter:='';
     Snoop1.ReadTimeOut:=100;
     Snoop1.SnapLen:=1600;
     Snoop1.ThreadSafe:=True;
     If SnoopMemory=Nil Then SnoopMemory:=TSnoopMemory.Create;
  i:=0; // <= HERE - adapter index
  TryToConnect(i);
  While NOT(Snoop1.Active) Do
  Begin
    i:=i+1;
    TryToConnect(i);
    If i>5 then Break;
  End;
  If i>5 then
    Application.Terminate;
end;
0
 
LVL 26

Accepted Solution

by:
Russell Libby earned 250 total points
ID: 12201663
Okay,
Here is the finished class object that should give you back the information you are looking for. The only method that you probably care about right now is GetBestAdapter, which will return the index of the adapter (starting at zero, and excludes the loopbacK) that has the best route to the specified destination.

eg

var net: TNetwork;
begin
  net:=Tnetwork.create;
  ShowMessage(IntToStr(net.GetBestAdapter('www.msn.com')));
  net.Free;
end;

There is also a few other properties/functions that were added, and you may find them useful at some point. Eg; determining the correct AdapterType (ctLan, ctModem) for the specified index.

If you have any problems let me know.

Russell

----

unit Network;
////////////////////////////////////////////////////////////////////////////////
//
//   Unit        :  Network
//   Date        :  09.30.2004
//   Required    :  Windows 98 or higher, IE v5 or higher
//   Author      :  rllibby
//
//   Description :  Provides a class object that can be used to determine current
//                  network information.
//
////////////////////////////////////////////////////////////////////////////////
interface

////////////////////////////////////////////////////////////////////////////////
//   Include Units (IP Helper units: ftp://delphi-jedi.org/api/IPHlpAPI.zip)
////////////////////////////////////////////////////////////////////////////////
uses
  Windows,
  SysUtils,
  WinSock,
  WinInet,
  IpExport,
  IpHlpApi,
  IpTypes,
  IpIfConst,
  IpRtrMib;

////////////////////////////////////////////////////////////////////////////////
//   Constants
////////////////////////////////////////////////////////////////////////////////
const
  MAX_NAMELEN       =  1024;
  SPEED_MODEM       =  9600;

////////////////////////////////////////////////////////////////////////////////
//   Constants for sens api
////////////////////////////////////////////////////////////////////////////////
const
  NETWORK_ALIVE_LAN =  1;
  NETWORK_ALIVE_WAN =  2;

////////////////////////////////////////////////////////////////////////////////
//   Structure for sensapi
////////////////////////////////////////////////////////////////////////////////
type
  tagQOCINFO        =  packed record
     dwSize:        DWORD;
     dwFlags:       DWORD;
     dwInSpeed:     DWORD;
     dwOutSpeed:    DWORD;
  end;
  QOCINFO           =  tagQOCINFO;
  TQOCInfo          =  QOCINFO;
  LPQOCINFO         =  ^QOCINFO;
  PQOCInfo          =  ^TQOCInfo;

////////////////////////////////////////////////////////////////////////////////
//   Buffer type for wininet usage
////////////////////////////////////////////////////////////////////////////////
type
  TNameBuffer       =  Array [0..Pred(MAX_NAMELEN)] of Char;

////////////////////////////////////////////////////////////////////////////////
//   Connection types for network class
////////////////////////////////////////////////////////////////////////////////
type
  TConnectionType   =  (ctNone, ctLan, ctModem);
  TConnectionTypes  =  set of TConnectionType;

////////////////////////////////////////////////////////////////////////////////
//   Imported functions
////////////////////////////////////////////////////////////////////////////////
function   InternetGetConnectedStateEx(lpdwFlags: LPDWORD; lpszConnectionName: PChar; dwNameLen, dwReserved: DWORD): BOOL; stdcall; external 'wininet.dll';
function   IsNetworkAlive(lpdwFlags: LPDWORD): BOOL; stdcall; external 'sensapi.dll';
function   IsDestinationReachable(lpszDestination: PChar; lpInfo: PQOCInfo): BOOL; stdcall; external 'sensapi.dll' name 'IsDestinationReachableA';

////////////////////////////////////////////////////////////////////////////////
//   Network Class
////////////////////////////////////////////////////////////////////////////////
type
  TNetwork          =  class(TObject)
  private
     // Private declarations
     FInterfaces:   PMibIfTable;
  protected
     // Protected declarations
     function       GetAdapterCount: Integer;
     function       GetConnectionTypes: TConnectionTypes;
     function       GetAdapterType(Index: Integer): TConnectionType;
  public
     // Public declarations
     constructor    Create;
     destructor     Destroy; override;
     function       IsConnected: Boolean;
     function       GetBestAdapter(DestAddr: String): Integer;
     function       IsReachable(DestAddr: String): Boolean;
     property       AdapterCount: Integer read GetAdapterCount;
     property       AdapterTypes[Index: Integer]: TConnectionType read GetAdapterType;
     property       ActiveConnectionTypes: TConnectionTypes read GetConnectionTypes;
  end;

implementation

function TNetwork.IsReachable(DestAddr: String): Boolean;
begin

  // Determine if the ip address is reachable
  result:=IsDestinationReachable(PChar(DestAddr), nil);

end;

function TNetwork.GetBestAdapter(DestAddr: String): Integer;
var  lpIntfTable:   PMibIfTable;
     dwSize:        ULONG;
     dwIndex:       LongWord;
     dwAddr:        Integer;
     lpPhe:         PHostEnt;
begin

  // Convert the address string
  dwAddr:=inet_addr(PChar(DestAddr));

  // If this was not x.x.x.x it would have failed, so check the result
  if (dwAddr = Integer(INADDR_NONE)) then
  begin
     // Need to convert the string to host ent structure
     lpPhe:=GetHostByName(PChar(DestAddr));
     // Check
     if (lpPhe = nil) then
        // Failure
        RaiseLastWin32Error
     else
        // Get the address
        dwAddr:=Integer(PInteger(lpPhe^.h_addr_list^)^);
  end;

  // Get the best interface to use
  if (GetBestInterface(dwAddr, dwIndex) = NO_ERROR) then
  begin
     // Need to convert this index into an absolute index
     dwSize:=0;
     if (GetIfTable(nil, dwSize, True) = ERROR_INSUFFICIENT_BUFFER) then
     begin
        // Allocate memory for the table
        lpIntfTable:=AllocMem(dwSize);
        try
           // Make the call again
           if (GetIfTable(lpIntfTable, dwSize, True) = NO_ERROR) then
           begin
              // Iterate
              result:=0;
              while (result < lpIntfTable^.dwNumEntries) do
              begin
                 // Check index
                 if (lpIntfTable^.Table[result].dwIndex = dwIndex) then break;
                 // Increment the counter
                 Inc(result);
              end;
              // Decrement to account for the loopback
              Dec(result);
           end
           else
              // Raise
              RaiseLastWin32Error;
        finally
           // Free memory
           FreeMem(lpIntfTable);
        end;
     end
     else
        // Raise
        RaiseLastWin32Error;
  end
  else
     // Raise
     RaiseLastWin32Error;

end;

function TNetwork.GetAdapterType(Index: Integer): TConnectionType;
var  lpIntfTable:   PMibIfTable;
     lpIntfRow:     PMibIfRow;
     dwIndex:       Integer;
     dwSize:        ULONG;
begin

  // Get the size to allocate
  dwSize:=0;
  if (GetIfTable(nil, dwSize, True) = ERROR_INSUFFICIENT_BUFFER) then
  begin
     // Allocate memory for the table
     lpIntfTable:=AllocMem(dwSize);
     try
        // Make the call again
        if (GetIfTable(lpIntfTable, dwSize, True) = NO_ERROR) then
        begin
           // Check index against count of entries
           dwIndex:=Succ(Index);
           if (dwIndex < 1) or (dwIndex >= lpIntfTable^.dwNumEntries) then raise Exception.Create('Invalid index specified');
           // Get the interface row
           lpIntfRow:=@lpIntfTable.Table[dwIndex];
           // Check the row to determine the adapter type. Note: research and documentation by
           // others has shown that the ip helper api is broken, and always returns 9600 for
           // modem type devices, regardless of the actual modem speed.
           if (lpIntfRow^.dwType = MIB_IF_TYPE_ETHERNET) and (lpIntfRow^.dwSpeed = SPEED_MODEM) then
              // Modem type
              result:=ctModem
           else if (lpIntfRow^.dwType = MIB_IF_TYPE_PPP) then
              // Modem type
              result:=ctModem
           else
              // Lan card (of some type)
              result:=ctLan;
        end
        else
           // Raise
           RaiseLastWin32Error;
     finally
        // Free memory
        FreeMem(lpIntfTable);
     end;
  end
  else
     // Raise
     RaiseLastWin32Error;

end;

function TNetwork.GetAdapterCount: Integer;
var  dwNumIf:       LongWord;
begin

  // Return the count of adapaters. This is done by getting the number of
  // interfaces (there is a one-one correlation between adapters and interfaces),
  // and subtracting one to account for the loopback interface
  if GetNumberOfInterfaces(dwNumIf) = NO_ERROR then
     // Return count
     result:=Pred(dwNumIf)
  else
     // Raise win32 error
     RaiseLastWin32Error;

end;

function TNetwork.GetConnectionTypes: TConnectionTypes;
var  dwFlags:       DWORD;
begin

  // Set default result
  result:=[];

  // Determine the current connections
  if IsNetworkAlive(@dwFlags) then
  begin
     // Set connection types
     if ((dwFlags and NETWORK_ALIVE_LAN) = NETWORK_ALIVE_LAN) then Include(result, ctLan);
     if ((dwFlags and NETWORK_ALIVE_WAN) = NETWORK_ALIVE_WAN) then Include(result, ctModem);
  end
  else
     // Not connected
     result:=[ctNone];

end;

function TNetwork.IsConnected: Boolean;
var  dwFlag1:       DWORD;
     dwFlag2:       DWORD;
     lpszName:      TNameBuffer;
begin

  // Determine if connected (uses both functions for completeness)
  result:=(InternetGetConnectedStateEx(@dwFlag1, @lpszName, MAX_NAMELEN, 0) and IsNetworkAlive(@dwFlag2));

end;

constructor TNetwork.Create;
begin

  // Perform inherited
  inherited Create;

end;

destructor TNetwork.Destroy;
begin

  // Perform inherited
  inherited Destroy;

end;

end.

0
 

Author Comment

by:pepoclv
ID: 12202895
I don't agree at this point:

// Get the best interface to use
  if (GetBestInterface(dwAddr, dwIndex) = NO_ERROR) then
  begin
     // Need to convert this index into an absolute index
     dwSize:=0;
     if (GetIfTable(nil, dwSize, True) = ERROR_INSUFFICIENT_BUFFER) then
     begin
        // Allocate memory for the table
        lpIntfTable:=AllocMem(dwSize);
        try
           // Make the call again
           if (GetIfTable(lpIntfTable, dwSize, True) = NO_ERROR) then
           begin
              // Iterate
              result:=0;
              while (result < lpIntfTable^.dwNumEntries) do
              begin
                 // Check index
                 if (lpIntfTable^.Table[result].dwIndex = dwIndex) then break;
                 // Increment the counter
                 Inc(result);
              end;
              // Decrement to account for the loopback
              Dec(result); ///////////////////<= HERE \\\\\\\\\\\\\\\\\\\\\\\
           end
           else
              // Raise
              RaiseLastWin32Error;
        finally
           // Free memory
           FreeMem(lpIntfTable);
        end;
     end
     else
        // Raise
        RaiseLastWin32Error;
  end
  else
     // Raise
     RaiseLastWin32Error;
--------------

Because  my best adapter is index 1, and when you decrement to avoid loopback it returns to zero and don't connect.
But I think your unit is perfect. I will do some tests with modem and LAN.

Thanks.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

708 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now