Link to home
Start Free TrialLog in
Avatar of pepoclv
pepoclv

asked on

How to discover which network adapter is connected to internet?

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.
Avatar of Russell Libby
Russell Libby
Flag of United States of America image


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.
Avatar of pepoclv
pepoclv

ASKER

Your example should display PPP for a modem and ethernet for a network card, but it returns ethernet for both adapters.

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
Avatar of pepoclv

ASKER

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.
Avatar of pepoclv

ASKER

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.

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
Avatar of pepoclv

ASKER

I just need to know the index or name of a adapter on my example that returns connection kind correctly.
Avatar of pepoclv

ASKER

I increased points. This question seems to be more difficult that I thought.

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



Avatar of pepoclv

ASKER

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.



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.
Avatar of pepoclv

ASKER

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;
ASKER CERTIFIED SOLUTION
Avatar of Russell Libby
Russell Libby
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of pepoclv

ASKER

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.