1/* 2 * ip6.h 3 * 4 * Internet Protocol, Version 6 (RFC 2460). 5 * 6 * Copyright (c) 2002 Dug Song <dugsong@monkey.org> 7 * 8 * $Id: ip6.h,v 1.6 2004/02/23 10:01:15 dugsong Exp $ 9 */ 10 11#ifndef DNET_IP6_H 12#define DNET_IP6_H 13 14#define IP6_ADDR_LEN 16 15#define IP6_ADDR_BITS 128 16 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 */ 20 21#define IP6_MTU_MIN 1280 /* minimum MTU (1024 + 256) */ 22 23typedef struct ip6_addr { 24 uint8_t data[IP6_ADDR_LEN]; 25} ip6_addr_t; 26 27#ifndef __GNUC__ 28# define __attribute__(x) 29# pragma pack(1) 30#endif 31 32/* 33 * IPv6 header 34 */ 35struct ip6_hdr { 36 union { 37 struct ip6_hdr_ctl { 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 */ 42 } ip6_un1; 43 uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */ 44 } ip6_ctlun; 45 ip6_addr_t ip6_src; 46 ip6_addr_t ip6_dst; 47} __attribute__((__packed__)); 48 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 54 55#define IP6_VERSION 0x60 56#define IP6_VERSION_MASK 0xf0 /* ip6_vfc version */ 57 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) */ 64#endif 65 66/* 67 * Hop limit (ip6_hlim) 68 */ 69#define IP6_HLIM_DEFAULT 64 70#define IP6_HLIM_MAX 255 71 72/* 73 * Preferred extension header order from RFC 2460, 4.1: 74 * 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_* 77 */ 78 79/* 80 * Routing header data (IP_PROTO_ROUTING) 81 */ 82struct 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__)); 87 88struct 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__)); 95 96/* 97 * Fragment header data (IP_PROTO_FRAGMENT) 98 */ 99struct ip6_ext_data_fragment { 100 uint16_t offlg; /* offset, reserved, and flag */ 101 uint32_t ident; /* identification */ 102} __attribute__((__packed__)); 103 104/* 105 * Fragmentation offset, reserved, and flags (offlg) 106 */ 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 */ 115#endif 116 117/* 118 * Option types, for IP_PROTO_HOPOPTS, IP_PROTO_DSTOPTS headers 119 */ 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 130 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 */ 136 137#define IP6_OPT_MUTABLE 0x20 /* option data may change en route */ 138 139/* 140 * Extension header (chained via {ip6,ext}_nxt, following IPv6 header) 141 */ 142struct ip6_ext_hdr { 143 uint8_t ext_nxt; /* next header */ 144 uint8_t ext_len; /* following length in units of 8 octets */ 145 union { 146 struct ip6_ext_data_routing routing; 147 struct ip6_ext_data_fragment fragment; 148 } ext_data; 149} __attribute__((__packed__)); 150 151#ifndef __GNUC__ 152# pragma pack() 153#endif 154 155/* 156 * Reserved addresses 157 */ 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" 162 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); \ 172} while (0); 173 174__BEGIN_DECLS 175char *ip6_ntop(const ip6_addr_t *ip6, char *dst, size_t size); 176int ip6_pton(const char *src, ip6_addr_t *dst); 177char *ip6_ntoa(const ip6_addr_t *ip6); 178#define ip6_aton ip6_pton 179 180void ip6_checksum(void *buf, size_t len); 181__END_DECLS 182 183#endif /* DNET_IP6_H */ 184