]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/ether-addr-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
4 #include <net/ethernet.h>
8 #include "ether-addr-util.h"
10 #include "string-util.h"
12 char* ether_addr_to_string(const struct ether_addr
*addr
, char buffer
[ETHER_ADDR_TO_STRING_MAX
]) {
16 /* Like ether_ntoa() but uses %02x instead of %x to print
17 * ethernet addresses, which makes them look less funny. Also,
18 * doesn't use a static buffer. */
20 sprintf(buffer
, "%02x:%02x:%02x:%02x:%02x:%02x",
21 addr
->ether_addr_octet
[0],
22 addr
->ether_addr_octet
[1],
23 addr
->ether_addr_octet
[2],
24 addr
->ether_addr_octet
[3],
25 addr
->ether_addr_octet
[4],
26 addr
->ether_addr_octet
[5]);
31 int ether_addr_compare(const struct ether_addr
*a
, const struct ether_addr
*b
) {
32 return memcmp(a
, b
, ETH_ALEN
);
35 static void ether_addr_hash_func(const struct ether_addr
*p
, struct siphash
*state
) {
36 siphash24_compress(p
, sizeof(struct ether_addr
), state
);
39 DEFINE_HASH_OPS(ether_addr_hash_ops
, struct ether_addr
, ether_addr_hash_func
, ether_addr_compare
);
41 int ether_addr_from_string(const char *s
, struct ether_addr
*ret
) {
42 size_t pos
= 0, n
, field
;
44 const char *hex
= HEXDIGITS
, *hexoff
;
48 #define parse_fields(v) \
49 for (field = 0; field < ELEMENTSOF(v); field++) { \
51 for (n = 0; n < (2 * sizeof(v[0])); n++) { \
54 hexoff = strchr(hex, s[pos]); \
57 assert(hexoff >= hex); \
69 if (field < (ELEMENTSOF(v)-1)) { \
80 s
+= strspn(s
, WHITESPACE
);
81 sep
= s
[strspn(s
, hex
)];
84 uint16_t shorts
[3] = { 0 };
91 for (n
= 0; n
< ELEMENTSOF(shorts
); n
++) {
92 ret
->ether_addr_octet
[2*n
] = ((shorts
[n
] & (uint16_t)0xff00) >> 8);
93 ret
->ether_addr_octet
[2*n
+ 1] = (shorts
[n
] & (uint16_t)0x00ff);
96 } else if (IN_SET(sep
, ':', '-')) {
97 struct ether_addr out
= ETHER_ADDR_NULL
;
99 parse_fields(out
.ether_addr_octet
);
104 for (n
= 0; n
< ELEMENTSOF(out
.ether_addr_octet
); n
++)
105 ret
->ether_addr_octet
[n
] = out
.ether_addr_octet
[n
];