iPXE
Data Structures | Macros | Functions | Variables
acpimac.c File Reference

ACPI MAC address. More...

#include <string.h>
#include <errno.h>
#include <ipxe/acpi.h>
#include <ipxe/base16.h>
#include <ipxe/ethernet.h>
#include <ipxe/if_ether.h>
#include <ipxe/settings.h>
#include <ipxe/acpimac.h>

Go to the source code of this file.

Data Structures

struct  acpimac_extractor
 An ACPI MAC extraction mechanism. More...
 

Macros

#define colour   FADT_SIGNATURE
 Colour for debug messages. More...
 
#define AMAC_SIGNATURE   ACPI_SIGNATURE ( 'A', 'M', 'A', 'C' )
 AMAC signature. More...
 
#define MACA_SIGNATURE   ACPI_SIGNATURE ( 'M', 'A', 'C', 'A' )
 MACA signature. More...
 
#define RTMA_SIGNATURE   ACPI_SIGNATURE ( 'R', 'T', 'M', 'A' )
 RTMA signature. More...
 
#define ACPIMAC_MAX_SKIP   8
 Maximum number of bytes to skip after ACPI signature. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 FILE_SECBOOT (PERMITTED)
 
static int acpimac_decode_base16 (const char *mac, uint8_t *hw_addr)
 Decode Base16-encoded MAC address. More...
 
static int acpimac_decode_raw (const char *mac, uint8_t *hw_addr)
 Decode raw MAC address. More...
 
static int acpimac_extract (const struct acpi_header *zsdt, size_t len, size_t offset, void *data, struct acpimac_extractor *extractor)
 Extract MAC address from DSDT/SSDT. More...
 
static int acpimac_extract_auxmac (const struct acpi_header *zsdt, size_t len, size_t offset, void *data)
 Extract "_AUXMAC_" MAC address from DSDT/SSDT. More...
 
static int acpimac_extract_rtxmac (const struct acpi_header *zsdt, size_t len, size_t offset, void *data)
 Extract "_RTXMAC_" MAC address from DSDT/SSDT. More...
 
int acpi_mac (uint8_t *hw_addr)
 Extract MAC address from DSDT/SSDT. More...
 
static int sysmac_fetch (void *data, size_t len)
 Fetch system MAC address setting. More...
 
const struct setting sysmac_setting __setting (SETTING_MISC, sysmac)
 System MAC address setting. More...
 

Variables

static struct acpimac_extractor acpimac_auxmac
 "_AUXMAC_" extraction mechanism More...
 
static struct acpimac_extractor acpimac_rtxmac
 "_RTXMAC_" extraction mechanism More...
 
struct builtin_setting sysmac_builtin_setting __builtin_setting
 System MAC address built-in setting. More...
 

Detailed Description

ACPI MAC address.

Definition in file acpimac.c.

Macro Definition Documentation

◆ colour

#define colour   FADT_SIGNATURE

Colour for debug messages.

Definition at line 43 of file acpimac.c.

◆ AMAC_SIGNATURE

#define AMAC_SIGNATURE   ACPI_SIGNATURE ( 'A', 'M', 'A', 'C' )

AMAC signature.

Definition at line 46 of file acpimac.c.

◆ MACA_SIGNATURE

#define MACA_SIGNATURE   ACPI_SIGNATURE ( 'M', 'A', 'C', 'A' )

MACA signature.

Definition at line 49 of file acpimac.c.

◆ RTMA_SIGNATURE

#define RTMA_SIGNATURE   ACPI_SIGNATURE ( 'R', 'T', 'M', 'A' )

RTMA signature.

Definition at line 52 of file acpimac.c.

◆ ACPIMAC_MAX_SKIP

#define ACPIMAC_MAX_SKIP   8

Maximum number of bytes to skip after ACPI signature.

This is entirely empirical.

Definition at line 58 of file acpimac.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ acpimac_decode_base16()

static int acpimac_decode_base16 ( const char *  mac,
uint8_t hw_addr 
)
static

Decode Base16-encoded MAC address.

Parameters
macEncoded MAC
hw_addrMAC address to fill in
Return values
rcReturn status code

Definition at line 82 of file acpimac.c.

82  {
83  int len;
84  int rc;
85 
86  /* Attempt to base16-decode MAC address */
87  len = base16_decode ( mac, hw_addr, ETH_ALEN );
88  if ( len < 0 ) {
89  rc = len;
90  DBGC ( colour, "ACPI could not decode base16 MAC \"%s\": %s\n",
91  mac, strerror ( rc ) );
92  return rc;
93  }
94 
95  return 0;
96 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
ring len
Length.
Definition: dwmac.h:231
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
#define colour
Colour for debug messages.
Definition: acpimac.c:43
#define ETH_ALEN
Definition: if_ether.h:9

References colour, DBGC, ETH_ALEN, len, mac, rc, and strerror().

◆ acpimac_decode_raw()

static int acpimac_decode_raw ( const char *  mac,
uint8_t hw_addr 
)
static

Decode raw MAC address.

Parameters
macEncoded MAC
hw_addrMAC address to fill in
Return values
rcReturn status code

Definition at line 105 of file acpimac.c.

105  {
106 
107  memcpy ( hw_addr, mac, ETH_ALEN );
108  return 0;
109 }
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define ETH_ALEN
Definition: if_ether.h:9

References ETH_ALEN, mac, and memcpy().

◆ acpimac_extract()

static int acpimac_extract ( const struct acpi_header zsdt,
size_t  len,
size_t  offset,
void *  data,
struct acpimac_extractor extractor 
)
static

Extract MAC address from DSDT/SSDT.

Parameters
zsdtDSDT or SSDT
lenLength of DSDT/SSDT
offsetOffset of signature within DSDT/SSDT
dataData buffer
extractorACPI MAC address extractor
Return values
rcReturn status code

Some vendors provide a "system MAC address" within the DSDT/SSDT, to be used to override the MAC address for a USB docking station.

A full implementation would require an ACPI bytecode interpreter, since at least one OEM allows the MAC address to be constructed by executable ACPI bytecode (rather than a fixed data structure).

We instead attempt to extract a plausible-looking "_AUXMAC_#.....#" string that appears shortly after an "AMAC" or "MACA" signature. This should work for most implementations encountered in practice.

Definition at line 146 of file acpimac.c.

148  {
149  size_t prefix_len = strlen ( extractor->prefix );
150  uint8_t *hw_addr = data;
151  size_t skip = 0;
152  char buf[ prefix_len + extractor->len + 1 /* "#" */ + 1 /* NUL */ ];
153  char *mac = &buf[prefix_len];
154  int rc;
155 
156  /* Skip signature and at least one tag byte */
157  offset += ( 4 /* signature */ + 1 /* tag byte */ );
158 
159  /* Scan for suitable string close to signature */
160  for ( skip = 0 ;
161  ( ( skip < ACPIMAC_MAX_SKIP ) &&
162  ( offset + skip + sizeof ( buf ) ) <= len ) ;
163  skip++ ) {
164 
165  /* Read value */
166  memcpy ( buf, ( ( ( const void * ) zsdt ) + offset + skip ),
167  sizeof ( buf ) );
168 
169  /* Check for expected format */
170  if ( memcmp ( buf, extractor->prefix, prefix_len ) != 0 )
171  continue;
172  if ( buf[ sizeof ( buf ) - 2 ] != '#' )
173  continue;
174  if ( buf[ sizeof ( buf ) - 1 ] != '\0' )
175  continue;
176  DBGC ( colour, "ACPI found MAC:\n" );
177  DBGC_HDA ( colour, ( offset + skip ), buf, sizeof ( buf ) );
178 
179  /* Terminate MAC address string */
180  mac[extractor->len] = '\0';
181 
182  /* Decode MAC address */
183  if ( ( rc = extractor->decode ( mac, hw_addr ) ) != 0 )
184  return rc;
185 
186  /* Check MAC address validity */
187  if ( ! is_valid_ether_addr ( hw_addr ) ) {
188  DBGC ( colour, "ACPI has invalid MAC %s\n",
189  eth_ntoa ( hw_addr ) );
190  return -EINVAL;
191  }
192 
193  return 0;
194  }
195 
196  return -ENOENT;
197 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * prefix
Prefix string.
Definition: acpimac.c:63
#define ACPIMAC_MAX_SKIP
Maximum number of bytes to skip after ACPI signature.
Definition: acpimac.c:58
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:515
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
int(* decode)(const char *mac, uint8_t *hw_addr)
Decode MAC.
Definition: acpimac.c:72
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define DBGC_HDA(...)
Definition: compiler.h:506
ring len
Length.
Definition: dwmac.h:231
#define colour
Colour for debug messages.
Definition: acpimac.c:43
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition: ethernet.c:176
size_t strlen(const char *src)
Get length of string.
Definition: string.c:244
unsigned char uint8_t
Definition: stdint.h:10
size_t len
Encoded MAC length.
Definition: acpimac.c:65
static int is_valid_ether_addr(const void *addr)
Check if Ethernet address is valid.
Definition: ethernet.h:78
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115

References ACPIMAC_MAX_SKIP, colour, data, DBGC, DBGC_HDA, acpimac_extractor::decode, EINVAL, ENOENT, eth_ntoa(), is_valid_ether_addr(), acpimac_extractor::len, len, mac, memcmp(), memcpy(), offset, acpimac_extractor::prefix, rc, and strlen().

Referenced by acpimac_extract_auxmac(), and acpimac_extract_rtxmac().

◆ acpimac_extract_auxmac()

static int acpimac_extract_auxmac ( const struct acpi_header zsdt,
size_t  len,
size_t  offset,
void *  data 
)
static

Extract "_AUXMAC_" MAC address from DSDT/SSDT.

Parameters
zsdtDSDT or SSDT
lenLength of DSDT/SSDT
offsetOffset of signature within DSDT/SSDT
dataData buffer
Return values
rcReturn status code

Definition at line 208 of file acpimac.c.

209  {
210 
211  return acpimac_extract ( zsdt, len, offset, data, &acpimac_auxmac );
212 }
static int acpimac_extract(const struct acpi_header *zsdt, size_t len, size_t offset, void *data, struct acpimac_extractor *extractor)
Extract MAC address from DSDT/SSDT.
Definition: acpimac.c:146
ring len
Length.
Definition: dwmac.h:231
static struct acpimac_extractor acpimac_auxmac
"_AUXMAC_" extraction mechanism
Definition: acpimac.c:112
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint16_t offset
Offset to command line.
Definition: bzimage.h:8

References acpimac_auxmac, acpimac_extract(), data, len, and offset.

Referenced by acpi_mac().

◆ acpimac_extract_rtxmac()

static int acpimac_extract_rtxmac ( const struct acpi_header zsdt,
size_t  len,
size_t  offset,
void *  data 
)
static

Extract "_RTXMAC_" MAC address from DSDT/SSDT.

Parameters
zsdtDSDT or SSDT
lenLength of DSDT/SSDT
offsetOffset of signature within DSDT/SSDT
dataData buffer
Return values
rcReturn status code

Definition at line 223 of file acpimac.c.

224  {
225 
226  return acpimac_extract ( zsdt, len, offset, data, &acpimac_rtxmac );
227 }
static int acpimac_extract(const struct acpi_header *zsdt, size_t len, size_t offset, void *data, struct acpimac_extractor *extractor)
Extract MAC address from DSDT/SSDT.
Definition: acpimac.c:146
ring len
Length.
Definition: dwmac.h:231
uint8_t data[48]
Additional event data.
Definition: ena.h:22
static struct acpimac_extractor acpimac_rtxmac
"_RTXMAC_" extraction mechanism
Definition: acpimac.c:119
uint16_t offset
Offset to command line.
Definition: bzimage.h:8

References acpimac_extract(), acpimac_rtxmac, data, len, and offset.

Referenced by acpi_mac().

◆ acpi_mac()

int acpi_mac ( uint8_t hw_addr)

Extract MAC address from DSDT/SSDT.

Parameters
hw_addrMAC address to fill in
Return values
rcReturn status code

Definition at line 235 of file acpimac.c.

235  {
236  int rc;
237 
238  /* Look for an "AMAC" address */
239  if ( ( rc = acpi_extract ( AMAC_SIGNATURE, hw_addr,
240  acpimac_extract_auxmac ) ) == 0 )
241  return 0;
242 
243  /* Look for a "MACA" address */
244  if ( ( rc = acpi_extract ( MACA_SIGNATURE, hw_addr,
245  acpimac_extract_auxmac ) ) == 0 )
246  return 0;
247 
248  /* Look for a "RTMA" address */
249  if ( ( rc = acpi_extract ( RTMA_SIGNATURE, hw_addr,
250  acpimac_extract_rtxmac ) ) == 0 )
251  return 0;
252 
253  return -ENOENT;
254 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int acpimac_extract_rtxmac(const struct acpi_header *zsdt, size_t len, size_t offset, void *data)
Extract "_RTXMAC_" MAC address from DSDT/SSDT.
Definition: acpimac.c:223
static int acpimac_extract_auxmac(const struct acpi_header *zsdt, size_t len, size_t offset, void *data)
Extract "_AUXMAC_" MAC address from DSDT/SSDT.
Definition: acpimac.c:208
#define MACA_SIGNATURE
MACA signature.
Definition: acpimac.c:49
#define AMAC_SIGNATURE
AMAC signature.
Definition: acpimac.c:46
#define ENOENT
No such file or directory.
Definition: errno.h:515
#define RTMA_SIGNATURE
RTMA signature.
Definition: acpimac.c:52
int acpi_extract(uint32_t signature, void *data, int(*extract)(const struct acpi_header *zsdt, size_t len, size_t offset, void *data))
Extract value from DSDT/SSDT.
Definition: acpi.c:228

References acpi_extract(), acpimac_extract_auxmac(), acpimac_extract_rtxmac(), AMAC_SIGNATURE, ENOENT, MACA_SIGNATURE, rc, and RTMA_SIGNATURE.

Referenced by ecm_fetch_mac(), sysmac_fetch(), and typeof().

◆ sysmac_fetch()

static int sysmac_fetch ( void *  data,
size_t  len 
)
static

Fetch system MAC address setting.

Parameters
dataBuffer to fill with setting data
lenLength of buffer
Return values
lenLength of setting data, or negative error

Definition at line 263 of file acpimac.c.

263  {
265  int rc;
266 
267  /* Try fetching ACPI MAC address */
268  if ( ( rc = acpi_mac ( mac ) ) != 0 )
269  return rc;
270 
271  /* Return MAC address */
272  if ( len > sizeof ( mac ) )
273  len = sizeof ( mac );
274  memcpy ( data, mac, len );
275  return ( sizeof ( mac ) );
276 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
void * memcpy(void *dest, const void *src, size_t len) __nonnull
int acpi_mac(uint8_t *hw_addr)
Extract MAC address from DSDT/SSDT.
Definition: acpimac.c:235
ring len
Length.
Definition: dwmac.h:231
unsigned char uint8_t
Definition: stdint.h:10
#define ETH_ALEN
Definition: if_ether.h:9
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References acpi_mac(), data, ETH_ALEN, len, mac, memcpy(), and rc.

◆ __setting()

const struct setting sysmac_setting __setting ( SETTING_MISC  ,
sysmac   
)

System MAC address setting.

Variable Documentation

◆ acpimac_auxmac

struct acpimac_extractor acpimac_auxmac
static
Initial value:
= {
.prefix = "_AUXMAC_#",
.len = ( ETH_ALEN * 2 ),
}
static int acpimac_decode_base16(const char *mac, uint8_t *hw_addr)
Decode Base16-encoded MAC address.
Definition: acpimac.c:82
#define ETH_ALEN
Definition: if_ether.h:9

"_AUXMAC_" extraction mechanism

Definition at line 112 of file acpimac.c.

Referenced by acpimac_extract_auxmac().

◆ acpimac_rtxmac

struct acpimac_extractor acpimac_rtxmac
static
Initial value:
= {
.prefix = "_RTXMAC_#",
.len = ETH_ALEN,
.decode = acpimac_decode_raw,
}
static int acpimac_decode_raw(const char *mac, uint8_t *hw_addr)
Decode raw MAC address.
Definition: acpimac.c:105
#define ETH_ALEN
Definition: if_ether.h:9

"_RTXMAC_" extraction mechanism

Definition at line 119 of file acpimac.c.

Referenced by acpimac_extract_rtxmac().

◆ __builtin_setting

struct builtin_setting sysmac_builtin_setting __builtin_setting
Initial value:
= {
.setting = &sysmac_setting,
.fetch = sysmac_fetch,
}
static int sysmac_fetch(void *data, size_t len)
Fetch system MAC address setting.
Definition: acpimac.c:263

System MAC address built-in setting.

Definition at line 287 of file acpimac.c.