Пример #1
0
        /* 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, &(struct ether_addr) { LLDP_MULTICAST_ADDR }, ETH_ALEN);
        memcpy(h->ether_shost, hwaddr, ETH_ALEN);

        p = (uint8_t*) packet + sizeof(struct ether_header);

        r = lldp_write_tlv_header(&p, LLDP_TYPE_CHASSIS_ID, 1 + machine_id_length);
        if (r < 0)
                return r;
        *(p++) = LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED;
        p = mempcpy(p, machine_id, machine_id_length);

        r = lldp_write_tlv_header(&p, LLDP_TYPE_PORT_ID, 1 + ifname_length);
        if (r < 0)
                return r;
        *(p++) = LLDP_PORT_SUBTYPE_INTERFACE_NAME;
        p = mempcpy(p, ifname, ifname_length);

        r = lldp_write_tlv_header(&p, LLDP_TYPE_TTL, 2);
        if (r < 0)
                return r;
        unaligned_write_be16(p, ttl);
Пример #2
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;
}