You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2696 lines
89 KiB
2696 lines
89 KiB
// Copyright (c) 1997, Microsoft Corporation, all rights reserved
|
|
//
|
|
// l2tpp.h
|
|
// RAS L2TP WAN mini-port/call-manager driver
|
|
// Main private header (precompiled)
|
|
//
|
|
// 01/07/97 Steve Cobb
|
|
//
|
|
//
|
|
// About naming:
|
|
//
|
|
// This driver contains code for both the L2TP mini-port and the L2TP call
|
|
// manager. All handler routines exported to NDIS are prefixed with either
|
|
// 'Lmp' for the mini-port handlers or 'Lcm' for the call manager handlers.
|
|
//
|
|
//
|
|
// About locks:
|
|
//
|
|
// Data structures that may change during simultaneous requests to different
|
|
// processors in a multi-processor system must be protected with spin-locks or
|
|
// accessed only with interlocked routines. Where locking is required to
|
|
// access a data field in this header, the comment for that field indicates
|
|
// same. A CoNDIS client is a trusted kernel mode component and presumed to
|
|
// follow the documented call sequences of CoNDIS. Some access conflicts that
|
|
// might be caused by goofy clients are not checked, though the easy ones are.
|
|
// Cases where multiple clients might conflict are protected even though, for
|
|
// now, the TAPI proxy is expected to be the only client.
|
|
//
|
|
//
|
|
// About TDI and NDIS compliance:
|
|
//
|
|
// This driver is generally compliant with documented TDI and NDIS procedures,
|
|
// but there are two compliance issues worth mentioning. First, it takes
|
|
// performance advantage from the fact that NDIS_BUFFERs and TDI I/O buffers
|
|
// are both defined as MDLs (see NDISBUFFERISMDL in tdix.c). Second, it is
|
|
// built by default to take advantage of an IRP handling optimization which
|
|
// may be non-TDI-compliant though the docs are not real clear on the point
|
|
// (see ALLOCATEIRPS in tdix.c). The driver could be made fully compliant on
|
|
// the first point in one hour and on the second by changing a #if
|
|
// option...but there would be a performance penalty. Finally,
|
|
// InterlockedExchangePointer and InterlockedCompareExchangePointer are used,
|
|
// though there don't currently appear to be any NDIS equivalents.
|
|
|
|
|
|
#ifndef _L2TPP_H_
|
|
#define _L2TPP_H_
|
|
|
|
|
|
// If set, less commom allocations such as 1-per-call control blocks are made
|
|
// from lookaside lists. Otherwise they are made using heap calls. This
|
|
// option makes sense where a large number of calls are expected to be
|
|
// handled.
|
|
//
|
|
#define LLISTALL 0
|
|
|
|
// If set, ReadFlags translates into a simple assigment, otherwise it is an
|
|
// Interlocked operation. Set this to 1 if a bus read of ULONG size is
|
|
// atomic.
|
|
//
|
|
#define READFLAGSDIRECT 1
|
|
|
|
#include <ntddk.h>
|
|
#include <tdi.h>
|
|
#include <tdikrnl.h>
|
|
#include <tdiinfo.h>
|
|
#include <ntddtcp.h>
|
|
#include <ntddip.h>
|
|
#include <ntddndis.h>
|
|
#include <ipinfo.h>
|
|
#include <tcpinfo.h>
|
|
#include <ndis.h>
|
|
#include <ndiswan.h>
|
|
#include <ndistapi.h>
|
|
#include <ntverp.h>
|
|
//#include <ndisadd.h> // Temporary
|
|
#include <md5.h>
|
|
#include <bpool.h>
|
|
#include <ppool.h>
|
|
#include <timer.h>
|
|
#include <debug.h>
|
|
#include <tdix.h>
|
|
#include <l2tp.h>
|
|
#include <l2tprfc.h>
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Constants
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// The NDIS version we report when registering mini-port and address family.
|
|
//
|
|
#define NDIS_MajorVersion 5
|
|
#define NDIS_MinorVersion 0
|
|
|
|
// Size of an IPv4 header. Because the RawIp driver returns the IP header on
|
|
// received datagrams, this must be added onto the allocated buffer size. We
|
|
// assume there will be no rarely used IP-option fields on L2TP traffic.
|
|
//
|
|
// Note: Suggested to PradeepB that RawIp should strip the IP header, and he
|
|
// is considering adding an open-address option. This can be removed if
|
|
// said option materializes.
|
|
//
|
|
#define IpFixedHeaderSize 20
|
|
|
|
// UDP header size
|
|
#define UDP_HEADER_SIZE 8
|
|
|
|
// The maximum number of bytes in a frame including the largest L2TP payload
|
|
// header, plus the 32 bytes the OID_WAN_GET_INFO documentation says should be
|
|
// reserved internally for "bridging and additional protocols". This value is
|
|
// used for receive buffer allocations internally. The L2TP draft/RFC
|
|
// guarantees that control messages will fit in L2TP_MaxFrameSize, so a buffer
|
|
// of this size is capable of receiving either payload or control packets.
|
|
//
|
|
#define L2TP_FrameBufferSize (L2TP_MaxFrameSize + L2TP_MaxPayloadHeader + 32)
|
|
|
|
// The maximum number of bytes in an L2TP control or payload header. This
|
|
// value is used for buffer allocations internally.
|
|
//
|
|
#define L2TP_HeaderBufferSize L2TP_MaxHeaderSize + IpFixedHeaderSize + UDP_HEADER_SIZE
|
|
|
|
// Reported speed of a LAN tunnel in bits/second.
|
|
//
|
|
#define L2TP_LanBps 10000000
|
|
|
|
// The vendor name passed to peer during tunnel creation.
|
|
//
|
|
#define L2TP_VendorName "Microsoft"
|
|
|
|
// The firmware/software revision passed to peer during tunnel creation. The
|
|
// value indicates "NT 5.0".
|
|
//
|
|
#define L2TP_FirmwareRevision VER_PRODUCTVERSION_W
|
|
// The maximum length of an IP address string of the form "a.b.c.d".
|
|
//
|
|
#define L2TP_MaxDottedIpLen 15
|
|
|
|
// Milliseconds in a Hello timer interval. Not to be confused with the Hello
|
|
// timeout which is generally much longer than this. See '*Hello*' fields in
|
|
// the TUNNELCB.
|
|
//
|
|
#define L2TP_HelloIntervalMs 10000
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Data types
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Forward declarations.
|
|
//
|
|
typedef struct _VCCB VCCB;
|
|
typedef struct _INCALLSETUP INCALLSETUP;
|
|
typedef struct _TUNNELWORK TUNNELWORK;
|
|
|
|
|
|
// Adapter control block defining the state of a single L2TP mini-port
|
|
// adapter. An adapter commonly supports multiple VPN devices. Adapter
|
|
// blocks are allocated in MiniportInitialize and deallocated in MiniportHalt.
|
|
//
|
|
typedef struct
|
|
_ADAPTERCB
|
|
{
|
|
// Set to MTAG_ADAPTERCB for easy identification in memory dumps and use
|
|
// in assertions.
|
|
//
|
|
ULONG ulTag;
|
|
|
|
// Reference count on this control block. The reference pairs are:
|
|
//
|
|
// (a) A reference is added when the MiniportAdapterHandle field is set,
|
|
// i.e. when LmpInitialize succeeds and cleared when the LmpHalt
|
|
// handler is called. The adapter block is actually passed to NDIS
|
|
// before it's known if LmpInitialize will succeed but according to
|
|
// ArvindM NDIS will not call halt unless it succeeds.
|
|
//
|
|
// (b) A reference is added when the NdisAfHandle field is set and removed
|
|
// when it is cleared.
|
|
//
|
|
// (c) A reference is added when the NdisSapHandle field is set and
|
|
// removed when it is cleared.
|
|
//
|
|
// (d) A reference is added for the VCCB's back pointer and removed when
|
|
// the VCCB is freed.
|
|
//
|
|
// (e) A reference is added for the TUNNELCB's back pointer and removed
|
|
// when the TUNNELCB is freed.
|
|
//
|
|
// (f) A reference is added when an NDIS_WORK_ITEM is scheduled and
|
|
// removed when it has completed.
|
|
//
|
|
// Access is via ReferenceAdapter and DereferenceAdapter only.
|
|
//
|
|
LONG lRef;
|
|
|
|
// ACBF_* bit flags indicating various options. Access restrictions are
|
|
// indicated for each individual flag. Many of these flags are set
|
|
// permanently at initialization and so have no access limitation.
|
|
//
|
|
// ACBF_OutgoingRoleLac: Set when the driver is to assume the role of the
|
|
// L2TP Access Concentrator (LAC) as opposed to the L2TP Network
|
|
// Server (LNS) when making outgoing calls. It would be simple to act
|
|
// either as LAC or LNS based on a CALL_PARAMETER field, if necessary,
|
|
// though this is not currently implemented.
|
|
//
|
|
// ACBF_IgnoreFramingMismatch: Set when a received framing type bit of
|
|
// "asynchronous" is to be ignored, rather than failing the
|
|
// negotiation. This is a hedge against buggy peers as there are late
|
|
// draft changes to the order of the framing type bits.
|
|
//
|
|
// ACBF_ExclusiveTunnels: Set when an exclusive tunnel is to be created to
|
|
// the peer for each outgoing call even if another tunnel already
|
|
// exists to the peer. This is a default and may be overridden in the
|
|
// L2TP specific call parameters.
|
|
//
|
|
// ACBF_SapActive: Set when the TDI open associated with the NdisSapHandle
|
|
// is successful and cleared when the corresponding TDI close is
|
|
// scheduled. Access is protected by 'lockSap'.
|
|
//
|
|
ULONG ulFlags;
|
|
#define ACBF_OutgoingRoleLac 0x00000001
|
|
#define ACBF_IgnoreFramingMismatch 0x00000002
|
|
#define ACBF_ExclusiveTunnels 0x00000004
|
|
#define ACBF_SapActive 0x00000010
|
|
|
|
// The maximum number of out-of-order packets that may be queued on any
|
|
// tunnel or link. The value is read from the registry. The value 0
|
|
// effectively disables out-of-order handling.
|
|
//
|
|
SHORT sMaxOutOfOrder;
|
|
|
|
// The maximum receive window we send to peer during tunnel setup for the
|
|
// control session. The value is read from the registry. The value 0
|
|
// means the Receive Window Size AVP should not be sent, though for
|
|
// control this just results in peer using a default of 4.
|
|
//
|
|
USHORT usControlReceiveWindow;
|
|
|
|
// The maximum receive window we send to peer during call setup for the
|
|
// payload session. The value is read from the registry. The value 0
|
|
// means the Receive Window Size AVP should not be sent, which results in
|
|
// no sequence/acknowledge numbers being used for calls we initiate. Note
|
|
// that on peer originatated calls where peer specifies a window, 0 will
|
|
// result in the default of 4 being offered.
|
|
//
|
|
USHORT usPayloadReceiveWindow;
|
|
|
|
// The Hello timeout in milliseconds, i.e. the time that must elapse from
|
|
// the last incoming packet before a "Hello" message is sent to verify the
|
|
// media is still up. The value is read from the registry. A value of 0
|
|
// effectively disables the Hello mechanism.
|
|
//
|
|
ULONG ulHelloMs;
|
|
|
|
// The maximum milliseconds to wait for an acknowledge after sending a
|
|
// control or payload packet. The value is read from the registry.
|
|
//
|
|
ULONG ulMaxSendTimeoutMs;
|
|
|
|
// The initial milliseconds to wait for an acknowledge after sending a
|
|
// control or payload packet. The send timeout is adaptive, so this value
|
|
// is the seed only. The value is read from the registry.
|
|
//
|
|
ULONG ulInitialSendTimeoutMs;
|
|
|
|
// The maximum milliseconds to wait for an outgoing packet on which to
|
|
// piggyback an acknowledge before sending a zero data acknowledge. If
|
|
// the value is greater than 1/4 of the current send timeout, the former
|
|
// is used, i.e. this is the "maximum adaptive maximum".
|
|
//
|
|
ULONG ulMaxAckDelayMs;
|
|
|
|
// The maximum number of times a control packet is retransmitted before
|
|
// the owning tunnel is reset. The value is read from the registry.
|
|
//
|
|
ULONG ulMaxRetransmits;
|
|
|
|
// The randomly unique tie-breaker AVP value sent with all SCCRQ messages.
|
|
// This field is currently unused. After due consideration, I have
|
|
// decided not to send tie-breaker AVPs in our SCCRQs. The mechanism is
|
|
// way too complicated for a rare case. If peer really doesn't want two
|
|
// tunnels he will simply ignore ours and let it timeout and fail anyway.
|
|
// This is a minor, and I believe harmless, incompliance with the
|
|
// draft/RFC. My guess is that others will reach this same conclusion and
|
|
// not send tie-breakers either.
|
|
//
|
|
CHAR achTieBreaker[ 8 ];
|
|
|
|
// The password shared with peer for tunnel identification. The value is
|
|
// read from the registry. Currently, only a single password for all
|
|
// peers is used, though a password indexed by 'hostname' will likely be
|
|
// added in the future.
|
|
//
|
|
CHAR* pszPassword;
|
|
|
|
// The driver description read from the registry. The value is used as
|
|
// the L2TP line name when reporting up capabilities.
|
|
//
|
|
WCHAR* pszDriverDesc;
|
|
|
|
// Our framing and bearer capablities bit masks as passed in SCCRQ.
|
|
//
|
|
ULONG ulFramingCaps;
|
|
ULONG ulBearerCaps;
|
|
|
|
// The string sent as the host name, or NULL if none. The value is read
|
|
// from the registry.
|
|
//
|
|
CHAR* pszHostName;
|
|
|
|
// The next progressively increasing reference number likely to be unique
|
|
// for all interconnected LACs/LNSs for a significant period of time. It
|
|
// is for use by administrators on either end of the tunnel to use when
|
|
// investigating call failure problems. Access is via Interlocked
|
|
// routines.
|
|
//
|
|
ULONG ulCallSerialNumber;
|
|
|
|
|
|
// VC TABLE --------------------------------------------------------------
|
|
|
|
// The array of VC control block addresses allocated during adapter
|
|
// initialization. The VC control blocks themselves are created and hung
|
|
// off this table dynamically. Our Call-ID context returned to us by peer
|
|
// in each L2TP packet is a 1-based index into this table. (The 0 Call-ID
|
|
// is reserved by L2TP to mean "not call specific").
|
|
//
|
|
// If an element is NULL, it means the Call-ID is not in use. If an
|
|
// element is -1, it means the Call-ID has been reserved, but messages
|
|
// with the Call-ID are not yet acceptable. Any other value is the
|
|
// address of a VCCB for which messages can be accepted. 'VCCB.pTunnel'
|
|
// is guaranteed valid while a VCCB is in the array.
|
|
//
|
|
// Access to the array is protected by 'lockVcs'.
|
|
//
|
|
VCCB** ppVcs;
|
|
|
|
// The number of elements in the 'ppVcs' array. This corresponds to the
|
|
// number of configured VPN devices read from the registry during
|
|
// initialization.
|
|
//
|
|
USHORT usMaxVcs;
|
|
|
|
// Number of slots in 'usMaxVcs' that are available, i.e. NULL. Access is
|
|
// protected by 'lockVcs'
|
|
//
|
|
LONG lAvailableVcSlots;
|
|
|
|
// Lock protecting the VC table, "available" counter, and 'listVcs'.
|
|
//
|
|
NDIS_SPIN_LOCK lockVcs;
|
|
|
|
// The next Call-ID above 'usMaxVcs' for use only in terminating a call
|
|
// gracefully. Access is by the GetNextTerminationCallId routine only.
|
|
//
|
|
USHORT usNextTerminationCallId;
|
|
|
|
|
|
// TUNNEL CHAIN ----------------------------------------------------------
|
|
|
|
// Head of a double-linked list of active TUNNELCBs. At no time will two
|
|
// tunnels in the list have the same 'TUNNELCB.usTunnelId' or same
|
|
// 'TUNNELCB.ulIpAddress'/'TUNNELCB.usAssignedTunnelId' pair. Access to
|
|
// the list links is protected by 'lockTunnels'.
|
|
//
|
|
LIST_ENTRY listTunnels;
|
|
NDIS_SPIN_LOCK lockTunnels;
|
|
|
|
// The tunnel identifier to assign to the next tunnel created. Only the
|
|
// GetNextTunnelId routine should access this field.
|
|
//
|
|
USHORT usNextTunnelId;
|
|
|
|
|
|
// TDI -------------------------------------------------------------------
|
|
|
|
// TDI extension context containing TDI state information for the adapter.
|
|
// Access is via Tdix* interface routines, which handle all locking
|
|
// internally.
|
|
//
|
|
TDIXCONTEXT tdix;
|
|
|
|
|
|
// NDIS BOOKKEEPING ------------------------------------------------------
|
|
|
|
// NDIS's handle for this mini-port adapter passed to us in
|
|
// MiniportInitialize. This is passed back to various NdisXxx calls.
|
|
//
|
|
NDIS_HANDLE MiniportAdapterHandle;
|
|
|
|
// NDIS's handle for our SAP as passed to our CmRegisterSapHandler or NULL
|
|
// if none. Only one SAP handle is supported because (a) the TAPI proxy's
|
|
// is expected to be the only one, and (b) there are no L2TP SAP
|
|
// properties that would ever lead us to direct a call to a second SAP
|
|
// anyway. Any client's attempt to register a second SAP will fail. A
|
|
// value of NULL indicates no SAP handle is currently registered. Writers
|
|
// must hold 'lockSap'. Readers must hold 'lockSap' or a SAP reference.
|
|
//
|
|
NDIS_HANDLE NdisSapHandle;
|
|
|
|
// Line and address IDs assigned by NDIS to the active SAP.
|
|
//
|
|
ULONG ulSapLineId;
|
|
ULONG ulSapAddressId;
|
|
|
|
// NDIS's handle for our Address Family as passed to our CmOpenAfHandler
|
|
// or NULL if none. Only one is supported. See NdisSapHandle above.
|
|
// Access is via Interlocked routines.
|
|
//
|
|
NDIS_HANDLE NdisAfHandle;
|
|
|
|
// This adapter's capabilities as returned to callers on
|
|
// OID_WAN_CO_GET_INFO. These capabilities are also used as defaults for
|
|
// the corresponding VCCB.linkinfo settings during MiniportCoCreateVc.
|
|
//
|
|
NDIS_WAN_CO_INFO info;
|
|
|
|
// Reference count on the NdisAfHandle. The reference pairs are:
|
|
//
|
|
// (a) A reference is added when the address family is opened and removed
|
|
// when it is closed.
|
|
//
|
|
// (b) A reference is added when a SAP is registered on the address family
|
|
// and removed when it is deregistered.
|
|
//
|
|
// (c) A reference is added when a VC is created on the address family and
|
|
// removed when it is deleted.
|
|
//
|
|
// Access is via ReferenceAf and DereferenceAf only.
|
|
//
|
|
LONG lAfRef;
|
|
|
|
// Reference count on the NdisSapHandle. The reference pairs are:
|
|
//
|
|
// (a) A reference is added when the SAP is registered and removed when it
|
|
// is de-registered.
|
|
//
|
|
// (b) A reference is added and immediately removed in FsmTunnelIdle to
|
|
// test for an active SAP in order to immediately reject requested
|
|
// tunnels when no SAP is active.
|
|
//
|
|
// (c) A reference is added when before calling
|
|
// NdisMCmDispatchIncomingCall and removed when the call returns.
|
|
//
|
|
// Access is via ReferenceSap and DereferenceSap only, excepting initial
|
|
// reference by RegisterSapPassive. Access is protected by 'lockSap'.
|
|
//
|
|
LONG lSapRef;
|
|
|
|
// This lock protects the 'lSapRef' and 'NdisSapHandle' fields.
|
|
//
|
|
NDIS_SPIN_LOCK lockSap;
|
|
|
|
|
|
// RESOURCE POOLS --------------------------------------------------------
|
|
|
|
// Count of initialized but not yet completed timers. We cannot allow a
|
|
// Halt to complete until this goes to 0, because if we did our driver
|
|
// could be unloaded with running timers in our memory which results in a
|
|
// bugcheck.
|
|
//
|
|
ULONG ulTimers;
|
|
|
|
// Pool of full frame buffers with pre-attached NDIS_BUFFER descriptors.
|
|
// The pool is accessed via the interface defined in bpool.h, which
|
|
// handles all locking internally.
|
|
//
|
|
BUFFERPOOL poolFrameBuffers;
|
|
|
|
// Pool of L2TP header buffers with pre-attached NDIS_BUFFER descriptors.
|
|
// The pool is accessed via the interface defined in bpool.h, which
|
|
// handles all locking internally.
|
|
//
|
|
BUFFERPOOL poolHeaderBuffers;
|
|
|
|
// Pool of NDIS_PACKET descriptors used in indication of received frames.
|
|
// The pool is accessed via the interface defined in ppool.h, which
|
|
// handles all locking internally.
|
|
//
|
|
PACKETPOOL poolPackets;
|
|
|
|
// Lookaside list of NDIS_WORK_ITEM scheduling descriptors with extra
|
|
// context space used by all tunnels and VCs attached to the adapter.
|
|
//
|
|
NPAGED_LOOKASIDE_LIST llistWorkItems;
|
|
|
|
// Lookaside list of TIMERQITEM timer event descriptors used by all
|
|
// tunnels and VCs attached to the adapter.
|
|
//
|
|
NPAGED_LOOKASIDE_LIST llistTimerQItems;
|
|
|
|
// Lookaside list of CONTROLSENT sent control packet contexts used by all
|
|
// tunnels attached to the adapter.
|
|
//
|
|
NPAGED_LOOKASIDE_LIST llistControlSents;
|
|
|
|
// Lookaside list of PAYLOADLSENT sent payload packet contexts used by all
|
|
// VCs attached to the adapter.
|
|
//
|
|
NPAGED_LOOKASIDE_LIST llistPayloadSents;
|
|
|
|
// Lookaside list of TUNNELWORK incoming VC setup contexts used for all
|
|
// tunnels attached to the adapter.
|
|
//
|
|
NPAGED_LOOKASIDE_LIST llistTunnelWorks;
|
|
|
|
// Lookaside list of CONTROLMSGINFO contexts used for all tunnels and VCs
|
|
// attached to the adapter.
|
|
//
|
|
NPAGED_LOOKASIDE_LIST llistControlMsgInfos;
|
|
|
|
#if LLISTALL
|
|
// Lookaside list of TUNNELCBs from which the 'listTunnels' control blocks
|
|
// are allocated.
|
|
//
|
|
NPAGED_LOOKASIDE_LIST llistTunnels;
|
|
|
|
// Lookaside list of VCCBs from which the control blocks dynamically
|
|
// attached to '*ppVcs' are allocated.
|
|
//
|
|
NPAGED_LOOKASIDE_LIST llistVcs;
|
|
|
|
// Lookaside list of TIMERQ descriptors used by all tunnels attached to
|
|
// the adapter.
|
|
//
|
|
NPAGED_LOOKASIDE_LIST llistTimerQs;
|
|
|
|
// Lookaside list of CONTROLRECEIVED received control packet contexts used
|
|
// by all tunnels attached to the adapter.
|
|
//
|
|
NPAGED_LOOKASIDE_LIST llistControlReceiveds;
|
|
|
|
// Lookaside list of PAYLOADRECEIVED received payload packet contexts used
|
|
// by all VCs attached to the adapter.
|
|
//
|
|
NPAGED_LOOKASIDE_LIST llistPayloadReceiveds;
|
|
|
|
// Lookaside list of CALLSETUP incoming VC setup contexts used for all
|
|
// incoming VCs attached to the adapter.
|
|
//
|
|
NPAGED_LOOKASIDE_LIST llistInCallSetups;
|
|
#endif
|
|
}
|
|
ADAPTERCB;
|
|
|
|
|
|
// Tunnel control block, describing the state of an L2TP tunnel, i.e. an L2TP
|
|
// control channel session to another L2TP LNS or LAC. Each tunnel may have
|
|
// zero or more VCs associated with it. Tunnel control blocks are allocated
|
|
// from 'ADAPTERCB.llistTunnels' in CmMakeCall and ReceiveControl. Blocks are
|
|
// deallocated when the last reference is removed, e.g. when the control
|
|
// connection FSM terminates the tunnel.
|
|
//
|
|
typedef struct
|
|
_TUNNELCB
|
|
{
|
|
// Links to the prev/next TUNNELCB in the owning adapter's tunnel list.
|
|
// Access to the list links is protected by 'ADAPTERCB.lockTunnels'.
|
|
//
|
|
LIST_ENTRY linkTunnels;
|
|
|
|
// Set to MTAG_TUNNELCB for easy identification in memory dumps and use in
|
|
// assertions.
|
|
//
|
|
ULONG ulTag;
|
|
|
|
// Reference count on this control block. The reference pairs are:
|
|
//
|
|
// (a) A reference is added when a call on a VCCB is active or becoming
|
|
// active and removed when it is deactivated, i.e. during the period
|
|
// the VCCB is on 'listVcs'. This covers the back pointer in the
|
|
// VCCB.
|
|
//
|
|
// (b) A reference is added when peer initiates a tunnel and removed when
|
|
// the tunnel transitions to idle state. This keeps peer-initiated
|
|
// tunnels from terminating when there are no no calls, since by
|
|
// convention, it is peer who closes the tunnel in that case.
|
|
//
|
|
// (c) A reference is added when a graceful tunnel close is initiated and
|
|
// removed when the tunnel transitions to idle state.
|
|
//
|
|
// (d) A reference is added when the delayed control acknowledge timer is
|
|
// scheduled and removed by the timer event handler.
|
|
//
|
|
// (e) LookUpTunnelAndVcCbs adds a reference that is removed at the end of
|
|
// the L2tpReceive handler. This covers the receive path.
|
|
//
|
|
// (f) A reference is added when a CONTROLSENT context is assigned a
|
|
// tunnel back pointer and removed when the context is freed.
|
|
//
|
|
// (g) A reference is added when a PAYLOADSENT context is assigned a
|
|
// tunnel back pointer and removed when the context is freed.
|
|
//
|
|
// (h) ScheduleTunnelWork adds a reference that is removed by TunnelWork
|
|
// after executing the work. This covers the tunnel pointer passed as
|
|
// a context to NdisScheduleWorkItem.
|
|
//
|
|
// Access is via ReferenceTunnel and DereferenceTunnel only which use
|
|
// 'ADAPTERCB.lockTunnels' for protection.
|
|
//
|
|
LONG lRef;
|
|
|
|
// Back pointer to owning adapter's control block.
|
|
//
|
|
ADAPTERCB* pAdapter;
|
|
|
|
// This lock protects TUNNELCB send, receive, and state fields as noted in
|
|
// other field descriptions.
|
|
//
|
|
NDIS_SPIN_LOCK lockT;
|
|
|
|
|
|
// TUNNEL SETUP ----------------------------------------------------------
|
|
|
|
// IP address and UDP port of the remote end of the tunnel in network byte
|
|
// order. The IP address is pulled from the call parameters passed to
|
|
// CmMakeCall. It is updated with the last source IP address received
|
|
// from a peer passing this tunnel's ID, per the L2TP draft/RFC section
|
|
// 8.1 on "L2TP over IP/UDP media". However, it is assumed that the
|
|
// updated source address will not match the address of another existing
|
|
// tunnel. The UDP port (not used in raw IP mode) is initially the well
|
|
// known L2TP port (1701). It is updated with the last source UDP port
|
|
// received from peer on this tunnel. Access is protected by
|
|
// 'pAdapter->lockTunnels'.
|
|
//
|
|
TDIXIPADDRESS address;
|
|
|
|
// IP address and ifindex of my end of the tunnel in network byte
|
|
// used to get the media speed and build IP header
|
|
TDIXIPADDRESS localaddress;
|
|
|
|
TDIXUDPCONNECTCONTEXT udpContext;
|
|
|
|
// "Connection" cookie returned by TdixAddHostRoute. This may be passed
|
|
// to TdixSendDatagram to send on the connected channel (used for sent
|
|
// payloads) as opposed to the unconnected channel (used for receives and
|
|
// sent controls). The address is invalid after TdixDeleteHostRoute is
|
|
// called.
|
|
//
|
|
TDIXROUTE* pRoute;
|
|
|
|
// Our unique tunnel identifier sent back to us by peer in the L2TP
|
|
// header. The value is chosen, using GetNextTunnelId, from a sequential
|
|
// counter in ADAPTERCB and has no further meaning.
|
|
//
|
|
USHORT usTunnelId;
|
|
|
|
// The tunnel identifier chosen by peer that we send back to him in the
|
|
// L2TP header Tunnel-ID field for all packets on this tunnel. A value of
|
|
// 0 indicates no ID has been assigned.
|
|
//
|
|
USHORT usAssignedTunnelId;
|
|
|
|
// TCBF_* bit flags indicating various options and states. Access is via
|
|
// the interlocked ReadFlags/SetFlags/ClearFlags routines only.
|
|
//
|
|
// TCBF_TdixReferenced: Set when the tunnel has referenced the adapter's
|
|
// TDI extension context by successfully calling TdixOpen.
|
|
// DereferenceTunnel uses this to automatically dereference the
|
|
// context when the tunnel is dereferenced.
|
|
//
|
|
// TCBF_CcInTransition: Set when the control connection FSM has begun but
|
|
// not finished a sequence of state changes that will end up in either
|
|
// Idle or Established state. When this flag is set new requests to
|
|
// bring the tunnel up or down are queued on 'listRequestingVcs' for
|
|
// re-execution when a result is known. Access to the bit is
|
|
// protected by 'lockT'.
|
|
//
|
|
// TCBF_PeerInitiated: Set when the tunnel was initiated by the peer,
|
|
// rather than a local request. If all calls are dropped and this bit
|
|
// is not set, we close the tunnel gracefully.
|
|
//
|
|
// TCBF_PeerInitRef: Set when a reference for peer initation is taken on
|
|
// the tunnel and cleared when the reference is removed.
|
|
//
|
|
// TCBF_HostRouteAdded: Set when the host route is successfully added and
|
|
// referenced and removed when it is dereferenced.
|
|
//
|
|
// TCBF_HostRouteChanged: Set when a host route changed has been attempted
|
|
// on the tunnel, and never cleared.
|
|
//
|
|
// TCBF_PeerNotResponding: Set when the tunnel is closed due to lack of
|
|
// response from peer, i.e. after all retries have been exhausted.
|
|
//
|
|
// TCBF_Closing: Set as soon as the tunnel is known to be transitioning to
|
|
// idle state. Access is protected by 'lockT'.
|
|
//
|
|
// TCBF_FsmCloseRef: Set when a graceful closing exchange is initiated by
|
|
// FsmClose and cleared when the tunnel reaches idle state.
|
|
//
|
|
// TCBF_InWork: Set when an APC is scheduled to execute work from the
|
|
// 'listWork' queue. Access is protected by 'lockWork'.
|
|
//
|
|
ULONG ulFlags;
|
|
#define TCBF_TdixReferenced 0x00000001
|
|
#define TCBF_CcInTransition 0x00000002
|
|
#define TCBF_PeerInitiated 0x00000004
|
|
#define TCBF_PeerInitRef 0x00000008
|
|
#define TCBF_HostRouteAdded 0x00000010
|
|
#define TCBF_PeerNotResponding 0x00000020
|
|
#define TCBF_HostRouteChanged 0x00000040
|
|
#define TCBF_Closing 0x00000100
|
|
#define TCBF_FsmCloseRef 0x00000200
|
|
#define TCBF_InWork 0x00001000
|
|
#define TCBF_SendConnected 0x00002000
|
|
#define TCBF_LocalAddrSet 0x00004000
|
|
|
|
// The current state of the tunnel's control connection creation FSM. See
|
|
// also 'VCCB.state'.
|
|
//
|
|
// Only one tunnel creation session may be underway even if CmMakeCall has
|
|
// been called on multiple VCs over this tunnel. For this reason,
|
|
// transitions to/from the Idle or Established states must be protected by
|
|
// 'lockT'. See also TCBF_CcInTransition flag and 'listRequestingVcs'.
|
|
//
|
|
// The protocol sorts out the case of simultaneous originate and receive
|
|
// requests ensuring that one gets dropped before it reaches Established
|
|
// state when either provides a tie-breaker. We always provide a
|
|
// tie-breaker for IP media. For QOS-enabled medias where one control
|
|
// channel per call makes sense and no tie-breakers are passed, a lower
|
|
// level VC ID will be used to distinguish tunnel control blocks on
|
|
// receive. So, a single TUNNELCB will never have both originated and
|
|
// received control channels in Established state.
|
|
//
|
|
L2TPCCSTATE state;
|
|
|
|
// Double-linked queue of all VCCBs waiting for the tunnel to open. New
|
|
// VCs must not be linked on closing tunnels, i.e. those with the
|
|
// TCBF_Closing flag set. Access is protected by 'lockT'.
|
|
//
|
|
LIST_ENTRY listRequestingVcs;
|
|
|
|
// Double-linked queue of VCCBs whose VCBF_XxxPending operation has
|
|
// completed. 'VCCB.status' is the status that will be indicated. This
|
|
// mechanism is necessary to avoid the spin-lock issues that results when
|
|
// one tries to call NDIS completion APIs from the bowels of the FSMs.
|
|
//
|
|
LIST_ENTRY listCompletingVcs;
|
|
|
|
// Peer's framing and bearer capablities.
|
|
//
|
|
ULONG ulFramingCaps;
|
|
ULONG ulBearerCaps;
|
|
|
|
// The challenge and challenge response sent to peer. These are in the
|
|
// control block for convenience, as they must be passed thru the work
|
|
// scheduling mechanism and don't fit easily into the generic arguments.
|
|
//
|
|
CHAR achChallengeToSend[ 16 ];
|
|
CHAR achResponseToSend[ 16 ];
|
|
|
|
|
|
// SEND STATE ------------------------------------------------------------
|
|
|
|
// Next Sent, the sequence number of next control packet transmitted on
|
|
// this tunnel. The field is initialized to 0 and incremented after
|
|
// assignment to an outgoing packet, excepting retransmissions. Access is
|
|
// protected by 'lockT'.
|
|
//
|
|
USHORT usNs;
|
|
|
|
// Double-linked list of outstanding sends, i.e. CONTROLSENTs sorted by
|
|
// the 'usNs' field with lower values near the head. The list contains
|
|
// all active unacknowledged CONTROLSENT contexts, even those that may be
|
|
// waiting for their first transmission. Access is protected by 'lockT'.
|
|
//
|
|
LIST_ENTRY listSendsOut;
|
|
|
|
// The number of control packets sent but not acknowledged or timed out.
|
|
// Access is protected by 'lockT'.
|
|
//
|
|
ULONG ulSendsOut;
|
|
|
|
// The number of sent but unacknowledged packets that may be outstanding.
|
|
// This value is adjusted dynamically. Per the draft/RFC, when
|
|
// 'ulAcksSinceSendTimeout' reaches the current setting, the window is
|
|
// increased by one. When a send timeout expires the window is reduced by
|
|
// half. Access is protected by 'lockT'.
|
|
//
|
|
ULONG ulSendWindow;
|
|
|
|
// The maximum value of 'ulSendWindow'. Peer chooses this value during
|
|
// call setup by offering a receive window.
|
|
//
|
|
ULONG ulMaxSendWindow;
|
|
|
|
// The number of packets acknowledged since the last timeout. The value
|
|
// is reset when a timeout occurs or the send window is adjusted upward.
|
|
// See 'ulSendWindow'. Access is protected by 'lockT'.
|
|
//
|
|
ULONG ulAcksSinceSendTimeout;
|
|
|
|
// The estimated round trip time in milliseconds. This is the RTT value
|
|
// from Appendix A of the draft/RFC. The value is adjusted as each
|
|
// acknowledge is received. It is initialized to the Packet Processing
|
|
// Delay reported by peer. See 'ulSendTimeoutMs'. Access is protected by
|
|
// 'lockT'.
|
|
//
|
|
ULONG ulRoundTripMs;
|
|
|
|
// The estimated mean deviation in milliseconds, an approximation of the
|
|
// standard deviation. This is the DEV value from Appendix A of the
|
|
// draft/RFC. The value is adjusted as each acknowledge is received. It
|
|
// is initially 0. See 'ulSendTimeoutMs'. Access is protected by
|
|
// 'lockT'.
|
|
//
|
|
LONG lDeviationMs;
|
|
|
|
// Milliseconds before it is assumed a sent packet will not be
|
|
// acknowledged and needs to be retransmitted. This is the ATO value from
|
|
// Appendix A of the draft/RFC. This value is adjusted as each
|
|
// acknowledge is received, with a maximum of
|
|
// 'ADAPTERCB.ulMaxSendTimeoutMs'. Access is protected by 'lockT'.
|
|
//
|
|
ULONG ulSendTimeoutMs;
|
|
|
|
// The timer event descriptor scheduled to occur when it is time to stop
|
|
// waiting for an outgoing send on which to piggyback an acknowledge.
|
|
// This will be NULL when no delayed acknowledge is pending. Per the
|
|
// draft/RFC, the timeout used is 1/4 of the 'ulSendTimeoutMs'. Access is
|
|
// protected by 'lockT'.
|
|
//
|
|
TIMERQITEM* pTqiDelayedAck;
|
|
|
|
// The timer event descriptor which expires when it's time to check for
|
|
// lack of any incoming packets. To reduce the cost of constantly
|
|
// resetting a Hello timer with a full timeout (which with unsequenced
|
|
// payloads usually results in an NdisCancelTimer/NdisSetTimer on each
|
|
// received packet), the timeout is broken into intervals of
|
|
// L2TP_HelloIntervalMs. If it expires and both 'ulRemainingHelloMs' and
|
|
// 'ulHelloResetsThisInterval' are 0, a "Hello" message is sent to the
|
|
// peer to verify that the media is still up. Access to this field is
|
|
// protected by 'lockT'.
|
|
//
|
|
TIMERQITEM* pTqiHello;
|
|
|
|
// The milliseconds left to wait in all remaining Hello intervals and the
|
|
// number of resets since the last Hello interval timeout.
|
|
//
|
|
ULONG ulRemainingHelloMs;
|
|
ULONG ulHelloResetsThisInterval;
|
|
|
|
// RECEIVE STATE ---------------------------------------------------------
|
|
|
|
// Next Received, the sequence number one higher than that of the last
|
|
// control packet received on this tunnel or 0 if none. Access is
|
|
// protected by 'lockT'.
|
|
//
|
|
USHORT usNr;
|
|
|
|
// Double-linked list of out-of-order receives, i.e. CONTROLRECEIVEs
|
|
// sorted by the 'usNs' field with lower values near the head. The
|
|
// maximum queue length is 'ADAPTERCB.sMaxOutOfOrder'. Access is
|
|
// protected by 'lockT'.
|
|
//
|
|
LIST_ENTRY listOutOfOrder;
|
|
|
|
|
|
// TIMER QUEUE -----------------------------------------------------------
|
|
|
|
// Timer queue for both the control and data channels. The timer queue is
|
|
// accessed via the interface defined in timer.h, which handles all
|
|
// locking internally.
|
|
//
|
|
TIMERQ* pTimerQ;
|
|
|
|
|
|
// WORK QUEUE ------------------------------------------------------------
|
|
|
|
// Double-linked list NDIS_WORK_ITEMs queued for serialized execution at
|
|
// PASSIVE IRQL. The next item to be executed is at the head of the list.
|
|
// Access is protected via the ScheduleTunnelWork routine, which protects
|
|
// the list with 'lockWork'. See also TCBF_InWork.
|
|
//
|
|
LIST_ENTRY listWork;
|
|
NDIS_SPIN_LOCK lockWork;
|
|
|
|
|
|
// VC CHAIN --------------------------------------------------------------
|
|
|
|
// Head of a double-linked list of VCCBs associated with the tunnel, i.e.
|
|
// with calls active or in the process of becoming active. New VCs must
|
|
// not be linked on closing tunnels, i.e. those with the TCBF_Closing flag
|
|
// set. Access to the links is protected by 'lockVcs'.
|
|
//
|
|
LIST_ENTRY listVcs;
|
|
NDIS_SPIN_LOCK lockVcs;
|
|
|
|
// media speed
|
|
ULONG ulMediaSpeed;
|
|
}
|
|
TUNNELCB;
|
|
|
|
|
|
// Call statistics block.
|
|
//
|
|
typedef struct
|
|
_CALLSTATS
|
|
{
|
|
// System time call reached established state. When the block is being
|
|
// used for cumulative statistics of multiple calls, this is the number of
|
|
// calls instead.
|
|
//
|
|
LONGLONG llCallUp;
|
|
|
|
// Duration in seconds of now idle call.
|
|
//
|
|
ULONG ulSeconds;
|
|
|
|
// Total data bytes received and sent.
|
|
//
|
|
ULONG ulDataBytesRecd;
|
|
ULONG ulDataBytesSent;
|
|
|
|
// Number of received packets indicated up.
|
|
//
|
|
ULONG ulRecdDataPackets;
|
|
|
|
// Number of received packets linked on the out-of-order queue before
|
|
// being indicated up.
|
|
//
|
|
ULONG ulDataPacketsDequeued;
|
|
|
|
// Number of received packets of zero length. Includes packets with the
|
|
// R-bit set.
|
|
//
|
|
ULONG ulRecdZlbs;
|
|
|
|
// Number of received packets with R-bit set.
|
|
//
|
|
ULONG ulRecdResets;
|
|
|
|
// Number of received packets with R-bit set that are out of date.
|
|
//
|
|
ULONG ulRecdResetsIgnored;
|
|
|
|
// Number of data packets sent with and without sequence numbers. The sum
|
|
// of the two is the total data packets sent.
|
|
//
|
|
ULONG ulSentDataPacketsSeq;
|
|
ULONG ulSentDataPacketsUnSeq;
|
|
|
|
// Number of packets sent that were acknowledged and timed out. If the
|
|
// call is cancelled with packets outstanding the sum of the two may be
|
|
// less than 'ulSentDataPacketsSeq'.
|
|
//
|
|
ULONG ulSentPacketsAcked;
|
|
ULONG ulSentPacketsTimedOut;
|
|
|
|
// Number of zero length acknowledges sent.
|
|
//
|
|
ULONG ulSentZAcks;
|
|
|
|
// Number of packets sent with the R-bit set.
|
|
//
|
|
ULONG ulSentResets;
|
|
|
|
// Number of times the send window was changed.
|
|
//
|
|
ULONG ulSendWindowChanges;
|
|
|
|
// Total of all send window sizes, one for each 'ulSentDataPacketsSeq'.
|
|
//
|
|
ULONG ulSendWindowTotal;
|
|
|
|
// Largest send window.
|
|
//
|
|
ULONG ulMaxSendWindow;
|
|
|
|
// Smallest send window.
|
|
//
|
|
ULONG ulMinSendWindow;
|
|
|
|
// Number of sample round trips. (sequenced packets only)
|
|
//
|
|
ULONG ulRoundTrips;
|
|
|
|
// Total of all round trips in milliseconds. (sequenced packets only)
|
|
//
|
|
ULONG ulRoundTripMsTotal;
|
|
|
|
// Longest round trip, (sequenced packets only)
|
|
//
|
|
ULONG ulMaxRoundTripMs;
|
|
|
|
// Shortest round trip. (sequenced packets only)
|
|
//
|
|
ULONG ulMinRoundTripMs;
|
|
}
|
|
CALLSTATS;
|
|
|
|
|
|
// Virtual circuit control block defining the state of a single L2TP VC, i.e.
|
|
// one line device endpoint and the call, if any, active on it. A VC is never
|
|
// used for incoming and outgoing calls simultaneously. A single NDIS VC maps
|
|
// to one of these.
|
|
//
|
|
typedef struct
|
|
_VCCB
|
|
{
|
|
// Links to the prev/next VCCB in the owning tunnel's active VC list.
|
|
// Access is protected by 'TUNNELCB.lockVcs'.
|
|
//
|
|
LIST_ENTRY linkVcs;
|
|
|
|
// Set to MTAG_VCCB for easy identification in memory dumps and use in
|
|
// assertions.
|
|
//
|
|
ULONG ulTag;
|
|
|
|
// Reference count on this VC control block. The reference pairs are:
|
|
//
|
|
// (a) LmpCoCreateVc adds a reference that is removed by LmpCoDeleteVc.
|
|
// This covers all clients that learn of the VCCB via NDIS.
|
|
//
|
|
// (b) LookUpTunnelAndVcCbs adds a reference that is removed at the end of
|
|
// the L2tpReceive handler. This covers the receive path.
|
|
//
|
|
// (c) A reference is added when a CONTROLSENT context with 'pVc'
|
|
// referring to this VCCB is assigned the back pointer and removed
|
|
// when the context is freed.
|
|
//
|
|
// (d) A reference is added when a PAYLOADSENT context with 'pVc'
|
|
// referring to this VCCB is assigned the back pointer and removed
|
|
// when the context is freed.
|
|
//
|
|
// (e) ScheduleTunnelWork adds a reference that is removed by TunnelWork
|
|
// after executing the work.
|
|
//
|
|
// (f) A reference is added before scheduling the delayed payload
|
|
// acknowledge timer and removed in the timer event handler.
|
|
//
|
|
// (g) A reference is taken by CompleteVcs covering use of the VC popped
|
|
// from the tunnel's completing list, and released after use.
|
|
//
|
|
// (h) A reference is taken prior to calling NdisMCmDispatchIncomingCall
|
|
// and removed by the completion handler.
|
|
//
|
|
// (i) A reference is added when a CONTROLRECEIVED context with 'pVc'
|
|
// referring to this VCCB is assigned the back pointer and removed
|
|
// when the context is freed.
|
|
//
|
|
// The field is accessed only by the ReferenceVc and DereferenceVc
|
|
// routines, which protect with Interlocked routines.
|
|
//
|
|
LONG lRef;
|
|
|
|
// Back pointer to owning adapter's control block.
|
|
//
|
|
ADAPTERCB* pAdapter;
|
|
|
|
// Back pointer to owning tunnel's control block or NULL if none.
|
|
// Guaranteed valid whenever the VC is linked into a tunnel's 'listVcs',
|
|
// i.e. when it holds a reference on the tunnel. It is safe to use this
|
|
// if you hold a reference on the call. Otherwise, it is not. Be very
|
|
// careful here.
|
|
//
|
|
TUNNELCB* pTunnel;
|
|
|
|
// This lock protects VCCB payload send and receive paths as noted in
|
|
// other field descriptions. In cases where both 'lockV' and
|
|
// 'pTunnel->lockT' are required 'lockT' must be obtained first.
|
|
//
|
|
NDIS_SPIN_LOCK lockV;
|
|
|
|
|
|
// CALL SETUP ------------------------------------------------------------
|
|
|
|
// Our unique call identifier sent back to us by peer in the L2TP header.
|
|
// The value is a 1-based index into the 'ADAPTERCB.ppVcs' array.
|
|
//
|
|
USHORT usCallId;
|
|
|
|
// The call identifier, chosen by peer, that we send back to him in the
|
|
// L2TP header Call-ID field for all packets on this call. A value of 0
|
|
// indicates no Call-ID has been assigned.
|
|
//
|
|
USHORT usAssignedCallId;
|
|
|
|
// VCBF_* bit flags indicating various options and states. Access is via
|
|
// the interlocked ReadFlags/SetFlags/ClearFlags routines.
|
|
//
|
|
// VCBF_IndicateReceivedTime: Set if MakeCall caller sets the
|
|
// MediaParameters.Flags RECEIVE_TIME_INDICATION flag requesting the
|
|
// TimeReceived field of the NDIS packet be filled with a timestamp.
|
|
//
|
|
// VCBF_CallClosableByClient: Set when a call is in a state where
|
|
// LcmCmCloseCall requests to initiate clean-up should be accepted.
|
|
// This may be set when VCBF_CallClosableByPeer is not, which means we
|
|
// have indicated an incoming close to client and are waiting for him
|
|
// to do a client close in response (in that weird CoNDIS way). The
|
|
// flag is protected by 'lockV'.
|
|
//
|
|
// VCBF_CallClosableByPeer: Set when the call is in a state where an idle
|
|
// transition without operations pending should be mapped to a
|
|
// PeerClose event. This will never be set when
|
|
// VCBF_CallClosableByClient is not. The flag is protected by
|
|
// 'lockV'.
|
|
//
|
|
// VCBF_DefaultLcParams: Set when the 'pLcParams' field was allocated by
|
|
// us rather than being owned by client.
|
|
//
|
|
// VCBF_IncomingFsm: Set when the VC is executing the Incoming Call FSM
|
|
// rather than Outgoing Call FSM in the active incoming/outgoing call.
|
|
// For client initiated calls this will set if the adapter's
|
|
// ACBF_OutgoingRoleLac flag, read from the registry, is set.
|
|
//
|
|
// VCBF_PeerInitiatedCall: Set when an the active call was initiated by
|
|
// the peer, clear if it was initiated by the client.
|
|
//
|
|
// VCBF_Sequencing: Set unless no Receive Window AVP is provided/received
|
|
// during call setup, resulting in "no sequencing" mode where Ns/Nr
|
|
// fields are not sent in the payload header. This also effectively
|
|
// disables out-of-order processing.
|
|
//
|
|
// VCBF_VcCreated: Set when the VC has been created successfully. This is
|
|
// the "creation" that occurs with the client, not the mini-port.
|
|
// VCBF_VcActivated: Set when the VC has been activated successfully.
|
|
// VCBF_VcDispatched: Set when the VC has dispatched an incoming call to
|
|
// the client and client has returned success or pended.
|
|
// VCBM_VcState: Bit mask including each of the above 3 NDIS state flags.
|
|
//
|
|
// VCBF_VcDeleted: Set when the DeleteVC handler has been called on this
|
|
// VC. This guards against NDPROXY double-deleting VCs which it has
|
|
// been known to do.
|
|
//
|
|
// The pending bits below are mutually exclusive (except ClientClose which
|
|
// may occur after but simultaneous with ClientOpen), and so require lock
|
|
// protection by 'lockV':
|
|
//
|
|
// VCBF_PeerOpenPending: Set when peer attempts to establish a call, and
|
|
// the result is not yet known.
|
|
// VCBF_ClientOpenPending: Set when client attempts to establish a call,
|
|
// and the result is not yet known.
|
|
// VCBF_PeerClosePending: Set when peer attempts to close an established
|
|
// call and the result is not yet known. Access is protected by
|
|
// 'lockV'.
|
|
// VCBF_ClientClosePending: Set when client attempts to close an
|
|
// established call and the result is not yet known. Access is
|
|
// protected by 'lockV'.
|
|
// VCBM_Pending: Bit mask that includes each of the 4 pending flags.
|
|
//
|
|
// VCBF_ClientCloseCompletion: Set when client close completion is in
|
|
// progress.
|
|
//
|
|
// VCBF_IcsAlloc: Set when the 'pInCall' block has been locked for
|
|
// allocation and cleared when the call is torn down. Accessed only
|
|
// by the LockIcs/UnlockIcs routines.
|
|
// VCBF_IcsGrace: Set when the 'pInCall' pointer has been locked for a
|
|
// grace period during which the response to the incoming call message
|
|
// is sent. Accessed only by the LockIcs/UnlockIcs routines.
|
|
//
|
|
// VCBF_WaitInCallComplete: Set when the client is expected to call our
|
|
// call manager's IncomingCallComplete handler. This guards against
|
|
// NDPROXY double completing calls which it has been known to do.
|
|
// VCBF_WaitCloseCall: Set when the client is expected to call our call
|
|
// manager's CloseCall handler. This is strictly a debug aid.
|
|
//
|
|
// VCBF_CompPending: Set when this VC is put on tunnel's listCompletingVcs list
|
|
//
|
|
ULONG ulFlags;
|
|
#define VCBF_IndicateTimeReceived 0x00000001
|
|
#define VCBF_CallClosableByClient 0x00000002
|
|
#define VCBF_CallClosableByPeer 0x00000004
|
|
#define VCBF_DefaultLcParams 0x00000008
|
|
#define VCBF_IncomingFsm 0x00000010
|
|
#define VCBF_PeerInitiatedCall 0x00000020
|
|
#define VCBF_Sequencing 0x00000040
|
|
#define VCBF_VcCreated 0x00000100
|
|
#define VCBF_VcActivated 0x00000200
|
|
#define VCBF_VcDispatched 0x00000400
|
|
#define VCBM_VcState 0x00000700
|
|
#define VCBF_PeerOpenPending 0x00001000
|
|
#define VCBF_ClientOpenPending 0x00002000
|
|
#define VCBF_PeerClosePending 0x00004000
|
|
#define VCBF_ClientClosePending 0x00008000
|
|
#define VCBM_Pending 0x0000F000
|
|
#define VCBF_VcDeleted 0x00010000
|
|
#define VCBF_ClientCloseCompletion 0x00020000
|
|
#define VCBF_IcsAlloc 0x00040000
|
|
#define VCBF_IcsGrace 0x00080000
|
|
#define VCBF_WaitInCallComplete 0x00100000
|
|
#define VCBF_WaitCloseCall 0x00200000
|
|
#define VCBF_CompPending 0x01000000
|
|
|
|
|
|
// Reference count on the active call. Fields in this CALL SETUP section
|
|
// and in the CALL STATISTICS section should not be accessed without a
|
|
// call reference while the VC is activated. References may only be added
|
|
// when the VCCB_VcActivated flag is set, and this is enforced by
|
|
// ReferenceCall. The reference pairs are:
|
|
//
|
|
// (a) A reference is added when a VC is activated and removed when it is
|
|
// de-activated.
|
|
//
|
|
// (b) A reference is added when the send handler accepts a packet. For
|
|
// unsequenced sends the reference is removed by the send complete
|
|
// routine. For sequenced sends it it removed when the PAYLOADSENT
|
|
// context is destroyed.
|
|
//
|
|
// (c) A reference is added before scheduling a ZLB send and removed by
|
|
// the send completion routine.
|
|
//
|
|
// (d) A reference is added before entering ReceivePayload and removed on
|
|
// exit from same.
|
|
//
|
|
// (e) A reference is added before dispatching the call that is removed
|
|
// when the dispatch is completed.
|
|
//
|
|
// The field is accessed only by the ReferenceCall and DereferenceCall
|
|
// routines, which protect the field with 'lockCall'.
|
|
//
|
|
LONG lCallRef;
|
|
NDIS_SPIN_LOCK lockCall;
|
|
|
|
// The current state of the VCs call creation, i.e. the control channel's
|
|
// data channel setup for this VC. Access is protected by 'lockV' once
|
|
// the VC is set up to receive call control messages.
|
|
//
|
|
L2TPCALLSTATE state;
|
|
|
|
// Links to the prev/next VCCB in the owning tunnel's requesting VC list
|
|
// VC list. Access is protected by 'TUNNELCB.lockT'.
|
|
//
|
|
LIST_ENTRY linkRequestingVcs;
|
|
|
|
// Links to the prev/next VCCB in the owning tunnel's completing VC list.
|
|
// Access is protected by 'TUNNELCB.lockT'.
|
|
//
|
|
LIST_ENTRY linkCompletingVcs;
|
|
|
|
// This is set to the pending peer open/close or client open operation
|
|
// result to be reported to client.
|
|
//
|
|
NDIS_STATUS status;
|
|
|
|
// The received call setup message context. When peer initiates a call,
|
|
// we must create a VC and dispatch the incoming call to the client above.
|
|
// This is an asynchronous operation that must occur right in the middle
|
|
// of receive processing. This context stores information about the
|
|
// received message so it can be processed when it is known if client will
|
|
// accept the call. It also includes the CO_CALL_PARAMETERS buffer
|
|
// dispatched to client on incoming calls. The field is valid only until
|
|
// LcmCmIncomingCallComplete handler is called, at which time it is set to
|
|
// NULL.
|
|
//
|
|
// Shortcut addresses of the TAPI call info passed up in the
|
|
// NdisMCmDispatchIncomingCall. Obviously, they are valid only when
|
|
// 'pInCall' is valid. When invalid they are set to NULL.
|
|
//
|
|
INCALLSETUP* pInCall;
|
|
CO_AF_TAPI_INCOMING_CALL_PARAMETERS UNALIGNED * pTiParams;
|
|
LINE_CALL_INFO* pTcInfo;
|
|
|
|
// Reference count on the 'pInCall' context. The reference pairs are:
|
|
//
|
|
// (a) A reference is added when the context is allocated and removed
|
|
// by CallSetupComplete.
|
|
//
|
|
// (b) A reference is added before passing addresses within the context to
|
|
// ReceiveControlExpected and removed after that routine returns.
|
|
//
|
|
// The field is accessed only by the ReferenceIcs and DereferenceIcs
|
|
// routines, which protect with Interlocked routines. An exception is
|
|
// initializion to 1 by SetupVcAsynchronously.
|
|
//
|
|
LONG lInCallRef;
|
|
|
|
// Address of the call parameters passed down in CmMakeCall. This field
|
|
// will only be valid until the NdisMCmMakeCallComplete notification for
|
|
// the associated call is made, at which time it is reset to NULL. Access
|
|
// is via Interlocked routines.
|
|
//
|
|
// Shortcut addresses of the TAPI call parameters (both levels) and the
|
|
// L2TP-specific call parameters in the 'pMakeCall' buffer. Obviously,
|
|
// they are valid only when 'pMakeCall' is valid. When invalid they are
|
|
// set to NULL.
|
|
//
|
|
CO_CALL_PARAMETERS* pMakeCall;
|
|
CO_AF_TAPI_MAKE_CALL_PARAMETERS UNALIGNED* pTmParams;
|
|
LINE_CALL_PARAMS* pTcParams;
|
|
|
|
// Shortcut address of the L2TP-specific call parameters in the
|
|
// 'pMakeCall' or 'pInCall' buffer. Obviously, this is only valid when
|
|
// 'pMakeCall' or 'pInCall' is non-NULL. When invalid this is NULL. On
|
|
// MakeCall, caller may not provide 'pLcParams' in which case one is
|
|
// allocated and initialized to defaults for the convenience of the rest
|
|
// of the code. This temporary buffer is not reported to caller on
|
|
// MakeCallComplete.
|
|
//
|
|
L2TP_CALL_PARAMETERS* pLcParams;
|
|
|
|
// The result and error to report in the coming incoming/outgoing call
|
|
// reply message.
|
|
//
|
|
USHORT usResult;
|
|
USHORT usError;
|
|
|
|
// The connect speed in bits/second. This is the transmit speed value
|
|
// reported by the peer LAC, or the value we reported to the peer LNS and
|
|
// to NDISWAN. Since we have no real knowledge of connect speed, we
|
|
// report the minimum of the maximum rate acceptable to peer and
|
|
// L2TP_LanBps.
|
|
//
|
|
ULONG ulConnectBps;
|
|
|
|
// SEND STATE ------------------------------------------------------------
|
|
|
|
// Next Sent, the sequence number of next payload packet transmitted on
|
|
// this call. The field is initialized to 0 and incremented after
|
|
// assignment to an outgoing packet, excepting retransmissions. Access is
|
|
// protected by 'lockV'.
|
|
//
|
|
USHORT usNs;
|
|
|
|
// Double-linked list of outstanding sends, i.e. PAYLOADSENTs sorted by
|
|
// the 'usNs' field with lower values near the head. Access is protected
|
|
// by 'lockV'.
|
|
//
|
|
LIST_ENTRY listSendsOut;
|
|
|
|
// The number of sent but unacknowledged packets that may be outstanding.
|
|
// This value is adjusted dynamically. Per the draft/RFC, when
|
|
// 'ulAcksSinceSendTimeout' reaches the current setting, the window is
|
|
// increased by one. When a send timeout expires the window is reduced by
|
|
// half. The actual send window throttling is done by NDISWAN, based on
|
|
// our indications of the changing window size. Access is protected by
|
|
// 'lockV'.
|
|
//
|
|
ULONG ulSendWindow;
|
|
|
|
// The maximum value of 'ulSendWindow'. Peer chooses this value during
|
|
// call setup.
|
|
//
|
|
ULONG ulMaxSendWindow;
|
|
|
|
// The number of packets acknowledged since the last timeout. The value
|
|
// is reset when a timeout occurs or the send window is adjusted upward.
|
|
// See 'ulSendWindow'. Access is protected by 'lockV'.
|
|
//
|
|
ULONG ulAcksSinceSendTimeout;
|
|
|
|
// The estimated round trip time in milliseconds. This is the RTT value
|
|
// from Appendix A of the draft/RFC. The value is adjusted as each
|
|
// acknowledge is received. It is initialized to the Packet Processing
|
|
// Delay reported by peer. See 'ulSendTimeoutMs'. Access is protected by
|
|
// 'lockV'.
|
|
//
|
|
ULONG ulRoundTripMs;
|
|
|
|
// The estimated mean deviation in milliseconds, an approximation of the
|
|
// standard deviation. This is the DEV value from Appendix A of the
|
|
// draft/RFC. The value is adjusted as each acknowledge is received. It
|
|
// is initially 0. See 'ulSendTimeoutMs'. Access is protected by
|
|
// 'lockV'.
|
|
//
|
|
LONG lDeviationMs;
|
|
|
|
// Milliseconds before it is assumed a sent packet will never be
|
|
// acknowledged. This is the ATO value from Appendix A of the draft/RFC.
|
|
// This value is adjusted as each acknowledge is received, with a maximum
|
|
// of 'ADAPTERCB.ulMaxSendTimeoutMs'. Access is protected by 'lockV'.
|
|
//
|
|
ULONG ulSendTimeoutMs;
|
|
|
|
// The timer event descriptor scheduled to occur when it is time to stop
|
|
// waiting for an outgoing send on which to piggyback an acknowledge.
|
|
// This will be NULL when no delayed acknowledge is pending. Per the
|
|
// draft/RFC, the timeout used is 1/4 of the 'ulSendTimeoutMs'. Access is
|
|
// protected by 'lockV'.
|
|
//
|
|
TIMERQITEM* pTqiDelayedAck;
|
|
|
|
|
|
// RECEIVE STATE ---------------------------------------------------------
|
|
|
|
// Next Received, the sequence number one higher than that of the last
|
|
// payload packet received on this call or 0 if none. Access is protected
|
|
// by 'lockV'.
|
|
//
|
|
USHORT usNr;
|
|
|
|
// Double-linked list of out-of-order receives, i.e. PAYLOADRECEIVEs
|
|
// sorted by the 'usNs' field with lower values near the head. The
|
|
// maximum queue length is 'ADAPTERCB.sMaxOutOfOrder'. Access is
|
|
// protected by 'lockV'.
|
|
//
|
|
LIST_ENTRY listOutOfOrder;
|
|
|
|
|
|
// NDIS BOOKKEEPING ------------------------------------------------------
|
|
|
|
// NDIS's handle for this VC passed to us in MiniportCoCreateVcHandler.
|
|
// This is passed back to NDIS in various NdisXxx calls.
|
|
//
|
|
NDIS_HANDLE NdisVcHandle;
|
|
|
|
// Configuration settings returned to callers on OID_WAN_CO_GET_INFO and
|
|
// modified by callers on OID_WAN_CO_SET_INFO. Older NDISWAN references to
|
|
// "LINK" map straight to "VC" in the NDIS 5.0 world. Access is not
|
|
// protected because each ULONG in the structure is independent so no
|
|
// incoherency can result from multiple access.
|
|
//
|
|
NDIS_WAN_CO_GET_LINK_INFO linkinfo;
|
|
|
|
|
|
// STATISTICS ------------------------------------------------------------
|
|
|
|
// Statistics for the current call. Access is protected by 'lockV'.
|
|
//
|
|
CALLSTATS stats;
|
|
}
|
|
VCCB;
|
|
|
|
|
|
// The "exploded" description of an L2TP header, as output by
|
|
// ExplodeL2tpHeader.
|
|
//
|
|
typedef struct
|
|
_L2TPHEADERINFO
|
|
{
|
|
// Addresses of header fields. Some may be NULL indicating the field was
|
|
// not present in the header.
|
|
//
|
|
USHORT* pusBits;
|
|
USHORT* pusLength;
|
|
USHORT* pusTunnelId;
|
|
USHORT* pusCallId;
|
|
USHORT* pusNs;
|
|
USHORT* pusNr;
|
|
|
|
// Length of the variable length header in bytes.
|
|
//
|
|
ULONG ulHeaderLength;
|
|
|
|
// Address and length in bytes of the data following the variable length
|
|
// header.
|
|
//
|
|
CHAR* pData;
|
|
ULONG ulDataLength;
|
|
}
|
|
L2TPHEADERINFO;
|
|
|
|
|
|
// The "exploded" description of an Attribute/Value Pair (AVP), as output by
|
|
// ExplodeAvpHeader. The "value" is located and sized but not interpreted or
|
|
// byte-ordered until a GetAvpValueXxx routine is applied.
|
|
//
|
|
typedef struct
|
|
_AVPINFO
|
|
{
|
|
// Addresses of header fields. All are always present.
|
|
//
|
|
UNALIGNED USHORT* pusBits;
|
|
UNALIGNED USHORT* pusVendorId;
|
|
UNALIGNED USHORT* pusAttribute;
|
|
|
|
// The length of the entire AVP, extracted from '*pusBits'.
|
|
//
|
|
USHORT usOverallLength;
|
|
|
|
// Length of the value in bytes and the address of the value.
|
|
//
|
|
USHORT usValueLength;
|
|
CHAR* pValue;
|
|
}
|
|
AVPINFO;
|
|
|
|
|
|
// The "exploded" description of a control message, as output by
|
|
// ExplodeControlAvps.
|
|
//
|
|
typedef struct
|
|
_CONTROLMSGINFO
|
|
{
|
|
// GERR_* code indicating the result of the ExplodeControlAvps operation.
|
|
// Other fields should not be referenced unless this is GERR_None.
|
|
//
|
|
USHORT usXError;
|
|
|
|
// True when the message is a tunnel setup message, false if it is a call
|
|
// setup message.
|
|
//
|
|
BOOLEAN fTunnelMsg;
|
|
|
|
// Address of message type AVP value. The message type AVP is present in
|
|
// all valid control messages.
|
|
//
|
|
UNALIGNED USHORT* pusMsgType;
|
|
|
|
// Addresses of additional AVP values. These may be NULL indicating the
|
|
// AVP was not found in the message. The length field following variable
|
|
// length fields is valid whenever the value address is non-NULL.
|
|
//
|
|
USHORT* pusResult;
|
|
USHORT* pusError;
|
|
CHAR* pchResultMsg;
|
|
USHORT usResultMsgLength;
|
|
UNALIGNED USHORT* pusProtocolVersion;
|
|
UNALIGNED USHORT* pusFirmwareRevision;
|
|
UNALIGNED ULONG* pulFramingCaps;
|
|
UNALIGNED ULONG* pulBearerCaps;
|
|
CHAR* pchTieBreaker;
|
|
CHAR* pchHostName;
|
|
USHORT usHostNameLength;
|
|
UNALIGNED USHORT* pusAssignedTunnelId;
|
|
UNALIGNED USHORT* pusRWindowSize;
|
|
UNALIGNED USHORT* pusAssignedCallId;
|
|
UNALIGNED ULONG* pulCallSerialNumber;
|
|
UNALIGNED ULONG* pulMinimumBps;
|
|
UNALIGNED ULONG* pulMaximumBps;
|
|
UNALIGNED ULONG* pulBearerType;
|
|
UNALIGNED ULONG* pulFramingType;
|
|
UNALIGNED USHORT* pusPacketProcDelay;
|
|
CHAR* pchDialedNumber;
|
|
USHORT usDialedNumberLength;
|
|
CHAR* pchDialingNumber;
|
|
USHORT usDialingNumberLength;
|
|
UNALIGNED ULONG* pulTxConnectSpeed;
|
|
UNALIGNED ULONG* pulPhysicalChannelId;
|
|
CHAR* pchSubAddress;
|
|
USHORT usSubAddressLength;
|
|
CHAR* pchChallenge;
|
|
USHORT usChallengeLength;
|
|
CHAR* pchResponse;
|
|
UNALIGNED USHORT* pusProxyAuthType;
|
|
CHAR* pchProxyAuthResponse;
|
|
USHORT usProxyAuthResponseLength;
|
|
UNALIGNED ULONG* pulCallErrors;
|
|
UNALIGNED ULONG* pulAccm;
|
|
BOOLEAN fSequencingRequired;
|
|
}
|
|
CONTROLMSGINFO;
|
|
|
|
|
|
// Context for a control packet received out of order which is queued rather
|
|
// than discarding in the hope that the missing packet will arrive.
|
|
//
|
|
typedef struct
|
|
_CONTROLRECEIVED
|
|
{
|
|
// Link to the prev/next link in the 'TUNNELCB.listOutOfOrder' list.
|
|
//
|
|
LIST_ENTRY linkOutOfOrder;
|
|
|
|
// 'Next Sent' sequence number received in the packet.
|
|
//
|
|
USHORT usNs;
|
|
|
|
// Associated VC or NULL if none.
|
|
//
|
|
VCCB* pVc;
|
|
|
|
// The received GetBufferFromPool buffer.
|
|
//
|
|
CHAR* pBuffer;
|
|
|
|
// The "exploded" description of the control message.
|
|
//
|
|
CONTROLMSGINFO control;
|
|
}
|
|
CONTROLRECEIVED;
|
|
|
|
|
|
// Context for a control packet sent but not yet acknowledged. This block is
|
|
// queued on the 'TUNNELCB.listSendsOut' and 'TUNNELCB.listSendsPending'
|
|
// lists, and is associated with SendControlTimerEvents.
|
|
//
|
|
typedef struct
|
|
_CONTROLSENT
|
|
{
|
|
// Link to the prev/next link in the 'TUNNELCB.listSendsOut' list.
|
|
//
|
|
LIST_ENTRY linkSendsOut;
|
|
|
|
// Reference count on this context. The reference pairs are:
|
|
//
|
|
// (a) A reference is added when the context is queued into the
|
|
// 'listSendsOut' list, and removed by the de-queuer.
|
|
//
|
|
// (b) A reference is added before sending (and also before
|
|
// 'pTqiSendTimeout' is scheduled) and is removed by the send
|
|
// completion routine.
|
|
//
|
|
// (c) A reference is added before 'pTqiSendTimeout' is scheduled and
|
|
// removed as the timer event handler exits.
|
|
//
|
|
LONG lRef;
|
|
|
|
// 'Next Sent' sequence number sent with the packet.
|
|
//
|
|
USHORT usNs;
|
|
|
|
// The message type of the packet. (debug use only)
|
|
//
|
|
USHORT usMsgType;
|
|
|
|
// Timer event descriptor scheduled for the packet.
|
|
//
|
|
TIMERQITEM* pTqiSendTimeout;
|
|
|
|
// Number of times the packet has been retransmitted.
|
|
//
|
|
ULONG ulRetransmits;
|
|
|
|
// CSF_* flags indicating various options.
|
|
//
|
|
// CSF_Pending: Set when transmission or retransmission of the packet is
|
|
// pending. Access is protected by 'pTunnel->lockT'.
|
|
//
|
|
// CSF_TunnelIdleOnAck: Set when TunnelTransitionComplete is to be
|
|
// executed when the message is acknowledged, moving to CCS_Idle
|
|
// state.
|
|
//
|
|
// CSF_CallIdleOnAck: Set when CallTransitionComplete is to be executed
|
|
// when the message is acknowledged, moving to CS_Idle state.
|
|
//
|
|
ULONG ulFlags;
|
|
#define CSF_Pending 0x00000001
|
|
#define CSF_TunnelIdleOnAck 0x00000010
|
|
#define CSF_CallIdleOnAck 0x00000020
|
|
#define CSF_QueryMediaSpeed 0x00000040
|
|
#define CSF_IpUdpHeaders 0x00000080
|
|
|
|
// The outstanding packet's buffer, as passed to TDI.
|
|
//
|
|
CHAR* pBuffer;
|
|
|
|
// The length of the data to send in 'pBuffer'.
|
|
//
|
|
ULONG ulBufferLength;
|
|
|
|
// Back pointer to owning tunnel.
|
|
//
|
|
TUNNELCB* pTunnel;
|
|
|
|
// Back pointer to owning VC, or NULL if none.
|
|
//
|
|
VCCB* pVc;
|
|
|
|
// The NDIS system time at which the packet was originally sent.
|
|
//
|
|
LONGLONG llTimeSent;
|
|
|
|
// The IRP passed to TDI by the TDIX extension library, or NULL if none or
|
|
// it's already been completed. (for debug purposes only)
|
|
//
|
|
IRP* pIrp;
|
|
}
|
|
CONTROLSENT;
|
|
|
|
|
|
// Context for a payload packet received out of order which is queued for a
|
|
// time rather than discarding in the hope that the missing packet will
|
|
// arrive.
|
|
//
|
|
typedef struct
|
|
_PAYLOADRECEIVED
|
|
{
|
|
// Link to the prev/next link in the 'VCCB.listOutOfOrder' list.
|
|
//
|
|
LIST_ENTRY linkOutOfOrder;
|
|
|
|
// 'Next Sent' sequence number received in the packet.
|
|
//
|
|
USHORT usNs;
|
|
|
|
// The received GetBufferFromPool buffer.
|
|
//
|
|
CHAR* pBuffer;
|
|
|
|
// Offset of the payload to indicate received in 'pBuffer'.
|
|
//
|
|
ULONG ulPayloadOffset;
|
|
|
|
// Length in bytes of the payload to indicate received in 'pBuffer'.
|
|
//
|
|
ULONG ulPayloadLength;
|
|
|
|
// NDIS time the packet was received from the net, or 0 if caller did not
|
|
// choose the RECEIVE_TIME_INDICATION option in his call parameters.
|
|
//
|
|
LONGLONG llTimeReceived;
|
|
}
|
|
PAYLOADRECEIVED;
|
|
|
|
|
|
// Context for a payload packet sent but not yet acknowledged. This block is
|
|
// queued on the 'VCCB.listSendsOut', and is associated with
|
|
// SendPayloadTimerEvents.
|
|
//
|
|
typedef struct
|
|
_PAYLOADSENT
|
|
{
|
|
// Link to the prev/next link in the 'VCCB.listSendsOut' list.
|
|
//
|
|
LIST_ENTRY linkSendsOut;
|
|
|
|
// Link to the prev/next link in the 'g_listDebugPs' list. The list is
|
|
// maintained only when PSDEBUG is defined, but this is included always
|
|
// for the convenience of KD extension users. (for debug purposes only)
|
|
//
|
|
LIST_ENTRY linkDebugPs;
|
|
|
|
// Reference count on this context. The reference pairs are:
|
|
//
|
|
// (a) A reference is added when the context is queued into the
|
|
// 'listSendsOut' list, and removed by the de-queuer.
|
|
//
|
|
// (b) A reference is added before sending (and also before the time is
|
|
// scheduled) and removed by the send completion routine.
|
|
//
|
|
// (c) A reference is added before scheduling the timer and removed by the
|
|
// timer event handler.
|
|
//
|
|
LONG lRef;
|
|
|
|
// 'Next Sent' sequence number sent with the packet.
|
|
//
|
|
USHORT usNs;
|
|
|
|
// Timer event descriptor scheduled to fire when it's time to give up on
|
|
// receiving an acknowledge of the packet.
|
|
//
|
|
TIMERQITEM* pTqiSendTimeout;
|
|
|
|
// The built NDIS packet.
|
|
//
|
|
NDIS_PACKET* pPacket;
|
|
|
|
// The L2TP header buffer prepended to the payload buffer.
|
|
//
|
|
CHAR* pBuffer;
|
|
|
|
// Back pointer to the owning tunnel control block.
|
|
//
|
|
TUNNELCB* pTunnel;
|
|
|
|
// Back pointer to the owning VC control block.
|
|
//
|
|
VCCB* pVc;
|
|
|
|
// Status of the completed packet.
|
|
//
|
|
NDIS_STATUS status;
|
|
|
|
// The NDIS system time at which the packet was originally sent.
|
|
//
|
|
LONGLONG llTimeSent;
|
|
|
|
// The IRP passed to TDI by the TDIX extension library, or NULL if none or
|
|
// it's already been completed. (for debug purposes only)
|
|
//
|
|
IRP* pIrp;
|
|
}
|
|
PAYLOADSENT;
|
|
|
|
|
|
// Tunnel work handler that executes tunnel related work at PASSIVE IRQL.
|
|
// 'PWork' is the work context that should be freed with FREE_TUNNELWORK when
|
|
// the handler is done accessing the 'punpArgs' array. 'PTunnel' is the
|
|
// owning tunnel. 'PVc' is the owning VC, or NULL if none. 'PunpArgs' is an
|
|
// array of 4 auxillary arguments as passed to ScheduleTunnelWork.
|
|
//
|
|
typedef
|
|
VOID
|
|
(*PTUNNELWORK)(
|
|
IN TUNNELWORK* pWork,
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN ULONG_PTR* punpArgs );
|
|
|
|
|
|
// Tunnel work item describing a single unit of tunnel related work to be
|
|
// executed serially at PASSIVE IRQL by the TunnelWork mechanism.
|
|
//
|
|
typedef struct
|
|
_TUNNELWORK
|
|
{
|
|
// Link to the prev/next link in the 'TUNNELCB.listWork' queue.
|
|
//
|
|
LIST_ENTRY linkWork;
|
|
|
|
// Handler that executes this work item.
|
|
//
|
|
PTUNNELWORK pHandler;
|
|
|
|
// The associated VC, if any.
|
|
//
|
|
VCCB* pVc;
|
|
|
|
// Auxillary arguments passed to handler.
|
|
//
|
|
ULONG_PTR aunpArgs[ 4 ];
|
|
}
|
|
TUNNELWORK;
|
|
|
|
|
|
// Context of call setup for an incoming call. The information is used to
|
|
// store and later resume receive processing of an peer's call initiation
|
|
// across the asynchronous CoNdis calls, and for building the call parameter
|
|
// buffer to dispatch to client.
|
|
//
|
|
typedef struct
|
|
_INCALLSETUP
|
|
{
|
|
// See ReceiveControl for descriptions.
|
|
//
|
|
CHAR* pBuffer;
|
|
L2TPHEADERINFO info;
|
|
CONTROLMSGINFO control;
|
|
|
|
// Buffer in which the incoming call parameters to be dispatched to caller
|
|
// are built.
|
|
//
|
|
PVOID pvDummyPointerAligner;
|
|
|
|
CHAR achCallParams[ sizeof(CO_CALL_PARAMETERS)
|
|
|
|
+ sizeof(PVOID)
|
|
+ sizeof(CO_CALL_MANAGER_PARAMETERS)
|
|
|
|
+ sizeof(PVOID)
|
|
+ sizeof(CO_MEDIA_PARAMETERS)
|
|
+ sizeof(CO_AF_TAPI_INCOMING_CALL_PARAMETERS)
|
|
|
|
+ sizeof(PVOID)
|
|
+ sizeof(LINE_CALL_INFO)
|
|
|
|
+ sizeof(PVOID)
|
|
+ sizeof(L2TP_CALL_PARAMETERS)
|
|
|
|
+ ((L2TP_MaxDottedIpLen + 1) * sizeof(WCHAR)) ];
|
|
}
|
|
INCALLSETUP;
|
|
|
|
|
|
// The L2TP role played by an L2TP peer. The values may be read from the
|
|
// registry, so don't change randomly.
|
|
//
|
|
typedef enum
|
|
_L2TPROLE
|
|
{
|
|
LR_Lns = 1,
|
|
LR_Lac = 2
|
|
}
|
|
L2TPROLE;
|
|
|
|
|
|
// The strategy employed when it is time to add a host route and that route is
|
|
// found to already exists.
|
|
//
|
|
// Note: The values currently match the those of the registry parameter
|
|
// "UseExistingRoutes". Check GetRegistrySettings code before changing.
|
|
//
|
|
typedef enum
|
|
_HOSTROUTEEXISTS
|
|
{
|
|
HRE_Use = 0,
|
|
HRE_Fail = 1,
|
|
HRE_Reference = 2
|
|
}
|
|
HOSTROUTEEXISTS;
|
|
|
|
|
|
// Link status block for transfer across locks. See TransferLinkStatusInfo
|
|
// and IndicateLinkStatus.
|
|
//
|
|
typedef struct
|
|
_LINKSTATUSINFO
|
|
{
|
|
NDIS_HANDLE MiniportAdapterHandle;
|
|
NDIS_HANDLE NdisVcHandle;
|
|
WAN_CO_LINKPARAMS params;
|
|
}
|
|
LINKSTATUSINFO;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Macros/inlines
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define CtrlObjFromUdpContext(_x) \
|
|
(_x)->pCtrlAddr
|
|
|
|
#define PayloadObjFromUdpContext(_x) \
|
|
(_x)->pPayloadAddr
|
|
|
|
// These basics are not in the DDK headers for some reason.
|
|
//
|
|
#define min( a, b ) (((a) < (b)) ? (a) : (b))
|
|
#define max( a, b ) (((a) > (b)) ? (a) : (b))
|
|
|
|
#define InsertBefore( pNewL, pL ) \
|
|
{ \
|
|
(pNewL)->Flink = (pL); \
|
|
(pNewL)->Blink = (pL)->Blink; \
|
|
(pNewL)->Flink->Blink = (pNewL); \
|
|
(pNewL)->Blink->Flink = (pNewL); \
|
|
}
|
|
|
|
#define InsertAfter( pNewL, pL ) \
|
|
{ \
|
|
(pNewL)->Flink = (pL)->Flink; \
|
|
(pNewL)->Blink = (pL); \
|
|
(pNewL)->Flink->Blink = (pNewL); \
|
|
(pNewL)->Blink->Flink = (pNewL); \
|
|
}
|
|
|
|
// Pad to the size of the given datatype. (Borrowed from wdm.h which is not
|
|
// otherwise needed)
|
|
//
|
|
#define ALIGN_DOWN(length, type) \
|
|
((ULONG)(length) & ~(sizeof(type) - 1))
|
|
|
|
#define ALIGN_UP(length, type) \
|
|
(ALIGN_DOWN(((ULONG)(length) + sizeof(type) - 1), type))
|
|
|
|
// Winsock-ish host/network byte order converters for short and long integers.
|
|
//
|
|
#if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || ((defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_FULL_VER > 13009175))
|
|
#define htons(x) _byteswap_ushort((USHORT)(x))
|
|
#define htonl(x) _byteswap_ulong((ULONG)(x))
|
|
#else
|
|
#define htons( a ) ((((a) & 0xFF00) >> 8) |\
|
|
(((a) & 0x00FF) << 8))
|
|
#define htonl( a ) ((((a) & 0xFF000000) >> 24) | \
|
|
(((a) & 0x00FF0000) >> 8) | \
|
|
(((a) & 0x0000FF00) << 8) | \
|
|
(((a) & 0x000000FF) << 24))
|
|
#endif
|
|
#define ntohs( a ) htons(a)
|
|
#define ntohl( a ) htonl(a)
|
|
|
|
// network byte order
|
|
#define IPADDR_IS_MULTICAST(_addr) (((_addr) & 0x000000f0) == 0x000000e0)
|
|
#define IPADDR_IS_BROADCAST(_addr) ((_addr) == 0xffffffff)
|
|
|
|
|
|
// Place in a TRACE argument list to correspond with a format of "%d.%d.%d.%d"
|
|
// to print network byte-ordered IP address 'x' in human readable form.
|
|
//
|
|
#define IPADDRTRACE( x ) ((x) & 0x000000FF), \
|
|
(((x) >> 8) & 0x000000FF), \
|
|
(((x) >> 16) & 0x000000FF), \
|
|
(((x) >> 24) & 0x000000FF)
|
|
|
|
// Place in a TRACE argument list to correspond with a format of "%d" to print
|
|
// a percentage of two integers, or an average of two integers, or those
|
|
// values rounded.
|
|
//
|
|
#define PCTTRACE( n, d ) ((d) ? (((n) * 100) / (d)) : 0)
|
|
#define AVGTRACE( t, c ) ((c) ? ((t) / (c)) : 0)
|
|
#define PCTRNDTRACE( n, d ) ((d) ? (((((n) * 1000) / (d)) + 5) / 10) : 0)
|
|
#define AVGRNDTRACE( t, c ) ((c) ? (((((t) * 10) / (c)) + 5) / 10) : 0)
|
|
|
|
// All memory allocations and frees are done with these ALLOC_*/FREE_*
|
|
// macros/inlines to allow memory management scheme changes without global
|
|
// editing. For example, might choose to lump several lookaside lists of
|
|
// nearly equal sized items into a single list for efficiency.
|
|
//
|
|
// NdisFreeMemory requires the length of the allocation as an argument. NT
|
|
// currently doesn't use this for non-paged memory, but according to JameelH,
|
|
// Windows95 does. These inlines stash the length at the beginning of the
|
|
// allocation, providing the traditional malloc/free interface. The
|
|
// stash-area is a ULONGLONG so that all allocated blocks remain ULONGLONG
|
|
// aligned as they would be otherwise, preventing problems on Alphas.
|
|
//
|
|
__inline
|
|
VOID*
|
|
ALLOC_NONPAGED(
|
|
IN ULONG ulBufLength,
|
|
IN ULONG ulTag )
|
|
{
|
|
CHAR* pBuf;
|
|
|
|
NdisAllocateMemoryWithTag(
|
|
&pBuf, (UINT )(ulBufLength + MEMORY_ALLOCATION_ALIGNMENT), ulTag );
|
|
if (!pBuf)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
((ULONG* )pBuf)[ 0 ] = ulBufLength;
|
|
((ULONG* )pBuf)[ 1 ] = 0xC0BBC0DE;
|
|
return pBuf + MEMORY_ALLOCATION_ALIGNMENT;
|
|
}
|
|
|
|
__inline
|
|
VOID
|
|
FREE_NONPAGED(
|
|
IN VOID* pBuf )
|
|
{
|
|
ULONG ulBufLen;
|
|
|
|
ulBufLen = *((ULONG* )(((CHAR* )pBuf) - MEMORY_ALLOCATION_ALIGNMENT));
|
|
NdisFreeMemory(
|
|
((CHAR* )pBuf) - MEMORY_ALLOCATION_ALIGNMENT,
|
|
(UINT )(ulBufLen + MEMORY_ALLOCATION_ALIGNMENT),
|
|
0 );
|
|
}
|
|
|
|
#define ALLOC_NDIS_WORK_ITEM( pA ) \
|
|
NdisAllocateFromNPagedLookasideList( &(pA)->llistWorkItems )
|
|
#define FREE_NDIS_WORK_ITEM( pA, pNwi ) \
|
|
NdisFreeToNPagedLookasideList( &(pA)->llistWorkItems, (pNwi) )
|
|
|
|
#define ALLOC_TIMERQITEM( pA ) \
|
|
NdisAllocateFromNPagedLookasideList( &(pA)->llistTimerQItems )
|
|
#define FREE_TIMERQITEM( pA, pTqi ) \
|
|
NdisFreeToNPagedLookasideList( &(pA)->llistTimerQItems, (pTqi) )
|
|
|
|
#define ALLOC_CONTROLSENT( pA ) \
|
|
NdisAllocateFromNPagedLookasideList( &(pA)->llistControlSents )
|
|
#define FREE_CONTROLSENT( pA, pCs ) \
|
|
NdisFreeToNPagedLookasideList( &(pA)->llistControlSents, (pCs) )
|
|
|
|
#define ALLOC_PAYLOADSENT( pA ) \
|
|
NdisAllocateFromNPagedLookasideList( &(pA)->llistPayloadSents )
|
|
#define FREE_PAYLOADSENT( pA, pPs ) \
|
|
NdisFreeToNPagedLookasideList( &(pA)->llistPayloadSents, (pPs) )
|
|
|
|
#define ALLOC_TUNNELWORK( pA ) \
|
|
NdisAllocateFromNPagedLookasideList( &(pA)->llistTunnelWorks )
|
|
#define FREE_TUNNELWORK( pA, pCs ) \
|
|
NdisFreeToNPagedLookasideList( &(pA)->llistTunnelWorks, (pCs) )
|
|
|
|
#if LLISTALL
|
|
|
|
#define ALLOC_TUNNELCB( pA ) \
|
|
NdisAllocateFromNPagedLookasideList( &(pA)->llistTunnels )
|
|
#define FREE_TUNNELCB( pA, pT ) \
|
|
NdisFreeToNPagedLookasideList( &(pA)->llistTunnels, (pT) )
|
|
|
|
#define ALLOC_VCCB( pA ) \
|
|
NdisAllocateFromNPagedLookasideList( &(pA)->llistVcs )
|
|
#define FREE_VCCB( pA, pV ) \
|
|
NdisFreeToNPagedLookasideList( &(pA)->llistVcs, (pV) )
|
|
|
|
#define ALLOC_TIMERQ( pA ) \
|
|
NdisAllocateFromNPagedLookasideList( &(pA)->llistTimerQs )
|
|
#define FREE_TIMERQ( pA, pTq ) \
|
|
NdisFreeToNPagedLookasideList( &(pA)->llistTimerQs, (pTq) )
|
|
|
|
#define ALLOC_CONTROLRECEIVED( pA ) \
|
|
NdisAllocateFromNPagedLookasideList( &(pA)->llistControlReceiveds )
|
|
#define FREE_CONTROLRECEIVED( pA, pCr ) \
|
|
NdisFreeToNPagedLookasideList( &(pA)->llistControlReceiveds, (pCr) )
|
|
|
|
#define ALLOC_PAYLOADRECEIVED( pA ) \
|
|
NdisAllocateFromNPagedLookasideList( &(pA)->llistPayloadReceiveds )
|
|
#define FREE_PAYLOADRECEIVED( pA, pPr ) \
|
|
NdisFreeToNPagedLookasideList( &(pA)->llistPayloadReceiveds, (pPr) )
|
|
|
|
#define ALLOC_INCALLSETUP( pA ) \
|
|
NdisAllocateFromNPagedLookasideList( &(pA)->llistInCallSetups )
|
|
#define FREE_INCALLSETUP( pA, pCs ) \
|
|
NdisFreeToNPagedLookasideList( &(pA)->llistInCallSetups, (pCs) )
|
|
|
|
#else // !LLISTALL
|
|
|
|
#define ALLOC_TUNNELCB( pA ) \
|
|
ALLOC_NONPAGED( sizeof(TUNNELCB), MTAG_TUNNELCB )
|
|
#define FREE_TUNNELCB( pA, pT ) \
|
|
FREE_NONPAGED( pT )
|
|
|
|
#define ALLOC_VCCB( pA ) \
|
|
ALLOC_NONPAGED( sizeof(VCCB), MTAG_VCCB )
|
|
#define FREE_VCCB( pA, pV ) \
|
|
FREE_NONPAGED( pV )
|
|
|
|
#define ALLOC_TIMERQ( pA ) \
|
|
ALLOC_NONPAGED( sizeof(TIMERQ), MTAG_TIMERQ )
|
|
#define FREE_TIMERQ( pA, pTq ) \
|
|
FREE_NONPAGED( pTq )
|
|
|
|
#define ALLOC_CONTROLRECEIVED( pA ) \
|
|
ALLOC_NONPAGED( sizeof(CONTROLRECEIVED), MTAG_CTRLRECD )
|
|
#define FREE_CONTROLRECEIVED( pA, pCr ) \
|
|
FREE_NONPAGED( pCr )
|
|
|
|
#define ALLOC_PAYLOADRECEIVED( pA ) \
|
|
ALLOC_NONPAGED( sizeof(PAYLOADRECEIVED), MTAG_PAYLRECD )
|
|
#define FREE_PAYLOADRECEIVED( pA, pPr ) \
|
|
FREE_NONPAGED( pPr )
|
|
|
|
#define ALLOC_INCALLSETUP( pA ) \
|
|
ALLOC_NONPAGED( sizeof(INCALLSETUP), MTAG_INCALL )
|
|
#define FREE_INCALLSETUP( pA, pCs ) \
|
|
FREE_NONPAGED( pCs )
|
|
|
|
#define ALLOC_CONTROLMSGINFO( pA ) \
|
|
NdisAllocateFromNPagedLookasideList( &(pA)->llistControlMsgInfos )
|
|
#define FREE_CONTROLMSGINFO( pA, pCmi ) \
|
|
NdisFreeToNPagedLookasideList( &(pA)->llistControlMsgInfos, (pCmi) )
|
|
|
|
#endif // !LLISTALL
|
|
|
|
#if READFLAGSDIRECT
|
|
|
|
#define ReadFlags( pulFlags ) \
|
|
(*pulFlags)
|
|
|
|
#endif
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Prototypes (alphabetically)
|
|
//-----------------------------------------------------------------------------
|
|
|
|
VOID
|
|
ActivateCallIdSlot(
|
|
IN VCCB* pVc );
|
|
|
|
VOID
|
|
AddHostRoute(
|
|
IN TUNNELWORK* pWork,
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN ULONG_PTR* punpArgs );
|
|
|
|
BOOLEAN
|
|
AdjustSendWindowAtAckReceived(
|
|
IN ULONG ulMaxSendWindow,
|
|
IN OUT ULONG* pulAcksSinceSendTimeout,
|
|
IN OUT ULONG* pulSendWindow );
|
|
|
|
VOID
|
|
AdjustTimeoutsAtAckReceived(
|
|
IN LONGLONG llSendTime,
|
|
IN ULONG ulMaxSendTimeoutMs,
|
|
OUT ULONG* pulSendTimeoutMs,
|
|
IN OUT ULONG* pulRoundTripMs,
|
|
IN OUT LONG* plDeviationMs );
|
|
|
|
VOID
|
|
AdjustTimeoutsAndSendWindowAtTimeout(
|
|
IN ULONG ulMaxSendTimeoutMs,
|
|
IN LONG lDeviationMs,
|
|
OUT ULONG* pulSendTimeoutMs,
|
|
IN OUT ULONG* pulRoundTripMs,
|
|
IN OUT ULONG* pulSendWindow,
|
|
OUT ULONG* pulAcksSinceSendTimeout );
|
|
|
|
VOID
|
|
CalculateResponse(
|
|
IN UCHAR* puchChallenge,
|
|
IN ULONG ulChallengeLength,
|
|
IN CHAR* pszPassword,
|
|
IN UCHAR uchId,
|
|
OUT UCHAR* puchResponse );
|
|
|
|
VOID
|
|
CallCleanUp(
|
|
IN VCCB* pVc );
|
|
|
|
VOID
|
|
CallTransitionComplete(
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN L2TPCALLSTATE state );
|
|
|
|
VOID
|
|
ChangeHostRoute(
|
|
IN TUNNELWORK* pWork,
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN ULONG_PTR* punpArgs );
|
|
|
|
VOID
|
|
ClearFlags(
|
|
IN OUT ULONG* pulFlags,
|
|
IN ULONG ulMask );
|
|
|
|
VOID
|
|
CloseCall(
|
|
IN TUNNELWORK* pWork,
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN ULONG_PTR* punpArgs );
|
|
|
|
BOOLEAN
|
|
CloseCall2(
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN USHORT usResult,
|
|
IN USHORT usError );
|
|
|
|
VOID
|
|
CloseTdix(
|
|
IN TUNNELWORK* pWork,
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN ULONG_PTR* punpArgs );
|
|
|
|
VOID
|
|
CloseTunnel(
|
|
IN TUNNELWORK* pWork,
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN ULONG_PTR* punpArgs );
|
|
|
|
VOID
|
|
CloseTunnel2(
|
|
IN TUNNELCB* pTunnel );
|
|
|
|
VOID
|
|
CompleteVcs(
|
|
IN TUNNELCB* pTunnel );
|
|
|
|
VOID
|
|
DeleteHostRoute(
|
|
IN TUNNELWORK* pWork,
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN ULONG_PTR* punpArgs );
|
|
|
|
VOID
|
|
DereferenceAdapter(
|
|
IN ADAPTERCB* pAdapter );
|
|
|
|
VOID
|
|
DereferenceCall(
|
|
IN VCCB* pVc );
|
|
|
|
LONG
|
|
DereferenceControlSent(
|
|
IN CONTROLSENT* pSent );
|
|
|
|
LONG
|
|
DereferencePayloadSent(
|
|
IN PAYLOADSENT* pPs );
|
|
|
|
VOID
|
|
DereferenceSap(
|
|
IN ADAPTERCB* pAdapter );
|
|
|
|
LONG
|
|
DereferenceTunnel(
|
|
IN TUNNELCB* pTunnel );
|
|
|
|
VOID
|
|
DereferenceVc(
|
|
IN VCCB* pVc );
|
|
|
|
VOID
|
|
DottedFromIpAddress(
|
|
IN ULONG ulIpAddress,
|
|
OUT CHAR* pszIpAddress,
|
|
IN BOOLEAN fUnicode );
|
|
|
|
NDIS_STATUS
|
|
ExecuteWork(
|
|
IN ADAPTERCB* pAdapter,
|
|
IN NDIS_PROC pProc,
|
|
IN PVOID pContext,
|
|
IN ULONG ulArg1,
|
|
IN ULONG ulArg2,
|
|
IN ULONG ulArg3,
|
|
IN ULONG ulArg4 );
|
|
|
|
#if 0
|
|
VOID
|
|
ExplodeWanAddress(
|
|
IN WAN_ADDRESS* pWanAddress,
|
|
OUT CHAR** ppArg1,
|
|
OUT ULONG* pulLength1,
|
|
OUT CHAR** ppArg2,
|
|
OUT ULONG* pulLength2,
|
|
OUT CHAR** ppArg3,
|
|
OUT ULONG* pulLength3 );
|
|
#endif
|
|
|
|
VOID
|
|
FsmCloseCall(
|
|
IN TUNNELWORK* pWork,
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN ULONG_PTR* punpArgs );
|
|
|
|
VOID
|
|
FsmCloseTunnel(
|
|
IN TUNNELWORK* pWork,
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN ULONG_PTR* punpArgs );
|
|
|
|
VOID
|
|
FsmOpenCall(
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc );
|
|
|
|
VOID
|
|
FsmOpenTunnel(
|
|
IN TUNNELWORK* pWork,
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN ULONG_PTR* punpArgs );
|
|
|
|
VOID
|
|
FsmOpenIdleTunnel(
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc );
|
|
|
|
BOOLEAN
|
|
FsmReceive(
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN CHAR* pBuffer,
|
|
IN CONTROLMSGINFO* pControl );
|
|
|
|
CHAR*
|
|
GetFullHostNameFromRegistry(
|
|
VOID );
|
|
|
|
USHORT
|
|
GetNextTerminationCallId(
|
|
IN ADAPTERCB* pAdapter );
|
|
|
|
USHORT
|
|
GetNextTunnelId(
|
|
IN ADAPTERCB* pAdapter );
|
|
|
|
VOID
|
|
IndicateLinkStatus(
|
|
IN VCCB* pVc,
|
|
IN LINKSTATUSINFO* pInfo );
|
|
|
|
ULONG
|
|
IpAddressFromDotted(
|
|
IN CHAR* pchIpAddress );
|
|
|
|
NDIS_STATUS
|
|
LcmCmOpenAf(
|
|
IN NDIS_HANDLE CallMgrBindingContext,
|
|
IN PCO_ADDRESS_FAMILY AddressFamily,
|
|
IN NDIS_HANDLE NdisAfHandle,
|
|
OUT PNDIS_HANDLE CallMgrAfContext );
|
|
|
|
NDIS_STATUS
|
|
LcmCmCloseAf(
|
|
IN NDIS_HANDLE CallMgrAfContext );
|
|
|
|
NDIS_STATUS
|
|
LcmCmRegisterSap(
|
|
IN NDIS_HANDLE CallMgrAfContext,
|
|
IN PCO_SAP Sap,
|
|
IN NDIS_HANDLE NdisSapHandle,
|
|
OUT PNDIS_HANDLE CallMgrSapContext );
|
|
|
|
NDIS_STATUS
|
|
LcmCmDeregisterSap(
|
|
NDIS_HANDLE CallMgrSapContext );
|
|
|
|
#ifndef OLDMCM
|
|
|
|
NDIS_STATUS
|
|
LcmCmCreateVc(
|
|
IN NDIS_HANDLE ProtocolAfContext,
|
|
IN NDIS_HANDLE NdisVcHandle,
|
|
OUT PNDIS_HANDLE ProtocolVcContext );
|
|
|
|
NDIS_STATUS
|
|
LcmCmDeleteVc(
|
|
IN NDIS_HANDLE ProtocolVcContext );
|
|
|
|
#endif // !OLDMCM
|
|
|
|
NDIS_STATUS
|
|
LcmCmMakeCall(
|
|
IN NDIS_HANDLE CallMgrVcContext,
|
|
IN OUT PCO_CALL_PARAMETERS CallParameters,
|
|
IN NDIS_HANDLE NdisPartyHandle,
|
|
OUT PNDIS_HANDLE CallMgrPartyContext );
|
|
|
|
NDIS_STATUS
|
|
LcmCmCloseCall(
|
|
IN NDIS_HANDLE CallMgrVcContext,
|
|
IN NDIS_HANDLE CallMgrPartyContext,
|
|
IN PVOID CloseData,
|
|
IN UINT Size );
|
|
|
|
VOID
|
|
LcmCmIncomingCallComplete(
|
|
IN NDIS_STATUS Status,
|
|
IN NDIS_HANDLE CallMgrVcContext,
|
|
IN PCO_CALL_PARAMETERS CallParameters );
|
|
|
|
VOID
|
|
LcmCmActivateVcComplete(
|
|
IN NDIS_STATUS Status,
|
|
IN NDIS_HANDLE CallMgrVcContext,
|
|
IN PCO_CALL_PARAMETERS CallParameters );
|
|
|
|
VOID
|
|
LcmCmDeactivateVcComplete(
|
|
IN NDIS_STATUS Status,
|
|
IN NDIS_HANDLE CallMgrVcContext );
|
|
|
|
NDIS_STATUS
|
|
LcmCmModifyCallQoS(
|
|
IN NDIS_HANDLE CallMgrVcContext,
|
|
IN PCO_CALL_PARAMETERS CallParameters );
|
|
|
|
NDIS_STATUS
|
|
LcmCmRequest(
|
|
IN NDIS_HANDLE CallMgrAfContext,
|
|
IN NDIS_HANDLE CallMgrVcContext,
|
|
IN NDIS_HANDLE CallMgrPartyContext,
|
|
IN OUT PNDIS_REQUEST NdisRequest );
|
|
|
|
NDIS_STATUS
|
|
LmpInitialize(
|
|
OUT PNDIS_STATUS OpenErrorStatus,
|
|
OUT PUINT SelectedMediumIndex,
|
|
IN PNDIS_MEDIUM MediumArray,
|
|
IN UINT MediumArraySize,
|
|
IN NDIS_HANDLE MiniportAdapterHandle,
|
|
IN NDIS_HANDLE WrapperConfigurationContext );
|
|
|
|
VOID
|
|
LmpHalt(
|
|
IN NDIS_HANDLE MiniportAdapterContext );
|
|
|
|
NDIS_STATUS
|
|
LmpReset(
|
|
OUT PBOOLEAN AddressingReset,
|
|
IN NDIS_HANDLE MiniportAdapterContext );
|
|
|
|
VOID
|
|
LmpReturnPacket(
|
|
IN NDIS_HANDLE MiniportAdapterContext,
|
|
IN PNDIS_PACKET Packet );
|
|
|
|
NDIS_STATUS
|
|
LmpQueryInformation(
|
|
IN NDIS_HANDLE MiniportAdapterContext,
|
|
IN NDIS_OID Oid,
|
|
IN PVOID InformationBuffer,
|
|
IN ULONG InformationBufferLength,
|
|
OUT PULONG BytesWritten,
|
|
OUT PULONG BytesNeeded );
|
|
|
|
NDIS_STATUS
|
|
LmpSetInformation(
|
|
IN NDIS_HANDLE MiniportAdapterContext,
|
|
IN NDIS_OID Oid,
|
|
IN PVOID InformationBuffer,
|
|
IN ULONG InformationBufferLength,
|
|
OUT PULONG BytesRead,
|
|
OUT PULONG BytesNeeded );
|
|
|
|
#ifdef OLDMCM
|
|
|
|
NDIS_STATUS
|
|
LmpCoCreateVc(
|
|
IN NDIS_HANDLE MiniportAdapterContext,
|
|
IN NDIS_HANDLE NdisVcHandle,
|
|
IN PNDIS_HANDLE MiniportVcContext );
|
|
|
|
NDIS_STATUS
|
|
LmpCoDeleteVc(
|
|
IN NDIS_HANDLE MiniportVcContext );
|
|
|
|
#endif // OLDMCM
|
|
|
|
NDIS_STATUS
|
|
LmpCoActivateVc(
|
|
IN NDIS_HANDLE MiniportVcContext,
|
|
IN OUT PCO_CALL_PARAMETERS CallParameters );
|
|
|
|
NDIS_STATUS
|
|
LmpCoDeactivateVc(
|
|
IN NDIS_HANDLE MiniportVcContext );
|
|
|
|
VOID
|
|
LmpCoSendPackets(
|
|
IN NDIS_HANDLE MiniportVcContext,
|
|
IN PPNDIS_PACKET PacketArray,
|
|
IN UINT NumberOfPackets );
|
|
|
|
NDIS_STATUS
|
|
LmpCoRequest(
|
|
IN NDIS_HANDLE MiniportAdapterContext,
|
|
IN NDIS_HANDLE MiniportVcContext,
|
|
IN OUT PNDIS_REQUEST NdisRequest );
|
|
|
|
VOID
|
|
L2tpReceive(
|
|
IN TDIXCONTEXT* pTdix,
|
|
IN TDIXRDGINFO* pRdg,
|
|
IN CHAR* pBuffer,
|
|
IN ULONG ulOffset,
|
|
IN ULONG ulBufferLen );
|
|
|
|
CHAR*
|
|
MsgTypePszFromUs(
|
|
IN USHORT usMsgType );
|
|
|
|
#if READFLAGSDIRECT == 0
|
|
ULONG
|
|
ReadFlags(
|
|
IN ULONG* pulFlags );
|
|
#endif
|
|
|
|
BOOLEAN
|
|
ReceiveControlExpected(
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN CHAR* pBuffer,
|
|
IN CONTROLMSGINFO* pControl );
|
|
|
|
VOID
|
|
ReferenceAdapter(
|
|
IN ADAPTERCB* pAdapter );
|
|
|
|
BOOLEAN
|
|
ReferenceCall(
|
|
IN VCCB* pVc );
|
|
|
|
VOID
|
|
ReferenceControlSent(
|
|
IN CONTROLSENT* pSent );
|
|
|
|
VOID
|
|
ReferencePayloadSent(
|
|
IN PAYLOADSENT* pPs );
|
|
|
|
BOOLEAN
|
|
ReferenceSap(
|
|
IN ADAPTERCB* pAdapter );
|
|
|
|
LONG
|
|
ReferenceTunnel(
|
|
IN TUNNELCB* pTunnel,
|
|
IN BOOLEAN fHaveLockTunnels );
|
|
|
|
VOID
|
|
ReferenceVc(
|
|
IN VCCB* pVc );
|
|
|
|
BOOLEAN
|
|
ReleaseCallIdSlot(
|
|
IN VCCB* pVc );
|
|
|
|
NDIS_STATUS
|
|
ReserveCallIdSlot(
|
|
IN VCCB* pVc );
|
|
|
|
VOID
|
|
ResetHelloTimer(
|
|
IN TUNNELCB* pTunnel );
|
|
|
|
VOID
|
|
ScheduleTunnelWork(
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN PTUNNELWORK pHandler,
|
|
IN ULONG_PTR unpArg0,
|
|
IN ULONG_PTR unpArg1,
|
|
IN ULONG_PTR unpArg2,
|
|
IN ULONG_PTR unpArg3,
|
|
IN BOOLEAN fTcbPreReferenced,
|
|
IN BOOLEAN fHighPriority );
|
|
|
|
NDIS_STATUS
|
|
ScheduleWork(
|
|
IN ADAPTERCB* pAdapter,
|
|
IN NDIS_PROC pProc,
|
|
IN PVOID pContext );
|
|
|
|
VOID
|
|
SendControlAck(
|
|
IN TUNNELWORK* pWork,
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN ULONG_PTR* punpArgs );
|
|
|
|
VOID
|
|
SendControl(
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN USHORT usMsgType,
|
|
IN ULONG ulBuildAvpsArg1,
|
|
IN ULONG ulBuildAvpsArg2,
|
|
IN PVOID pvBuildAvpsArg3,
|
|
IN ULONG ulFlags );
|
|
|
|
VOID
|
|
SendControlTimerEvent(
|
|
IN TIMERQITEM* pItem,
|
|
IN VOID* pContext,
|
|
IN TIMERQEVENT event );
|
|
|
|
VOID
|
|
SendPayload(
|
|
IN VCCB* pVc,
|
|
IN NDIS_PACKET* pPacket );
|
|
|
|
VOID
|
|
SendPayloadAck(
|
|
IN TUNNELWORK* pWork,
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN ULONG_PTR* punpArgs );
|
|
|
|
VOID
|
|
SendPending(
|
|
IN TUNNELWORK* pWork,
|
|
IN TUNNELCB* pTunnel,
|
|
IN VCCB* pVc,
|
|
IN ULONG_PTR* punpArgs );
|
|
|
|
VOID
|
|
SetFlags(
|
|
IN OUT ULONG* pulFlags,
|
|
IN ULONG ulMask );
|
|
|
|
TUNNELCB*
|
|
SetupTunnel(
|
|
IN ADAPTERCB* pAdapter,
|
|
IN ULONG ulIpAddress,
|
|
IN USHORT usUdpPort,
|
|
IN USHORT usAssignedTunnelId,
|
|
IN BOOLEAN fExclusive );
|
|
|
|
VOID
|
|
SetupVcAsynchronously(
|
|
IN TUNNELCB* pTunnel,
|
|
IN ULONG ulIpAddress,
|
|
IN CHAR* pBuffer,
|
|
IN CONTROLMSGINFO* pControl );
|
|
|
|
WCHAR*
|
|
StrDupAsciiToUnicode(
|
|
IN CHAR* psz,
|
|
IN ULONG ulPszBytes );
|
|
|
|
WCHAR*
|
|
StrDupNdisString(
|
|
IN NDIS_STRING* pNdisString );
|
|
|
|
CHAR*
|
|
StrDupNdisVarDataDescStringA(
|
|
IN NDIS_VAR_DATA_DESC* pDesc );
|
|
|
|
CHAR*
|
|
StrDupNdisVarDataDescStringToA(
|
|
IN NDIS_VAR_DATA_DESC UNALIGNED* pDesc );
|
|
|
|
CHAR*
|
|
StrDupNdisStringToA(
|
|
IN NDIS_STRING* pNdisString );
|
|
|
|
CHAR*
|
|
StrDupSized(
|
|
IN CHAR* psz,
|
|
IN ULONG ulLength,
|
|
IN ULONG ulExtra );
|
|
|
|
CHAR*
|
|
StrDupUnicodeToAscii(
|
|
IN WCHAR* pwsz,
|
|
IN ULONG ulPwszBytes );
|
|
|
|
ULONG
|
|
StrLenW(
|
|
IN WCHAR* psz );
|
|
|
|
VOID
|
|
TransferLinkStatusInfo(
|
|
IN VCCB* pVc,
|
|
OUT LINKSTATUSINFO* pInfo );
|
|
|
|
TUNNELCB*
|
|
TunnelCbFromIpAddressAndAssignedTunnelId(
|
|
IN ADAPTERCB* pAdapter,
|
|
IN ULONG ulIpAddress,
|
|
IN USHORT usUdpPort,
|
|
IN USHORT usAssignedTunnelId );
|
|
|
|
VOID
|
|
TunnelTransitionComplete(
|
|
IN TUNNELCB* pTunnel,
|
|
IN L2TPCCSTATE state );
|
|
|
|
VOID
|
|
UpdateGlobalCallStats(
|
|
IN VCCB* pVc );
|
|
|
|
VCCB*
|
|
VcCbFromCallId(
|
|
IN TUNNELCB* pTunnel,
|
|
IN USHORT usCallId );
|
|
|
|
|
|
#endif // _L2TPP_H_
|