Network Interface Hardware Address
Default MAC Address
When starting an Interface, µC/TCP-IP can automatically use a MAC address either defined in the configuration or already loaded in MAC controller. As specified in Network Interface Configuration each device configuration contains which specify if the MAC address must be load from the MAC, null string, or must load a custom MAC address, string that contain a valid MAC address.
Getting MAC Address
Many types of network interface hardware require the use of a link layer protocol address. In the case of Ethernet, this address is sometimes known as the hardware address or MAC address. In some applications, it may be desirable to get the current configured hardware address for a specific interface. This may be performed by calling NetIF_AddrHW_Get()
with the appropriate arguments.
NetIF_AddrHW_Get((NET_IF_NBR ) if_nbr, (1) (CPU_INT08U *)&addr_hw_sender[0], (2) (CPU_INT08U *)&addr_hw_len, (3) (NET_ERR *) perr); (4)
- The first argument specifies the interface number from which to get the hardware address. The interface number is acquired upon the successful addition of the interface.
- The second argument is a pointer to a
CPU_INT08U
array used to provide storage for the returned hardware address. This array must be sized large enough to hold the returned number of bytes for the given interface’s hardware address. The lowest index number in the hardware address array represents the most significant byte of the hardware address. - The third function is a pointer to a
CPU_INT08U
variable that the function returns the length of the specified interface’s hardware address. - The fourth argument is a pointer to a
NET_ERR
variable containing the return error code for the function. If the hardware address is successfully obtained, then the return error code will contain the valueNET_IF_ERR_NONE
.
Setting MAC Address
Some applications prefer to configure the hardware device’s hardware address via software during run-time as opposed to a run-time auto-loading EEPROM as is common for many Ethernet devices. If the application is to set or change the hardware address during run-time, this may be performed by calling NetIF_AddrHW_Set()
with the appropriate arguments. Alternatively, the hardware address may be statically configured via the device configuration structure and later changed during run-time.
NetIF_AddrHW_Set((NET_IF_NBR ) if_nbr, (1) (CPU_INT08U *)&addr_hw[0], (2) (CPU_INT08U *)&addr_hw_len, (3) (NET_ERR *) perr); (4)
- The first argument specifies the interface number to set the hardware address. The interface number is acquired upon the successful addition of the interface.
- The second argument is a pointer to a
CPU_INT08U
array which contains the desired hardware address to set. The lowest index number in the hardware address array represents the most significant byte of the hardware address. - The third function is a pointer to a
CPU_INT08U
variable that specifies the length of the hardware address being set. In most cases, this can be specified assizeof(addr_hw)
assumingaddr_hw
is declared as an array ofCPU_INT08U
. - The fourth argument is a pointer to a
NET_ERR
variable containing the return error code for the function. If the hardware address is successfully obtained, then the return error code will contain the valueNET_IF_ERR_NONE
.
Note: In order to set the hardware address for a particular interface, it must first be stopped. The hardware address may then be set, and the interface re-started.
Getting a Host MAC Address on the Network
In order to determine the MAC address of a host on the network, the Network Protocol Stack must have an ARP cache entry for the specified host protocol address. An application may check to see if an ARP cache entry is present by calling NetARP_CacheGetAddrHW()
.
If an ARP cache entry is not found, the application may call NetARP_CacheProbeAddrOnNet()
to send an ARP request to all hosts on the network. If the target host is present, an ARP reply will be received shortly and the application should wait and then call NetARP_CacheGetAddrHW()
to determine if the ARP reply has been entered into the ARP cache.
The following example shows how to obtain the Ethernet MAC address of a host on the local area network:
void AppGetRemoteHW_Addr (NET_IF_NBR if_nbr) { NET_IPv4_ADDR addr_ipv4_local; NET_IPv4_ADDR addr_ipv4_remote; CPU_CHAR *p_addr_ipv4_remote; CPU_CHAR addr_hw_str[NET_IF_ETHER_ADDR_SIZE_STR]; CPU_INT08U addr_hw[NET_IF_ETHER_ADDR_SIZE]; NET_ERR err; /* ------------- PREPARE IPv4 ADDRs ------------- */ p_addr_ipv4_local = "10.10.1.10"; /* MUST be one of host's configured IPv4 addrs. */ addr_ipv4_local = NetASCII_Str_to_IP((CPU_CHAR *) p_addr_ipv4_local, (NET_ERR *)&err); if (err != NET_ASCII_ERR_NONE) { printf(" Error #%d converting IPv4 address %s", err, p_addr_ipv4_local); return; } p_addr_ipv4_remote = "10.10.1.50"; /* Remote host's IPv4 addr to get hardware addr. */ (void)NetASCII_Str_to_IP((CPU_CHAR *) p_addr_ipv4_remote, (void *)&addr_ipv4_remote, NET_IPv4_ADDR_SIZE, (NET_ERR *)&err); if (err != NET_ASCII_ERR_NONE) { printf(" Error #%d converting IPv4 address %s", err, p_addr_ipv4_remote); return; } addr_ipv4_local = NET_UTIL_HOST_TO_NET_32(addr_ipv4_local); addr_ipv4_remote = NET_UTIL_HOST_TO_NET_32(addr_ipv4_remote); /* ------------- PROBE ADDR ON NET -------------- */ NetARP_CacheProbeAddrOnNet((NET_PROTOCOL_TYPE) NET_PROTOCOL_TYPE_IP_V4, (CPU_INT08U *) &addr_ipv4_local, (CPU_INT08U *) &addr_ipv4_remote, (NET_CACHE_ADDR_LEN) sizeof(addr_ipv4_remote), (NET_ERR *) &err); if (err != NET_ARP_ERR_NONE) { printf(" Error #%d probing address %s on network", err, addr_ipv4_remote); return; } OSTimeDly(2); /* Delay short time for ARP to probe network. */ /* ----- QUERY ARP CACHE FOR REMOTE HW ADDR ----- */ (void)NetARP_CacheGetAddrHW((NET_IF_NBR ) if_nbr, (CPU_INT08U *)&addr_hw[0], (NET_CACHE_ADDR_LEN) sizeof(addr_hw_str), (CPU_INT08U *)&addr_ipv4_remote, (NET_CACHE_ADDR_LEN) sizeof(addr_ipv4_remote), (NET_ERR *)&err); switch (err) { case NET_ARP_ERR_NONE: NetASCII_MAC_to_Str((CPU_INT08U *)&addr_hw[0], (CPU_CHAR *)&addr_hw_str[0], (CPU_BOOLEAN ) DEF_NO, (CPU_BOOLEAN ) DEF_YES, (NET_ERR *)&err); if (err != NET_ASCII_ERR_NONE) { printf(" Error #%d converting hardware address", err); return; } printf(" Remote IPv4 Addr %s @ HW Addr %s\n\r", p_addr_ipv4_remote, &addr_hw_str[0]); break; case NET_ARP_ERR_CACHE_NOT_FOUND: printf(" Remote IPv4 Addr %s NOT found on network\n\r", p_addr_ipv4_remote); break; case NET_ARP_ERR_CACHE_PEND: printf(" Remote IPv4 Addr %s NOT YET found on network\n\r", p_addr_ipv4_remote); break; case NET_ARP_ERR_NULL_PTR: case NET_ARP_ERR_INVALID_HW_ADDR_LEN: case NET_ARP_ERR_INVALID_PROTOCOL_ADDR_LEN: default: printf(" Error #%d querying ARP cache", err); break; } }