Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 26 Next »

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.

Listing - Calling NetIF_AddrHW_Get()
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)


  1. 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.
  2. 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.
  3. The third function is a pointer to a CPU_INT08U variable that the function returns the length of the specified interface’s hardware address.
  4. 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 value NET_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.

Listing - Calling NetIF_AddrHW_Set()
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)
  1. The first argument specifies the interface number to set the hardware address. The interface number is acquired upon the successful addition of the interface.
  2. 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.
  3. 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 as sizeof(addr_hw) assuming addr_hw is declared as an array of CPU_INT08U.
  4. 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 value NET_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:

Listing - Obtaining the Ethernet MAC address of a host
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;
  }
}


Since ARP module is only used in affiliation with IPv4, getting the MAC address associated with an IP address is only supported for IPv4 address. IPv6 layer uses NDP (Neighbor Discovery Protocol) to associate IPv6 address with Link-Layer address. Unfortunately, NDP does not yet provides API function to get the MAC address associated with an IPv6 address.
  • No labels