diff options
Diffstat (limited to 'src/daemon/frame.h')
-rw-r--r-- | src/daemon/frame.h | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/daemon/frame.h b/src/daemon/frame.h new file mode 100644 index 0000000..714de09 --- /dev/null +++ b/src/daemon/frame.h @@ -0,0 +1,102 @@ +/* -*- mode: c; c-file-style: "openbsd" -*- */ +/* + * Copyright (c) 2009 Vincent Bernat <bernat@luffy.cx> + * Copyright (c) 2014 Michael Chapman + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _FRAME_H +#define _FRAME_H + +static union { + uint8_t f_uint8; + uint16_t f_uint16; + uint32_t f_uint32; +} types; + +/* This set of macro are used to build packets. The current position in buffer + * is `pos'. The length of the remaining space in buffer is `length'. `type' + * should be a member of `types'. + * + * This was stolen from ladvd which was adapted from Net::CDP. The original + * author of those macros, Michael Chapman, has relicensed those macros under + * the ISC license. */ + +#define POKE(value, type, func) \ + ((length >= sizeof(type)) && \ + (type = func(value), memcpy(pos, &type, sizeof(type)), length -= sizeof(type), \ + pos += sizeof(type), 1)) +#define POKE_UINT8(value) POKE(value, types.f_uint8, ) +#define POKE_UINT16(value) POKE(value, types.f_uint16, htons) +#define POKE_UINT32(value) POKE(value, types.f_uint32, htonl) +#define POKE_BYTES(value, bytes) \ + ((length >= (bytes)) && \ + (memcpy(pos, value, bytes), length -= (bytes), pos += (bytes), 1)) +#define POKE_SAVE(where) (where = pos, 1) +#define POKE_RESTORE(where) \ + do { \ + if ((where) > pos) \ + length -= ((where)-pos); \ + else \ + length += (pos - (where)); \ + pos = (where); \ + } while (0) + +/* This set of macro are used to parse packets. The same variable as for POKE_* + * are used. There is no check on boundaries. */ + +#define PEEK(type, func) \ + (memcpy(&type, pos, sizeof(type)), length -= sizeof(type), pos += sizeof(type), \ + func(type)) +#define PEEK_UINT8 PEEK(types.f_uint8, ) +#define PEEK_UINT16 PEEK(types.f_uint16, ntohs) +#define PEEK_UINT32 PEEK(types.f_uint32, ntohl) +#define PEEK_BYTES(value, bytes) \ + do { \ + memcpy(value, pos, bytes); \ + length -= (bytes); \ + pos += (bytes); \ + } while (0) +#define PEEK_DISCARD(bytes) \ + do { \ + length -= (bytes); \ + pos += (bytes); \ + } while (0) +#define PEEK_DISCARD_UINT8 PEEK_DISCARD(1) +#define PEEK_DISCARD_UINT16 PEEK_DISCARD(2) +#define PEEK_DISCARD_UINT32 PEEK_DISCARD(4) +#define PEEK_CMP(value, bytes) \ + (length -= (bytes), pos += (bytes), memcmp(pos - bytes, value, bytes)) +#define PEEK_SAVE POKE_SAVE +#define PEEK_RESTORE POKE_RESTORE + +/* LLDP specific. We need a `tlv' pointer. */ +#define POKE_START_LLDP_TLV(type) (tlv = pos, POKE_UINT16(type << 9)) +#define POKE_END_LLDP_TLV \ + (memcpy(&types.f_uint16, tlv, sizeof(uint16_t)), \ + types.f_uint16 |= htons((pos - (tlv + 2)) & 0x01ff), \ + memcpy(tlv, &types.f_uint16, sizeof(uint16_t)), 1) + +/* Same for CDP */ +#define POKE_START_CDP_TLV(type) ((void)POKE_UINT16(type), tlv = pos, POKE_UINT16(0)) +#define POKE_END_CDP_TLV \ + (types.f_uint16 = htons(pos - tlv + 2), \ + memcpy(tlv, &types.f_uint16, sizeof(uint16_t)), 1) + +/* Same for EDP */ +#define POKE_START_EDP_TLV(type) \ + ((void)POKE_UINT8(EDP_TLV_MARKER), (void)POKE_UINT8(type), tlv = pos, POKE_UINT16(0)) +#define POKE_END_EDP_TLV POKE_END_CDP_TLV + +#endif /* _FRAME_H */ |