Merge pull request #21276 from yuwata/ether-addr-util
ether-addr-util: introduce parse_hw_addr() and related conf parsers
This commit is contained in:
+151
-62
@@ -48,6 +48,7 @@ static void hw_addr_hash_func(const struct hw_addr_data *p, struct siphash *stat
|
||||
}
|
||||
|
||||
DEFINE_HASH_OPS(hw_addr_hash_ops, struct hw_addr_data, hw_addr_hash_func, hw_addr_compare);
|
||||
DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(hw_addr_hash_ops_free, struct hw_addr_data, hw_addr_hash_func, hw_addr_compare, free);
|
||||
|
||||
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
|
||||
assert(addr);
|
||||
@@ -93,75 +94,163 @@ static void ether_addr_hash_func(const struct ether_addr *p, struct siphash *sta
|
||||
}
|
||||
|
||||
DEFINE_HASH_OPS(ether_addr_hash_ops, struct ether_addr, ether_addr_hash_func, ether_addr_compare);
|
||||
DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(ether_addr_hash_ops_free, struct ether_addr, ether_addr_hash_func, ether_addr_compare, free);
|
||||
|
||||
int ether_addr_from_string(const char *s, struct ether_addr *ret) {
|
||||
size_t pos = 0, n, field;
|
||||
char sep = '\0';
|
||||
const char *hex = HEXDIGITS, *hexoff;
|
||||
size_t x;
|
||||
bool touched;
|
||||
static int parse_hw_addr_one_field(const char **s, char sep, size_t len, uint8_t *buf) {
|
||||
const char *hex = HEXDIGITS, *p;
|
||||
uint16_t data = 0;
|
||||
bool cont;
|
||||
|
||||
#define parse_fields(v) \
|
||||
for (field = 0; field < ELEMENTSOF(v); field++) { \
|
||||
touched = false; \
|
||||
for (n = 0; n < (2 * sizeof(v[0])); n++) { \
|
||||
if (s[pos] == '\0') \
|
||||
break; \
|
||||
hexoff = strchr(hex, s[pos]); \
|
||||
if (!hexoff) \
|
||||
break; \
|
||||
assert(hexoff >= hex); \
|
||||
x = hexoff - hex; \
|
||||
if (x >= 16) \
|
||||
x -= 6; /* A-F */ \
|
||||
assert(x < 16); \
|
||||
touched = true; \
|
||||
v[field] <<= 4; \
|
||||
v[field] += x; \
|
||||
pos++; \
|
||||
} \
|
||||
if (!touched) \
|
||||
return -EINVAL; \
|
||||
if (field < (ELEMENTSOF(v)-1)) { \
|
||||
if (s[pos] != sep) \
|
||||
return -EINVAL; \
|
||||
else \
|
||||
pos++; \
|
||||
} \
|
||||
assert(s);
|
||||
assert(*s);
|
||||
assert(IN_SET(len, 1, 2));
|
||||
assert(buf);
|
||||
|
||||
p = *s;
|
||||
|
||||
for (size_t i = 0; i < len * 2; i++) {
|
||||
const char *hexoff;
|
||||
size_t x;
|
||||
|
||||
if (*p == '\0' || *p == sep) {
|
||||
if (i == 0)
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
hexoff = strchr(hex, *p);
|
||||
if (!hexoff)
|
||||
return -EINVAL;
|
||||
|
||||
assert(hexoff >= hex);
|
||||
x = hexoff - hex;
|
||||
if (x >= 16)
|
||||
x -= 6; /* A-F */
|
||||
|
||||
assert(x < 16);
|
||||
data <<= 4;
|
||||
data += x;
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p != '\0' && *p != sep)
|
||||
return -EINVAL;
|
||||
|
||||
switch (len) {
|
||||
case 1:
|
||||
buf[0] = data;
|
||||
break;
|
||||
case 2:
|
||||
buf[0] = (data & 0xff00) >> 8;
|
||||
buf[1] = data & 0xff;
|
||||
break;
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
cont = *p == sep;
|
||||
*s = p + cont;
|
||||
return cont;
|
||||
}
|
||||
|
||||
int parse_hw_addr_full(const char *s, size_t expected_len, struct hw_addr_data *ret) {
|
||||
size_t field_size, max_len, len = 0;
|
||||
uint8_t bytes[HW_ADDR_MAX_SIZE];
|
||||
char sep;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
assert(expected_len <= HW_ADDR_MAX_SIZE || expected_len == SIZE_MAX);
|
||||
assert(ret);
|
||||
|
||||
/* This accepts the following formats:
|
||||
*
|
||||
* Dot separated 2 bytes format: xxyy.zzaa.bbcc
|
||||
* Colon separated 1 bytes format: xx:yy:zz:aa:bb:cc
|
||||
* Hyphen separated 1 bytes format: xx-yy-zz-aa-bb-cc
|
||||
*
|
||||
* Moreover, if expected_len == 0, 4, or 16, this also accepts:
|
||||
*
|
||||
* IPv4 format: used by IPv4 tunnel, e.g. ipgre
|
||||
* IPv6 format: used by IPv6 tunnel, e.g. ip6gre
|
||||
*
|
||||
* The expected_len argument controls the length of acceptable addresses:
|
||||
*
|
||||
* 0: accepts 4 (AF_INET), 16 (AF_INET6), 6 (ETH_ALEN), or 20 (INFINIBAND_ALEN).
|
||||
* SIZE_MAX: accepts arbitrary length, but at least one separator must be included.
|
||||
* Otherwise: accepts addresses with matching length.
|
||||
*/
|
||||
|
||||
if (IN_SET(expected_len, 0, sizeof(struct in_addr), sizeof(struct in6_addr))) {
|
||||
union in_addr_union a;
|
||||
int family;
|
||||
|
||||
if (expected_len == 0)
|
||||
r = in_addr_from_string_auto(s, &family, &a);
|
||||
else {
|
||||
family = expected_len == sizeof(struct in_addr) ? AF_INET : AF_INET6;
|
||||
r = in_addr_from_string(family, s, &a);
|
||||
}
|
||||
if (r >= 0) {
|
||||
ret->length = FAMILY_ADDRESS_SIZE(family);
|
||||
memcpy(ret->bytes, a.bytes, ret->length);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
max_len =
|
||||
expected_len == 0 ? INFINIBAND_ALEN :
|
||||
expected_len == SIZE_MAX ? HW_ADDR_MAX_SIZE : expected_len;
|
||||
sep = s[strspn(s, HEXDIGITS)];
|
||||
|
||||
if (sep == '.')
|
||||
field_size = 2;
|
||||
else if (IN_SET(sep, ':', '-'))
|
||||
field_size = 1;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
if (max_len % field_size != 0)
|
||||
return -EINVAL;
|
||||
|
||||
for (size_t i = 0; i < max_len / field_size; i++) {
|
||||
r = parse_hw_addr_one_field(&s, sep, field_size, bytes + i * field_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
len = (i + 1) * field_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (len == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (expected_len == 0) {
|
||||
if (!IN_SET(len, 4, 16, ETH_ALEN, INFINIBAND_ALEN))
|
||||
return -EINVAL;
|
||||
} else if (expected_len != SIZE_MAX) {
|
||||
if (len != expected_len)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret->length = len;
|
||||
memcpy(ret->bytes, bytes, ret->length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_ether_addr(const char *s, struct ether_addr *ret) {
|
||||
struct hw_addr_data a;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
assert(ret);
|
||||
|
||||
s += strspn(s, WHITESPACE);
|
||||
sep = s[strspn(s, hex)];
|
||||
|
||||
if (sep == '.') {
|
||||
uint16_t shorts[3] = { 0 };
|
||||
|
||||
parse_fields(shorts);
|
||||
|
||||
if (s[pos] != '\0')
|
||||
return -EINVAL;
|
||||
|
||||
for (n = 0; n < ELEMENTSOF(shorts); n++) {
|
||||
ret->ether_addr_octet[2*n] = ((shorts[n] & (uint16_t)0xff00) >> 8);
|
||||
ret->ether_addr_octet[2*n + 1] = (shorts[n] & (uint16_t)0x00ff);
|
||||
}
|
||||
|
||||
} else if (IN_SET(sep, ':', '-')) {
|
||||
struct ether_addr out = ETHER_ADDR_NULL;
|
||||
|
||||
parse_fields(out.ether_addr_octet);
|
||||
|
||||
if (s[pos] != '\0')
|
||||
return -EINVAL;
|
||||
|
||||
for (n = 0; n < ELEMENTSOF(out.ether_addr_octet); n++)
|
||||
ret->ether_addr_octet[n] = out.ether_addr_octet[n];
|
||||
|
||||
} else
|
||||
return -EINVAL;
|
||||
r = parse_hw_addr_full(s, ETH_ALEN, &a);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = a.ether;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "hash-funcs.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "macro.h"
|
||||
#include "memory-util.h"
|
||||
|
||||
@@ -18,10 +19,18 @@ struct hw_addr_data {
|
||||
union {
|
||||
struct ether_addr ether;
|
||||
uint8_t infiniband[INFINIBAND_ALEN];
|
||||
struct in_addr in;
|
||||
struct in6_addr in6;
|
||||
uint8_t bytes[HW_ADDR_MAX_SIZE];
|
||||
};
|
||||
};
|
||||
|
||||
int parse_hw_addr_full(const char *s, size_t expected_len, struct hw_addr_data *ret);
|
||||
static inline int parse_hw_addr(const char *s, struct hw_addr_data *ret) {
|
||||
return parse_hw_addr_full(s, 0, ret);
|
||||
}
|
||||
int parse_ether_addr(const char *s, struct ether_addr *ret);
|
||||
|
||||
#define HW_ADDR_TO_STRING_MAX (3*HW_ADDR_MAX_SIZE)
|
||||
char* hw_addr_to_string(const struct hw_addr_data *addr, char buffer[HW_ADDR_TO_STRING_MAX]);
|
||||
|
||||
@@ -42,6 +51,7 @@ static inline bool hw_addr_is_null(const struct hw_addr_data *addr) {
|
||||
}
|
||||
|
||||
extern const struct hash_ops hw_addr_hash_ops;
|
||||
extern const struct hash_ops hw_addr_hash_ops_free;
|
||||
|
||||
#define ETHER_ADDR_FORMAT_STR "%02X%02X%02X%02X%02X%02X"
|
||||
#define ETHER_ADDR_FORMAT_VAL(x) (x).ether_addr_octet[0], (x).ether_addr_octet[1], (x).ether_addr_octet[2], (x).ether_addr_octet[3], (x).ether_addr_octet[4], (x).ether_addr_octet[5]
|
||||
@@ -83,6 +93,5 @@ static inline bool ether_addr_is_local(const struct ether_addr *addr) {
|
||||
return !FLAGS_SET(addr->ether_addr_octet[0], 0x02);
|
||||
}
|
||||
|
||||
int ether_addr_from_string(const char *s, struct ether_addr *ret);
|
||||
|
||||
extern const struct hash_ops ether_addr_hash_ops;
|
||||
extern const struct hash_ops ether_addr_hash_ops_free;
|
||||
|
||||
@@ -353,7 +353,7 @@ static int network_set_mac_address(Context *context, const char *ifname, const c
|
||||
if (!network)
|
||||
return -ENODEV;
|
||||
|
||||
return ether_addr_from_string(mac, &network->mac);
|
||||
return parse_ether_addr(mac, &network->mac);
|
||||
}
|
||||
|
||||
static int network_set_address(Context *context, const char *ifname, int family, unsigned char prefixlen,
|
||||
@@ -909,7 +909,7 @@ static int parse_cmdline_ifname(Context *context, const char *key, const char *v
|
||||
|
||||
name = strndupa_safe(value, p - value);
|
||||
|
||||
r = ether_addr_from_string(p + 1, &mac);
|
||||
r = parse_ether_addr(p + 1, &mac);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -386,7 +386,7 @@ int config_parse_ad_actor_system(
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = ether_addr_from_string(rvalue, &n);
|
||||
r = parse_ether_addr(rvalue, &n);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Not a valid MAC address %s. Ignoring assignment: %m",
|
||||
|
||||
@@ -620,7 +620,7 @@ int config_parse_macsec_hw_address(
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = ether_addr_from_string(rvalue, b ? &b->sci.mac : &c->sci.mac);
|
||||
r = parse_ether_addr(rvalue, b ? &b->sci.mac : &c->sci.mac);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to parse MAC address for secure channel identifier. "
|
||||
|
||||
@@ -127,7 +127,7 @@ static void macvlan_done(NetDev *n) {
|
||||
|
||||
assert(m);
|
||||
|
||||
set_free_free(m->match_source_mac);
|
||||
set_free(m->match_source_mac);
|
||||
}
|
||||
|
||||
static void macvlan_init(NetDev *n) {
|
||||
|
||||
@@ -49,7 +49,7 @@ NetDev.Description, config_parse_string,
|
||||
NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname)
|
||||
NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)
|
||||
NetDev.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(NetDev, mtu)
|
||||
NetDev.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac)
|
||||
NetDev.MACAddress, config_parse_ether_addr, 0, offsetof(NetDev, mac)
|
||||
VLAN.Id, config_parse_vlanid, 0, offsetof(VLan, id)
|
||||
VLAN.Protocol, config_parse_vlanprotocol, 0, offsetof(VLan, protocol)
|
||||
VLAN.GVRP, config_parse_tristate, 0, offsetof(VLan, gvrp)
|
||||
@@ -59,10 +59,10 @@ VLAN.ReorderHeader, config_parse_tristate,
|
||||
VLAN.EgressQOSMaps, config_parse_vlan_qos_maps, 0, offsetof(VLan, egress_qos_maps)
|
||||
VLAN.IngressQOSMaps, config_parse_vlan_qos_maps, 0, offsetof(VLan, ingress_qos_maps)
|
||||
MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
|
||||
MACVLAN.SourceMACAddress, config_parse_hwaddrs, 0, offsetof(MacVlan, match_source_mac)
|
||||
MACVLAN.SourceMACAddress, config_parse_ether_addrs, 0, offsetof(MacVlan, match_source_mac)
|
||||
MACVLAN.BroadcastMulticastQueueLength, config_parse_macvlan_broadcast_queue_size, 0, offsetof(MacVlan, bc_queue_length)
|
||||
MACVTAP.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
|
||||
MACVTAP.SourceMACAddress, config_parse_hwaddrs, 0, offsetof(MacVlan, match_source_mac)
|
||||
MACVTAP.SourceMACAddress, config_parse_ether_addrs, 0, offsetof(MacVlan, match_source_mac)
|
||||
IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode)
|
||||
IPVLAN.Flags, config_parse_ipvlan_flags, 0, offsetof(IPVlan, flags)
|
||||
IPVTAP.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode)
|
||||
@@ -111,7 +111,7 @@ L2TPSession.PeerSessionId, config_parse_l2tp_session_id,
|
||||
L2TPSession.Layer2SpecificHeader, config_parse_l2tp_session_l2spec, 0, 0
|
||||
L2TPSession.Name, config_parse_l2tp_session_name, 0, 0
|
||||
Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer)
|
||||
Peer.MACAddress, config_parse_hwaddr, 0, offsetof(Veth, mac_peer)
|
||||
Peer.MACAddress, config_parse_ether_addr, 0, offsetof(Veth, mac_peer)
|
||||
VXCAN.Peer, config_parse_ifname, 0, offsetof(VxCan, ifname_peer)
|
||||
VXLAN.VNI, config_parse_uint32, 0, offsetof(VxLan, vni)
|
||||
VXLAN.Id, config_parse_uint32, 0, offsetof(VxLan, vni) /* deprecated */
|
||||
|
||||
@@ -286,7 +286,7 @@ int config_parse_fdb_hwaddr(
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = ether_addr_from_string(rvalue, &fdb->mac_addr);
|
||||
r = parse_ether_addr(rvalue, &fdb->mac_addr);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Not a valid MAC address, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
|
||||
@@ -184,7 +184,7 @@ int config_parse_dhcp_static_lease_hwaddr(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = ether_addr_from_string(rvalue, &hwaddr);
|
||||
r = parse_ether_addr(rvalue, &hwaddr);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to parse MAC address for DHCPv4 static lease, ignoring assignment: %s", rvalue);
|
||||
|
||||
@@ -680,7 +680,7 @@ int config_parse_neighbor_lladdr(
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = ether_addr_from_string(rvalue, &n->lladdr.mac);
|
||||
r = parse_ether_addr(rvalue, &n->lladdr.mac);
|
||||
if (r >= 0)
|
||||
n->lladdr_size = sizeof(n->lladdr.mac);
|
||||
else {
|
||||
@@ -725,7 +725,7 @@ int config_parse_neighbor_hwaddr(
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = ether_addr_from_string(rvalue, &n->lladdr.mac);
|
||||
r = parse_ether_addr(rvalue, &n->lladdr.mac);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Neighbor MACAddress= is invalid, ignoring assignment: %s", rvalue);
|
||||
|
||||
@@ -45,14 +45,14 @@ struct ConfigPerfItem;
|
||||
%struct-type
|
||||
%includes
|
||||
%%
|
||||
Match.MACAddress, config_parse_hwaddrs, 0, offsetof(Network, match.mac)
|
||||
Match.PermanentMACAddress, config_parse_hwaddrs, 0, offsetof(Network, match.permanent_mac)
|
||||
Match.MACAddress, config_parse_ether_addrs, 0, offsetof(Network, match.mac)
|
||||
Match.PermanentMACAddress, config_parse_ether_addrs, 0, offsetof(Network, match.permanent_mac)
|
||||
Match.Path, config_parse_match_strv, 0, offsetof(Network, match.path)
|
||||
Match.Driver, config_parse_match_strv, 0, offsetof(Network, match.driver)
|
||||
Match.Type, config_parse_match_strv, 0, offsetof(Network, match.iftype)
|
||||
Match.WLANInterfaceType, config_parse_match_strv, 0, offsetof(Network, match.wlan_iftype)
|
||||
Match.SSID, config_parse_match_strv, 0, offsetof(Network, match.ssid)
|
||||
Match.BSSID, config_parse_hwaddrs, 0, offsetof(Network, match.bssid)
|
||||
Match.BSSID, config_parse_ether_addrs, 0, offsetof(Network, match.bssid)
|
||||
Match.Name, config_parse_match_ifnames, IFNAME_VALID_ALTERNATIVE, offsetof(Network, match.ifname)
|
||||
Match.Property, config_parse_match_property, 0, offsetof(Network, match.property)
|
||||
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, conditions)
|
||||
@@ -61,7 +61,7 @@ Match.KernelCommandLine, config_parse_net_condition,
|
||||
Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(Network, conditions)
|
||||
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, conditions)
|
||||
Match.Firmware, config_parse_net_condition, CONDITION_FIRMWARE, offsetof(Network, conditions)
|
||||
Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac)
|
||||
Link.MACAddress, config_parse_ether_addr, 0, offsetof(Network, mac)
|
||||
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(Network, mtu)
|
||||
Link.Group, config_parse_link_group, 0, 0
|
||||
Link.ARP, config_parse_tristate, 0, offsetof(Network, arp)
|
||||
|
||||
@@ -523,7 +523,7 @@ int config_parse_sr_iov_mac(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = ether_addr_from_string(rvalue, &sr_iov->mac);
|
||||
r = parse_ether_addr(rvalue, &sr_iov->mac);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to parse SR-IOV '%s=', ignoring assignment: %s", lvalue, rvalue);
|
||||
|
||||
@@ -51,11 +51,11 @@ static void test_config_parse_duid_rawdata_one(const char *rvalue, int ret, cons
|
||||
}
|
||||
}
|
||||
|
||||
static void test_config_parse_hwaddr_one(const char *rvalue, int ret, const struct ether_addr* expected) {
|
||||
static void test_config_parse_ether_addr_one(const char *rvalue, int ret, const struct ether_addr* expected) {
|
||||
struct ether_addr *actual = NULL;
|
||||
int r;
|
||||
|
||||
r = config_parse_hwaddr("network", "filename", 1, "section", 1, "lvalue", 0, rvalue, &actual, NULL);
|
||||
r = config_parse_ether_addr("network", "filename", 1, "section", 1, "lvalue", 0, rvalue, &actual, NULL);
|
||||
assert_se(ret == r);
|
||||
if (expected) {
|
||||
assert_se(actual);
|
||||
@@ -66,10 +66,10 @@ static void test_config_parse_hwaddr_one(const char *rvalue, int ret, const stru
|
||||
free(actual);
|
||||
}
|
||||
|
||||
static void test_config_parse_hwaddrs_one(const char *rvalue, const struct ether_addr* list, size_t n) {
|
||||
static void test_config_parse_ether_addrs_one(const char *rvalue, const struct ether_addr* list, size_t n) {
|
||||
_cleanup_set_free_free_ Set *s = NULL;
|
||||
|
||||
assert_se(config_parse_hwaddrs("network", "filename", 1, "section", 1, "lvalue", 0, rvalue, &s, NULL) == 0);
|
||||
assert_se(config_parse_ether_addrs("network", "filename", 1, "section", 1, "lvalue", 0, rvalue, &s, NULL) == 0);
|
||||
assert_se(set_size(s) == n);
|
||||
|
||||
for (size_t m = 0; m < n; m++) {
|
||||
@@ -101,68 +101,68 @@ static void test_config_parse_duid_rawdata(void) {
|
||||
test_config_parse_duid_rawdata_one(&BYTES_0_128[2], 0, &(DUID){0, 128, BYTES_1_128});
|
||||
}
|
||||
|
||||
static void test_config_parse_hwaddr(void) {
|
||||
static void test_config_parse_ether_addr(void) {
|
||||
const struct ether_addr t[] = {
|
||||
{ .ether_addr_octet = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff } },
|
||||
{ .ether_addr_octet = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab } },
|
||||
};
|
||||
|
||||
test_config_parse_hwaddr_one("", 0, NULL);
|
||||
test_config_parse_hwaddr_one("no:ta:ma:ca:dd:re", 0, NULL);
|
||||
test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:fx", 0, NULL);
|
||||
test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:ff", 0, &t[0]);
|
||||
test_config_parse_hwaddr_one(" aa:bb:cc:dd:ee:ff", 0, &t[0]);
|
||||
test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:ff \t\n", 0, NULL);
|
||||
test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:ff \t\nxxx", 0, NULL);
|
||||
test_config_parse_hwaddr_one("aa:bb:cc: dd:ee:ff", 0, NULL);
|
||||
test_config_parse_hwaddr_one("aa:bb:cc:d d:ee:ff", 0, NULL);
|
||||
test_config_parse_hwaddr_one("aa:bb:cc:dd:ee", 0, NULL);
|
||||
test_config_parse_hwaddr_one("9:aa:bb:cc:dd:ee:ff", 0, NULL);
|
||||
test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:ff:gg", 0, NULL);
|
||||
test_config_parse_hwaddr_one("aa:Bb:CC:dd:ee:ff", 0, &t[0]);
|
||||
test_config_parse_hwaddr_one("01:23:45:67:89:aB", 0, &t[1]);
|
||||
test_config_parse_hwaddr_one("1:23:45:67:89:aB", 0, &t[1]);
|
||||
test_config_parse_hwaddr_one("aa-bb-cc-dd-ee-ff", 0, &t[0]);
|
||||
test_config_parse_hwaddr_one("AA-BB-CC-DD-EE-FF", 0, &t[0]);
|
||||
test_config_parse_hwaddr_one("01-23-45-67-89-ab", 0, &t[1]);
|
||||
test_config_parse_hwaddr_one("aabb.ccdd.eeff", 0, &t[0]);
|
||||
test_config_parse_hwaddr_one("0123.4567.89ab", 0, &t[1]);
|
||||
test_config_parse_hwaddr_one("123.4567.89ab.", 0, NULL);
|
||||
test_config_parse_hwaddr_one("aabbcc.ddeeff", 0, NULL);
|
||||
test_config_parse_hwaddr_one("aabbccddeeff", 0, NULL);
|
||||
test_config_parse_hwaddr_one("aabbccddee:ff", 0, NULL);
|
||||
test_config_parse_hwaddr_one("012345.6789ab", 0, NULL);
|
||||
test_config_parse_hwaddr_one("123.4567.89ab", 0, &t[1]);
|
||||
test_config_parse_ether_addr_one("", 0, NULL);
|
||||
test_config_parse_ether_addr_one("no:ta:ma:ca:dd:re", 0, NULL);
|
||||
test_config_parse_ether_addr_one("aa:bb:cc:dd:ee:fx", 0, NULL);
|
||||
test_config_parse_ether_addr_one("aa:bb:cc:dd:ee:ff", 0, &t[0]);
|
||||
test_config_parse_ether_addr_one(" aa:bb:cc:dd:ee:ff", 0, NULL);
|
||||
test_config_parse_ether_addr_one("aa:bb:cc:dd:ee:ff \t\n", 0, NULL);
|
||||
test_config_parse_ether_addr_one("aa:bb:cc:dd:ee:ff \t\nxxx", 0, NULL);
|
||||
test_config_parse_ether_addr_one("aa:bb:cc: dd:ee:ff", 0, NULL);
|
||||
test_config_parse_ether_addr_one("aa:bb:cc:d d:ee:ff", 0, NULL);
|
||||
test_config_parse_ether_addr_one("aa:bb:cc:dd:ee", 0, NULL);
|
||||
test_config_parse_ether_addr_one("9:aa:bb:cc:dd:ee:ff", 0, NULL);
|
||||
test_config_parse_ether_addr_one("aa:bb:cc:dd:ee:ff:gg", 0, NULL);
|
||||
test_config_parse_ether_addr_one("aa:Bb:CC:dd:ee:ff", 0, &t[0]);
|
||||
test_config_parse_ether_addr_one("01:23:45:67:89:aB", 0, &t[1]);
|
||||
test_config_parse_ether_addr_one("1:23:45:67:89:aB", 0, &t[1]);
|
||||
test_config_parse_ether_addr_one("aa-bb-cc-dd-ee-ff", 0, &t[0]);
|
||||
test_config_parse_ether_addr_one("AA-BB-CC-DD-EE-FF", 0, &t[0]);
|
||||
test_config_parse_ether_addr_one("01-23-45-67-89-ab", 0, &t[1]);
|
||||
test_config_parse_ether_addr_one("aabb.ccdd.eeff", 0, &t[0]);
|
||||
test_config_parse_ether_addr_one("0123.4567.89ab", 0, &t[1]);
|
||||
test_config_parse_ether_addr_one("123.4567.89ab.", 0, NULL);
|
||||
test_config_parse_ether_addr_one("aabbcc.ddeeff", 0, NULL);
|
||||
test_config_parse_ether_addr_one("aabbccddeeff", 0, NULL);
|
||||
test_config_parse_ether_addr_one("aabbccddee:ff", 0, NULL);
|
||||
test_config_parse_ether_addr_one("012345.6789ab", 0, NULL);
|
||||
test_config_parse_ether_addr_one("123.4567.89ab", 0, &t[1]);
|
||||
|
||||
test_config_parse_hwaddrs_one("", t, 0);
|
||||
test_config_parse_hwaddrs_one("no:ta:ma:ca:dd:re", t, 0);
|
||||
test_config_parse_hwaddrs_one("aa:bb:cc:dd:ee:fx", t, 0);
|
||||
test_config_parse_hwaddrs_one("aa:bb:cc:dd:ee:ff", t, 1);
|
||||
test_config_parse_hwaddrs_one(" aa:bb:cc:dd:ee:ff", t, 1);
|
||||
test_config_parse_hwaddrs_one("aa:bb:cc:dd:ee:ff \t\n", t, 1);
|
||||
test_config_parse_hwaddrs_one("aa:bb:cc:dd:ee:ff \t\nxxx", t, 1);
|
||||
test_config_parse_hwaddrs_one("aa:bb:cc: dd:ee:ff", t, 0);
|
||||
test_config_parse_hwaddrs_one("aa:bb:cc:d d:ee:ff", t, 0);
|
||||
test_config_parse_hwaddrs_one("aa:bb:cc:dd:ee", t, 0);
|
||||
test_config_parse_hwaddrs_one("9:aa:bb:cc:dd:ee:ff", t, 0);
|
||||
test_config_parse_hwaddrs_one("aa:bb:cc:dd:ee:ff:gg", t, 0);
|
||||
test_config_parse_hwaddrs_one("aa:Bb:CC:dd:ee:ff", t, 1);
|
||||
test_config_parse_hwaddrs_one("01:23:45:67:89:aB", &t[1], 1);
|
||||
test_config_parse_hwaddrs_one("1:23:45:67:89:aB", &t[1], 1);
|
||||
test_config_parse_hwaddrs_one("aa-bb-cc-dd-ee-ff", t, 1);
|
||||
test_config_parse_hwaddrs_one("AA-BB-CC-DD-EE-FF", t, 1);
|
||||
test_config_parse_hwaddrs_one("01-23-45-67-89-ab", &t[1], 1);
|
||||
test_config_parse_hwaddrs_one("aabb.ccdd.eeff", t, 1);
|
||||
test_config_parse_hwaddrs_one("0123.4567.89ab", &t[1], 1);
|
||||
test_config_parse_hwaddrs_one("123.4567.89ab.", t, 0);
|
||||
test_config_parse_hwaddrs_one("aabbcc.ddeeff", t, 0);
|
||||
test_config_parse_hwaddrs_one("aabbccddeeff", t, 0);
|
||||
test_config_parse_hwaddrs_one("aabbccddee:ff", t, 0);
|
||||
test_config_parse_hwaddrs_one("012345.6789ab", t, 0);
|
||||
test_config_parse_hwaddrs_one("123.4567.89ab", &t[1], 1);
|
||||
test_config_parse_ether_addrs_one("", t, 0);
|
||||
test_config_parse_ether_addrs_one("no:ta:ma:ca:dd:re", t, 0);
|
||||
test_config_parse_ether_addrs_one("aa:bb:cc:dd:ee:fx", t, 0);
|
||||
test_config_parse_ether_addrs_one("aa:bb:cc:dd:ee:ff", t, 1);
|
||||
test_config_parse_ether_addrs_one(" aa:bb:cc:dd:ee:ff", t, 1);
|
||||
test_config_parse_ether_addrs_one("aa:bb:cc:dd:ee:ff \t\n", t, 1);
|
||||
test_config_parse_ether_addrs_one("aa:bb:cc:dd:ee:ff \t\nxxx", t, 1);
|
||||
test_config_parse_ether_addrs_one("aa:bb:cc: dd:ee:ff", t, 0);
|
||||
test_config_parse_ether_addrs_one("aa:bb:cc:d d:ee:ff", t, 0);
|
||||
test_config_parse_ether_addrs_one("aa:bb:cc:dd:ee", t, 0);
|
||||
test_config_parse_ether_addrs_one("9:aa:bb:cc:dd:ee:ff", t, 0);
|
||||
test_config_parse_ether_addrs_one("aa:bb:cc:dd:ee:ff:gg", t, 0);
|
||||
test_config_parse_ether_addrs_one("aa:Bb:CC:dd:ee:ff", t, 1);
|
||||
test_config_parse_ether_addrs_one("01:23:45:67:89:aB", &t[1], 1);
|
||||
test_config_parse_ether_addrs_one("1:23:45:67:89:aB", &t[1], 1);
|
||||
test_config_parse_ether_addrs_one("aa-bb-cc-dd-ee-ff", t, 1);
|
||||
test_config_parse_ether_addrs_one("AA-BB-CC-DD-EE-FF", t, 1);
|
||||
test_config_parse_ether_addrs_one("01-23-45-67-89-ab", &t[1], 1);
|
||||
test_config_parse_ether_addrs_one("aabb.ccdd.eeff", t, 1);
|
||||
test_config_parse_ether_addrs_one("0123.4567.89ab", &t[1], 1);
|
||||
test_config_parse_ether_addrs_one("123.4567.89ab.", t, 0);
|
||||
test_config_parse_ether_addrs_one("aabbcc.ddeeff", t, 0);
|
||||
test_config_parse_ether_addrs_one("aabbccddeeff", t, 0);
|
||||
test_config_parse_ether_addrs_one("aabbccddee:ff", t, 0);
|
||||
test_config_parse_ether_addrs_one("012345.6789ab", t, 0);
|
||||
test_config_parse_ether_addrs_one("123.4567.89ab", &t[1], 1);
|
||||
|
||||
test_config_parse_hwaddrs_one("123.4567.89ab aa:bb:cc:dd:ee:ff 01-23-45-67-89-ab aa:Bb:CC:dd:ee:ff", t, 2);
|
||||
test_config_parse_hwaddrs_one("123.4567.89ab aa:bb:cc:dd:ee:fx hogehoge 01-23-45-67-89-ab aaaa aa:Bb:CC:dd:ee:ff", t, 2);
|
||||
test_config_parse_ether_addrs_one("123.4567.89ab aa:bb:cc:dd:ee:ff 01-23-45-67-89-ab aa:Bb:CC:dd:ee:ff", t, 2);
|
||||
test_config_parse_ether_addrs_one("123.4567.89ab aa:bb:cc:dd:ee:fx hogehoge 01-23-45-67-89-ab aaaa aa:Bb:CC:dd:ee:ff", t, 2);
|
||||
}
|
||||
|
||||
static void test_config_parse_address_one(const char *rvalue, int family, unsigned n_addresses, const union in_addr_union *u, unsigned char prefixlen) {
|
||||
@@ -248,7 +248,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
test_config_parse_duid_type();
|
||||
test_config_parse_duid_rawdata();
|
||||
test_config_parse_hwaddr();
|
||||
test_config_parse_ether_addr();
|
||||
test_config_parse_address();
|
||||
test_config_parse_match_ifnames();
|
||||
test_config_parse_match_strv();
|
||||
|
||||
+100
-8
@@ -1320,7 +1320,101 @@ int config_parse_vlanprotocol(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_hwaddr(
|
||||
int config_parse_hw_addr(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
struct hw_addr_data a, *hwaddr = data;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
*hwaddr = HW_ADDR_NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_hw_addr_full(rvalue, ltype, &a);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Not a valid hardware address, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*hwaddr = a;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_hw_addrs(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
Set **hwaddrs = data;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
/* Empty assignment resets the list */
|
||||
*hwaddrs = set_free(*hwaddrs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (const char *p = rvalue;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
_cleanup_free_ struct hw_addr_data *n = NULL;
|
||||
|
||||
r = extract_first_word(&p, &word, NULL, 0);
|
||||
if (r == 0)
|
||||
return 0;
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid syntax, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = new(struct hw_addr_data, 1);
|
||||
if (!n)
|
||||
return log_oom();
|
||||
|
||||
r = parse_hw_addr_full(word, ltype, n);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Not a valid hardware address, ignoring: %s", word);
|
||||
continue;
|
||||
}
|
||||
|
||||
r = set_ensure_consume(hwaddrs, &hw_addr_hash_ops_free, TAKE_PTR(n));
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
}
|
||||
|
||||
int config_parse_ether_addr(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
@@ -1350,7 +1444,7 @@ int config_parse_hwaddr(
|
||||
if (!n)
|
||||
return log_oom();
|
||||
|
||||
r = ether_addr_from_string(rvalue, n);
|
||||
r = parse_ether_addr(rvalue, n);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Not a valid MAC address, ignoring assignment: %s", rvalue);
|
||||
@@ -1362,7 +1456,7 @@ int config_parse_hwaddr(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_hwaddrs(
|
||||
int config_parse_ether_addrs(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
@@ -1384,7 +1478,7 @@ int config_parse_hwaddrs(
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
/* Empty assignment resets the list */
|
||||
*hwaddrs = set_free_free(*hwaddrs);
|
||||
*hwaddrs = set_free(*hwaddrs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1407,18 +1501,16 @@ int config_parse_hwaddrs(
|
||||
if (!n)
|
||||
return log_oom();
|
||||
|
||||
r = ether_addr_from_string(word, n);
|
||||
r = parse_ether_addr(word, n);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Not a valid MAC address, ignoring: %s", word);
|
||||
continue;
|
||||
}
|
||||
|
||||
r = set_ensure_put(hwaddrs, ðer_addr_hash_ops, n);
|
||||
r = set_ensure_consume(hwaddrs, ðer_addr_hash_ops_free, TAKE_PTR(n));
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
if (r > 0)
|
||||
TAKE_PTR(n); /* avoid cleanup */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -149,8 +149,10 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ip_port);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_mtu);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_rlimit);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_vlanprotocol);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddrs);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_hw_addr);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_hw_addrs);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_ether_addr);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_ether_addrs);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_in_addr_non_null);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_percent);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_permyriad);
|
||||
|
||||
@@ -17,8 +17,8 @@ void net_match_clear(NetMatch *match) {
|
||||
if (!match)
|
||||
return;
|
||||
|
||||
match->mac = set_free_free(match->mac);
|
||||
match->permanent_mac = set_free_free(match->permanent_mac);
|
||||
match->mac = set_free(match->mac);
|
||||
match->permanent_mac = set_free(match->permanent_mac);
|
||||
match->path = strv_free(match->path);
|
||||
match->driver = strv_free(match->driver);
|
||||
match->iftype = strv_free(match->iftype);
|
||||
@@ -26,7 +26,7 @@ void net_match_clear(NetMatch *match) {
|
||||
match->property = strv_free(match->property);
|
||||
match->wlan_iftype = strv_free(match->wlan_iftype);
|
||||
match->ssid = strv_free(match->ssid);
|
||||
match->bssid = set_free_free(match->bssid);
|
||||
match->bssid = set_free(match->bssid);
|
||||
}
|
||||
|
||||
bool net_match_is_empty(const NetMatch *match) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "ether-addr-util.h"
|
||||
#include "string-util.h"
|
||||
#include "tests.h"
|
||||
|
||||
#define INFINIBAD_ADDR_1 ((const struct hw_addr_data){ .length = 20, .infiniband = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20} })
|
||||
@@ -34,9 +35,110 @@ static void test_HW_ADDR_TO_STRING(void) {
|
||||
log_info("joint: %s, %s", s, p);
|
||||
}
|
||||
|
||||
static void test_parse_hw_addr_full_one(const char *in, size_t expected_len, const char *expected) {
|
||||
struct hw_addr_data h;
|
||||
int r;
|
||||
|
||||
r = parse_hw_addr_full(in, expected_len, &h);
|
||||
log_debug_errno(r, "parse_hw_addr(\"%s\", len=%zu) → \"%s\" (expected: \"%s\") : %d/%m",
|
||||
in, expected_len, r >= 0 ? HW_ADDR_TO_STR(&h) : "n/a", strna(expected), r);
|
||||
assert_se((r >= 0) == !!expected);
|
||||
if (r >= 0) {
|
||||
if (!IN_SET(expected_len, 0, SIZE_MAX))
|
||||
assert_se(h.length == expected_len);
|
||||
assert_se(streq(HW_ADDR_TO_STR(&h), expected));
|
||||
}
|
||||
}
|
||||
|
||||
static void test_parse_hw_addr(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
/* IPv4 */
|
||||
test_parse_hw_addr_full_one("10.0.0.1", 0, "0a:00:00:01");
|
||||
test_parse_hw_addr_full_one("10.0.0.1", 4, "0a:00:00:01");
|
||||
test_parse_hw_addr_full_one("192.168.0.1", 0, "c0:a8:00:01");
|
||||
test_parse_hw_addr_full_one("192.168.0.1", 4, "c0:a8:00:01");
|
||||
/* IPv6 */
|
||||
test_parse_hw_addr_full_one("::", 0, "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00");
|
||||
test_parse_hw_addr_full_one("::", 16, "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00");
|
||||
test_parse_hw_addr_full_one("::1", 0, "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:01");
|
||||
test_parse_hw_addr_full_one("::1", 16, "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:01");
|
||||
test_parse_hw_addr_full_one("1234::", 0, "12:34:00:00:00:00:00:00:00:00:00:00:00:00:00:00");
|
||||
test_parse_hw_addr_full_one("1234::", 16, "12:34:00:00:00:00:00:00:00:00:00:00:00:00:00:00");
|
||||
test_parse_hw_addr_full_one("12:34::56", 0, "00:12:00:34:00:00:00:00:00:00:00:00:00:00:00:56");
|
||||
test_parse_hw_addr_full_one("12:34::56", 16, "00:12:00:34:00:00:00:00:00:00:00:00:00:00:00:56");
|
||||
test_parse_hw_addr_full_one("12aa:34::56", 0, "12:aa:00:34:00:00:00:00:00:00:00:00:00:00:00:56");
|
||||
test_parse_hw_addr_full_one("12aa:34::56", 16, "12:aa:00:34:00:00:00:00:00:00:00:00:00:00:00:56");
|
||||
test_parse_hw_addr_full_one("1234:5678:90ab:cdef:1234:5678:90ab:cdef", 0, "12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef");
|
||||
test_parse_hw_addr_full_one("1234:5678:90ab:cdef:1234:5678:90ab:cdef", 16, "12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef");
|
||||
/* Dot */
|
||||
test_parse_hw_addr_full_one("12.34", 0, "00:12:00:34");
|
||||
test_parse_hw_addr_full_one("12.34", 4, "00:12:00:34");
|
||||
test_parse_hw_addr_full_one("12.34", SIZE_MAX, "00:12:00:34");
|
||||
test_parse_hw_addr_full_one("12.34.56", 0, "00:12:00:34:00:56");
|
||||
test_parse_hw_addr_full_one("12.34.56", 6, "00:12:00:34:00:56");
|
||||
test_parse_hw_addr_full_one("12.34.56", SIZE_MAX, "00:12:00:34:00:56");
|
||||
test_parse_hw_addr_full_one("12.34.56.78", 0, "0c:22:38:4e"); /* IPv4 address */
|
||||
test_parse_hw_addr_full_one("12.34.56.78", 4, "0c:22:38:4e"); /* IPv4 address */
|
||||
test_parse_hw_addr_full_one("12.34.56.78", 8, "00:12:00:34:00:56:00:78");
|
||||
test_parse_hw_addr_full_one("12.34.56.78", SIZE_MAX, "00:12:00:34:00:56:00:78");
|
||||
test_parse_hw_addr_full_one("12.34.56.78.90", 0, NULL);
|
||||
test_parse_hw_addr_full_one("12.34.56.78.90", 10, "00:12:00:34:00:56:00:78:00:90");
|
||||
test_parse_hw_addr_full_one("12.34.56.78.90", SIZE_MAX, "00:12:00:34:00:56:00:78:00:90");
|
||||
test_parse_hw_addr_full_one("aabb.ccdd", 0, "aa:bb:cc:dd");
|
||||
test_parse_hw_addr_full_one("aabb.ccdd", 4, "aa:bb:cc:dd");
|
||||
test_parse_hw_addr_full_one("aabb.ccdd", SIZE_MAX, "aa:bb:cc:dd");
|
||||
test_parse_hw_addr_full_one("aabb.ccdd.eeff", 0, "aa:bb:cc:dd:ee:ff");
|
||||
test_parse_hw_addr_full_one("aabb.ccdd.eeff", 6, "aa:bb:cc:dd:ee:ff");
|
||||
test_parse_hw_addr_full_one("aabb.ccdd.eeff", SIZE_MAX, "aa:bb:cc:dd:ee:ff");
|
||||
/* Colon */
|
||||
test_parse_hw_addr_full_one("12:34", 0, NULL);
|
||||
test_parse_hw_addr_full_one("12:34", 2, "12:34");
|
||||
test_parse_hw_addr_full_one("12:34", SIZE_MAX, "12:34");
|
||||
test_parse_hw_addr_full_one("12:34:56:78:90:ab", 0, "12:34:56:78:90:ab");
|
||||
test_parse_hw_addr_full_one("12:34:56:78:90:ab", 6, "12:34:56:78:90:ab");
|
||||
test_parse_hw_addr_full_one("12:34:56:78:90:ab", SIZE_MAX, "12:34:56:78:90:ab");
|
||||
test_parse_hw_addr_full_one("12:34:56:78:90:ab:cd:ef", 0, "00:12:00:34:00:56:00:78:00:90:00:ab:00:cd:00:ef"); /* IPv6 */
|
||||
test_parse_hw_addr_full_one("12:34:56:78:90:ab:cd:ef", 8, "12:34:56:78:90:ab:cd:ef");
|
||||
test_parse_hw_addr_full_one("12:34:56:78:90:ab:cd:ef", 16, "00:12:00:34:00:56:00:78:00:90:00:ab:00:cd:00:ef"); /* IPv6 */
|
||||
test_parse_hw_addr_full_one("12:34:56:78:90:ab:cd:ef", SIZE_MAX, "12:34:56:78:90:ab:cd:ef");
|
||||
test_parse_hw_addr_full_one("12:34:56:78:90:AB:CD:EF", 0, "00:12:00:34:00:56:00:78:00:90:00:ab:00:cd:00:ef"); /* IPv6 */
|
||||
test_parse_hw_addr_full_one("12:34:56:78:90:AB:CD:EF", 8, "12:34:56:78:90:ab:cd:ef");
|
||||
test_parse_hw_addr_full_one("12:34:56:78:90:AB:CD:EF", 16, "00:12:00:34:00:56:00:78:00:90:00:ab:00:cd:00:ef"); /* IPv6 */
|
||||
test_parse_hw_addr_full_one("12:34:56:78:90:AB:CD:EF", SIZE_MAX, "12:34:56:78:90:ab:cd:ef");
|
||||
/* Hyphen */
|
||||
test_parse_hw_addr_full_one("12-34", 0, NULL);
|
||||
test_parse_hw_addr_full_one("12-34", 2, "12:34");
|
||||
test_parse_hw_addr_full_one("12-34", SIZE_MAX, "12:34");
|
||||
test_parse_hw_addr_full_one("12-34-56-78-90-ab-cd-ef", 0, NULL);
|
||||
test_parse_hw_addr_full_one("12-34-56-78-90-ab-cd-ef", 8, "12:34:56:78:90:ab:cd:ef");
|
||||
test_parse_hw_addr_full_one("12-34-56-78-90-ab-cd-ef", SIZE_MAX, "12:34:56:78:90:ab:cd:ef");
|
||||
test_parse_hw_addr_full_one("12-34-56-78-90-AB-CD-EF", 0, NULL);
|
||||
test_parse_hw_addr_full_one("12-34-56-78-90-AB-CD-EF", 8, "12:34:56:78:90:ab:cd:ef");
|
||||
test_parse_hw_addr_full_one("12-34-56-78-90-AB-CD-EF", SIZE_MAX, "12:34:56:78:90:ab:cd:ef");
|
||||
|
||||
/* Invalid */
|
||||
test_parse_hw_addr_full_one("", SIZE_MAX, NULL);
|
||||
test_parse_hw_addr_full_one("12", SIZE_MAX, NULL);
|
||||
test_parse_hw_addr_full_one("12.", SIZE_MAX, NULL);
|
||||
test_parse_hw_addr_full_one("12.34.", SIZE_MAX, NULL);
|
||||
test_parse_hw_addr_full_one(".12", SIZE_MAX, NULL);
|
||||
test_parse_hw_addr_full_one(".12.34", SIZE_MAX, NULL);
|
||||
test_parse_hw_addr_full_one("12.34:56", SIZE_MAX, NULL);
|
||||
test_parse_hw_addr_full_one("1234:56", SIZE_MAX, NULL);
|
||||
test_parse_hw_addr_full_one("1234:56", SIZE_MAX, NULL);
|
||||
test_parse_hw_addr_full_one("12:34:", SIZE_MAX, NULL);
|
||||
test_parse_hw_addr_full_one(":12:34", SIZE_MAX, NULL);
|
||||
test_parse_hw_addr_full_one("::1", SIZE_MAX, NULL);
|
||||
test_parse_hw_addr_full_one("aa:bb-cc", SIZE_MAX, NULL);
|
||||
test_parse_hw_addr_full_one("aa:xx", SIZE_MAX, NULL);
|
||||
test_parse_hw_addr_full_one("aa bb", SIZE_MAX, NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_setup_logging(LOG_INFO);
|
||||
|
||||
test_HW_ADDR_TO_STRING();
|
||||
test_parse_hw_addr();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ struct ConfigPerfItem;
|
||||
%struct-type
|
||||
%includes
|
||||
%%
|
||||
Match.MACAddress, config_parse_hwaddrs, 0, offsetof(LinkConfig, match.mac)
|
||||
Match.PermanentMACAddress, config_parse_hwaddrs, 0, offsetof(LinkConfig, match.permanent_mac)
|
||||
Match.MACAddress, config_parse_ether_addrs, 0, offsetof(LinkConfig, match.mac)
|
||||
Match.PermanentMACAddress, config_parse_ether_addrs, 0, offsetof(LinkConfig, match.permanent_mac)
|
||||
Match.OriginalName, config_parse_match_ifnames, 0, offsetof(LinkConfig, match.ifname)
|
||||
Match.Path, config_parse_match_strv, 0, offsetof(LinkConfig, match.path)
|
||||
Match.Driver, config_parse_match_strv, 0, offsetof(LinkConfig, match.driver)
|
||||
@@ -35,7 +35,7 @@ Match.KernelVersion, config_parse_net_condition,
|
||||
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(LinkConfig, conditions)
|
||||
Link.Description, config_parse_string, 0, offsetof(LinkConfig, description)
|
||||
Link.MACAddressPolicy, config_parse_mac_address_policy, 0, offsetof(LinkConfig, mac_address_policy)
|
||||
Link.MACAddress, config_parse_hwaddr, 0, offsetof(LinkConfig, mac)
|
||||
Link.MACAddress, config_parse_ether_addr, 0, offsetof(LinkConfig, mac)
|
||||
Link.NamePolicy, config_parse_name_policy, 0, offsetof(LinkConfig, name_policy)
|
||||
Link.Name, config_parse_ifname, 0, offsetof(LinkConfig, name)
|
||||
Link.AlternativeName, config_parse_ifnames, IFNAME_VALID_ALTERNATIVE, offsetof(LinkConfig, alternative_names)
|
||||
|
||||
@@ -118,8 +118,8 @@ static int link_parse_wol_password(LinkConfig *link, const char *str) {
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Reuse ether_addr_from_string(), as their formats are equivalent. */
|
||||
r = ether_addr_from_string(str, (struct ether_addr*) p);
|
||||
/* Reuse parse_ether_addr(), as their formats are equivalent. */
|
||||
r = parse_ether_addr(str, (struct ether_addr*) p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user