Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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.

Code Block
languagecpp
firstline1
titleListing - Calling NetIF_AddrHW_Get()
linenumberstrue
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)


Panel
bgColor#f0f0f0
  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.


Code Block
languagecpp
firstline1
titleListing - Calling NetIF_AddrHW_Set()
linenumberstrue
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)


Panel
  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

...

The following example shows how to obtain the Ethernet MAC address of a host on the local area network:

Code Block
languagecpp
firstline1
titleListing - Obtaining the Ethernet MAC address of a host
linenumberstrue
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;
  }
}


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