]> git.ipfire.org Git - thirdparty/lldpd.git/blob - src/frame.h
Update ISC license wording.
[thirdparty/lldpd.git] / src / frame.h
1 /*
2 * Copyright (c) 2009 Vincent Bernat <bernat@luffy.cx>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #ifndef _FRAME_H
18 #define _FRAME_H
19
20 union {
21 uint8_t uint8;
22 uint16_t uint16;
23 uint32_t uint32;
24 } types;
25
26 /* This set of macro are used to build packets. The current position in buffer
27 * is `pos'. The length of the remaining space in buffer is `length'. `type'
28 * should be a member of `types'. This was stolen from ladvd which was adapted
29 * from Net::CDP. */
30
31 #define POKE(value, type, func) \
32 ((length >= sizeof(type)) && \
33 ( \
34 type = func(value), \
35 memcpy(pos, &type, sizeof(type)), \
36 length -= sizeof(type), \
37 pos += sizeof(type), \
38 1 \
39 ))
40 #define POKE_UINT8(value) POKE(value, types.uint8, )
41 #define POKE_UINT16(value) POKE(value, types.uint16, htons)
42 #define POKE_UINT32(value) POKE(value, types.uint32, htonl)
43 #define POKE_BYTES(value, bytes) \
44 ((length >= (bytes)) && \
45 ( \
46 memcpy(pos, value, bytes), \
47 length -= (bytes), \
48 pos += (bytes), \
49 1 \
50 ))
51 #define POKE_SAVE(where) \
52 (where = pos, 1)
53 #define POKE_RESTORE(where) \
54 do { \
55 if ((where) > pos) \
56 length -= ((where) - pos); \
57 else \
58 length += (pos - (where)); \
59 pos = (where); \
60 } while(0)
61
62 /* This set of macro are used to parse packets. The same variable as for POKE_*
63 * are used. There is no check on boundaries. */
64
65 #define PEEK(type, func) \
66 ( \
67 memcpy(&type, pos, sizeof(type)), \
68 length -= sizeof(type), \
69 pos += sizeof(type), \
70 func(type) \
71 )
72 #define PEEK_UINT8 PEEK(types.uint8, )
73 #define PEEK_UINT16 PEEK(types.uint16, ntohs)
74 #define PEEK_UINT32 PEEK(types.uint32, ntohl)
75 #define PEEK_BYTES(value, bytes) \
76 do { \
77 memcpy(value, pos, bytes); \
78 length -= (bytes); \
79 pos += (bytes); \
80 } while (0)
81 #define PEEK_DISCARD(bytes) \
82 do { \
83 length -= (bytes); \
84 pos += (bytes); \
85 } while (0)
86 #define PEEK_DISCARD_UINT8 PEEK_DISCARD(1)
87 #define PEEK_DISCARD_UINT16 PEEK_DISCARD(2)
88 #define PEEK_DISCARD_UINT32 PEEK_DISCARD(3)
89 #define PEEK_CMP(value, bytes) \
90 (length -= (bytes), \
91 pos += (bytes), \
92 memcmp(pos-bytes, value, bytes))
93 #define PEEK_SAVE POKE_SAVE
94 #define PEEK_RESTORE POKE_RESTORE
95
96 /* LLDP specific. We need a `tlv' pointer. */
97 #define POKE_START_LLDP_TLV(type) \
98 ( \
99 tlv = pos, \
100 POKE_UINT16(type << 9) \
101 )
102 #define POKE_END_LLDP_TLV \
103 ( \
104 memcpy(&types.uint16, tlv, sizeof(uint16_t)), \
105 types.uint16 |= htons((pos - (tlv + 2)) & 0x01ff), \
106 memcpy(tlv, &types.uint16, sizeof(uint16_t)), \
107 1 \
108 )
109
110 /* Same for CDP */
111 #define POKE_START_CDP_TLV(type) \
112 ( \
113 (void)POKE_UINT16(type), \
114 tlv = pos, \
115 POKE_UINT16(0) \
116 )
117 #define POKE_END_CDP_TLV \
118 ( \
119 types.uint16 = htons(pos - tlv + 2), \
120 memcpy(tlv, &types.uint16, sizeof(uint16_t)), \
121 1 \
122 )
123
124 /* Same for EDP */
125 #define POKE_START_EDP_TLV(type) \
126 ( \
127 (void)POKE_UINT8(EDP_TLV_MARKER), \
128 (void)POKE_UINT8(type), \
129 tlv = pos, \
130 POKE_UINT16(0) \
131 )
132 #define POKE_END_EDP_TLV POKE_END_CDP_TLV
133
134 u_int16_t frame_checksum(const u_int8_t *, int, int);
135
136 #endif /* _FRAME_H */