275 lines
10 KiB
C
275 lines
10 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:
|
||
|
//
|
||
|
// Link-layer IPv6 interface definitions.
|
||
|
//
|
||
|
// This file contains the definitions defining the interface between IPv6
|
||
|
// and a link layer, such as Ethernet or Token-Ring.
|
||
|
//
|
||
|
// Also see Packet6Context and IPv6Packet in ip6imp.h.
|
||
|
//
|
||
|
// NB: We implicitly assume that all link-layer addresses that a
|
||
|
// particular interface will communicate with are the same length,
|
||
|
// although different interfaces/links may be using addresses of
|
||
|
// different lengths.
|
||
|
//
|
||
|
|
||
|
|
||
|
#ifndef LLIP6IF_INCLUDED
|
||
|
#define LLIP6IF_INCLUDED
|
||
|
|
||
|
#define MAX_LINK_LAYER_ADDRESS_LENGTH 64
|
||
|
|
||
|
//
|
||
|
// Structure of information passed to IPAddInterface.
|
||
|
//
|
||
|
// lip_defmtu must be less than or equal to lip_maxmtu.
|
||
|
// lip_defmtu and lip_maxmtu do NOT include lip_hdrsize.
|
||
|
//
|
||
|
typedef struct LLIPBindInfo {
|
||
|
void *lip_context; // LL context handle.
|
||
|
uint lip_maxmtu; // Max MTU that the link can use.
|
||
|
uint lip_defmtu; // Default MTU for the link.
|
||
|
uint lip_flags; // Various indicators, defined in ntddip6.h.
|
||
|
uint lip_type; // What kind of link - defined in ntddip6.h.
|
||
|
uint lip_hdrsize; // Size of link-layer header.
|
||
|
uint lip_addrlen; // Length of address in bytes - see max above.
|
||
|
uchar *lip_addr; // Pointer to interface address.
|
||
|
uint lip_dadxmit; // Default value for DupAddrDetectTransmits.
|
||
|
uint lip_pref; // Interface preference for routing decisions.
|
||
|
|
||
|
//
|
||
|
// The following five link-layer functions should return quickly.
|
||
|
// They may be called from DPC context or with spin-locks held.
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// Initializes the interface identifier portion of the Address
|
||
|
// with the interface identifier of this interface.
|
||
|
// The interface identifier may depend on state (like the ifindex)
|
||
|
// that is determined during CreateInterface, so it can't
|
||
|
// be passed as a parameter to CreateInterface.
|
||
|
//
|
||
|
void (*lip_token)(IN void *LlContext, OUT IPv6Addr *Address);
|
||
|
|
||
|
//
|
||
|
// Given a pointer to a Source/Target Link-Layer Address Option
|
||
|
// (see RFC 2461), return a pointer to the link-layer address.
|
||
|
// Returns NULL if the option is misformatted (eg, the length is bad).
|
||
|
//
|
||
|
// lip_rdllopt may be NULL if the interface does not support
|
||
|
// Neighbor Discovery (IF_FLAG_NEIGHBOR_DISCOVERS).
|
||
|
//
|
||
|
const void *(*lip_rdllopt)(IN void *LlContext, IN const uchar *OptionData);
|
||
|
|
||
|
//
|
||
|
// Given a pointer to a Source/Target Link-Layer Address Option
|
||
|
// (see RFC 2461), initializes the option data with the link-layer
|
||
|
// address and zeroes any padding bytes in the option data.
|
||
|
// Does not modify the option type/length bytes.
|
||
|
//
|
||
|
// lip_wrllopt may be NULL if the interface does not support
|
||
|
// Neighbor Discovery (IF_FLAG_NEIGHBOR_DISCOVERS).
|
||
|
//
|
||
|
void (*lip_wrllopt)(IN void *LlContext, OUT uchar *OptionData,
|
||
|
IN const void *LinkAddress);
|
||
|
|
||
|
//
|
||
|
// Statically converts an IPv6 address into a link-layer address.
|
||
|
// The return value is a Neighbor Discovery state value.
|
||
|
// If static conversion is not possible (a common case),
|
||
|
// returns ND_STATE_INCOMPLETE to indicate the use of Neighbor Discovery.
|
||
|
// If static conversion is possible (for example with multicast
|
||
|
// addresses or with a p2p interface), returns (typically)
|
||
|
// ND_STATE_PERMANENT or ND_STATE_STALE. ND_STATE_STALE indicates
|
||
|
// that Neighbor Unreachability Detection should be performed.
|
||
|
//
|
||
|
ushort (*lip_cvaddr)(IN void *LlContext,
|
||
|
IN const IPv6Addr *Address,
|
||
|
OUT void *LinkAddress);
|
||
|
|
||
|
//
|
||
|
// Set the default router's link-layer address on an NBMA link,
|
||
|
// as well as our own link-layer address to use in stateless
|
||
|
// address configuration, since we may have multiple choices available.
|
||
|
//
|
||
|
NTSTATUS (*lip_setrtrlladdr)(IN void *LlContext,
|
||
|
IN const void *TokenLinkAddress,
|
||
|
IN const void *RouterLinkAddress);
|
||
|
|
||
|
//
|
||
|
// Transmits the packet to the link-layer address.
|
||
|
// The Offset argument indicates the location of the IPv6 header
|
||
|
// in the packet. The IPv6 layer guarantees that Offset >= lip_hdrsize,
|
||
|
// leaving room for the link-layer header.
|
||
|
//
|
||
|
// May be called from thread or DPC context, but should not be called
|
||
|
// with spin-locks held. Calls are not serialized.
|
||
|
//
|
||
|
void (*lip_transmit)(IN void *LlContext, IN PNDIS_PACKET Packet,
|
||
|
IN uint Offset, IN const void *LinkAddress);
|
||
|
|
||
|
//
|
||
|
// Sets the multicast address list on the interface.
|
||
|
// LinkAddresses is an array of link-layer addresses.
|
||
|
// The first NumKeep addresses were part of the previous
|
||
|
// multicast list and are to be kept. The next NumAdd
|
||
|
// addresses are new additions to the multicast address list.
|
||
|
// The remaining NumDel addresses should be removed
|
||
|
// from the multicast address list.
|
||
|
//
|
||
|
// A NULL lip_mclist function is valid and indicates
|
||
|
// that the interface does not support link-layer multicast.
|
||
|
// For example, a point-to-point or NBMA interface.
|
||
|
// If lip_mclist is non-NULL, then lip_cvaddr must be non-NULL
|
||
|
// and it should return ND_STATE_PERMANENT for multicast addresses.
|
||
|
//
|
||
|
// Called only from thread context; may block or otherwise
|
||
|
// take a long time. The IPv6 layer serializes its calls.
|
||
|
// Also see RestartLinkLayerMulticast below.
|
||
|
//
|
||
|
NDIS_STATUS (*lip_mclist)(IN void *LlContext, IN const void *LinkAddresses,
|
||
|
IN uint NumKeep, IN uint NumAdd, IN uint NumDel);
|
||
|
|
||
|
//
|
||
|
// Initiate shut down of the link-layer connection.
|
||
|
// The link layer should release its reference(s) for the IPv6 interface.
|
||
|
// However, the IPv6 interface is not freed until after the call
|
||
|
// to lip_cleanup and the link layer can make some use of it until then.
|
||
|
//
|
||
|
// Called only from thread context; may block or otherwise
|
||
|
// take a long time. The IPv6 layer will only call once.
|
||
|
//
|
||
|
void (*lip_close)(IN void *LlContext);
|
||
|
|
||
|
//
|
||
|
// Final cleanup of the link-layer connection.
|
||
|
// Called by the IPv6 layer when there are no more references.
|
||
|
//
|
||
|
// Called only from thread context; may block or otherwise
|
||
|
// take a long time. The IPv6 layer will only call once,
|
||
|
// after lip_close has returned.
|
||
|
//
|
||
|
// Up until the call to lip_cleanup, the IPv6 layer
|
||
|
// may still make calls down to the link layer.
|
||
|
// In lip_cleanup, the link layer should release any references
|
||
|
// that it has for lower-layer data structures and
|
||
|
// free its own context structure.
|
||
|
//
|
||
|
void (*lip_cleanup)(IN void *LlContext);
|
||
|
} LLIPBindInfo;
|
||
|
|
||
|
//
|
||
|
// These values should agree with definitions also
|
||
|
// found in ip6def.h and ntddip6.h.
|
||
|
//
|
||
|
#define IF_TYPE_LOOPBACK 0
|
||
|
#define IF_TYPE_ETHERNET 1
|
||
|
#define IF_TYPE_FDDI 2
|
||
|
#define IF_TYPE_TUNNEL_AUTO 3
|
||
|
#define IF_TYPE_TUNNEL_6OVER4 4
|
||
|
#define IF_TYPE_TUNNEL_V6V4 5
|
||
|
#define IF_TYPE_TUNNEL_6TO4 6
|
||
|
#define IF_TYPE_TUNNEL_TEREDO 7
|
||
|
|
||
|
//
|
||
|
// These values should agree with definitions also
|
||
|
// found in ip6def.h and ntddip6.h.
|
||
|
//
|
||
|
#define IF_FLAG_PSEUDO 0x00000001
|
||
|
#define IF_FLAG_P2P 0x00000002
|
||
|
#define IF_FLAG_NEIGHBOR_DISCOVERS 0x00000004
|
||
|
#define IF_FLAG_FORWARDS 0x00000008
|
||
|
#define IF_FLAG_ADVERTISES 0x00000010
|
||
|
#define IF_FLAG_MULTICAST 0x00000020
|
||
|
#define IF_FLAG_ROUTER_DISCOVERS 0x00000040
|
||
|
#define IF_FLAG_PERIODICMLD 0x00000080
|
||
|
#define IF_FLAG_MEDIA_DISCONNECTED 0x00001000
|
||
|
|
||
|
//
|
||
|
// Return values for lip_cvaddr.
|
||
|
// These definitions are also in ip6def.h.
|
||
|
//
|
||
|
#define ND_STATE_INCOMPLETE 0
|
||
|
#define ND_STATE_PROBE 1
|
||
|
#define ND_STATE_DELAY 2
|
||
|
#define ND_STATE_STALE 3
|
||
|
#define ND_STATE_REACHABLE 4
|
||
|
#define ND_STATE_PERMANENT 5
|
||
|
|
||
|
//
|
||
|
// The link-layer code calls these IPv6 functions.
|
||
|
// See the function definitions for explanatory comments.
|
||
|
//
|
||
|
|
||
|
extern NTSTATUS
|
||
|
CreateInterface(IN const GUID *Guid, IN const LLIPBindInfo *BindInfo,
|
||
|
OUT void **IpContext);
|
||
|
|
||
|
extern void *
|
||
|
AdjustPacketBuffer(IN PNDIS_PACKET Packet,
|
||
|
IN uint SpaceAvail, IN uint SpaceNeeded);
|
||
|
|
||
|
extern void
|
||
|
UndoAdjustPacketBuffer(IN PNDIS_PACKET Packet);
|
||
|
|
||
|
extern void
|
||
|
IPv6ReceiveComplete(void);
|
||
|
|
||
|
//
|
||
|
// The packet itself holds a reference for the IPv6 interface,
|
||
|
// so the link layer does not need to hold another reference.
|
||
|
//
|
||
|
extern void
|
||
|
IPv6SendComplete(IN void *IpContext,
|
||
|
IN PNDIS_PACKET Packet, IN IP_STATUS Status);
|
||
|
|
||
|
//
|
||
|
// The following calls must be made before lip_cleanup
|
||
|
// returns. Normally they require a reference for the IPv6 interface,
|
||
|
// but between lip_close and lip_cleanup the link layer may call them
|
||
|
// without holding a reference for the IPv6 interface.
|
||
|
//
|
||
|
// NB: IPv6Receive does not take IpContext (the IPv6 interface)
|
||
|
// as an explicit argument. Instead it is passed as Packet->NTEorIF.
|
||
|
//
|
||
|
extern int
|
||
|
IPv6Receive(IN IPv6Packet *Packet);
|
||
|
|
||
|
extern void
|
||
|
SetInterfaceLinkStatus(IN void *IpContext, IN int MediaConnected);
|
||
|
|
||
|
extern void
|
||
|
DestroyInterface(IN void *IpContext);
|
||
|
|
||
|
//
|
||
|
// This function asks the IPv6 layer to call lip_mclist again,
|
||
|
// adding all the link-layer multicast addresses to the interface
|
||
|
// as if for the first time. In other words, with NumKeep zero.
|
||
|
// The ResetDone function is called under a lock that serializes
|
||
|
// the ResetDone call with lip_mclist calls on this interface.
|
||
|
// Hence the link layer can know at what point in the sequence
|
||
|
// of lip_mclist calls the reset took place.
|
||
|
//
|
||
|
extern void
|
||
|
RestartLinkLayerMulticast(IN void *IpContext,
|
||
|
IN void (*ResetDone)(IN void *LlContext));
|
||
|
|
||
|
//
|
||
|
// The link layer must hold a reference
|
||
|
// for the IPv6 interface to make the following calls.
|
||
|
//
|
||
|
extern void
|
||
|
ReleaseInterface(IN void *IpContext);
|
||
|
|
||
|
#endif // LLIP6IF_INCLUDED
|