#include <netinet/ether.h>
#include <string.h>
+#include <sys/random.h>
+
+#include "logging.h"
typedef struct ether_addr nw_address_t;
return strdup(buffer);
}
+static inline int nw_address_generate(nw_address_t* addr) {
+ ssize_t bytes = getrandom(addr, sizeof(*addr), 0);
+ if (bytes < 0) {
+ ERROR("getrandom() failed: %m\n");
+ return 1;
+ }
+
+ // Check if we filled the entire buffer
+ if (bytes < (ssize_t)sizeof(*addr)) {
+ ERROR("Could not gather enough randomness\n");
+ return 1;
+ }
+
+ // Clear the multicast bit
+ addr->ether_addr_octet[0] &= 0xfe;
+
+ // Set the software-generated bit
+ addr->ether_addr_octet[1] |= 0x02;
+
+ return 0;
+}
+
#endif /* NETWORKD_ADDRESS_H */
const char* s = nw_config_get(port->config, "ADDRESS");
if (!s) {
ERROR("Port %s: Address isn't set\n", port->name);
- return 1;
+ goto ERROR;
}
// Parse the address
r = nw_address_from_string(&port->address, s);
if (r) {
ERROR("Port %s: Could not parse address: %m\n", port->name);
- return r;
+ goto ERROR;
}
// XXX Do we need to check for multicast here?
+ return 0;
+
+ERROR:
+ // Generate a random Ethernet address
+ r = nw_address_generate(&port->address);
+ if (r) {
+ ERROR("Could not generate a random Ethernet address: %m\n");
+ return r;
+ }
+
return 0;
}