|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Visual Basic Network Services Netbios: Determine Local Adapter MAC Address |
|
Posted: | Friday August 21, 1998 |
Updated: | Monday December 26, 2011 |
Applies to: | VB4-32, VB5, VB6 |
Developed with: | VB6, Windows NT4 |
OS restrictions: | None |
Author: | VBnet - Randy Birch, MSKB |
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 |
Installed network card, NetBIOS. |
|
Keeping
it simple, this is a wrapper routine that will return the Medium Access Control (MAC) address for the installed network card. A MAC Address
is a unique 48-bit number assigned to the network interface card (NIC) by the manufacturer. MAC addresses (which are physical addresses) are
used for mapping in TCP/IP network communication.
TCP\IP under Windows NT allows a computer to communicate over a network with another computer by using either an IP address, a host name, or a NetBIOS name. However, when one computer attempts to communicate with another computer using one of these three naming conventions, that name must ultimately be resolved to a hardware address, the MAC address. This code is roughly based on MS knowledge base article Q175472. |
BAS Module Code |
None. |
|
Form Code |
To a form add a command button (Command1), and a text box (Text1). Labels and frames are optional. Add the following: |
|
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 NCBASTAT As Long = &H33 Private Const NCBNAMSZ As Long = 16 Private Const HEAP_ZERO_MEMORY As Long = &H8 Private Const HEAP_GENERATE_EXCEPTIONS As Long = &H4 Private Const NCBRESET As Long = &H32 Private Type NET_CONTROL_BLOCK 'NCB ncb_command As Byte ncb_retcode As Byte ncb_lsn As Byte ncb_num As Byte ncb_buffer As Long ncb_length As Integer ncb_callname As String * NCBNAMSZ ncb_name As String * NCBNAMSZ ncb_rto As Byte ncb_sto As Byte ncb_post As Long ncb_lana_num As Byte ncb_cmd_cplt As Byte ncb_reserve(9) As Byte 'Reserved, must be 0 ncb_event As Long End Type Private Type ADAPTER_STATUS adapter_address(5) As Byte rev_major As Byte reserved0 As Byte adapter_type As Byte rev_minor As Byte duration As Integer frmr_recv As Integer frmr_xmit As Integer iframe_recv_err As Integer xmit_aborts As Integer xmit_success As Long recv_success As Long iframe_xmit_err As Integer recv_buff_unavail As Integer t1_timeouts As Integer ti_timeouts As Integer Reserved1 As Long free_ncbs As Integer max_cfg_ncbs As Integer max_ncbs As Integer xmit_buf_unavail As Integer max_dgram_size As Integer pending_sess As Integer max_cfg_sess As Integer max_sess As Integer max_sess_pkt_size As Integer name_count As Integer End Type Private Type NAME_BUFFER name As String * NCBNAMSZ name_num As Integer name_flags As Integer End Type Private Type ASTAT adapt As ADAPTER_STATUS NameBuff(30) As NAME_BUFFER End Type Private Declare Function Netbios Lib "netapi32" _ (pncb As NET_CONTROL_BLOCK) As Byte Private Declare Sub CopyMemory Lib "kernel32" _ Alias "RtlMoveMemory" _ (hpvDest As Any, ByVal _ hpvSource As Long, ByVal _ cbCopy As Long) Private Declare Function GetProcessHeap Lib "kernel32" () As Long Private Declare Function HeapAlloc Lib "kernel32" _ (ByVal hHeap As Long, _ ByVal dwFlags As Long, _ ByVal dwBytes As Long) As Long Private Declare Function HeapFree Lib "kernel32" _ (ByVal hHeap As Long, _ ByVal dwFlags As Long, _ lpMem As Any) As Long Private Sub Command1_Click() 'in calling, pass the character you 'want as a delimiter between MAC 'address members Text1.Text = GetMACAddress("-") End Sub Private Function GetMACAddress(sDelimiter As String) As String 'retrieve the MAC Address for the network controller 'installed, returning a formatted string Dim tmp As String Dim pASTAT As Long Dim NCB As NET_CONTROL_BLOCK Dim AST As ASTAT Dim cnt As Long 'The IBM NetBIOS 3.0 specifications defines four basic 'NetBIOS environments under the NCBRESET command. Win32 'follows the OS/2 Dynamic Link Routine (DLR) environment. 'This means that the first NCB issued by an application 'must be a NCBRESET, with the exception of NCBENUM. 'The Windows NT implementation differs from the IBM 'NetBIOS 3.0 specifications in the NCB_CALLNAME field. NCB.ncb_command = NCBRESET Call Netbios(NCB) 'To get the Media Access Control (MAC) address for an 'ethernet adapter programmatically, use the Netbios() 'NCBASTAT command and provide a "*" as the name in the 'NCB.ncb_CallName field (in a 16-chr string). NCB.ncb_callname = "* " NCB.ncb_command = NCBASTAT 'For machines with multiple network adapters you need to 'enumerate the LANA numbers and perform the NCBASTAT 'command on each. Even when you have a single network 'adapter, it is a good idea to enumerate valid LANA numbers 'first and perform the NCBASTAT on one of the valid LANA 'numbers. It is considered bad programming to hardcode the 'LANA number to 0 (see the comments section below). NCB.ncb_lana_num = 0 NCB.ncb_length = Len(AST) pASTAT = HeapAlloc(GetProcessHeap(), _ HEAP_GENERATE_EXCEPTIONS Or _ HEAP_ZERO_MEMORY, _ NCB.ncb_length) If pASTAT <> 0 Then NCB.ncb_buffer = pASTAT Call Netbios(NCB) CopyMemory AST, NCB.ncb_buffer, Len(AST) 'convert the byte array to a string GetMACAddress = MakeMacAddress(AST.adapt.adapter_address(), sDelimiter) HeapFree GetProcessHeap(), 0, pASTAT Else Debug.Print "memory allocation failed!" Exit Function End If 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 |
Other hardware and software may be assigned their own MAC
addresses. For example, a modem can have a MAC address. Also, a RAS client or server can install "dummy" network adapters that
correspond to a dialup or serial connection. Normally, these MAC addresses are randomly generated. If an adapter status is called on a LANA
that corresponds to one of these adapters when no connection is present,
NetBIOS returns error 0x34 (NRC_ENVNOTDEF) even if a reset was
previously performed.
With the NetBEUI and IPX transports, the same information can be obtained at a command prompt by using: net config workstation The ID given is the MAC address. How to Use LANA Numbers in a 32-bit Environment SUMMARY MORE INFORMATION Originally, IBM sent NetBIOS packets over the NetBEUI protocol, also known as the NetBIOS Frames protocol. This was the only transport NetBIOS could use to send data across the network. In other words, each network adapter had only one protocol to send and receive NetBIOS packets. Because most computers have only one network adapter, many MS-DOS-based applications send all their requests to a LANA value of zero (also called simply 'LANA zero'). If a second network adapter is installed, some programs allow the user to configure the application to use LANA one instead. As a result, LANA zero became a default setting, though it was never intended to be a default. Today's network technology allows NetBIOS to use transports other than NetBEUI. Microsoft has extended the meaning of LANA to indicate a specific transport on a specific adapter. For example, if you have two network adapters, and have IPX/SPX and NetBEUI transports installed, you have four LANAs. The LANAs may or may not be sequential, and there is no systematic way to identify which transport maps to which LANA. In addition to extending the meaning of a LANA, Microsoft also added an NCB command (NCBENUM) that returns an array of available LANA numbers. As an example, the LANA_ENUM structure filled by NCBENUM might hold an array with values 0, 3, 5, and 6. Zero might map to IPX/SPX on the first adapter, three might map to NETBEUI on a second adapter, and so on. In Windows NT and Windows 95, network adapters consist of physical adapters (like a 3Com Etherlink II) and software adapters (like the Dial Up Adapter). In addition, a user may have TCP/IP, NETBEUI, IPX/SPX, and other transports installed, all of which have NetBIOS support. For Windows NT, LANAs are configurable through the control panel. Choose the Network applet, choose the NetBIOS Interface component, then choose Configure. A dialog appears that allows you to edit the LANAs. For Windows 95, you may only set LANA zero, the default protocol, and if no protocol is set as default, there won't be a LANA zero. You can set the default protocol in the control panel. Choose the Network applet, choose the protocol you want as default, choose Properties, the Advanced tab, and finally check 'Set this protocol to be the default protocol'. LANAs may seem like a constraint that your application must work around. However, making your application ignorant of how users want to configure their machines is a powerful idea, and one that makes life easier for your customers. The best way to write a NetBIOS application is to support all LANAs, and establish connections over any LANA. A good approach is outlined in the following steps:
It is a good idea to submit NCBADDNAME, NCBLISTEN, NCBFINDNAME, and NCBCALL asynchronously. Asynchronous requests will be processed almost in parallel on each transport. This architecture is quite beneficial. Once your application is written to establish connections in this manner, it will support any transport that NetBIOS can use. As a result, your customers will not have to configure anything within your application, and your application will not be affected by dynamic LANAs such as dial-up adapters or plug-and-play hardware. Last reviewed: August 7, 1996 |
|
|
|
|||||
|
|||||
|
|||||
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |