|
|
//============================================================================
// Copyright (c) 1995, Microsoft Corporation
//
// File: table.h
//
// History:
// Abolade Gbadegesin Aug-8-1995 Created.
//
// V Raman Oct-3-1996
// Added Deactivate Event to IF_TABLE_ENTRY
//
// V Raman Oct-27-1996
// Removed Deactivate Event in IF_TABLE_ENTRY
// and made interface deactivation synchronous
//
// Contains structures and macros used for table management.
//============================================================================
#ifndef _TABLE_H_
#define _TABLE_H_
#define GETMODE_EXACT 0
#define GETMODE_FIRST 1
#define GETMODE_NEXT 2
//
// TYPE DEFINITIONS FOR INTERFACE MANAGEMENT
//
//
// struct: IF_TABLE_ENTRY
//
// declares the components of an interface table entry
//
//
typedef struct _IF_TABLE_ENTRY {
LIST_ENTRY ITE_LinkByAddress; LIST_ENTRY ITE_LinkByIndex; LIST_ENTRY ITE_HTLinkByIndex; NET_INTERFACE_TYPE ITE_Type; DWORD ITE_Index; DWORD ITE_Flags; HANDLE ITE_FullOrDemandUpdateTimer; IPRIP_IF_STATS ITE_Stats; PIPRIP_IF_CONFIG ITE_Config; PIPRIP_IF_BINDING ITE_Binding; SOCKET *ITE_Sockets;
} IF_TABLE_ENTRY, *PIF_TABLE_ENTRY;
#define ITEFLAG_ENABLED ((DWORD)0x00000001)
#define ITEFLAG_BOUND ((DWORD)0x00000002)
#define ITEFLAG_FULL_UPDATE_PENDING ((DWORD)0x00000004)
#define ITEFLAG_FULL_UPDATE_INQUEUE ((DWORD)0x00000008)
#define IF_IS_ENABLED(i) \
((i)->ITE_Flags & ITEFLAG_ENABLED) #define IF_IS_BOUND(i) \
((i)->ITE_Flags & ITEFLAG_BOUND) #define IF_IS_ACTIVE(i) \
(IF_IS_BOUND(i) && IF_IS_ENABLED(i))
#define IF_IS_DISABLED(i) !IF_IS_ENABLED(i)
#define IF_IS_UNBOUND(i) !IF_IS_BOUND(i)
#define IF_IS_INACTIVE(i) !IF_IS_ACTIVE(i)
#define IF_FULL_UPDATE_PENDING(i) \
((i)->ITE_Flags & ITEFLAG_FULL_UPDATE_PENDING) #define IF_FULL_UPDATE_INQUEUE(i) \
((i)->ITE_Flags & ITEFLAG_FULL_UPDATE_INQUEUE)
//
// macros and definitions used by interface tables
//
#define IF_HASHTABLE_SIZE 29
#define IF_HASHVALUE(i) ((i) % IF_HASHTABLE_SIZE)
//
// struct: IF_TABLE
//
// declares the structure of an interface table. consists of a hash-table
// of IF_TABLE_ENTRY structures hashed on interface index, and a list
// of all activated interfaces ordered by IP address
//
// The IT_CS section is used to synchronize the generation of updates;
// it is acquired when updates are started and finished on interfaces
// in this table, and thus it protects the flags field.
//
// The IT_RWL section is used to synchronize modifications to the table;
// it must be acquired exclusively when entries are being added or deleted
// from the table, and when the states of entries are being changed.
// (e.g. binding, unbinding, enabling and disabling entries).
//
// IT_RWL must be acquired non-exclusively on all other acceses.
//
// When IT_RWL and IT_CS must both be acquired, IT_RWL must be acquired first.
//
typedef struct _IF_TABLE {
DWORD IT_Created; DWORD IT_Flags; LARGE_INTEGER IT_LastUpdateTime; HANDLE IT_FinishTriggeredUpdateTimer; HANDLE IT_FinishFullUpdateTimer; CRITICAL_SECTION IT_CS; READ_WRITE_LOCK IT_RWL; LIST_ENTRY IT_ListByAddress; LIST_ENTRY IT_ListByIndex; LIST_ENTRY IT_HashTableByIndex[IF_HASHTABLE_SIZE];
} IF_TABLE, *PIF_TABLE;
//
// constants and macros used for the flags field
//
#define IPRIP_FLAG_FULL_UPDATE_PENDING ((DWORD)0x00000001)
#define IPRIP_FLAG_TRIGGERED_UPDATE_PENDING ((DWORD)0x00000002)
#define IPRIP_FULL_UPDATE_PENDING(t) \
((t)->IT_Flags & IPRIP_FLAG_FULL_UPDATE_PENDING)
#define IPRIP_TRIGGERED_UPDATE_PENDING(t) \
((t)->IT_Flags & IPRIP_FLAG_TRIGGERED_UPDATE_PENDING)
DWORD CreateIfTable( PIF_TABLE pTable );
DWORD DeleteIfTable( PIF_TABLE pTable );
DWORD CreateIfEntry( PIF_TABLE pTable, DWORD dwIndex, NET_INTERFACE_TYPE dwIfType, PIPRIP_IF_CONFIG pConfig, PIF_TABLE_ENTRY *ppEntry );
DWORD DeleteIfEntry( PIF_TABLE pIfTable, DWORD dwIndex );
DWORD ValidateIfConfig( PIPRIP_IF_CONFIG pic );
DWORD CreateIfSocket( PIF_TABLE_ENTRY pITE );
DWORD DeleteIfSocket( PIF_TABLE_ENTRY pITE );
DWORD BindIfEntry( PIF_TABLE pTable, DWORD dwIndex, PIP_ADAPTER_BINDING_INFO pBinding );
DWORD UnBindIfEntry( PIF_TABLE pTable, DWORD dwIndex );
DWORD EnableIfEntry( PIF_TABLE pTable, DWORD dwIndex );
DWORD ConfigureIfEntry( PIF_TABLE pTable, DWORD dwIndex, PIPRIP_IF_CONFIG pConfig );
DWORD DisableIfEntry( PIF_TABLE pTable, DWORD dwIndex );
PIF_TABLE_ENTRY GetIfByIndex( PIF_TABLE pTable, DWORD dwIndex );
PIF_TABLE_ENTRY GetIfByAddress( PIF_TABLE pTable, DWORD dwAddress, DWORD dwGetMode, PDWORD pdwErr );
PIF_TABLE_ENTRY GetIfByListIndex( PIF_TABLE pTable, DWORD dwAddress, DWORD dwGetMode, PDWORD pdwErr );
#define IF_TABLE_CREATED(pTable) ((pTable)->IT_Created == 0x12345678)
//
// TYPE DEFINITIONS FOR THE PEER STATISTICS HASH TABLE
//
//
// struct: PEER_TABLE_ENTRY
//
// declares the structure of each entry in the peer table
//
typedef struct _PEER_TABLE_ENTRY {
LIST_ENTRY PTE_LinkByAddress; LIST_ENTRY PTE_HTLinkByAddress; DWORD PTE_Address; IPRIP_PEER_STATS PTE_Stats;
} PEER_TABLE_ENTRY, *PPEER_TABLE_ENTRY;
//
// macros and definitions used by peer statistics tables
//
#define PEER_HASHTABLE_SIZE 29
#define PEER_HASHVALUE(a) \
(((a) + \ ((a) >> 8) + \ ((a) >> 16) + \ ((a) >> 24)) % PEER_HASHTABLE_SIZE)
//
// struct: PEER_TABLE
//
// this table contains the entries for keeping statistics about each peer.
// it consists of a hash-table of peer stats (for fast direct access to
// a specific entry) and a list of peer stats entries ordered by address
// (for easy enumeration via MibGetNext)
//
typedef struct _PEER_TABLE {
READ_WRITE_LOCK PT_RWL; DWORD PT_Created; LIST_ENTRY PT_ListByAddress; LIST_ENTRY PT_HashTableByAddress[PEER_HASHTABLE_SIZE];
} PEER_TABLE, *PPEER_TABLE;
DWORD CreatePeerTable( PPEER_TABLE pTable );
DWORD DeletePeerTable( PPEER_TABLE pTable );
DWORD CreatePeerEntry( PPEER_TABLE pTable, DWORD dwAddress, PPEER_TABLE_ENTRY *ppEntry );
DWORD DeletePeerEntry( PPEER_TABLE pTable, DWORD dwAddress );
PPEER_TABLE_ENTRY GetPeerByAddress( PPEER_TABLE pTable, DWORD dwAddress, DWORD dwGetMode, PDWORD pdwErr );
#define PEER_TABLE_CREATED(pTable) ((pTable)->PT_Created == 0x12345678)
//
// TYPE DEFINITIONS FOR THE ROUTE TABLE USED FOR NETWORK SUMMARY
//
//
// struct: ROUTE_TABLE_ENTRY
//
// declares the structure of each entry in the route table
//
typedef struct _ROUTE_TABLE_ENTRY {
LIST_ENTRY RTE_Link; DWORD RTE_TTL; DWORD RTE_HoldTTL; RIP_IP_ROUTE RTE_Route;
} ROUTE_TABLE_ENTRY, *PROUTE_TABLE_ENTRY;
//
// declares the structure of the protocol specific data
//
//
// macros and definitions used by the route table
//
//
// These flags are used in the ProtocolSpecificData array
// to distinguish routes pending expiration from routes pending removal,
// and to store the route tag for each route.
// The first DWORD in the PSD_Data array is treated here as a byte-array;
// the first two bytes are used to store the route tag;
// the third byte is used to store the route flag
//
#define PSD(route) (route)->RR_ProtocolSpecificData.PSD_Data
#define PSD_TAG0 0
#define PSD_TAG1 1
#define PSD_FLAG 2
#define ROUTEFLAG_SUMMARY ((BYTE)0x03)
#define SETROUTEFLAG(route, flag) (((PBYTE)&PSD(route))[PSD_FLAG] = (flag))
#define GETROUTEFLAG(route) ((PBYTE)&PSD(route))[PSD_FLAG]
#define SETROUTETAG(route, tag) \
((PBYTE)&PSD(route))[PSD_TAG0] = LOBYTE(tag), \ ((PBYTE)&PSD(route))[PSD_TAG1] = HIBYTE(tag)
#define GETROUTETAG(route) \
MAKEWORD(((PBYTE)&PSD(route))[PSD_TAG0],((PBYTE)&PSD(route))[PSD_TAG1])
#define SETROUTEMETRIC(route, metric) \
(route)->RR_FamilySpecificData.FSD_Metric1 = (metric)
#define GETROUTEMETRIC(route) \
(route)->RR_FamilySpecificData.FSD_Metric1
#define COMPUTE_ROUTE_METRIC(route) \
(route)->RR_FamilySpecificData.FSD_Metric = \ (route)->RR_FamilySpecificData.FSD_Metric1
//
// Macros to manipulate entity specific info in RTMv2 routes
//
#define ESD(route) (route)->EntitySpecificInfo
#define ESD_TAG0 0
#define ESD_TAG1 1
#define ESD_FLAG 2
#define SETRIPFLAG(route, flag) (((PBYTE)&ESD(route))[ESD_FLAG] = (flag))
#define GETRIPFLAG(route) ((PBYTE)&ESD(route))[ESD_FLAG]
#define SETRIPTAG(route, tag) \
((PBYTE)&ESD(route))[ESD_TAG0] = LOBYTE(tag), \ ((PBYTE)&ESD(route))[ESD_TAG1] = HIBYTE(tag)
#define GETRIPTAG(route) \
MAKEWORD(((PBYTE)&ESD(route))[ESD_TAG0],((PBYTE)&ESD(route))[ESD_TAG1])
#define ROUTE_HASHTABLE_SIZE 29
#define ROUTE_HASHVALUE(a) \
(((a) + \ ((a) >> 8) + \ ((a) >> 16) + \ ((a) >> 24)) % ROUTE_HASHTABLE_SIZE)
//
// struct: ROUTE_TABLE
//
// declares the structure of a route table, which consists of a hash-table
// of routes hashed on the destination network. Note that no synchronization
// is included since this structure is only used during full-updates, to
// store summary routes, and at most one thread may be sending a full-update
// at any given time.
//
typedef struct _ROUTE_TABLE {
DWORD RT_Created; LIST_ENTRY RT_HashTableByNetwork[ROUTE_HASHTABLE_SIZE];
} ROUTE_TABLE, *PROUTE_TABLE;
DWORD CreateRouteTable( PROUTE_TABLE pTable );
DWORD DeleteRouteTable( PROUTE_TABLE pTable );
DWORD WriteSummaryRoutes( PROUTE_TABLE pTable, HANDLE hRtmHandle );
DWORD CreateRouteEntry( PROUTE_TABLE pTable, PRIP_IP_ROUTE pRoute, DWORD dwTTL, DWORD dwHoldTTL );
DWORD DeleteRouteEntry( PROUTE_TABLE pTable, PRIP_IP_ROUTE pRoute );
PROUTE_TABLE_ENTRY GetRouteByRoute( PROUTE_TABLE pTable, PRIP_IP_ROUTE pRoute );
#define ROUTE_TABLE_CREATED(pTable) ((pTable)->RT_Created == 0x12345678)
//
// TYPE DEFINITIONS FOR BINDING TABLE
//
//
// struct: BINDING_TABLE_ENTRY
//
// this entry contains a single binding.
// a binding entry consists of an IP address, a network number (found
// using the network class mask, not the subnet mask),
// and a subnet mask.
// All of the above are available when an interface is bound.
// When a route arrives and its mask is to be guessed, its network number
// can be computed (using the routes network class mask); we then search
// the binding table for matching networks, and for each one we compare
// (stored subnet mask) AND (interface IP address)
// to
// (stored subnet mask) AND (incoming route IP address).
// When we find a match, (stored subnet mask) is our guess.
//
typedef struct _BINDING_TABLE_ENTRY {
DWORD BTE_Address; DWORD BTE_Network; DWORD BTE_Netmask; LIST_ENTRY BTE_Link;
} BINDING_TABLE_ENTRY, *PBINDING_TABLE_ENTRY;
#define BINDING_HASHTABLE_SIZE 29
#define BINDING_HASHVALUE(a) \
(((a) + \ ((a) >> 8) + \ ((a) >> 16) + \ ((a) >> 24)) % BINDING_HASHTABLE_SIZE)
//
// struct: BINDING_TABLE
//
// this table is used to store binding information that is used to guess
// the subnet masks of incoming routes. it contains the bindings of all
// interfaces which have been added to IPRIP, in an array to speed up access
//
typedef struct _BINDING_TABLE {
READ_WRITE_LOCK BT_RWL; DWORD BT_Created; LIST_ENTRY BT_HashTableByNetwork[BINDING_HASHTABLE_SIZE];
} BINDING_TABLE, *PBINDING_TABLE;
#define BINDING_TABLE_CREATED(b) ((b)->BT_Created == 0x12345678)
DWORD CreateBindingTable( PBINDING_TABLE pTable );
DWORD DeleteBindingTable( PBINDING_TABLE pTable );
DWORD CreateBindingEntry( PBINDING_TABLE pTable, PIPRIP_IF_BINDING pib );
DWORD DeleteBindingEntry( PBINDING_TABLE pTable, PIPRIP_IF_BINDING pib );
DWORD GuessSubnetMask( DWORD dwAddress, PDWORD pdwNetclassMask );
DWORD AddRtmRoute( RTM_ENTITY_HANDLE hRtmHandle, PRIP_IP_ROUTE prir, RTM_NEXTHOP_HANDLE hNextHop OPTIONAL, DWORD dwTimeOut, DWORD dwHoldTime, BOOL bActive );
DWORD GetRouteInfo( IN RTM_ROUTE_HANDLE hRoute, IN PRTM_ROUTE_INFO pInRouteInfo OPTIONAL, IN PRTM_DEST_INFO pInDestInfo OPTIONAL, OUT PRIP_IP_ROUTE pRoute );
#endif // _TABLE_H_
|