Jump to content

How to get used networkcard on destination IP?


Recommended Posts

Hello,

ok, this is not really a autoit issue, but as I wanted to "au3" it anyway, I believe here is a good starting point.

Env:

Multiple network cards with different static IPs

eg. One with 192.168.0.10 and one with 10.0.0.20

Both are up and connected to a separated net.

Task: Return the network card that reaches eg. a given destination 192.168.0.11.

(IP is reachable)

I already got a au3 that returns me all possible properties of network card (with the help of Win32_NetworkAdapterConfiguration and Win32_NetworkAdapter).

So is there some command (cmd) like arp, tracert, route that returns on a destination IP the local used network card.

In the example above it should return: 192.168.0.10

(but MAC, Caption, Name,Id, would be fine too)

It is no problem to use something like

Run(@ComSpec & " /c " & 'commandName', "", @SW_HIDE)
and catch the output

The only limit I would like to add is: Windows 7/XP included tools.

Is there a chance to get this?

Link to comment
Share on other sites

If you use tracert the first IP address shown should tell you which network it's going through.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

An example of using tracert and follow BrewManNH's advice.

#include <Constants.au3>

MsgBox($MB_SYSTEMMODAL, '', _Tracert('www.duckduckgo.com') & @CRLF)

Func _Tracert($sURL)
    ; -d = Do Not Resolve Host & -h Is The Number Of Hops.
    Local Const $sData = _RunStdOutRead('tracert -d -h 1 ' & $sURL, @SystemDir)
    Local Const $aReturn = StringRegExp($sData, '\[([\d.]{7,15})\]', 3)
    If @error Then
        Return SetError(1, 0, -1)
    EndIf
    Return $aReturn[0]
EndFunc   ;==>_Tracert

Func _RunStdOutRead($sCommand, $sWorkingDirectory = @SystemDir)
    Local Const $iPID = Run(@ComSpec & ' /c ' & $sCommand, $sWorkingDirectory, @SW_HIDE, $STDOUT_CHILD + $STDERR_CHILD)
    Local $sOutput = ''
    While 1
        $sOutput &= StdoutRead($iPID)
        If @error Then
            ExitLoop
        EndIf
    WEnd
    Return $sOutput
EndFunc   ;==>_RunStdOutRead
Edited by guinness

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

Thank you for the advice, it works for let's say, in normal setup network.

the Ip on "a.b.c.250" in the first tracert line tells me what network is used. Ok.

But (yes there is always a but...), in my example network which is let's say a simple static env with only a IP and Subnet no Gateways, no DNS.

The result of my tracert is: (local IP of eth0 is 192.168.0.10)

C:\Users\Administrator>tracert -d -h 1 192.168.0.11
Tracing route to 192.168.0.11 over a maximum of 1 hops
1    1 ms <1 ms <1 ms 192.168.0.11

And just as I'm typing and thinking about missed options on the tracert I found a "ping" option that looks like a solution.

Usage: ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS]
         [-r count] [-s count] [[-j host-list] | [-k host-list]]
         [-w timeout] [-R] [-S srcaddr] [-4] [-6] target_name
Options:
-t           Ping the specified host until stopped.
                 To see statistics and continue - type Control-Break;
                 To stop - type Control-C.
-a           Resolve addresses to hostnames.
-n count     Number of echo requests to send.
-l size  Send buffer size.
-f           Set Don't Fragment flag in packet (IPv4-only).
-i TTL       Time To Live.
-v TOS       Type Of Service (IPv4-only. This setting has been deprecated
                 and has no effect on the type of service field in the IP Head
er).
-r count     Record route for count hops (IPv4-only).
-s count     Timestamp for count hops (IPv4-only).
-j host-list Loose source route along host-list (IPv4-only).
-k host-list Strict source route along host-list (IPv4-only).
-w timeout   Timeout in milliseconds to wait for each reply.
-R           Use routing header to test reverse route also (IPv6-only).
-S srcaddr   Source address to use.
-4           Force using IPv4.
-6           Force using IPv6.

So my current plan is, as I got a list of enabled local IPs I will loop through all IPS with a command like this:

"ping -n 1 -4 192.168.0.11 -S 192.168.0.10"
or
"ping -n 1 -4 <destinationIP> -S <LocalIp>"

In case the sourceIp is able to reach the destinationIp it will return NOT return ExitCode 0or "PING: transmit failed. General failure." (maybe not language independent...)

I will post my sample solution when done and when I'm sure that this is a working way.....

Thank you for kickstart my brain

Link to comment
Share on other sites

So here is my "in-progress"-code.

I added a _optParse.au3 from eltorro, because in the end it will be a CUI.

The _arraydisplay at the end is of course not the final one.

The last trick I needed was that "PING" does sometimes always return "0" even the host is dead. So I search now for "TTL=" simply because MS kept this for all languages of Windows.

Finally some words about the idea:

In the beginning I was searching for the Network Name (like "local area connection 2" or "home" or "my strange named network connection 3") and after finding these informations I wanted also to know which adapter is used to reach a given destination Ip.

#include <Array.au3>
#include <Debug.au3>
#include <Constants.au3>
#Include "include\_OptParse.au3"

#AutoIt3Wrapper_Change2CUI=Y
#AutoIt3Wrapper_Icon=NETWORK_QUERY.ICO   ;Filename of the Ico file to use
#AutoIt3Wrapper_Res_Comment=Get Network names and mark the used adapter              ;Comment field
#AutoIt3Wrapper_Res_Description=Get Network names and mark the used adapter
#AutoIt3Wrapper_Res_Fileversion=1.0.0.0
#AutoIt3Wrapper_Res_FileVersion_AutoIncrement=N
AutoItSetOption("MustDeclareVars", 1)

#region Var

global $strComputer = "."
global $objNetwork = ObjCreate("WScript.Network")
global $strComputer = $objNetwork.ComputerName
global $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")
global $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'True'", "WQL", 0x20 + 0x10)
global $adapterCount=0
global $aNetWorkAdapters[1]
global $DestinationIp
#endregion Var

_DebugSetup("GET_NIC_INFO",false,2)
getCommandline()
getNICProperties()




for $i = 0 to $adapterCount-1
local $sPingOutput=_getUsedAdapter($DestinationIp,$aNetWorkAdapters [$i] [1])
;~ TTL is the only valid string in a language independed situation while ping does not return a exitcode in Windows 7 anymore
if StringInStr($sPingOutput," TTL=") then
;~ Mark the Adapter that reaches the given IP with a x
$aNetWorkAdapters [$i] [4] = "x"
ExitLoop
EndIf
Next

_Arraydisplay($aNetWorkAdapters)


func _getUsedAdapter($Destination,$Source)
_DebugOut("Check now DestinationIP="&$Destination&" with local SourceIp="&$Source)
$sPingOutput=_RunStdOutRead("ping -n 1 "&$Destination&" -S "&$Source)
return $sPingOutput
EndFunc

Func _RunStdOutRead($sCommand, $sWorkingDirectory = @SystemDir)
Local Const $iPID = Run(@ComSpec & ' /c ' & $sCommand, $sWorkingDirectory, @SW_HIDE, $STDOUT_CHILD + $STDERR_CHILD)
ConsoleWrite("$iPID = " & $iPID & @LF)
Local $sOutput = ''
While 1
$sOutput &= StdoutRead($iPID)
If @error Then
ExitLoop
EndIf
WEnd
return $sOutput

EndFunc ;==>_RunStdOutRead

func getNICProperties()
For $objItem in $colItems
local $IP = $objItem.IPAddress(0)
;~ Consolewrite( "TYPE :" & VarGetType ($IP)&":"&@CRLF)
If string($IP)<>"" Then
;~       Consolewrite( "IPAddress:" & $objItem.IPAddress(0)&":"&@CRLF)
;~       Consolewrite( "MACAddress:" & $objItem.MACAddress&":"&@CRLF)
;~       Consolewrite( "-----------------------------------"&@CRLF)
ReDim $aNetWorkAdapters [$adapterCount + 1] [5]
$aNetWorkAdapters [$adapterCount] [0] = $objItem.MACAddress
$aNetWorkAdapters [$adapterCount] [1] = $objItem.IPAddress(0)
$aNetWorkAdapters [$adapterCount] [2] = $objItem.Caption
$adapterCount += 1
EndIf
Next

Consolewrite("$adapterCount:"&$adapterCount&@CRLF)



local $o_WMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")

for $i = 0 to $adapterCount-1
local $a_CollectedConnections = $o_WMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapter Where NetEnabled='True'", "WQL", 0x20 + 0x10)
Consolewrite("------------------------------------------"&@CRLF)
Consolewrite("MACAddress Array :" & $aNetWorkAdapters [$i][0]&":"&@CRLF)
For $o_ConnectionItem In $a_CollectedConnections

;~ Consolewrite("MACAddress Object:" & $o_ConnectionItem.MACAddress&":"&@CRLF)
;~ Consolewrite("NetworkId   :" & $o_ConnectionItem.NetConnectionID&":"&@CRLF)


If $o_ConnectionItem.MACAddress == $aNetWorkAdapters[$i][0] Then
;~ Consolewrite("ID:" & $o_ConnectionItem.NetConnectionID&":"&@CRLF)
;~ Consolewrite("Status:" & $o_ConnectionItem.NetConnectionStatus&":"&@CRLF)
;~ Consolewrite("MACAddress:" & $o_ConnectionItem.MACAddress&":"&@CRLF)
Consolewrite( "Mac Matches the the info from Win32_NetworkAdapterConfiguration"&@CRLF)
Consolewrite( "-----------------------------------"&@CRLF)
$aNetWorkAdapters [$i] [3] = $o_ConnectionItem.NetConnectionID
ExitLoop
EndIf
Next
Next
EndFunc


func getCommandline()
Local $validOpts, $options, $msg, $iIndx, $i
Local $cmdln = $CmdLine
;initialize options parser
_OptParse_Init ($validOpts, _
@Scriptname&" \n", _
"2013, Version:"&FileGetVersion(@ScriptName)&"\n", _
"Displays some infos of a nic\n")
;create a list of vaild options
;the parser checks for / or - to indicate a switch/flag/option/parameter
;grouping (/inf or -inf instead of /i /n /f or -i -n -f ) is not parsed.
_OptParse_Add ($validOpts, "d", "destination", $OPT_ARG_REQ, "destination Ip")


_OptParse_Add ($validOpts, "v", "version", $OPT_ARG_NONE, "Display this scripts version number.")
_OptParse_Add ($validOpts, "h", "help", $OPT_ARG_NONE, "Display this message.")
_OptParse_Add ($validOpts, "?", "", $OPT_ARG_NONE, "Display this Message.")
_OptParse_SetDisplay (0) ; 0= console, 1= msgbox
;make a copy of the CmdLine params so it can get modified
$options = _OptParse_GetOpts ($cmdln, $validOpts)
If @error Then
_OptParse_ShowUsage ($validOpts, 0)
Exit
EndIf
;Check for matches and perform action.
If _OptParse_MatchOption ("?,h,help", $options, $iIndx) Then
_OptParse_Display("Help Requested!")
_OptParse_ShowUsage ($validOpts)
exit
Return
EndIf

If _OptParse_MatchOption ("v,version", $options, $iIndx) Then
_OptParse_ShowVersion ($validOpts)
exit
Return
EndIf

If _OptParse_MatchOption("d,destination",$options,$iIndx) Then $DestinationIp=$options[$iIndx][1]

EndFunc

I tested it with 3.3.8.1 in Windows 7 (64) with 8 adapters and Windows 2008 R2 with 2 adapters.

Both showed me the correct results.

//edit: Oh, I forgot, yes there is a "gap" the TCP Port 4 /echo must be responding.....

Edited by Tankbuster
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...