1 #pragma once
2 
3 #ifdef __cplusplus
4 extern "C" {
5 #endif
6 
7 #include <endian.h>
8 #include <netinet/in.h>
9 #include <stdint.h>
10 
11 struct ip6_hdr {
12     union {
13         struct ip6_hdrctl {
14             uint32_t ip6_un1_flow;
15             uint16_t ip6_un1_plen;
16             uint8_t ip6_un1_nxt;
17             uint8_t ip6_un1_hlim;
18         } ip6_un1;
19         uint8_t ip6_un2_vfc;
20     } ip6_ctlun;
21     struct in6_addr ip6_src;
22     struct in6_addr ip6_dst;
23 };
24 
25 #define ip6_vfc ip6_ctlun.ip6_un2_vfc
26 #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
27 #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
28 #define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
29 #define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
30 #define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
31 
32 struct ip6_ext {
33     uint8_t ip6e_nxt;
34     uint8_t ip6e_len;
35 };
36 
37 struct ip6_hbh {
38     uint8_t ip6h_nxt;
39     uint8_t ip6h_len;
40 };
41 
42 struct ip6_dest {
43     uint8_t ip6d_nxt;
44     uint8_t ip6d_len;
45 };
46 
47 struct ip6_rthdr {
48     uint8_t ip6r_nxt;
49     uint8_t ip6r_len;
50     uint8_t ip6r_type;
51     uint8_t ip6r_segleft;
52 };
53 
54 struct ip6_rthdr0 {
55     uint8_t ip6r0_nxt;
56     uint8_t ip6r0_len;
57     uint8_t ip6r0_type;
58     uint8_t ip6r0_segleft;
59     uint8_t ip6r0_reserved;
60     uint8_t ip6r0_slmap[3];
61     struct in6_addr ip6r0_addr[];
62 };
63 
64 struct ip6_frag {
65     uint8_t ip6f_nxt;
66     uint8_t ip6f_reserved;
67     uint16_t ip6f_offlg;
68     uint32_t ip6f_ident;
69 };
70 
71 #if __BYTE_ORDER == __BIG_ENDIAN
72 #define IP6F_OFF_MASK 0xfff8
73 #define IP6F_RESERVED_MASK 0x0006
74 #define IP6F_MORE_FRAG 0x0001
75 #else
76 #define IP6F_OFF_MASK 0xf8ff
77 #define IP6F_RESERVED_MASK 0x0600
78 #define IP6F_MORE_FRAG 0x0100
79 #endif
80 
81 struct ip6_opt {
82     uint8_t ip6o_type;
83     uint8_t ip6o_len;
84 };
85 
86 #define IP6OPT_TYPE(o) ((o)&0xc0)
87 #define IP6OPT_TYPE_SKIP 0x00
88 #define IP6OPT_TYPE_DISCARD 0x40
89 #define IP6OPT_TYPE_FORCEICMP 0x80
90 #define IP6OPT_TYPE_ICMP 0xc0
91 #define IP6OPT_TYPE_MUTABLE 0x20
92 
93 #define IP6OPT_PAD1 0
94 #define IP6OPT_PADN 1
95 
96 #define IP6OPT_JUMBO 0xc2
97 #define IP6OPT_NSAP_ADDR 0xc3
98 #define IP6OPT_TUNNEL_LIMIT 0x04
99 #define IP6OPT_ROUTER_ALERT 0x05
100 
101 struct ip6_opt_jumbo {
102     uint8_t ip6oj_type;
103     uint8_t ip6oj_len;
104     uint8_t ip6oj_jumbo_len[4];
105 };
106 #define IP6OPT_JUMBO_LEN 6
107 
108 struct ip6_opt_nsap {
109     uint8_t ip6on_type;
110     uint8_t ip6on_len;
111     uint8_t ip6on_src_nsap_len;
112     uint8_t ip6on_dst_nsap_len;
113 };
114 
115 struct ip6_opt_tunnel {
116     uint8_t ip6ot_type;
117     uint8_t ip6ot_len;
118     uint8_t ip6ot_encap_limit;
119 };
120 
121 struct ip6_opt_router {
122     uint8_t ip6or_type;
123     uint8_t ip6or_len;
124     uint8_t ip6or_value[2];
125 };
126 
127 #if __BYTE_ORDER == __BIG_ENDIAN
128 #define IP6_ALERT_MLD 0x0000
129 #define IP6_ALERT_RSVP 0x0001
130 #define IP6_ALERT_AN 0x0002
131 #else
132 #define IP6_ALERT_MLD 0x0000
133 #define IP6_ALERT_RSVP 0x0100
134 #define IP6_ALERT_AN 0x0200
135 #endif
136 
137 #ifdef __cplusplus
138 }
139 #endif
140