Visual Basic Network Services
SendARP: Determine Local or Remote Adapter MAC Addresses
     
Posted:   Wednesday August 21, 2002
Updated:   Monday December 26, 2011
     
Applies to:   VB4-32, VB5, VB6
Developed with:   VB6, Windows XP
OS restrictions:   Windows 2000, Windows XP, Windows .Net server
Author:   VBnet - Randy Birch
     

Related:  

Netbios: Determine Local Adapter MAC Address
SendARP: Determine Local or Remote Adapter MAC Addresses
gethostbyname: Determine Network Host Name and IP Address
Netbios: Determine Local Adapter MAC Addresses through LANA Enumeration
gethostbyaddr: Obtain Host Name from IP Address
IcmpSendEcho: Ping a Machine by IP Address
IcmpSendEcho: Ping a Machine by Host Name

URLDownloadToFile: Obtain Machine's Public IP Behind Router
IcmpSendEcho: Perform a Tracert (Trace Route) in VB with Host Name Resolution
     
 Prerequisites
Remote machine with network card.

Unlike the complex code required to obtain your own MAC address, this is considerably easier involving three API calls in total.

The iphlpapi.dll library exposes a SendArp call whose only purpose is send an ARP request to obtain the physical address that corresponds to the specified destination IP address.

  • The DestIP member specifies the destination IP address, and the ARP request attempts to obtain the physical address corresponding to this IP address.
  • SrcIP can specify the IP address of the sender. This is optional, and zero for this parameter.
  • Following the call the pMacAddr member contains the pointer to an array of ULONG variables. The first six bytes of this array receive the physical address that corresponds to the IP address specified by the DestIP parameter. These are copied to a byte array, from which the MAC address is extracted.
  • PhyAddrLen is passed with 6 representing the length of the physical address pointed to by the pMacAddr parameter.

Note that this call is only available under Windows 2000; Windows XP Pro; and Windows .NET Server. No corresponding NT4 or 9x call is supplied.

Note: There's something weird going on with this code and Native code compiling. Specifically, the app will crash if the return data type from GetRemoteMACAddress is changed to String .  try and modify this code to return a string from the  user reported a weird problem I have confirmed with this particular code code when compiled to an exe using the Native code option.  The problem stems (for some reason) in the assignment of compiling and the assignment of a string return type to GetRemoteMACAddress. (Bugs in applications compiled to Native code are not news nor uncommon). To remedy this problem the code below sets the call's return type as Boolean rather than string, and fills a string variable passed as a parameter with the remote MAC address. These mods enable the code below to be successfully executed in either a pcode or native code exe.  Anyone interested in testing this can affect this same crash by simply commenting out the GetRemoteMACAddress=True and =False statements, redefine the function to As String, and assign

 BAS Module Code
None.

 Form Code
To a form add a command button (Command1), and two text boxes (Text1, Text2). Labels are optional. Add the following code, and be sure to set Text1 in Form_Load to point to a valid IP address (local or remote machine) workgroup network or domain:

Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Const NO_ERROR = 0

Private Declare Function inet_addr Lib "wsock32.dll" _
  (ByVal s As String) As Long

Private Declare Function SendARP Lib "iphlpapi.dll" _
  (ByVal DestIP As Long, _
   ByVal SrcIP As Long, _
   pMacAddr As Long, _
   PhyAddrLen As Long) As Long

Private Declare Sub CopyMemory Lib "kernel32" _
   Alias "RtlMoveMemory" _
  (dst As Any, _
   src As Any, _
   ByVal bcount As Long)
   


Private Sub Form_Load()

   Text1.Text = "192.168.1.101" 'or address of interest
   Text2.Text = ""
   Command1.Caption = "Get Remote Mac Address"
   
End Sub


Private Sub Command1_Click()

   Dim sRemoteMacAddress As String
   
   If Len(Text1.Text) > 0 Then
   
      If GetRemoteMACAddress(Text1.Text, sRemoteMacAddress, "-") Then
         Text2.Text = sRemoteMacAddress
      Else
         Text2.Text = "(SendARP call failed)"
      End If
      
   End If

End Sub


Private Function GetRemoteMACAddress(ByVal sRemoteIP As String, _
                                     sRemoteMacAddress As String, _
                                     sDelimiter As String) As Boolean

   Dim dwRemoteIP As Long
   Dim pMacAddr As Long
   Dim bpMacAddr() As Byte
   Dim PhyAddrLen As Long
    
  'convert the string IP into
  'an unsigned long value containing
  'a suitable binary representation
  'of the Internet address given
   dwRemoteIP = ConvertIPtoLong(sRemoteIP)

   If dwRemoteIP <> 0 Then
   
     'must set this up first!
      PhyAddrLen = 6
   
    'assume failure 
     GetRemoteMACAddress = False
     
     'retrieve the remote MAC address
      If SendARP(dwRemoteIP, 0&, pMacAddr, PhyAddrLen) = NO_ERROR Then
      
         If (pMacAddr <> 0) And (PhyAddrLen <> 0) Then
      
           'returned value is a long pointer
           'to the MAC address, so copy data
           'to a byte array
            ReDim bpMacAddr(0 To PhyAddrLen - 1)
            CopyMemory bpMacAddr(0), pMacAddr, ByVal PhyAddrLen
            
           'convert the byte array to a string 
           'and return success 
            sRemoteMacAddress = MakeMacAddress(bpMacAddr(), sDelimiter)
            GetRemoteMACAddress = True
            
         End If 'pMacAddr

      End If  'SendARP
      
   End If  'dwRemoteIP
      
End Function


Private Function ConvertIPtoLong(sIpAddress) As Long

   ConvertIPtoLong = inet_addr(sIpAddress)

End Function


Private Function MakeMacAddress(b() As Byte, sDelim As String) As String

   Dim cnt As Long
   Dim buff As String
   
   On Local Error GoTo MakeMac_error
 
  'so far, MAC addresses are
  'exactly 6 segments in size (0-5)
   If UBound(b) = 5 Then
   
     'concatenate the first five values
     'together and separate with the
     'delimiter char
      For cnt = 0 To 4
         buff = buff & Right$("00" & Hex(b(cnt)), 2) & sDelim
      Next
      
     'and append the last value
      buff = buff & Right$("00" & Hex(b(5)), 2)
         
   End If  'UBound(b)
   
   MakeMacAddress = buff
   
MakeMac_exit:
   Exit Function
   
MakeMac_error:
   MakeMacAddress = "(error building MAC address)"
   Resume MakeMac_exit
   
End Function
 Comments
I use a local router that assigns DHCP addresses in the 192.168.1.xxx range. This code should work to resolve the MAC address for any IP in the local network or domain.

 
 

PayPal Link
Make payments with PayPal - it's fast, free and secure!

 
 
 
 

Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy

 

Hit Counter