int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) { sd_id128_t machine_id; int r; assert(duid); assert(len); r = sd_id128_get_machine(&machine_id); if (r < 0) return r; unaligned_write_be16(&duid->type, DHCP6_DUID_EN); unaligned_write_be32(&duid->en.pen, SYSTEMD_PEN); *len = sizeof(duid->type) + sizeof(duid->en); /* a bit of snake-oil perhaps, but no need to expose the machine-id directly */ siphash24(duid->en.id, &machine_id, sizeof(machine_id), HASH_KEY.bytes); return 0; }
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) { sd_id128_t machine_id; uint64_t hash; int r; assert(duid); assert(len); r = sd_id128_get_machine(&machine_id); if (r < 0) return r; unaligned_write_be16(&duid->type, DUID_TYPE_EN); unaligned_write_be32(&duid->en.pen, SYSTEMD_PEN); *len = sizeof(duid->type) + sizeof(duid->en); /* a bit of snake-oil perhaps, but no need to expose the machine-id directly; duid->en.id might not be aligned, so we need to copy */ hash = htole64(siphash24(&machine_id, sizeof(machine_id), HASH_KEY.bytes)); memcpy(duid->en.id, &hash, sizeof(duid->en.id)); return 0; }
static void test_be(void) { uint8_t scratch[16]; assert_se(unaligned_read_be16(&data[0]) == 0x0001); assert_se(unaligned_read_be16(&data[1]) == 0x0102); assert_se(unaligned_read_be32(&data[0]) == 0x00010203); assert_se(unaligned_read_be32(&data[1]) == 0x01020304); assert_se(unaligned_read_be32(&data[2]) == 0x02030405); assert_se(unaligned_read_be32(&data[3]) == 0x03040506); assert_se(unaligned_read_be64(&data[0]) == 0x0001020304050607); assert_se(unaligned_read_be64(&data[1]) == 0x0102030405060708); assert_se(unaligned_read_be64(&data[2]) == 0x0203040506070809); assert_se(unaligned_read_be64(&data[3]) == 0x030405060708090a); assert_se(unaligned_read_be64(&data[4]) == 0x0405060708090a0b); assert_se(unaligned_read_be64(&data[5]) == 0x05060708090a0b0c); assert_se(unaligned_read_be64(&data[6]) == 0x060708090a0b0c0d); assert_se(unaligned_read_be64(&data[7]) == 0x0708090a0b0c0d0e); zero(scratch); unaligned_write_be16(&scratch[0], 0x0001); assert_se(memcmp(&scratch[0], &data[0], sizeof(uint16_t)) == 0); zero(scratch); unaligned_write_be16(&scratch[1], 0x0102); assert_se(memcmp(&scratch[1], &data[1], sizeof(uint16_t)) == 0); zero(scratch); unaligned_write_be32(&scratch[0], 0x00010203); assert_se(memcmp(&scratch[0], &data[0], sizeof(uint32_t)) == 0); zero(scratch); unaligned_write_be32(&scratch[1], 0x01020304); assert_se(memcmp(&scratch[1], &data[1], sizeof(uint32_t)) == 0); zero(scratch); unaligned_write_be32(&scratch[2], 0x02030405); assert_se(memcmp(&scratch[2], &data[2], sizeof(uint32_t)) == 0); zero(scratch); unaligned_write_be32(&scratch[3], 0x03040506); assert_se(memcmp(&scratch[3], &data[3], sizeof(uint32_t)) == 0); zero(scratch); unaligned_write_be64(&scratch[0], 0x0001020304050607); assert_se(memcmp(&scratch[0], &data[0], sizeof(uint64_t)) == 0); zero(scratch); unaligned_write_be64(&scratch[1], 0x0102030405060708); assert_se(memcmp(&scratch[1], &data[1], sizeof(uint64_t)) == 0); zero(scratch); unaligned_write_be64(&scratch[2], 0x0203040506070809); assert_se(memcmp(&scratch[2], &data[2], sizeof(uint64_t)) == 0); zero(scratch); unaligned_write_be64(&scratch[3], 0x030405060708090a); assert_se(memcmp(&scratch[3], &data[3], sizeof(uint64_t)) == 0); zero(scratch); unaligned_write_be64(&scratch[4], 0x0405060708090a0b); assert_se(memcmp(&scratch[4], &data[4], sizeof(uint64_t)) == 0); zero(scratch); unaligned_write_be64(&scratch[5], 0x05060708090a0b0c); assert_se(memcmp(&scratch[5], &data[5], sizeof(uint64_t)) == 0); zero(scratch); unaligned_write_be64(&scratch[6], 0x060708090a0b0c0d); assert_se(memcmp(&scratch[6], &data[6], sizeof(uint64_t)) == 0); zero(scratch); unaligned_write_be64(&scratch[7], 0x0708090a0b0c0d0e); assert_se(memcmp(&scratch[7], &data[7], sizeof(uint64_t)) == 0); }
static int lldp_make_packet( LLDPEmit mode, const struct ether_addr *hwaddr, const char *machine_id, const char *ifname, uint16_t ttl, const char *port_description, const char *hostname, const char *pretty_hostname, uint16_t system_capabilities, uint16_t enabled_capabilities, void **ret, size_t *sz) { size_t machine_id_length, ifname_length, port_description_length = 0, hostname_length = 0, pretty_hostname_length = 0; _cleanup_free_ void *packet = NULL; struct ether_header *h; uint8_t *p; size_t l; int r; assert(mode > LLDP_EMIT_NO); assert(mode < _LLDP_EMIT_MAX); assert(hwaddr); assert(machine_id); assert(ifname); assert(ret); assert(sz); machine_id_length = strlen(machine_id); ifname_length = strlen(ifname); if (port_description) port_description_length = strlen(port_description); if (hostname) hostname_length = strlen(hostname); if (pretty_hostname) pretty_hostname_length = strlen(pretty_hostname); l = sizeof(struct ether_header) + /* Chassis ID */ 2 + 1 + machine_id_length + /* Port ID */ 2 + 1 + ifname_length + /* TTL */ 2 + 2 + /* System Capabilities */ 2 + 4 + /* End */ 2; /* Port Description */ if (port_description) l += 2 + port_description_length; /* System Name */ if (hostname) l += 2 + hostname_length; /* System Description */ if (pretty_hostname) l += 2 + pretty_hostname_length; packet = malloc(l); if (!packet) return -ENOMEM; h = (struct ether_header*) packet; h->ether_type = htobe16(ETHERTYPE_LLDP); memcpy(h->ether_dhost, lldp_multicast_addr + mode, ETH_ALEN); memcpy(h->ether_shost, hwaddr, ETH_ALEN); p = (uint8_t*) packet + sizeof(struct ether_header); r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_CHASSIS_ID, 1 + machine_id_length); if (r < 0) return r; *(p++) = SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED; p = mempcpy(p, machine_id, machine_id_length); r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_PORT_ID, 1 + ifname_length); if (r < 0) return r; *(p++) = SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME; p = mempcpy(p, ifname, ifname_length); r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_TTL, 2); if (r < 0) return r; unaligned_write_be16(p, ttl); p += 2; if (port_description) { r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_PORT_DESCRIPTION, port_description_length); if (r < 0) return r; p = mempcpy(p, port_description, port_description_length); } if (hostname) { r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_NAME, hostname_length); if (r < 0) return r; p = mempcpy(p, hostname, hostname_length); } if (pretty_hostname) { r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_DESCRIPTION, pretty_hostname_length); if (r < 0) return r; p = mempcpy(p, pretty_hostname, pretty_hostname_length); } r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_CAPABILITIES, 4); if (r < 0) return r; unaligned_write_be16(p, system_capabilities); p += 2; unaligned_write_be16(p, enabled_capabilities); p += 2; r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_END, 0); if (r < 0) return r; assert(p == (uint8_t*) packet + l); *ret = packet; *sz = l; packet = NULL; return 0; }