#include "common.h" LIBNET_API libnet_ptag_t libnet_build_lldp_chassis(const uint8_t subtype, const uint8_t *value, const uint8_t value_s, libnet_t *l, libnet_ptag_t ptag) { struct libnet_lldp_hdr hdr = { 0 }; uint16_t type_and_len; libnet_pblock_t *p; uint32_t n, h; if (l == NULL) return (-1); if (value == NULL) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): Chassis ID string is NULL", __func__); return (-1); } if (value_s == 0) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): Incorrect Chassis ID string length", __func__); return (-1); } /* size of memory block */ n = h = LIBNET_LLDP_TLV_HDR_SIZE + /* TLV Header size */ LIBNET_LLDP_SUBTYPE_SIZE + /* Chassis ID subtype size */ value_s; /* Chassis ID string length */ LIBNET_LLDP_TLV_SET_TYPE(hdr.tlv_info, LIBNET_LLDP_CHASSIS_ID); LIBNET_LLDP_TLV_SET_LEN(hdr.tlv_info, value_s + LIBNET_LLDP_SUBTYPE_SIZE); /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LLDP_CHASSIS_H); if (p == NULL) { return (-1); } type_and_len = htons(hdr.tlv_info); if (libnet_pblock_append(l, p, &type_and_len, sizeof(type_and_len)) == -1) goto bad; if (libnet_pblock_append(l, p, &subtype, sizeof(subtype)) == -1) goto bad; if (libnet_pblock_append(l, p, value, value_s) == -1) goto bad; return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_LLDP_CHASSIS_H)); bad: libnet_pblock_delete(l, p); return (-1); } LIBNET_API libnet_ptag_t libnet_build_lldp_port(const uint8_t subtype, const uint8_t *value, const uint8_t value_s, libnet_t *l, libnet_ptag_t ptag) { struct libnet_lldp_hdr hdr = { 0 }; uint16_t type_and_len; libnet_pblock_t *p; uint32_t n, h; if (l == NULL) return (-1); if (value == NULL) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): Port ID string is NULL", __func__); return (-1); } if (value_s == 0) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): Incorrect Port ID string length", __func__); return (-1); } /* size of memory block */ n = h = LIBNET_LLDP_TLV_HDR_SIZE + /* TLV Header size */ LIBNET_LLDP_SUBTYPE_SIZE + /* Port ID subtype size */ value_s; /* Port ID string length */ LIBNET_LLDP_TLV_SET_TYPE(hdr.tlv_info, LIBNET_LLDP_PORT_ID); LIBNET_LLDP_TLV_SET_LEN(hdr.tlv_info, value_s + LIBNET_LLDP_SUBTYPE_SIZE); /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LLDP_PORT_H); if (p == NULL) return (-1); type_and_len = htons(hdr.tlv_info); if (libnet_pblock_append(l, p, &type_and_len, sizeof(type_and_len)) == -1) goto bad; if (libnet_pblock_append(l, p, &subtype, sizeof(subtype)) == -1) goto bad; if (libnet_pblock_append(l, p, value, value_s) == -1) goto bad; if (ptag) return ptag; return libnet_pblock_update(l, p, h, LIBNET_PBLOCK_LLDP_PORT_H); bad: libnet_pblock_delete(l, p); return (-1); } LIBNET_API libnet_ptag_t libnet_build_lldp_ttl(const uint16_t ttl, libnet_t *l, libnet_ptag_t ptag) { struct libnet_lldp_hdr hdr = { 0 }; uint16_t type_and_len; libnet_pblock_t *p; uint32_t n, h; if (l == NULL) return (-1); if (ttl > UINT16_MAX) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): Incorrect value of ttl", __func__); return (-1); } /* size of memory block */ n = h = LIBNET_LLDP_TLV_HDR_SIZE + /* TLV Header size */ sizeof(uint16_t); /* Size of 2 octets */ LIBNET_LLDP_TLV_SET_TYPE(hdr.tlv_info, LIBNET_LLDP_TTL); LIBNET_LLDP_TLV_SET_LEN(hdr.tlv_info, sizeof(uint16_t)); /* Size is 2 octets */ /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LLDP_TTL_H); if (p == NULL) return (-1); type_and_len = htons(hdr.tlv_info); if (libnet_pblock_append(l, p, &type_and_len, sizeof(type_and_len)) == -1) goto bad; if (libnet_pblock_append(l, p, &ttl, sizeof(ttl)) == -1) goto bad; if (ptag) return ptag; return libnet_pblock_update(l, p, h, LIBNET_PBLOCK_LLDP_TTL_H); bad: libnet_pblock_delete(l, p); return (-1); } LIBNET_API libnet_ptag_t libnet_build_lldp_end(libnet_t *l, libnet_ptag_t ptag) { struct libnet_lldp_hdr hdr = { 0 }; uint16_t type_and_len; libnet_pblock_t *p; uint32_t n, h; if (l == NULL) return (-1); /* size of memory block */ n = h = LIBNET_LLDP_TLV_HDR_SIZE; /* TLV Header size */ LIBNET_LLDP_TLV_SET_TYPE(hdr.tlv_info, LIBNET_LLDP_END_LLDPDU); LIBNET_LLDP_TLV_SET_LEN(hdr.tlv_info, 0); /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LLDP_TTL_H); if (p == NULL) return (-1); type_and_len = htons(hdr.tlv_info); if (libnet_pblock_append(l, p, &type_and_len, sizeof(type_and_len)) == -1) goto bad; if (ptag) return ptag; return libnet_pblock_update(l, p, h, LIBNET_PBLOCK_LLDP_TTL_H); bad: libnet_pblock_delete(l, p); return (-1); } LIBNET_API libnet_ptag_t libnet_build_lldp_org_spec(const uint8_t *value, const uint16_t value_s, libnet_t *l, libnet_ptag_t ptag) { struct libnet_lldp_hdr hdr = { 0 }; uint16_t type_and_len; libnet_pblock_t *p; uint32_t n, h; if (l == NULL) return (-1); if (value == NULL) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): Organization Specific string is NULL", __func__); return (-1); } if ((value_s < 4) || (value_s > 511)) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): Incorrect TLV information string length", __func__); return (-1); } LIBNET_LLDP_TLV_SET_TYPE(hdr.tlv_info, LIBNET_LLDP_ORG_SPEC); LIBNET_LLDP_TLV_SET_LEN(hdr.tlv_info, value_s); /* size of memory block */ n = h = LIBNET_LLDP_TLV_HDR_SIZE + /* TLV Header size */ value_s; /* TLV Information length*/ /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LLDP_ORG_SPEC_H); if (p == NULL) return (-1); type_and_len = htons(hdr.tlv_info); if (libnet_pblock_append(l, p, &type_and_len, sizeof(type_and_len)) == -1) goto bad; if (libnet_pblock_append(l, p, value, value_s) == -1) goto bad; if (ptag) return ptag; return libnet_pblock_update(l, p, h, LIBNET_PBLOCK_LLDP_ORG_SPEC_H); bad: libnet_pblock_delete(l, p); return (-1); } /** * Local Variables: * indent-tabs-mode: nil * c-file-style: "stroustrup" * End: */