]>
Commit | Line | Data |
---|---|---|
4b292b55 | 1 | /* -*- mode: c; c-file-style: "openbsd" -*- */ |
a8105c1b VB |
2 | /* |
3 | * Copyright (c) 2009 Vincent Bernat <bernat@luffy.cx> | |
b96ca40c | 4 | * Copyright (c) 2014 Michael Chapman |
a8105c1b | 5 | * |
51434125 | 6 | * Permission to use, copy, modify, and/or distribute this software for any |
a8105c1b VB |
7 | * purpose with or without fee is hereby granted, provided that the above |
8 | * copyright notice and this permission notice appear in all copies. | |
9 | * | |
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 | */ | |
18 | ||
19 | #ifndef _FRAME_H | |
20 | #define _FRAME_H | |
21 | ||
e66b7f34 | 22 | static union { |
58ebf59e SK |
23 | uint8_t f_uint8; |
24 | uint16_t f_uint16; | |
25 | uint32_t f_uint32; | |
a8105c1b VB |
26 | } types; |
27 | ||
28 | /* This set of macro are used to build packets. The current position in buffer | |
29 | * is `pos'. The length of the remaining space in buffer is `length'. `type' | |
b96ca40c VB |
30 | * should be a member of `types'. |
31 | * | |
32 | * This was stolen from ladvd which was adapted from Net::CDP. The original | |
33 | * author of those macros, Michael Chapman, has relicensed those macros under | |
34 | * the ISC license. */ | |
a8105c1b | 35 | |
8b549648 VB |
36 | #define POKE(value, type, func) \ |
37 | ((length >= sizeof(type)) && \ | |
38 | (type = func(value), memcpy(pos, &type, sizeof(type)), length -= sizeof(type), \ | |
39 | pos += sizeof(type), 1)) | |
3b3a1960 VB |
40 | #define POKE_UINT8(value) POKE(value, types.f_uint8, ) |
41 | #define POKE_UINT16(value) POKE(value, types.f_uint16, htons) | |
42 | #define POKE_UINT32(value) POKE(value, types.f_uint32, htonl) | |
8b549648 VB |
43 | #define POKE_BYTES(value, bytes) \ |
44 | ((length >= (bytes)) && \ | |
45 | (memcpy(pos, value, bytes), length -= (bytes), pos += (bytes), 1)) | |
46 | #define POKE_SAVE(where) (where = pos, 1) | |
47 | #define POKE_RESTORE(where) \ | |
48 | do { \ | |
49 | if ((where) > pos) \ | |
50 | length -= ((where)-pos); \ | |
51 | else \ | |
52 | length += (pos - (where)); \ | |
53 | pos = (where); \ | |
54 | } while (0) | |
a8105c1b VB |
55 | |
56 | /* This set of macro are used to parse packets. The same variable as for POKE_* | |
57 | * are used. There is no check on boundaries. */ | |
58 | ||
8b549648 VB |
59 | #define PEEK(type, func) \ |
60 | (memcpy(&type, pos, sizeof(type)), length -= sizeof(type), pos += sizeof(type), \ | |
61 | func(type)) | |
58ebf59e SK |
62 | #define PEEK_UINT8 PEEK(types.f_uint8, ) |
63 | #define PEEK_UINT16 PEEK(types.f_uint16, ntohs) | |
64 | #define PEEK_UINT32 PEEK(types.f_uint32, ntohl) | |
8b549648 VB |
65 | #define PEEK_BYTES(value, bytes) \ |
66 | do { \ | |
67 | memcpy(value, pos, bytes); \ | |
68 | length -= (bytes); \ | |
69 | pos += (bytes); \ | |
70 | } while (0) | |
71 | #define PEEK_DISCARD(bytes) \ | |
72 | do { \ | |
73 | length -= (bytes); \ | |
74 | pos += (bytes); \ | |
75 | } while (0) | |
a8105c1b VB |
76 | #define PEEK_DISCARD_UINT8 PEEK_DISCARD(1) |
77 | #define PEEK_DISCARD_UINT16 PEEK_DISCARD(2) | |
a8d8006c | 78 | #define PEEK_DISCARD_UINT32 PEEK_DISCARD(4) |
8b549648 VB |
79 | #define PEEK_CMP(value, bytes) \ |
80 | (length -= (bytes), pos += (bytes), memcmp(pos - bytes, value, bytes)) | |
a8105c1b VB |
81 | #define PEEK_SAVE POKE_SAVE |
82 | #define PEEK_RESTORE POKE_RESTORE | |
83 | ||
84 | /* LLDP specific. We need a `tlv' pointer. */ | |
8b549648 VB |
85 | #define POKE_START_LLDP_TLV(type) (tlv = pos, POKE_UINT16(type << 9)) |
86 | #define POKE_END_LLDP_TLV \ | |
87 | (memcpy(&types.f_uint16, tlv, sizeof(uint16_t)), \ | |
88 | types.f_uint16 |= htons((pos - (tlv + 2)) & 0x01ff), \ | |
89 | memcpy(tlv, &types.f_uint16, sizeof(uint16_t)), 1) | |
a8105c1b VB |
90 | |
91 | /* Same for CDP */ | |
8b549648 VB |
92 | #define POKE_START_CDP_TLV(type) ((void)POKE_UINT16(type), tlv = pos, POKE_UINT16(0)) |
93 | #define POKE_END_CDP_TLV \ | |
94 | (types.f_uint16 = htons(pos - tlv + 2), \ | |
95 | memcpy(tlv, &types.f_uint16, sizeof(uint16_t)), 1) | |
a8105c1b VB |
96 | |
97 | /* Same for EDP */ | |
8b549648 VB |
98 | #define POKE_START_EDP_TLV(type) \ |
99 | ((void)POKE_UINT8(EDP_TLV_MARKER), (void)POKE_UINT8(type), tlv = pos, POKE_UINT16(0)) | |
a8105c1b VB |
100 | #define POKE_END_EDP_TLV POKE_END_CDP_TLV |
101 | ||
a8105c1b | 102 | #endif /* _FRAME_H */ |