Reputation: 734
I have a few network adapters in my system:
When I'm only connected to WiFI - my IP address is 192.168.1.101 (gateway 192.168.1.1) Activating VPN connections brings me next IP's (ex. (PPTP) 192.168.90.101, (OpenVPN) 10.9.0.6)
Question is: How to determine which IP address is "default" for internet connection?
Scenarios:
No 1 - only WiFi - ER (Expected Result): 192.168.1.101
No 2 - WiFi + PPTP (with "Use default gateway on remote network") - ER: 192.168.90.101
No 3 - WiFi + PPTP (without "Use default gateway on remote network") - ER: 192.168.1.101
No 4 - WiFi + OpenVPN - ER: 192.168.1.101
And so on...
Btw. IP from OpenVPN is never returned. This network doesn't route internet connections.
When I use tracert - I can read this information looking on what is first entry in result. But I have to get this information using Delphi or external library used from Delphi app.
I'm using Delphi XE3.
Any ideas? Thanks for help!
PS. Get information about the installed network adapters I tried this solution, but there is no info that NIC is default for internet.
Best regards, Robert
Upvotes: 3
Views: 3620
Reputation: 53
Open a TidUDPClient and TidUDPServer both with broadcast enabled and with the same port number. Send out a recognizable message on 255.255.255.255 and when it bounces back read the PeerIP from the returned TidSocketHandle.
Upvotes: 2
Reputation: 19096
You can retrieve the routing information by route print
from the command prompt.
IPv4 Route Table =========================================================================== Active Routes: Network Destination Netmask Gateway Interface Metric 0.0.0.0 0.0.0.0 192.168.69.1 192.168.69.15 20 127.0.0.0 255.0.0.0 On-link 127.0.0.1 306 127.0.0.1 255.255.255.255 On-link 127.0.0.1 306 127.255.255.255 255.255.255.255 On-link 127.0.0.1 306 192.168.69.0 255.255.255.0 On-link 192.168.69.15 276 192.168.69.15 255.255.255.255 On-link 192.168.69.15 276 192.168.69.255 255.255.255.255 On-link 192.168.69.15 276 224.0.0.0 240.0.0.0 On-link 127.0.0.1 306 224.0.0.0 240.0.0.0 On-link 192.168.69.15 276 255.255.255.255 255.255.255.255 On-link 127.0.0.1 306 255.255.255.255 255.255.255.255 On-link 192.168.69.15 276
The "internet" has network destination 0.0.0.0
. So you just have to lookup, which interface and gateway is resposible for that destination (here 192.168.69.15
via 192.168.69.1
).
This information can also be retrieved by WMI Win32_IP4RouteTable
.
A good starting point for WMI queries with delphi is WMI Delphi Code Creator
Upvotes: 0
Reputation: 32953
You could use this class that implements traceroute, as except for what traceroute does using ICMP (ping) packets, consulting an external service is the only reliable option I know of. If your version of Indy doesn't have TIdTraceRoute
yet, you can use this code that just needs basic ICMP :
unit TraceRt;
interface
// ===========================================================================
// TRACEROUTE Class
// Mike Heydon Dec 2003
//
// Method
// Trace(IpAddress : string; ResultList : TStrings)
// Returns semi-colon delimited list of ip routes to target
// format .. IP ADDRESS; PING TIME MS; TIME TO LIVE; STATUS
//
// Properties
// IcmpTimeOut : integer (Default = 5000ms)
// IcmpMaxHops : integer (Default = 40)
// ===========================================================================
uses Forms, Windows, Classes, SysUtils, IdIcmpClient;
type
TTraceRoute = class(TObject)
protected
procedure ProcessResponse(Status : TReplyStatus);
procedure AddRoute(AResponseTime : DWORD;
AStatus: TReplyStatus; const AInfo: string );
private
FIcmpTimeOut,
FIcmpMaxHops : integer;
FResults : TStringList;
FICMP : TIdIcmpClient;
FPingStart : cardinal;
FCurrentTTL : integer;
procedure PingTarget;
public
constructor Create;
procedure Trace(const AIpAddress : string; AResultList : TStrings);
property IcmpTimeOut : integer read FIcmpTimeOut write FIcmpTimeOut;
property IcmpMaxHops : integer read FIcmpMaxHops write FIcmpMaxHops;
end;
// ---------------------------------------------------------------------------
implementation
// ========================================
// Create the class and set defaults
// ========================================
constructor TTraceRoute.Create;
begin
IcmpTimeOut := 5000;
IcmpMaxHops := 40;
end;
// =============================================
// Use Indy component to ping hops to target
// =============================================
procedure TTraceRoute.PingTarget;
var wOldMode : DWORD;
begin
Application.ProcessMessages;
inc(FCurrentTTL);
if FCurrentTTL < FIcmpMaxHops then begin
FICMP.TTL := FCurrentTTL;
FICMP.ReceiveTimeout := FIcmpTimeOut;
FPingStart := GetTickCount;
wOldMode := SetErrorMode(SEM_FAILCRITICALERRORS);
try
FICMP.Ping;
ProcessResponse(FICMP.ReplyStatus);
except
FResults.Add('0.0.0.0;0;0;ERROR');
end;
SetErrorMode(wOldMode);
end
else
FResults.Add('0.0.0.0;0;0;MAX HOPS EXCEEDED');
end;
// ============================================================
// Add the ping reply status data to the returned stringlist
// ============================================================
procedure TTraceRoute.AddRoute(AResponseTime : DWORD;
AStatus: TReplyStatus;
const AInfo: string );
begin
FResults.Add(AStatus.FromIPAddress + ';' +
IntToStr(GetTickCount - AResponseTime) + ';' +
IntToStr(AStatus.TimeToLive) + ';' + AInfo);
end;
// ============================================================
// Process the ping reply status record and add to stringlist
// ============================================================
procedure TTraceRoute.ProcessResponse(Status : TReplyStatus);
begin
case Status.ReplyStatusType of
// Last Leg - Terminate Trace
rsECHO : AddRoute(FPingStart,Status,'OK');
// More Hops to go - Continue Pinging
rsErrorTTLExceeded : begin
AddRoute(FPingStart,Status,'OK');
PingTarget;
end;
// Error conditions - Terminate Trace
rsTimeOut : AddRoute(FPingStart,Status,'TIMEOUT');
rsErrorUnreachable : AddRoute(FPingStart,Status,'UNREACHABLE');
rsError : AddRoute(FPingStart,Status,'ERROR');
end;
end;
// ======================================================
// Trace route to target IP address
// Results returned in semi-colon delimited stringlist
// IP; TIME MS; TIME TO LIVE; STATUS
// ======================================================
procedure TTraceRoute.Trace(const AIpAddress : string;
AResultList : TStrings);
begin
FICMP := TIdIcmpClient.Create(nil);
FICMP.Host := AIpAddress;
FResults := TStringList(AResultList);
FResults.Clear;
FCurrentTTL := 0;
PingTarget;
FICMP.Free;
end;
{eof}
end.
Upvotes: 1