lldp-tlv.c revision 11e8357164694d8307dea5bcae017c98c5f125ab
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/***
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright (C) 2014 Tom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright (C) 2014 Susant Sahani
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering***/
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <net/ethernet.h>
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering#include <arpa/inet.h>
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen#include "macro.h"
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering#include "lldp-tlv.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
9df3ba6c6cb65eecec06f39dfe85a3596cedac4eTom Gundersenint tlv_section_new(tlv_section **ret) {
9df3ba6c6cb65eecec06f39dfe85a3596cedac4eTom Gundersen tlv_section *s;
9df3ba6c6cb65eecec06f39dfe85a3596cedac4eTom Gundersen
9df3ba6c6cb65eecec06f39dfe85a3596cedac4eTom Gundersen s = new0(tlv_section, 1);
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen if (!s)
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen return -ENOMEM;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen *ret = s;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen return 0;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringvoid tlv_section_free(tlv_section *m) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering if (!m)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering
3c0cf502796be355431d4a64d738e75f543aa51dLennart Poettering free(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint tlv_packet_new(tlv_packet **ret) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering tlv_packet *m;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m = new0(tlv_packet, 1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!m)
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering return -ENOMEM;
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering LIST_HEAD_INIT(m->sections);
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering m->n_ref = 1;
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering *ret = m;
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering return 0;
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering}
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poetteringtlv_packet *sd_lldp_packet_ref(tlv_packet *m) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!m)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen assert(m->n_ref > 0);
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering m->n_ref++;
f4461e5641d53f27d6e76e0607bdaa9c0c58c1f6Lennart Poettering
f4461e5641d53f27d6e76e0607bdaa9c0c58c1f6Lennart Poettering return m;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen}
d74fb368b18f0fbd9a4fe6f15691bbea7f3c4a01Tom Gundersen
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poetteringtlv_packet *sd_lldp_packet_unref(tlv_packet *m) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering tlv_section *s, *n;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
9df3ba6c6cb65eecec06f39dfe85a3596cedac4eTom Gundersen if (!m)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering assert(m->n_ref > 0);
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering m->n_ref--;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering if (m->n_ref > 0)
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering return m;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering LIST_FOREACH_SAFE(section, s, n, m->sections)
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering tlv_section_free(s);
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering free(m);
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering return NULL;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering}
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poetteringint tlv_packet_append_bytes(tlv_packet *m, const void *data, size_t data_length) {
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering uint8_t *p;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering assert_return(m, -EINVAL);
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering assert_return(data, -EINVAL);
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering assert_return(data_length, -EINVAL);
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (m->length + data_length > ETHER_MAX_LEN)
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering p = m->pdu + m->length;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering memcpy(p, data, data_length);
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering m->length += data_length;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
3e684349c2cead2e6fd2f816c34eb17daba23a49Lennart Poettering return 0;
3e684349c2cead2e6fd2f816c34eb17daba23a49Lennart Poettering}
3e684349c2cead2e6fd2f816c34eb17daba23a49Lennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poetteringint tlv_packet_append_u8(tlv_packet *m, uint8_t data) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert_return(m, -EINVAL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return tlv_packet_append_bytes(m, &data, sizeof(uint8_t));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersenint tlv_packet_append_u16(tlv_packet *m, uint16_t data) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering uint16_t type;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert_return(m, -EINVAL);
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen type = htons(data);
cab5b05903096e1c9cf5575ccc73f89d15c8db69Lennart Poettering
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen return tlv_packet_append_bytes(m, &type, sizeof(uint16_t));
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen}
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poetteringint tlv_packet_append_u32(tlv_packet *m, uint32_t data) {
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen uint32_t type;
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen
3e684349c2cead2e6fd2f816c34eb17daba23a49Lennart Poettering assert_return(m, -EINVAL);
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering type = htonl(data);
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering return tlv_packet_append_bytes(m, &type, sizeof(uint32_t));
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poetteringint tlv_packet_append_string(tlv_packet *m, char *data, uint16_t size) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert_return(m, -EINVAL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering return tlv_packet_append_bytes(m, data, size);
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering}
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poetteringint lldp_tlv_packet_open_container(tlv_packet *m, uint16_t type) {
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering assert_return(m, -EINVAL);
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering m->container_pos = m->pdu + m->length;
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering return tlv_packet_append_u16(m, type << 9);
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering}
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poetteringint lldp_tlv_packet_close_container(tlv_packet *m) {
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering uint16_t type;
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering assert_return(m, -EINVAL);
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering assert_return(m->container_pos, -EINVAL);
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering memcpy(&type, m->container_pos, sizeof(uint16_t));
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering type |= htons(((m->pdu + m->length) - (m->container_pos + 2)) & 0x01ff);
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering memcpy(m->container_pos, &type, sizeof(uint16_t));
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering return 0;
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering}
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poetteringstatic inline int tlv_packet_read_internal(tlv_section *m, void **data) {
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering assert_return(m->read_pos, -EINVAL);
eed857b71702f8551b46b66b31fa0d08583cf23cLennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering *data = m->read_pos;
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering return 0;
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering}
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poetteringint tlv_packet_read_u8(tlv_packet *m, uint8_t *data) {
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering void *val = NULL;
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering int r;
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering assert_return(m, -EINVAL);
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering r = tlv_packet_read_internal(m->container, &val);
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen if (r < 0)
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen return r;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering memcpy(data, val, sizeof(uint8_t));
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering m->container->read_pos ++;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering return 0;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering}
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poetteringint tlv_packet_read_u16(tlv_packet *m, uint16_t *data) {
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering uint16_t t;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering void *val = NULL;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering int r;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering assert_return(m, -EINVAL);
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering r = tlv_packet_read_internal(m->container, &val);
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering if (r < 0)
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering return r;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering memcpy(&t, val, sizeof(uint16_t));
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering *data = ntohs(t);
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering m->container->read_pos += 2;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering return 0;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering}
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poetteringint tlv_packet_read_u32(tlv_packet *m, uint32_t *data) {
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering uint32_t t;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering void *val;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering int r;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering assert_return(m, -EINVAL);
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering r = tlv_packet_read_internal(m->container, &val);
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering if (r < 0)
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering return r;
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering memcpy(&t, val, sizeof(uint32_t));
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering *data = ntohl(t);
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering m->container->read_pos += 4;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
9df3ba6c6cb65eecec06f39dfe85a3596cedac4eTom Gundersen return r;
9df3ba6c6cb65eecec06f39dfe85a3596cedac4eTom Gundersen}
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poetteringint tlv_packet_read_string(tlv_packet *m, char **data, uint16_t *data_length) {
b652d4a2099d1c167584dcc1d179d47c58dc38a2Lennart Poettering void *val = NULL;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering int r;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
f4461e5641d53f27d6e76e0607bdaa9c0c58c1f6Lennart Poettering assert_return(m, -EINVAL);
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen r = tlv_packet_read_internal(m->container, &val);
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering if (r < 0)
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering return r;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering *data = (char *) val;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering *data_length = m->container->length;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering m->container->read_pos += m->container->length;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering return 0;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering}
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poetteringint tlv_packet_read_bytes(tlv_packet *m, uint8_t **data, uint16_t *data_length) {
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering void *val = NULL;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering int r;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering assert_return(m, -EINVAL);
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering r = tlv_packet_read_internal(m->container, &val);
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering if (r < 0)
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering return r;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering *data = (uint8_t *) val;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering *data_length = m->container->length;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering m->container->read_pos += m->container->length;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
84129d46cd6e95e142973da93aede4c7433c9600Lennart Poettering return 0;
d74fb368b18f0fbd9a4fe6f15691bbea7f3c4a01Tom Gundersen}
d74fb368b18f0fbd9a4fe6f15691bbea7f3c4a01Tom Gundersen
d74fb368b18f0fbd9a4fe6f15691bbea7f3c4a01Tom Gundersen/* parse raw TLV packet */
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poetteringint tlv_packet_parse_pdu(tlv_packet *m, uint16_t size) {
d74fb368b18f0fbd9a4fe6f15691bbea7f3c4a01Tom Gundersen tlv_section *section, *tail;
d74fb368b18f0fbd9a4fe6f15691bbea7f3c4a01Tom Gundersen uint16_t t, l;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen uint8_t *p;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen int r;
efd46a696d31097c38f653b36921e00c4df62319Lennart Poettering
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen assert_return(m, -EINVAL);
9df3ba6c6cb65eecec06f39dfe85a3596cedac4eTom Gundersen assert_return(size, -EINVAL);
9df3ba6c6cb65eecec06f39dfe85a3596cedac4eTom Gundersen
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering p = m->pdu;
9df3ba6c6cb65eecec06f39dfe85a3596cedac4eTom Gundersen
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen /* extract ethernet herader */
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen memcpy(&m->mac, p, ETH_ALEN);
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering p += sizeof(struct ether_header);
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering for (l = 0; l <= size; ) {
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering r = tlv_section_new(&section);
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering if (r < 0)
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering return r;
9df3ba6c6cb65eecec06f39dfe85a3596cedac4eTom Gundersen
84129d46cd6e95e142973da93aede4c7433c9600Lennart Poettering memcpy(&t, p, sizeof(uint16_t));
84129d46cd6e95e142973da93aede4c7433c9600Lennart Poettering
84129d46cd6e95e142973da93aede4c7433c9600Lennart Poettering section->type = ntohs(t) >> 9;
84129d46cd6e95e142973da93aede4c7433c9600Lennart Poettering section->length = ntohs(t) & 0x01ff;
9df3ba6c6cb65eecec06f39dfe85a3596cedac4eTom Gundersen
9df3ba6c6cb65eecec06f39dfe85a3596cedac4eTom Gundersen if (section->type == LLDP_TYPE_END || section->type >=_LLDP_TYPE_MAX) {
f4461e5641d53f27d6e76e0607bdaa9c0c58c1f6Lennart Poettering tlv_section_free(section);
4e0b8b17a7465653f4e7b819dad5f8e30d64c0c4Tom Gundersen break;
4e0b8b17a7465653f4e7b819dad5f8e30d64c0c4Tom Gundersen }
4e0b8b17a7465653f4e7b819dad5f8e30d64c0c4Tom Gundersen
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering p += 2;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering section->data = p;
f4461e5641d53f27d6e76e0607bdaa9c0c58c1f6Lennart Poettering
4e0b8b17a7465653f4e7b819dad5f8e30d64c0c4Tom Gundersen LIST_FIND_TAIL(section, m->sections, tail);
4e0b8b17a7465653f4e7b819dad5f8e30d64c0c4Tom Gundersen LIST_INSERT_AFTER(section, m->sections, tail, section);
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering p += section->length;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering l += (section->length + 2);
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering }
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering return 0;
571370c1555d2aa697733479a50957aff024bbcbLennart Poettering}
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poetteringint lldp_tlv_packet_enter_container(tlv_packet *m, uint16_t type) {
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering tlv_section *s;
571370c1555d2aa697733479a50957aff024bbcbLennart Poettering
571370c1555d2aa697733479a50957aff024bbcbLennart Poettering assert_return(m, -EINVAL);
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
4e0b8b17a7465653f4e7b819dad5f8e30d64c0c4Tom Gundersen LIST_FOREACH(section, s, m->sections)
4e0b8b17a7465653f4e7b819dad5f8e30d64c0c4Tom Gundersen if (s->type == type)
b652d4a2099d1c167584dcc1d179d47c58dc38a2Lennart Poettering break;
b652d4a2099d1c167584dcc1d179d47c58dc38a2Lennart Poettering if (!s)
b652d4a2099d1c167584dcc1d179d47c58dc38a2Lennart Poettering return -1;
b652d4a2099d1c167584dcc1d179d47c58dc38a2Lennart Poettering
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering m->container = s;
b652d4a2099d1c167584dcc1d179d47c58dc38a2Lennart Poettering
b652d4a2099d1c167584dcc1d179d47c58dc38a2Lennart Poettering m->container->read_pos = s->data;
b652d4a2099d1c167584dcc1d179d47c58dc38a2Lennart Poettering if (!m->container->read_pos) {
b652d4a2099d1c167584dcc1d179d47c58dc38a2Lennart Poettering m->container = 0;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen return -1;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen }
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen return 0;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen}
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersenint lldp_tlv_packet_exit_container(tlv_packet *m) {
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen assert_return(m, -EINVAL);
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen m->container = 0;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen return 0;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen}
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersenstatic int lldp_tlv_packet_read_u16_tlv(tlv_packet *tlv, uint16_t type, uint16_t *value) {
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen int r;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen assert_return(tlv, -EINVAL);
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen
011842775f750711833526d5bba1b818713947f5Lennart Poettering r = lldp_tlv_packet_enter_container(tlv, type);
011842775f750711833526d5bba1b818713947f5Lennart Poettering if (r < 0)
011842775f750711833526d5bba1b818713947f5Lennart Poettering goto out;
011842775f750711833526d5bba1b818713947f5Lennart Poettering
011842775f750711833526d5bba1b818713947f5Lennart Poettering r = tlv_packet_read_u16(tlv, value);
011842775f750711833526d5bba1b818713947f5Lennart Poettering
011842775f750711833526d5bba1b818713947f5Lennart Poettering (void) lldp_tlv_packet_exit_container(tlv);
011842775f750711833526d5bba1b818713947f5Lennart Poettering
011842775f750711833526d5bba1b818713947f5Lennart Poettering out:
011842775f750711833526d5bba1b818713947f5Lennart Poettering return r;
f4461e5641d53f27d6e76e0607bdaa9c0c58c1f6Lennart Poettering}
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersenstatic int lldp_tlv_packet_read_string_tlv(tlv_packet *tlv, uint16_t type, char **data, uint16_t *length) {
f4461e5641d53f27d6e76e0607bdaa9c0c58c1f6Lennart Poettering char *s;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen int r;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen
f4461e5641d53f27d6e76e0607bdaa9c0c58c1f6Lennart Poettering assert_return(tlv, -EINVAL);
b652d4a2099d1c167584dcc1d179d47c58dc38a2Lennart Poettering
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen r = lldp_tlv_packet_enter_container(tlv, type);
011842775f750711833526d5bba1b818713947f5Lennart Poettering if (r < 0)
011842775f750711833526d5bba1b818713947f5Lennart Poettering return r;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering r = tlv_packet_read_string(tlv, &s, length);
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering if (r < 0)
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering goto out;
f4461e5641d53f27d6e76e0607bdaa9c0c58c1f6Lennart Poettering
f4461e5641d53f27d6e76e0607bdaa9c0c58c1f6Lennart Poettering *data = (char *) s;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering out:
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen (void) lldp_tlv_packet_exit_container(tlv);
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering return r;
6a1a5eec43892dee3ff6e208bceb1931c25c782eLennart Poettering}
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poetteringint sd_lldp_packet_read_chassis_id(tlv_packet *tlv,
6a1a5eec43892dee3ff6e208bceb1931c25c782eLennart Poettering uint8_t *type,
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen uint8_t **data,
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering uint16_t *length) {
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering uint8_t subtype;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering int r;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering assert_return(tlv, -EINVAL);
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_CHASSIS_ID);
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering if (r < 0)
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering goto out2;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering r = tlv_packet_read_u8(tlv, &subtype);
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering if (r < 0)
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering goto out1;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering switch (subtype) {
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering case LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS:
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering r = tlv_packet_read_bytes(tlv, data, length);
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering if (r < 0)
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering goto out1;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering break;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering default:
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering r = -EOPNOTSUPP;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering break;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering }
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering *type = subtype;
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering out1:
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering (void) lldp_tlv_packet_exit_container(tlv);
011842775f750711833526d5bba1b818713947f5Lennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering out2:
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poettering return r;
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering}
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering
6bb2c08597c999c429e889cd2403b2fef5f3e1a0Lennart Poetteringint sd_lldp_packet_read_port_id(tlv_packet *tlv,
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen uint8_t *type,
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen uint8_t **data,
f4461e5641d53f27d6e76e0607bdaa9c0c58c1f6Lennart Poettering uint16_t *length) {
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen uint8_t subtype;
be808ea083fa07271116b4519c3c27fd20c5f077Tom Gundersen char *s;
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering int r;
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering assert_return(tlv, -EINVAL);
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_PORT_ID);
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering if (r < 0)
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering goto out2;
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering r = tlv_packet_read_u8(tlv, &subtype);
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering if (r < 0)
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering goto out1;
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering switch (subtype) {
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering case LLDP_PORT_SUBTYPE_PORT_COMPONENT:
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering case LLDP_PORT_SUBTYPE_INTERFACE_ALIAS:
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering case LLDP_PORT_SUBTYPE_INTERFACE_NAME:
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering case LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED:
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering r = tlv_packet_read_string(tlv, &s, length);
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering if (r < 0)
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering goto out1;
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering *data = (uint8_t *) s;
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering break;
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering case LLDP_PORT_SUBTYPE_MAC_ADDRESS:
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering
519ef04651b07a547f010d6462603669d7fde4e5Lennart Poettering r = tlv_packet_read_bytes(tlv, data, length);
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering if (r < 0)
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering goto out1;
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering break;
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering default:
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering r = -EOPNOTSUPP;
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering break;
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering }
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering *type = subtype;
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering out1:
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering (void) lldp_tlv_packet_exit_container(tlv);
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering out2:
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering return r;
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering}
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poetteringint sd_lldp_packet_read_ttl(tlv_packet *tlv, uint16_t *ttl) {
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering return lldp_tlv_packet_read_u16_tlv(tlv, LLDP_TYPE_TTL, ttl);
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering}
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poetteringint sd_lldp_packet_read_system_name(tlv_packet *tlv,
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering char **data,
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering uint16_t *length) {
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering return lldp_tlv_packet_read_string_tlv(tlv, LLDP_TYPE_SYSTEM_NAME, data, length);
92ec902aad1ade7acbe50efd7b8ef87fbdc63af3Lennart Poettering}
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersen
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poetteringint sd_lldp_packet_read_system_description(tlv_packet *tlv,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering char **data,
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersen uint16_t *length) {
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering return lldp_tlv_packet_read_string_tlv(tlv, LLDP_TYPE_SYSTEM_DESCRIPTION, data, length);
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersen}
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersen
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poetteringint sd_lldp_packet_read_port_description(tlv_packet *tlv,
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering char **data,
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt uint16_t *length) {
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering return lldp_tlv_packet_read_string_tlv(tlv, LLDP_TYPE_PORT_DESCRIPTION, data, length);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering}
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poetteringint sd_lldp_packet_read_system_capability(tlv_packet *tlv, uint16_t *data) {
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering return lldp_tlv_packet_read_u16_tlv(tlv, LLDP_TYPE_SYSTEM_CAPABILITIES, data);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering}
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poetteringint sd_lldp_packet_get_destination_type(tlv_packet *tlv, int *dest) {
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering assert_return(tlv, -EINVAL);
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt assert_return(dest, -EINVAL);
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt /* 802.1AB-2009, Table 7-1 */
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt if (!memcmp(&tlv->mac, LLDP_MAC_NEAREST_BRIDGE, ETH_ALEN))
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt *dest = SD_LLDP_DESTINATION_TYPE_NEAREST_BRIDGE;
636e813dc98ea40c58c6c85bc5e7e3c9f0904ea2Lennart Poettering else if (!memcmp(&tlv->mac, LLDP_MAC_NEAREST_NON_TPMR_BRIDGE, ETH_ALEN))
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering *dest = SD_LLDP_DESTINATION_TYPE_NEAREST_NON_TPMR_BRIDGE;
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering else if (!memcmp(&tlv->mac, LLDP_MAC_NEAREST_CUSTOMER_BRIDGE, ETH_ALEN))
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering *dest = SD_LLDP_DESTINATION_TYPE_NEAREST_CUSTOMER_BRIDGE;
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering else
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering return -EINVAL;
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering return 0;
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering}
636e813dc98ea40c58c6c85bc5e7e3c9f0904ea2Lennart Poettering