12632SN/A/* 22632SN/A * ip6.h 32632SN/A * 42632SN/A * Internet Protocol, Version 6 (RFC 2460). 52632SN/A * 62632SN/A * Copyright (c) 2002 Dug Song <dugsong@monkey.org> 72632SN/A * 82632SN/A * $Id: ip6.h,v 1.6 2004/02/23 10:01:15 dugsong Exp $ 92632SN/A */ 102632SN/A 112632SN/A#ifndef DNET_IP6_H 122632SN/A#define DNET_IP6_H 132632SN/A 142632SN/A#define IP6_ADDR_LEN 16 152632SN/A#define IP6_ADDR_BITS 128 162632SN/A 172632SN/A#define IP6_HDR_LEN 40 /* IPv6 header length */ 182632SN/A#define IP6_LEN_MIN IP6_HDR_LEN 192632SN/A#define IP6_LEN_MAX 65535 /* non-jumbo payload */ 202632SN/A 212632SN/A#define IP6_MTU_MIN 1280 /* minimum MTU (1024 + 256) */ 222632SN/A 232632SN/Atypedef struct ip6_addr { 242632SN/A uint8_t data[IP6_ADDR_LEN]; 252632SN/A} ip6_addr_t; 262632SN/A 272632SN/A#ifndef __GNUC__ 282632SN/A# define __attribute__(x) 292632SN/A# pragma pack(1) 302632SN/A#endif 312632SN/A 322632SN/A/* 332632SN/A * IPv6 header 342632SN/A */ 352632SN/Astruct ip6_hdr { 362632SN/A union { 372632SN/A struct ip6_hdr_ctl { 382632SN/A uint32_t ip6_un1_flow; /* 20 bits of flow ID */ 392632SN/A uint16_t ip6_un1_plen; /* payload length */ 402632SN/A uint8_t ip6_un1_nxt; /* next header */ 412632SN/A uint8_t ip6_un1_hlim; /* hop limit */ 422632SN/A } ip6_un1; 432632SN/A uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */ 442632SN/A } ip6_ctlun; 452632SN/A ip6_addr_t ip6_src; 462632SN/A ip6_addr_t ip6_dst; 472632SN/A} __attribute__((__packed__)); 482632SN/A 492632SN/A#define ip6_vfc ip6_ctlun.ip6_un2_vfc 502632SN/A#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow 512632SN/A#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen 522632SN/A#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt /* IP_PROTO_* */ 532632SN/A#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim 542632SN/A 552632SN/A#define IP6_VERSION 0x60 562632SN/A#define IP6_VERSION_MASK 0xf0 /* ip6_vfc version */ 572632SN/A 582632SN/A#if DNET_BYTESEX == DNET_BIG_ENDIAN 592632SN/A#define IP6_FLOWINFO_MASK 0x0fffffff /* ip6_flow info (28 bits) */ 602632SN/A#define IP6_FLOWLABEL_MASK 0x000fffff /* ip6_flow label (20 bits) */ 612632SN/A#elif DNET_BYTESEX == DNET_LIL_ENDIAN 622632SN/A#define IP6_FLOWINFO_MASK 0xffffff0f /* ip6_flow info (28 bits) */ 632632SN/A#define IP6_FLOWLABEL_MASK 0xffff0f00 /* ip6_flow label (20 bits) */ 642632SN/A#endif 652632SN/A 662632SN/A/* 672632SN/A * Hop limit (ip6_hlim) 682632SN/A */ 692632SN/A#define IP6_HLIM_DEFAULT 64 702632SN/A#define IP6_HLIM_MAX 255 712632SN/A 722632SN/A/* 732632SN/A * Preferred extension header order from RFC 2460, 4.1: 742632SN/A * 752632SN/A * IP_PROTO_IPV6, IP_PROTO_HOPOPTS, IP_PROTO_DSTOPTS, IP_PROTO_ROUTING, 762632SN/A * IP_PROTO_FRAGMENT, IP_PROTO_AH, IP_PROTO_ESP, IP_PROTO_DSTOPTS, IP_PROTO_* 772632SN/A */ 782632SN/A 792632SN/A/* 802632SN/A * Routing header data (IP_PROTO_ROUTING) 812632SN/A */ 822632SN/Astruct ip6_ext_data_routing { 832632SN/A uint8_t type; /* routing type */ 842632SN/A uint8_t segleft; /* segments left */ 852632SN/A /* followed by routing type specific data */ 862632SN/A} __attribute__((__packed__)); 872632SN/A 882632SN/Astruct ip6_ext_data_routing0 { 892632SN/A uint8_t type; /* always zero */ 902632SN/A uint8_t segleft; /* segments left */ 912632SN/A uint8_t reserved; /* reserved field */ 922632SN/A uint8_t slmap[3]; /* strict/loose bit map */ 932632SN/A ip6_addr_t addr[1]; /* up to 23 addresses */ 942632SN/A} __attribute__((__packed__)); 952632SN/A 962632SN/A/* 972632SN/A * Fragment header data (IP_PROTO_FRAGMENT) 982632SN/A */ 992632SN/Astruct ip6_ext_data_fragment { 1002632SN/A uint16_t offlg; /* offset, reserved, and flag */ 1012632SN/A uint32_t ident; /* identification */ 1022632SN/A} __attribute__((__packed__)); 1032632SN/A 1042632SN/A/* 1052632SN/A * Fragmentation offset, reserved, and flags (offlg) 1062632SN/A */ 1072632SN/A#if DNET_BYTESEX == DNET_BIG_ENDIAN 1082632SN/A#define IP6_OFF_MASK 0xfff8 /* mask out offset from offlg */ 1092632SN/A#define IP6_RESERVED_MASK 0x0006 /* reserved bits in offlg */ 1102632SN/A#define IP6_MORE_FRAG 0x0001 /* more-fragments flag */ 1112632SN/A#elif DNET_BYTESEX == DNET_LIL_ENDIAN 1122632SN/A#define IP6_OFF_MASK 0xf8ff /* mask out offset from offlg */ 1132632SN/A#define IP6_RESERVED_MASK 0x0600 /* reserved bits in offlg */ 1142632SN/A#define IP6_MORE_FRAG 0x0100 /* more-fragments flag */ 1152632SN/A#endif 1162632SN/A 1172632SN/A/* 1182632SN/A * Option types, for IP_PROTO_HOPOPTS, IP_PROTO_DSTOPTS headers 1192632SN/A */ 1202632SN/A#define IP6_OPT_PAD1 0x00 /* 00 0 00000 */ 1212632SN/A#define IP6_OPT_PADN 0x01 /* 00 0 00001 */ 1222632SN/A#define IP6_OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */ 1232632SN/A#define IP6_OPT_JUMBO_LEN 6 1242632SN/A#define IP6_OPT_RTALERT 0x05 /* 00 0 00101 */ 1252632SN/A#define IP6_OPT_RTALERT_LEN 4 1262632SN/A#define IP6_OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */ 1272632SN/A#define IP6_OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */ 1282632SN/A#define IP6_OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */ 1292632SN/A#define IP6_OPT_LEN_MIN 2 1302632SN/A 1312632SN/A#define IP6_OPT_TYPE(o) ((o) & 0xC0) /* high 2 bits of opt_type */ 1322632SN/A#define IP6_OPT_TYPE_SKIP 0x00 /* continue processing on failure */ 1332632SN/A#define IP6_OPT_TYPE_DISCARD 0x40 /* discard packet on failure */ 1342632SN/A#define IP6_OPT_TYPE_FORCEICMP 0x80 /* discard and send ICMP on failure */ 1352632SN/A#define IP6_OPT_TYPE_ICMP 0xC0 /* ...only if non-multicast dst */ 1362632SN/A 1372632SN/A#define IP6_OPT_MUTABLE 0x20 /* option data may change en route */ 1382632SN/A 1392632SN/A/* 1402632SN/A * Extension header (chained via {ip6,ext}_nxt, following IPv6 header) 1412632SN/A */ 1422632SN/Astruct ip6_ext_hdr { 1432632SN/A uint8_t ext_nxt; /* next header */ 1442632SN/A uint8_t ext_len; /* following length in units of 8 octets */ 1452632SN/A union { 1462632SN/A struct ip6_ext_data_routing routing; 1472632SN/A struct ip6_ext_data_fragment fragment; 1482632SN/A } ext_data; 1492632SN/A} __attribute__((__packed__)); 1502632SN/A 1512632SN/A#ifndef __GNUC__ 1522632SN/A# pragma pack() 1532632SN/A#endif 1542632SN/A 1552632SN/A/* 1562632SN/A * Reserved addresses 1572632SN/A */ 1582632SN/A#define IP6_ADDR_UNSPEC \ 1592632SN/A "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 1602632SN/A#define IP6_ADDR_LOOPBACK \ 1612632SN/A "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" 1622632SN/A 1632632SN/A#define ip6_pack_hdr(hdr, fc, fl, plen, nxt, hlim, src, dst) do { \ 1642632SN/A struct ip6_hdr *ip6 = (struct ip6_hdr *)(hdr); \ 1652632SN/A ip6->ip6_flow = htonl(((uint32_t)(fc) << 28) & \ 1662632SN/A (IP6_FLOWLABEL_MASK | (fl))); \ 1672632SN/A ip6->ip6_vfc = (IP6_VERSION | ((fc) >> 4)); \ 1682632SN/A ip6->ip6_plen = htons((plen)); \ 1692632SN/A ip6->ip6_nxt = (nxt); ip6->ip6_hlim = (hlim); \ 1702632SN/A memmove(&ip6->ip6_src, &(src), IP6_ADDR_LEN); \ 1712632SN/A memmove(&ip6->ip6_dst, &(dst), IP6_ADDR_LEN); \ 1722632SN/A} while (0); 1732632SN/A 1742632SN/A__BEGIN_DECLS 1752632SN/Achar *ip6_ntop(const ip6_addr_t *ip6, char *dst, size_t size); 1762632SN/Aint ip6_pton(const char *src, ip6_addr_t *dst); 1772632SN/Achar *ip6_ntoa(const ip6_addr_t *ip6); 1782632SN/A#define ip6_aton ip6_pton 1792632SN/A 1802632SN/Avoid ip6_checksum(void *buf, size_t len); 1812632SN/A__END_DECLS 1822632SN/A 1832632SN/A#endif /* DNET_IP6_H */ 184