199 lines
6.6 KiB
C
199 lines
6.6 KiB
C
// -*- 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 for using IPv4 as a link-layer for IPv6.
|
|
//
|
|
|
|
|
|
#ifndef TUNNEL_INCLUDED
|
|
#define TUNNEL_INCLUDED 1
|
|
|
|
//
|
|
// A few IPv4 definitions that we need.
|
|
// Including the v4 header files causes errors.
|
|
// REVIEW: can we fix this?
|
|
//
|
|
|
|
#define INADDR_LOOPBACK 0x0100007f
|
|
|
|
|
|
//
|
|
// IP Header format.
|
|
//
|
|
typedef struct IPHeader {
|
|
uchar iph_verlen; // Version and length.
|
|
uchar iph_tos; // Type of service.
|
|
ushort iph_length; // Total length of datagram.
|
|
ushort iph_id; // Identification.
|
|
ushort iph_offset; // Flags and fragment offset.
|
|
uchar iph_ttl; // Time to live.
|
|
uchar iph_protocol; // Protocol.
|
|
ushort iph_xsum; // Header checksum.
|
|
IPAddr iph_src; // Source address.
|
|
IPAddr iph_dest; // Destination address.
|
|
} IPHeader;
|
|
|
|
//
|
|
// ICMP Header format.
|
|
//
|
|
typedef struct ICMPHeader {
|
|
uchar ich_type; // Type of ICMP packet.
|
|
uchar ich_code; // Subcode of type.
|
|
ushort ich_xsum; // Checksum of packet.
|
|
ulong ich_param; // Type-specific parameter field.
|
|
} ICMPHeader;
|
|
|
|
#define ICMP_DEST_UNREACH 3
|
|
#define ICMP_SOURCE_QUENCH 4
|
|
#define ICMP_TIME_EXCEED 11
|
|
#define ICMP_PARAM_PROBLEM 12
|
|
|
|
#define ICMP_TTL_IN_TRANSIT 0
|
|
#define ICMP_TTL_IN_REASSEM 1
|
|
|
|
#define ICMP_NET_UNREACH 0
|
|
#define ICMP_HOST_UNREACH 1
|
|
#define ICMP_PROT_UNREACH 2
|
|
#define ICMP_PORT_UNREACH 3
|
|
#define ICMP_FRAG_NEEDED 4
|
|
#define ICMP_SR_FAILED 5
|
|
#define ICMP_DEST_NET_UNKNOWN 6
|
|
#define ICMP_DEST_HOST_UNKNOWN 7
|
|
#define ICMP_SRC_ISOLATED 8
|
|
#define ICMP_DEST_NET_ADMIN 9
|
|
#define ICMP_DEST_HOST_ADMIN 10
|
|
#define ICMP_NET_UNREACH_TOS 11
|
|
#define ICMP_HOST_UNREACH_TOS 12
|
|
|
|
//
|
|
// Tunnel protocol constants.
|
|
//
|
|
#define WideStr(x) L#x
|
|
#define TUNNEL_DEVICE_NAME(proto) (DD_RAW_IP_DEVICE_NAME L"\\" WideStr(proto))
|
|
#define TUNNEL_6OVER4_TTL 16
|
|
|
|
//
|
|
// We don't yet support Path MTU Discovery inside a tunnel,
|
|
// so we use a single MTU for the tunnel.
|
|
// Our buffer size for receiving IPv4 packets must be larger
|
|
// than that MTU, because other implementations might use
|
|
// a different value for their tunnel MTU.
|
|
//
|
|
#define TUNNEL_DEFAULT_MTU IPv6_MINIMUM_MTU
|
|
#define TUNNEL_MAX_MTU (64 * 1024 - sizeof(IPHeader) - 1)
|
|
#define TUNNEL_RECEIVE_BUFFER (64 * 1024)
|
|
#define TUNNEL_DEFAULT_PREFERENCE 1
|
|
|
|
//
|
|
// Each tunnel interface (including the pseudo-interface)
|
|
// provides a TunnelContext to the IPv6 code as its link-level context.
|
|
//
|
|
// Each tunnel interface uses a separate v4 TDI address object
|
|
// for sending packets. This allows v4 attributes of the packets
|
|
// (like source address and TTL) to be controlled individually
|
|
// for each tunnel interface.
|
|
//
|
|
// The pseudo-tunnel interface does not control the v4 source address
|
|
// of the packets that it sends; the v4 stack is free to chose
|
|
// any v4 address. Note that this means a packet with a v4-compatible
|
|
// v6 source address might be sent using a v4 source address
|
|
// that is not derived from the v6 source address.
|
|
//
|
|
// The 6-over-4 and point-to-point virtual interfaces, however,
|
|
// do strictly control the v4 source addresses of their packets.
|
|
// As "real" interfaces, they participate in Neighbor Discovery
|
|
// and their link-level (v4) address is important.
|
|
//
|
|
// In contrast to sending, the receive path uses a single address object
|
|
// for all tunnel interfaces. We use the TDI address object
|
|
// associated with the pseudo-interface; because it's bound to INADDR_ANY
|
|
// it receives all encapsulated v6 packets sent to the machine.
|
|
//
|
|
|
|
typedef struct TunnelContext {
|
|
struct TunnelContext *Prev, *Next;
|
|
|
|
//
|
|
// This DstAddr must follow SrcAddr in memory;
|
|
// see BindInfo.lip_addr initialization.
|
|
//
|
|
IPAddr SrcAddr; // Our v4 address.
|
|
IPAddr DstAddr; // Address of the other tunnel endpoint.
|
|
// (Zero for 6-over-4 tunnels.)
|
|
IPAddr TokenAddr; // The link-layer address. Same as
|
|
// SrcAddr on interfaces except the ISATAP one.
|
|
|
|
Interface *IF; // Holds a reference.
|
|
|
|
//
|
|
// This field is effectively locked by IF->WorkerLock.
|
|
//
|
|
int SetMCListOK; // Can TunnelSetMulticastAddressList proceed?
|
|
|
|
//
|
|
// Although we only use AOFile (the pointer version of AOHandle),
|
|
// we must keep AOHandle open so AOFile will work. AOHandle
|
|
// is in the kernel process context, so any open/close operations
|
|
// must be done in the kernel process context.
|
|
//
|
|
PFILE_OBJECT AOFile;
|
|
HANDLE AOHandle;
|
|
} TunnelContext;
|
|
|
|
//
|
|
// Information we keep globally.
|
|
//
|
|
// The spinlock and the mutex are used together to protect
|
|
// the chains of tunnel contexts rooted at Tunnel.List and Tunnel.AOList.
|
|
// Both must be held to modify a list; either is sufficient for read.
|
|
// If both are acquired, the order is mutex first then spinlock.
|
|
//
|
|
typedef struct TunnelGlobals {
|
|
KSPIN_LOCK Lock;
|
|
KMUTEX Mutex;
|
|
|
|
PDEVICE_OBJECT V4Device; // Does not hold a reference.
|
|
|
|
//
|
|
// List.IF is NULL; it is not a context for an interface.
|
|
// But the other fields (particularly AOFile and AOHandle)
|
|
// do store global values.
|
|
//
|
|
TunnelContext List; // List of tunnel contexts.
|
|
|
|
// Used by TunnelReceive/TunnelReceiveComplete.
|
|
PIRP ReceiveIrp; // Protected by Tunnel.Lock.
|
|
TDI_CONNECTION_INFORMATION ReceiveInputInfo;
|
|
TDI_CONNECTION_INFORMATION ReceiveOutputInfo;
|
|
|
|
PEPROCESS KernelProcess; // For later comparisons.
|
|
HANDLE TdiHandle; // For unregistering.
|
|
|
|
//
|
|
// This is not actually a list of tunnels.
|
|
// We use a list of TunnelContext structures
|
|
// to track mappings from IPv4 address to TDI address object.
|
|
// See TunnelTransmit for more information.
|
|
//
|
|
TunnelContext AOList; // List of address objects.
|
|
|
|
//
|
|
// For receiving ICMPv4 packets.
|
|
//
|
|
PFILE_OBJECT IcmpFile;
|
|
HANDLE IcmpHandle;
|
|
} TunnelGlobals;
|
|
|
|
extern TunnelGlobals Tunnel;
|
|
|
|
#endif // TUNNEL_INCLUDED
|