4 * Internet Protocol, Version 6 (RFC 2460).
6 * Copyright (c) 2002 Dug Song <dugsong@monkey.org>
8 * $Id: ip6.h,v 1.6 2004/02/23 10:01:15 dugsong Exp $
14 #define IP6_ADDR_LEN 16
15 #define IP6_ADDR_BITS 128
17 #define IP6_HDR_LEN 40 /* IPv6 header length */
18 #define IP6_LEN_MIN IP6_HDR_LEN
19 #define IP6_LEN_MAX 65535 /* non-jumbo payload */
21 #define IP6_MTU_MIN 1280 /* minimum MTU (1024 + 256) */
23 typedef struct ip6_addr
{
24 uint8_t data
[IP6_ADDR_LEN
];
28 # define __attribute__(x)
38 uint32_t ip6_un1_flow
; /* 20 bits of flow ID */
39 uint16_t ip6_un1_plen
; /* payload length */
40 uint8_t ip6_un1_nxt
; /* next header */
41 uint8_t ip6_un1_hlim
; /* hop limit */
43 uint8_t ip6_un2_vfc
; /* 4 bits version, top 4 bits class */
47 } __attribute__((__packed__
));
49 #define ip6_vfc ip6_ctlun.ip6_un2_vfc
50 #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
51 #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
52 #define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt /* IP_PROTO_* */
53 #define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
55 #define IP6_VERSION 0x60
56 #define IP6_VERSION_MASK 0xf0 /* ip6_vfc version */
58 #if DNET_BYTESEX == DNET_BIG_ENDIAN
59 #define IP6_FLOWINFO_MASK 0x0fffffff /* ip6_flow info (28 bits) */
60 #define IP6_FLOWLABEL_MASK 0x000fffff /* ip6_flow label (20 bits) */
61 #elif DNET_BYTESEX == DNET_LIL_ENDIAN
62 #define IP6_FLOWINFO_MASK 0xffffff0f /* ip6_flow info (28 bits) */
63 #define IP6_FLOWLABEL_MASK 0xffff0f00 /* ip6_flow label (20 bits) */
67 * Hop limit (ip6_hlim)
69 #define IP6_HLIM_DEFAULT 64
70 #define IP6_HLIM_MAX 255
73 * Preferred extension header order from RFC 2460, 4.1:
75 * IP_PROTO_IPV6, IP_PROTO_HOPOPTS, IP_PROTO_DSTOPTS, IP_PROTO_ROUTING,
76 * IP_PROTO_FRAGMENT, IP_PROTO_AH, IP_PROTO_ESP, IP_PROTO_DSTOPTS, IP_PROTO_*
80 * Routing header data (IP_PROTO_ROUTING)
82 struct ip6_ext_data_routing
{
83 uint8_t type
; /* routing type */
84 uint8_t segleft
; /* segments left */
85 /* followed by routing type specific data */
86 } __attribute__((__packed__
));
88 struct ip6_ext_data_routing0
{
89 uint8_t type
; /* always zero */
90 uint8_t segleft
; /* segments left */
91 uint8_t reserved
; /* reserved field */
92 uint8_t slmap
[3]; /* strict/loose bit map */
93 ip6_addr_t addr
[1]; /* up to 23 addresses */
94 } __attribute__((__packed__
));
97 * Fragment header data (IP_PROTO_FRAGMENT)
99 struct ip6_ext_data_fragment
{
100 uint16_t offlg
; /* offset, reserved, and flag */
101 uint32_t ident
; /* identification */
102 } __attribute__((__packed__
));
105 * Fragmentation offset, reserved, and flags (offlg)
107 #if DNET_BYTESEX == DNET_BIG_ENDIAN
108 #define IP6_OFF_MASK 0xfff8 /* mask out offset from offlg */
109 #define IP6_RESERVED_MASK 0x0006 /* reserved bits in offlg */
110 #define IP6_MORE_FRAG 0x0001 /* more-fragments flag */
111 #elif DNET_BYTESEX == DNET_LIL_ENDIAN
112 #define IP6_OFF_MASK 0xf8ff /* mask out offset from offlg */
113 #define IP6_RESERVED_MASK 0x0600 /* reserved bits in offlg */
114 #define IP6_MORE_FRAG 0x0100 /* more-fragments flag */
118 * Option types, for IP_PROTO_HOPOPTS, IP_PROTO_DSTOPTS headers
120 #define IP6_OPT_PAD1 0x00 /* 00 0 00000 */
121 #define IP6_OPT_PADN 0x01 /* 00 0 00001 */
122 #define IP6_OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
123 #define IP6_OPT_JUMBO_LEN 6
124 #define IP6_OPT_RTALERT 0x05 /* 00 0 00101 */
125 #define IP6_OPT_RTALERT_LEN 4
126 #define IP6_OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */
127 #define IP6_OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */
128 #define IP6_OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */
129 #define IP6_OPT_LEN_MIN 2
131 #define IP6_OPT_TYPE(o) ((o) & 0xC0) /* high 2 bits of opt_type */
132 #define IP6_OPT_TYPE_SKIP 0x00 /* continue processing on failure */
133 #define IP6_OPT_TYPE_DISCARD 0x40 /* discard packet on failure */
134 #define IP6_OPT_TYPE_FORCEICMP 0x80 /* discard and send ICMP on failure */
135 #define IP6_OPT_TYPE_ICMP 0xC0 /* ...only if non-multicast dst */
137 #define IP6_OPT_MUTABLE 0x20 /* option data may change en route */
140 * Extension header (chained via {ip6,ext}_nxt, following IPv6 header)
143 uint8_t ext_nxt
; /* next header */
144 uint8_t ext_len
; /* following length in units of 8 octets */
146 struct ip6_ext_data_routing routing
;
147 struct ip6_ext_data_fragment fragment
;
149 } __attribute__((__packed__
));
158 #define IP6_ADDR_UNSPEC \
159 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
160 #define IP6_ADDR_LOOPBACK \
161 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
163 #define ip6_pack_hdr(hdr, fc, fl, plen, nxt, hlim, src, dst) do { \
164 struct ip6_hdr *ip6 = (struct ip6_hdr *)(hdr); \
165 ip6->ip6_flow = htonl(((uint32_t)(fc) << 28) & \
166 (IP6_FLOWLABEL_MASK | (fl))); \
167 ip6->ip6_vfc = (IP6_VERSION | ((fc) >> 4)); \
168 ip6->ip6_plen = htons((plen)); \
169 ip6->ip6_nxt = (nxt); ip6->ip6_hlim = (hlim); \
170 memmove(&ip6->ip6_src, &(src), IP6_ADDR_LEN); \
171 memmove(&ip6->ip6_dst, &(dst), IP6_ADDR_LEN); \
175 char *ip6_ntop(const ip6_addr_t
*ip6
, char *dst
, size_t size
);
176 int ip6_pton(const char *src
, ip6_addr_t
*dst
);
177 char *ip6_ntoa(const ip6_addr_t
*ip6
);
178 #define ip6_aton ip6_pton
180 void ip6_checksum(void *buf
, size_t len
);
183 #endif /* DNET_IP6_H */