1#pragma once
2
3#ifdef __cplusplus
4extern "C" {
5#endif
6
7#include <netinet/in.h>
8#include <stdint.h>
9#include <string.h>
10#include <sys/types.h>
11
12#define ICMP6_FILTER 1
13
14#define ICMP6_FILTER_BLOCK 1
15#define ICMP6_FILTER_PASS 2
16#define ICMP6_FILTER_BLOCKOTHERS 3
17#define ICMP6_FILTER_PASSONLY 4
18
19struct icmp6_filter {
20    uint32_t icmp6_filt[8];
21};
22
23struct icmp6_hdr {
24    uint8_t icmp6_type;
25    uint8_t icmp6_code;
26    uint16_t icmp6_cksum;
27    union {
28        uint32_t icmp6_un_data32[1];
29        uint16_t icmp6_un_data16[2];
30        uint8_t icmp6_un_data8[4];
31    } icmp6_dataun;
32};
33
34#define icmp6_data32 icmp6_dataun.icmp6_un_data32
35#define icmp6_data16 icmp6_dataun.icmp6_un_data16
36#define icmp6_data8 icmp6_dataun.icmp6_un_data8
37#define icmp6_pptr icmp6_data32[0]
38#define icmp6_mtu icmp6_data32[0]
39#define icmp6_id icmp6_data16[0]
40#define icmp6_seq icmp6_data16[1]
41#define icmp6_maxdelay icmp6_data16[0]
42
43#define ICMP6_DST_UNREACH 1
44#define ICMP6_PACKET_TOO_BIG 2
45#define ICMP6_TIME_EXCEEDED 3
46#define ICMP6_PARAM_PROB 4
47
48#define ICMP6_INFOMSG_MASK 0x80
49
50#define ICMP6_ECHO_REQUEST 128
51#define ICMP6_ECHO_REPLY 129
52#define MLD_LISTENER_QUERY 130
53#define MLD_LISTENER_REPORT 131
54#define MLD_LISTENER_REDUCTION 132
55
56#define ICMP6_DST_UNREACH_NOROUTE 0
57#define ICMP6_DST_UNREACH_ADMIN 1
58#define ICMP6_DST_UNREACH_BEYONDSCOPE 2
59#define ICMP6_DST_UNREACH_ADDR 3
60#define ICMP6_DST_UNREACH_NOPORT 4
61
62#define ICMP6_TIME_EXCEED_TRANSIT 0
63#define ICMP6_TIME_EXCEED_REASSEMBLY 1
64
65#define ICMP6_PARAMPROB_HEADER 0
66#define ICMP6_PARAMPROB_NEXTHEADER 1
67#define ICMP6_PARAMPROB_OPTION 2
68
69#define ICMP6_FILTER_WILLPASS(type, filterp) \
70    ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type)&31))) == 0)
71
72#define ICMP6_FILTER_WILLBLOCK(type, filterp) \
73    ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type)&31))) != 0)
74
75#define ICMP6_FILTER_SETPASS(type, filterp) \
76    ((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type)&31))))
77
78#define ICMP6_FILTER_SETBLOCK(type, filterp) \
79    ((((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type)&31))))
80
81#define ICMP6_FILTER_SETPASSALL(filterp) memset(filterp, 0, sizeof(struct icmp6_filter));
82
83#define ICMP6_FILTER_SETBLOCKALL(filterp) memset(filterp, 0xFF, sizeof(struct icmp6_filter));
84
85#define ND_ROUTER_SOLICIT 133
86#define ND_ROUTER_ADVERT 134
87#define ND_NEIGHBOR_SOLICIT 135
88#define ND_NEIGHBOR_ADVERT 136
89#define ND_REDIRECT 137
90
91struct nd_router_solicit {
92    struct icmp6_hdr nd_rs_hdr;
93};
94
95#define nd_rs_type nd_rs_hdr.icmp6_type
96#define nd_rs_code nd_rs_hdr.icmp6_code
97#define nd_rs_cksum nd_rs_hdr.icmp6_cksum
98#define nd_rs_reserved nd_rs_hdr.icmp6_data32[0]
99
100struct nd_router_advert {
101    struct icmp6_hdr nd_ra_hdr;
102    uint32_t nd_ra_reachable;
103    uint32_t nd_ra_retransmit;
104};
105
106#define nd_ra_type nd_ra_hdr.icmp6_type
107#define nd_ra_code nd_ra_hdr.icmp6_code
108#define nd_ra_cksum nd_ra_hdr.icmp6_cksum
109#define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0]
110#define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1]
111#define ND_RA_FLAG_MANAGED 0x80
112#define ND_RA_FLAG_OTHER 0x40
113#define ND_RA_FLAG_HOME_AGENT 0x20
114#define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1]
115
116struct nd_neighbor_solicit {
117    struct icmp6_hdr nd_ns_hdr;
118    struct in6_addr nd_ns_target;
119};
120
121#define nd_ns_type nd_ns_hdr.icmp6_type
122#define nd_ns_code nd_ns_hdr.icmp6_code
123#define nd_ns_cksum nd_ns_hdr.icmp6_cksum
124#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]
125
126struct nd_neighbor_advert {
127    struct icmp6_hdr nd_na_hdr;
128    struct in6_addr nd_na_target;
129};
130
131#define nd_na_type nd_na_hdr.icmp6_type
132#define nd_na_code nd_na_hdr.icmp6_code
133#define nd_na_cksum nd_na_hdr.icmp6_cksum
134#define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0]
135#if __BYTE_ORDER == __BIG_ENDIAN
136#define ND_NA_FLAG_ROUTER 0x80000000
137#define ND_NA_FLAG_SOLICITED 0x40000000
138#define ND_NA_FLAG_OVERRIDE 0x20000000
139#else
140#define ND_NA_FLAG_ROUTER 0x00000080
141#define ND_NA_FLAG_SOLICITED 0x00000040
142#define ND_NA_FLAG_OVERRIDE 0x00000020
143#endif
144
145struct nd_redirect {
146    struct icmp6_hdr nd_rd_hdr;
147    struct in6_addr nd_rd_target;
148    struct in6_addr nd_rd_dst;
149};
150
151#define nd_rd_type nd_rd_hdr.icmp6_type
152#define nd_rd_code nd_rd_hdr.icmp6_code
153#define nd_rd_cksum nd_rd_hdr.icmp6_cksum
154#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
155
156struct nd_opt_hdr {
157    uint8_t nd_opt_type;
158    uint8_t nd_opt_len;
159};
160
161#define ND_OPT_SOURCE_LINKADDR 1
162#define ND_OPT_TARGET_LINKADDR 2
163#define ND_OPT_PREFIX_INFORMATION 3
164#define ND_OPT_REDIRECTED_HEADER 4
165#define ND_OPT_MTU 5
166#define ND_OPT_RTR_ADV_INTERVAL 7
167#define ND_OPT_HOME_AGENT_INFO 8
168
169struct nd_opt_prefix_info {
170    uint8_t nd_opt_pi_type;
171    uint8_t nd_opt_pi_len;
172    uint8_t nd_opt_pi_prefix_len;
173    uint8_t nd_opt_pi_flags_reserved;
174    uint32_t nd_opt_pi_valid_time;
175    uint32_t nd_opt_pi_preferred_time;
176    uint32_t nd_opt_pi_reserved2;
177    struct in6_addr nd_opt_pi_prefix;
178};
179
180#define ND_OPT_PI_FLAG_ONLINK 0x80
181#define ND_OPT_PI_FLAG_AUTO 0x40
182#define ND_OPT_PI_FLAG_RADDR 0x20
183
184struct nd_opt_rd_hdr {
185    uint8_t nd_opt_rh_type;
186    uint8_t nd_opt_rh_len;
187    uint16_t nd_opt_rh_reserved1;
188    uint32_t nd_opt_rh_reserved2;
189};
190
191struct nd_opt_mtu {
192    uint8_t nd_opt_mtu_type;
193    uint8_t nd_opt_mtu_len;
194    uint16_t nd_opt_mtu_reserved;
195    uint32_t nd_opt_mtu_mtu;
196};
197
198struct mld_hdr {
199    struct icmp6_hdr mld_icmp6_hdr;
200    struct in6_addr mld_addr;
201};
202
203#define mld_type mld_icmp6_hdr.icmp6_type
204#define mld_code mld_icmp6_hdr.icmp6_code
205#define mld_cksum mld_icmp6_hdr.icmp6_cksum
206#define mld_maxdelay mld_icmp6_hdr.icmp6_data16[0]
207#define mld_reserved mld_icmp6_hdr.icmp6_data16[1]
208
209#define ICMP6_ROUTER_RENUMBERING 138
210
211struct icmp6_router_renum {
212    struct icmp6_hdr rr_hdr;
213    uint8_t rr_segnum;
214    uint8_t rr_flags;
215    uint16_t rr_maxdelay;
216    uint32_t rr_reserved;
217};
218
219#define rr_type rr_hdr.icmp6_type
220#define rr_code rr_hdr.icmp6_code
221#define rr_cksum rr_hdr.icmp6_cksum
222#define rr_seqnum rr_hdr.icmp6_data32[0]
223
224#define ICMP6_RR_FLAGS_TEST 0x80
225#define ICMP6_RR_FLAGS_REQRESULT 0x40
226#define ICMP6_RR_FLAGS_FORCEAPPLY 0x20
227#define ICMP6_RR_FLAGS_SPECSITE 0x10
228#define ICMP6_RR_FLAGS_PREVDONE 0x08
229
230struct rr_pco_match {
231    uint8_t rpm_code;
232    uint8_t rpm_len;
233    uint8_t rpm_ordinal;
234    uint8_t rpm_matchlen;
235    uint8_t rpm_minlen;
236    uint8_t rpm_maxlen;
237    uint16_t rpm_reserved;
238    struct in6_addr rpm_prefix;
239};
240
241#define RPM_PCO_ADD 1
242#define RPM_PCO_CHANGE 2
243#define RPM_PCO_SETGLOBAL 3
244
245struct rr_pco_use {
246    uint8_t rpu_uselen;
247    uint8_t rpu_keeplen;
248    uint8_t rpu_ramask;
249    uint8_t rpu_raflags;
250    uint32_t rpu_vltime;
251    uint32_t rpu_pltime;
252    uint32_t rpu_flags;
253    struct in6_addr rpu_prefix;
254};
255
256#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x20
257#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10
258
259#if __BYTE_ORDER == __BIG_ENDIAN
260#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000
261#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000
262#else
263#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80
264#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40
265#endif
266
267struct rr_result {
268    uint16_t rrr_flags;
269    uint8_t rrr_ordinal;
270    uint8_t rrr_matchedlen;
271    uint32_t rrr_ifid;
272    struct in6_addr rrr_prefix;
273};
274
275#if __BYTE_ORDER == __BIG_ENDIAN
276#define ICMP6_RR_RESULT_FLAGS_OOB 0x0002
277#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001
278#else
279#define ICMP6_RR_RESULT_FLAGS_OOB 0x0200
280#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100
281#endif
282
283struct nd_opt_adv_interval {
284    uint8_t nd_opt_adv_interval_type;
285    uint8_t nd_opt_adv_interval_len;
286    uint16_t nd_opt_adv_interval_reserved;
287    uint32_t nd_opt_adv_interval_ival;
288};
289
290struct nd_opt_home_agent_info {
291    uint8_t nd_opt_home_agent_info_type;
292    uint8_t nd_opt_home_agent_info_len;
293    uint16_t nd_opt_home_agent_info_reserved;
294    uint16_t nd_opt_home_agent_info_preference;
295    uint16_t nd_opt_home_agent_info_lifetime;
296};
297
298#ifdef __cplusplus
299}
300#endif
301