//============================================================================= // Copyright (c) 1998 Microsoft Corporation // Module Name: main.c // Abstract: // // Author: K.S.Lokesh (lokeshs@) 1-1-98 //============================================================================= // // forward declarations // struct _DVMRP_IF_TABLE; struct _ASYNC_SOCKET_DATA; //----------------------------------------------------------------------------- // globals structure //----------------------------------------------------------------------------- typedef struct _GLOBALS1 { ULONG RunningStatus; ULONG InitFlags; CRITICAL_SECTION WorkItemCS; HANDLE Heap; LOCKED_LIST RtmQueue; } GLOBALS1; typedef struct _GLOBALS { HANDLE LogHandle; //logging handle DWORD TraceId; //tracing handle DWORD ActivityCount; //count of pending work items HANDLE ActivityEvent; //signal it to notify 0 work items HANDLE RtmNotifyEvent; //signal it to notify Rtm DYNAMIC_LOCKS_STORE DynamicCSStore; //global store for dynamic CS DYNAMIC_LOCKS_STORE DynamicRWLStore; //global store for dynamic RWL struct _DVMRP_IF_TABLE *pIfTable; //interface table LARGE_INTEGER CurrentTime; //keeps current 64 bit tick time HANDLE MgmDvmrpHandle; //handle returned by MGM } GLOBALS; typedef DVMRP_GLOBAL_CONFIG GLOBAL_CONFIG; typedef PDVMRP_GLOBAL_CONFIG PGLOBAL_CONFIG; typedef DVMRP_IF_CONFIG IF_CONFIG; typedef PDVMRP_IF_CONFIG PIF_CONFIG; //----------------------------------------------------------------------------- // DVMRP_IF_TABLE //----------------------------------------------------------------------------- typedef struct _DVMRP_IF_TABLE { LIST_ENTRY IfList; // in order of increasing index CRITICAL_SECTION IfList_CS; // CS protecting IfList DWORD NumInterfaces; PLIST_ENTRY IfHashTable; PDYNAMIC_RW_LOCK *aIfDRWL; CRITICAL_SECTION PeerLists_CS; // common lock for add/remove peers DWORD NumActiveIfs; } DVMRP_IF_TABLE, *PDVMRP_IF_TABLE; #define IF_HASHTABLE_SIZE 50 //----------------------------------------------------------------------------- // IF_TABLE_ENTRY //----------------------------------------------------------------------------- typedef struct _IF_TABLE_ENTRY { LIST_ENTRY Link; LIST_ENTRY HTLink; DWORD IfIndex; IPADDR IpAddr; DWORD Status; DWORD CreationFlags; DWORD RefCount; PIF_CONFIG pConfig; DWORD NumAddrBound; PDVMRP_ADDR_MASK pBinding; struct _IF_INFO *pInfo; DWORD NumPeers; // peers in PeerList LIST_ENTRY PeerList; // list of peers being created LIST_ENTRY DeletedPeerList; // list of peers being deleted SOCKET Socket; struct _ASYNC_SOCKET_DATA *pSocketData; RTM_ENTITY_HANDLE RtmHandle; // register with Rtm } IF_TABLE_ENTRY, *PIF_TABLE_ENTRY; #define IF_CREATED_FLAG 0x00000001 #define IF_BOUND_FLAG 0x00000002 #define IF_ENABLED_FLAG 0x00000004 #define IF_ACTIVATED_FLAG 0x00000008 #define IF_DELETED_FLAG 0x80000000 #define IS_IF_BOUND(pite) \ ((pite)->Status&IF_BOUND_FLAG) #define IS_IF_ENABLED_BY_RTRMGR(pite) \ ((pite)->Status&IF_ENABLED_FLAG) #define IS_IF_ENABLED_IN_CONFIG(pite) \ (IS_DVMRP_IF_ENABLED_FLAG_SET((pite)->pConfig->Flags)) #define IS_IF_ENABLED(pite) \ ( IS_IF_ENABLED_BY_RTRMGR(pite) && IS_IF_ENABLED_IN_CONFIG(pite) ) #define IS_IF_ENABLED_BOUND(pite) \ (IS_IF_ENABLED(pite)&&IS_IF_BOUND(pite)) #define IS_IF_DELETED(pite) \ ((pite)->Status&IF_DELETED_FLAG) #define IS_IF_ACTIVATED(pite) \ ( !((pite)->Status&IF_DELETED_FLAG) \ && ((pite)->Status & IF_ACTIVATED_FLAG) ) #define IF_FLAGS_SOCKETS_CREATED 0x00000001 #define IF_FLAGS_PROTO_REGISTERED_WITH_MGM 0x00000002 #define IF_FLAGS_IF_REGISTERED_WITH_MGM 0x00000004 //----------------------------------------------------------------------------- // IF_INFO //----------------------------------------------------------------------------- typedef struct _IF_INFO { LONGLONG TimeWhenActivated; } IF_INFO, *PIF_INFO; //----------------------------------------------------------------------------- // type definitions for event message queue //----------------------------------------------------------------------------- typedef struct _EVENT_QUEUE_ENTRY { ROUTING_PROTOCOL_EVENTS EventType; MESSAGE Msg; LIST_ENTRY Link; } EVENT_QUEUE_ENTRY, *PEVENT_QUEUE_ENTRY; // // extern variables // extern GLOBALS Globals; extern GLOBALS1 Globals1; extern GLOBAL_CONFIG GlobalConfig; #define G_pIfTable (Globals.pIfTable) // // defines // //----------------------------------------------------------------------------- // #defines for global structure //----------------------------------------------------------------------------- // // various codes describing states of dvmrp // typedef enum { DVMRP_STATUS_STARTING = 100, DVMRP_STATUS_RUNNING = 101, DVMRP_STATUS_STOPPING = 102, DVMRP_STATUS_STOPPED = 103 } DVMRP_STATUS_CODE; // // WorkItemCS lock macros // #define ACQUIRE_WORKITEM_LOCK(proc) EnterCriticalSection(&Globals1.WorkItemCS) #define RELEASE_WORKITEM_LOCK(proc) LeaveCriticalSection(&Globals1.WorkItemCS) //----------------------------------------------------------------------------- // #defines for global config //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // macros for IfTable //----------------------------------------------------------------------------- #define IF_HASH_VALUE(_index) ((_index) % IF_HASHTABLE_SIZE) #define GET_IF_HASH_BUCKET(Index) \ &G_pIfTable->IfHashTable[IF_HASH_VALUE(IfIndex)]; // macros for If DRW lock #define ACQUIRE_IF_LOCK_EXCLUSIVE(_IfIndex, _proc) \ AcquireDynamicRWLock( \ &G_pIfTable->aIfDRWL[IF_HASH_VALUE(_IfIndex)], \ LOCK_MODE_WRITE, &Globals.DynamicRWLStore) #define RELEASE_IF_LOCK_EXCLUSIVE(_IfIndex, _proc) \ ReleaseDynamicRWLock( \ &G_pIfTable->aIfDRWL[IF_HASH_VALUE(_IfIndex)],\ LOCK_MODE_WRITE, &Globals.DynamicRWLStore) #define ACQUIRE_IF_LOCK_SHARED(_IfIndex, _proc) \ AcquireDynamicRWLock( \ &G_pIfTable->aIfDRWL[IF_HASH_VALUE(_IfIndex)],\ LOCK_MODE_READ, &Globals.DynamicRWLStore) #define RELEASE_IF_LOCK_SHARED(_IfIndex, _proc) \ ReleaseDynamicRWLock( \ &G_pIfTable->aIfDRWL[IF_HASH_VALUE(_IfIndex)], \ LOCK_MODE_READ, &Globals.DynamicRWLStore) // macros for IfList_CS lock #define ACQUIRE_IF_LIST_LOCK(_proc) \ ENTER_CRITICAL_SECTION(&G_pIfTable->IfList_CS, "G_IfListCS", _proc); #define RELEASE_IF_LIST_LOCK(_proc) \ LEAVE_CRITICAL_SECTION(&G_pIfTable->IfList_CS, "G_IfListCS", _proc); // macros for PeerLists_CS lock (see in peer.h) // // local prototypes // DWORD WINAPI StartProtocol( IN HANDLE hRtmNotifyEvent, IN PSUPPORT_FUNCTIONS pSupportFunctions, IN PVOID pGlobalConfig, IN ULONG ulStructureVersion, IN ULONG ulStructureSize, IN ULONG ulStructureCount ); DWORD APIENTRY StartComplete( VOID ); DWORD APIENTRY StopProtocol( VOID ); DWORD WINAPI GetGlobalInfo( IN OUT PVOID pvConfig, IN OUT PDWORD pdwSize, IN OUT PULONG pulStructureVersion, IN OUT PULONG pulStructureSize, IN OUT PULONG pulStructureCount ); DWORD WINAPI SetGlobalInfo( IN PVOID pvConfig, IN ULONG ulStructureVersion, IN ULONG ulStructureSize, IN ULONG ulStructureCount ); DWORD APIENTRY GetEventMessage( OUT ROUTING_PROTOCOL_EVENTS *pEventType, OUT PMESSAGE pMessage ); DWORD EnqueueEvent( PLOCKED_LIST pQueue, ROUTING_PROTOCOL_EVENTS EventType, MESSAGE Msg ); DWORD DequeueEvent( PLOCKED_LIST pQueue, ROUTING_PROTOCOL_EVENTS *pEventType, PMESSAGE pResult ); BOOL DllStartup( ); BOOL DllCleanup( ); VOID ProtocolCleanup( ); DWORD ValidateGlobalConfig( PDVMRP_GLOBAL_CONFIG pGlobalConfig, DWORD StructureSize );