|
|
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
//
// Copyright (c) 1985-2000 Microsoft Corporation
//
// This file is part of the Microsoft Research IPv6 Network Protocol Stack.
// You should have received a copy of the Microsoft End-User License Agreement
// for this software along with this release; see the file "license.txt".
// If not, please see http://www.research.microsoft.com/msripv6/license.htm,
// or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
//
// Abstract:
//
// Definitions derived from the IPv6 protocol specifications.
//
#ifndef IP6_INCLUDED
#define IP6_INCLUDED 1
#define IPV6_ADDRESS_LENGTH 128 // Bits in an address.
#define IPV6_ID_LENGTH 64 // Bits in an interface identifier.
//
// IPv6 Header Format.
// See RFC 1883, page 5 (and subsequent draft updates to same).
//
typedef struct IPv6Header { u_long VersClassFlow; // 4 bits Version, 8 Traffic Class, 20 Flow Label.
u_short PayloadLength; // Zero indicates Jumbo Payload hop-by-hop option.
u_char NextHeader; // Values are superset of IPv4's Protocol field.
u_char HopLimit; struct in6_addr Source; struct in6_addr Dest; } IPv6Header;
//
// Maximum value for the PayloadLength field.
// Note that the 40-byte IPv6 header is NOT included.
//
#define MAX_IPv6_PAYLOAD 65535
//
// Minimum size of an IPv6 link's MTU.
// Note that the 40-byte IPv6 header IS included,
// but any link-layer header is not.
//
#define IPv6_MINIMUM_MTU 1280
//
// Useful constants for working with various fields in the IPv6 header.
//
// NOTE: We keep the Version, Traffic Class and Flow Label fields as a single
// NOTE: 32 bit value (VersClassFlow) in network byte order (big-endian).
// NOTE: Since NT is little-endian, this means all loads/stores to/from this
// NOTE: field need to be byte swapped.
//
#define IP_VER_MASK 0x000000F0 // Version is high 4 bits of VersClassFlow.
#define IP_VERSION 0x00000060 // This is 6 << 28 (after byte swap).
#define IP_TRAFFIC_CLASS_MASK 0x0000F00F // 0x0FF00000 (after byte swap).
#define MAX_IP_PROTOCOL 255
//
// Protocol (i.e. "Next Header" field) values for included protocols.
//
#define IP_PROTOCOL_HOP_BY_HOP 0 // IPv6 Hop-by-Hop Options Header.
#define IP_PROTOCOL_ICMPv4 1 // IPv4 Internet Control Message Protocol.
#define IP_PROTOCOL_V6 41 // IPv6 Header.
#define IP_PROTOCOL_ROUTING 43 // IPv6 Routing Header.
#define IP_PROTOCOL_FRAGMENT 44 // IPv6 Fragment Header.
#define IP_PROTOCOL_ESP 50 // IPSec Encapsulating Security Payload Hdr.
#define IP_PROTOCOL_AH 51 // IPSec Authentication Hdr.
#define IP_PROTOCOL_ICMPv6 58 // IPv6 Internet Control Message Protocol.
#define IP_PROTOCOL_NONE 59 // No next header - ignore packet remainder.
#define IP_PROTOCOL_DEST_OPTS 60 // IPv6 Destination Options Header.
__inline int IsExtensionHeader(u_char Prot) { if ((Prot == IP_PROTOCOL_HOP_BY_HOP) || (Prot == IP_PROTOCOL_ROUTING) || (Prot == IP_PROTOCOL_FRAGMENT) || (Prot == IP_PROTOCOL_DEST_OPTS) || (Prot == IP_PROTOCOL_ESP) || (Prot == IP_PROTOCOL_AH)) return TRUE; return FALSE; }
//
// IPv6 type-length-value (TLV) encoded option types found in some
// extension headers. The upper two bits of each type are encoded
// so as to specify what action the node should take if it doesn't
// grok the option type. The third-highest-order bit specifies if
// the option data can change en-route to the final destination.
// See RFC 1883, section 4.2 (pages 9-10) for more information.
//
#define IPv6_OPT_ACTION_MASK 0xc0 // High two bits.
#define IPv6_OPT_DYNDATA_MASK 0x20 // Third-highest bit.
//
// Hop-by-Hop and Destination Options Headers.
// We use a single structure for both.
//
typedef struct IPv6OptionsHeader { u_char NextHeader; u_char HeaderExtLength; // In 8-byte units, not counting first 8.
} IPv6OptionsHeader;
//
// Routing Header.
//
typedef struct IPv6RoutingHeader { u_char NextHeader; u_char HeaderExtLength; // In 8-byte units, not counting first 8.
u_char RoutingType; u_char SegmentsLeft; // Number of nodes still left to be visited.
u_char Reserved[4]; // Not a u_int to avoid alignment.
} IPv6RoutingHeader;
//
// Fragment Header.
//
typedef struct FragmentHeader { u_char NextHeader; u_char Reserved; u_short OffsetFlag; // Offset is upper 13 bits, flag is lowest bit.
u_long Id; } FragmentHeader;
#define FRAGMENT_OFFSET_MASK 0xfff8
#define FRAGMENT_FLAG_MASK 0x0001
//
// Generic Extension Header.
//
typedef struct ExtensionHeader { u_char NextHeader; u_char HeaderExtLength; // In 8-byte units, not counting first 8.
} ExtensionHeader;
#define EXT_LEN_UNIT 8 // 8-byte units used for extension hdr length.
//
// Generic Options Header.
//
typedef struct OptionHeader { u_char Type; u_char DataLength; // In bytes, not counting two for the header.
} OptionHeader;
//
// Format of the router alert within the Hop-by-Hop Option header.
//
typedef struct IPv6RouterAlertOption { u_char Type; u_char Length; u_short Value; } IPv6RouterAlertOption;
//
// Mobile IPv6 destination option formats.
//
#pragma pack(1)
typedef struct IPv6BindingUpdateOption { u_char Type; u_char Length; u_char Flags; // See mask values below.
u_char PrefixLength; // Only used for "home registration" updates.
u_short SeqNumber; u_int Lifetime; // Number of seconds before binding expires.
} IPv6BindingUpdateOption; #pragma pack()
// Masks for the Flags field.
#define IPV6_BINDING_ACK 0x80 // Request a binding acknowledgement.
#define IPV6_BINDING_HOME_REG 0x40 // Request host to act as home agent.
#define IPV6_BINDING_ROUTER 0x20 // Sender is a router (valid w/ HOME_REG).
#define IPV6_BINDING_DAD 0x10 // Request HA perform DAD on home link.
typedef u_char BindingUpdateDisposition;
#pragma pack(1)
typedef struct IPv6BindingAcknowledgementOption { u_char Type; u_char Length; BindingUpdateDisposition Status; // Disposition of the MN's binding update.
u_short SeqNumber; u_int Lifetime; // Granted lifetime if binding accepted.
u_int Refresh; // Interval recommended to send new binging update.
} IPv6BindingAcknowledgementOption; #pragma pack()
// Disposition status values.
#define IPV6_BINDING_ACCEPTED 0
#define IPV6_BINDING_REJECTED 128 // Rejected for unspecified reason.
// was IPV6_BINDING_POORLY_FORMED 129 // Poorly formed binding update.
#define IPV6_BINDING_PROHIBITED 130 // Administratively prohibited.
#define IPV6_BINDING_NO_RESOURCES 131
#define IPV6_BINDING_HOME_REG_NOT_SUPPORTED 132 // Registration not supported.
#define IPV6_BINDING_NOT_HOME_SUBNET 133
#define IPV6_BINDING_SEQ_NO_TOO_SMALL 134 // Internal only - never on wire.
// was IPV6_BINDING_DYNAMIC_RESPONSE 135 // Dynamic HA discovery response.
#define IPV6_BINDING_BAD_IF_LENGTH 136 // Incorrect interface id length.
#define IPV6_BINDING_NOT_HOME_AGENT 137 // Not the HA for this mobile node.
#define IPV6_BINDING_DAD_FAILED 138 // DAD failed.
typedef struct IPv6BindingRequestOption { u_char Type; u_char Length; } IPv6BindingRequstOption;
#pragma pack(1)
typedef struct IPv6HomeAddressOption { u_char Type; u_char Length; struct in6_addr HomeAddress; } IPv6HomeAddressOption; #pragma pack()
typedef struct SubOptionHeader { u_char Type; u_char DataLength; // In bytes, not counting two for the header.
} SubOptionHeader;
#define SUBOPT6_UNIQUE_ID 1
#define SUBOPT6_HOME_AGENTS_LIST 2
#define SUBOPT6_CARE_OF_ADDRESS 4
#pragma pack(1)
typedef struct IPv6UniqueIdSubOption { u_char Type; u_char Length; u_short UniqueId; } IPv6UniqueIdSubOption; #pragma pack()
#pragma pack(1)
typedef struct IPv6HomeAgentsListSubOption { u_char Type; u_char Length; // The list of home agents follows at this point.
} IPv6HomeAgentsListSubOption; #pragma pack()
#pragma pack(1)
typedef struct IPv6CareOfAddrSubOption { u_char Type; u_char Length; struct in6_addr CareOfAddr; } IPv6CareOfAddrSubOption; #pragma pack()
// Option Header Values.
#define OPT6_PAD_1 0 // Single byte pad.
#define OPT6_PAD_N 1 // Multiple byte pad.
#define OPT6_JUMBO_PAYLOAD 194 // Jumbo payload (greater than 64KB).
#define OPT6_TUNNEL_ENCAP_LIMIT 4 // REVIEW: Tentative, waiting for IANA.
#define OPT6_ROUTER_ALERT 5 // REVIEW: Tentative, waiting for IANA.
// Options related to IPv6 Mobility.
// REVIEW: These are all tentative, waiting for IANA approval.
#define OPT6_BINDING_UPDATE 198
#define OPT6_BINDING_ACK 7
#define OPT6_BINDING_REQUEST 8
#define OPT6_HOME_ADDRESS 201
// Options we don't yet care about.
#define OPT6_ENDPOINT_ID 168 // Charles Lynn?
#define OPT6_NSAP_ADDR 195 // RFC 1888.
// REVIEW: The below duplicates the IPv6_OPT_* stuff above.
// REVIEW: The above is nicely commented, but the below is what we use.
// Type of actions to be taken with unrecognized header options.
#define OPT6_ACTION(a) ((a) & 0xc0) // Get action bits.
#define OPT6_A_SKIP 0x00 // Skip and continue.
#define OPT6_A_DISCARD 0x40 // Discard packet.
#define OPT6_A_SEND_ICMP_ALL 0x80 // Send ICMP regardless of source addr.
#define OPT6_A_SEND_ICMP_NON_MULTI 0xc0 // Send ICMP if non-multicast src addr.
// Determining whether and option is mutiple or not.
#define OPT6_MUTABLE 0x20
#define OPT6_ISMUTABLE(t) ((t) & OPT6_MUTABLE)
//
// Authentication Header.
//
// The header conceptually includes a variable amount of Authentication Data
// which follows these fixed-size fields.
//
// Calling this "AHHeader" is redundant, but then again so is "TCP Protocol".
//
typedef struct AHHeader { u_char NextHeader; u_char PayloadLen; // In 4-byte units, not counting first 8 bytes.
u_short Reserved; // Padding. Must be zero on transmit.
u_long SPI; // Security Parameters Index.
u_long Seq; // Sequence number for anti-replay algorithms.
} AHHeader;
//
// Encapsulating Security Payload header and trailer.
//
// The header is followed by a variable amount of payload data, followed by
// a variable amount of padding (255 bytes maximum), followed by a byte for
// the Pad Length and a byte for the Next Header field, followed by a
// variable amount of Authentication Data.
//
// The amount of padding should be picked such that the Pad Length and
// Next Header field end up aligned on a 32 bit boundary.
//
typedef struct ESPHeader{ u_long SPI; // Security Parameters Index.
u_long Seq; // Sequence number for anti-replay algorithms.
} ESPHeader;
typedef struct ESPTrailer{ u_char PadLength; // Number of bytes in pad.
u_char NextHeader; } ESPTrailer;
#endif // IP6_INCLUDED
|