//============================================================================= // Copyright (c) 1997 Microsoft Corporation // // File: table.h // // Abstract: // This module contains declarations for interface and group table // structures, related macros, and function prototypes. // // Author: K.S.Lokesh (lokeshs@) 11-1-97 // // Revision History: //============================================================================= #ifndef _IGMP_TABLE_H_ #define _IGMP_TABLE_H_ // // forward declarations // struct _IF_TABLE_ENTRY; struct _GROUP_TABLE_ENTRY; struct _GI_ENTRY; // // struct: GLOBAL_CONFIG (same as mib structs in igmprm.h) // typedef IGMP_MIB_GLOBAL_CONFIG GLOBAL_CONFIG; typedef PIGMP_MIB_GLOBAL_CONFIG PGLOBAL_CONFIG; //--------------------------------------------------- // struct: IGMP_GLOBAL_STATS //--------------------------------------------------- typedef struct _GLOBAL_STATS { DWORD CurrentGroupMemberships; DWORD GroupMembershipsAdded; LARGE_INTEGER TimeWhenRtrStarted; } IGMP_GLOBAL_STATS, *PIGMP_GLOBAL_STATS; //------------------------------------------------- // static group structures(external) //------------------------------------------------- typedef struct _STATIC_GROUP_V3 { IGMP_STATIC_GROUP_V3; DWORD Sources[0]; } STATIC_GROUP_V3, *PSTATIC_GROUP_V3; typedef struct _MIB_GROUP_INFO_V3 { IGMP_MIB_GROUP_INFO_V3; IGMP_MIB_GROUP_SOURCE_INFO_V3 Sources[0]; } MIB_GROUP_INFO_V3, *PMIB_GROUP_INFO_V3; typedef PIGMP_MIB_GROUP_INFO PMIB_GROUP_INFO; typedef IGMP_MIB_GROUP_INFO MIB_GROUP_INFO; #define GET_FIRST_STATIC_GROUP_V3(pConfig) \ ((PSTATIC_GROUP_V3)((PIGMP_MIB_IF_CONFIG)(pConfig)+1)) #define GET_NEXT_STATIC_GROUP_V3(pStaticGroupV3) \ ((PSTATIC_GROUP_V3) ((PCHAR)pStaticGroupV3+sizeof(IGMP_STATIC_GROUP_V3) \ +sizeof(IPADDR)*pStaticGroupV3->NumSources)) //---------------------------------------------------------------------------- // struct: IF_STATIC_GROUP //---------------------------------------------------------------------------- typedef struct _IF_STATIC_GROUP { LIST_ENTRY Link; STATIC_GROUP_V3; } IF_STATIC_GROUP, *PIF_STATIC_GROUP; //--------------------------------------------------------------- // struct: IGMP_IF_CONFIG (same as mib structs in igmprm.h) // // if they are made different, then CopyMemory should not be used //--------------------------------------------------------------- typedef struct _IGMP_IF_CONFIG { IGMP_MIB_IF_CONFIG; //v3: NonQuerier saves old values DWORD RobustnessVariableOld; DWORD GenQueryIntervalOld; DWORD OtherQuerierPresentIntervalOld; DWORD GroupMembershipTimeoutOld; DWORD ExtSize; LIST_ENTRY ListOfStaticGroups; } IGMP_IF_CONFIG, *PIGMP_IF_CONFIG; //--------------------------------------------------- // struct: IF_INFO //--------------------------------------------------- typedef struct _IF_INFO { UCHAR QuerierState; //if made DWORD, then change to interlocked operations DWORD QuerierIpAddr; LONGLONG QuerierPresentTimeout; //when the last query was heard. only if I am not querier LONGLONG LastQuerierChangeTime; // when the last querier was changed LONGLONG V1QuerierPresentTime; //when the last v1 query was heard LONGLONG OtherVerPresentTimeWarn; //when the last warning was given DWORD StartupQueryCountCurrent; DWORD GroupQueriesSent; DWORD GroupQueriesReceived; LONGLONG TimeWhenActivated; DWORD TotalIgmpPacketsReceived; DWORD TotalIgmpPacketsForRouter; DWORD GenQueriesSent; DWORD GenQueriesReceived; DWORD WrongVersionQueries; DWORD JoinsReceived; DWORD LeavesReceived; DWORD CurrentGroupMemberships; DWORD GroupMembershipsAdded; DWORD WrongChecksumPackets; DWORD ShortPacketsReceived; DWORD LongPacketsReceived; DWORD PacketsWithoutRtrAlert; DWORD PacketSize; } IF_INFO, *PIF_INFO; //--------------------------------------------------- // struct RAS_CLIENT_INFO //--------------------------------------------------- typedef struct _RAS_CLIENT_INFO { DWORD SendFailures; DWORD TotalIgmpPacketsReceived; DWORD TotalIgmpPacketsForRouter; DWORD GenQueriesReceived; DWORD JoinsReceived; DWORD LeavesReceived; DWORD CurrentGroupMemberships; DWORD GroupMembershipsAdded; DWORD GroupMembershipsRemoved; DWORD WrongChecksumPackets; DWORD ShortPacketsReceived; DWORD LongPacketsReceived; DWORD WrongVersionQueries; } RAS_CLIENT_INFO, *PRAS_CLIENT_INFO; //--------------------------------------------------- // struct: RAS_TABLE_ENTRY //--------------------------------------------------- typedef struct _RAS_TABLE_ENTRY { LIST_ENTRY LinkByAddr; LIST_ENTRY HTLinkByAddr; LIST_ENTRY ListOfSameClientGroups; DWORD NHAddr; struct _IF_TABLE_ENTRY *IfTableEntry; DWORD Status; RAS_CLIENT_INFO Info; DWORD CreationFlags; // see below. } RAS_TABLE_ENTRY, *PRAS_TABLE_ENTRY; //--------------------------------------------------- // struct: RAS_TABLE //--------------------------------------------------- #define RAS_HASH_TABLE_SZ 256 typedef struct _RAS_TABLE { LIST_ENTRY ListByAddr; //links ras clients LIST_ENTRY HashTableByAddr[RAS_HASH_TABLE_SZ]; struct _IF_TABLE_ENTRY *pIfTable; //ptr to interface table entry DWORD RefCount; DWORD Status; } RAS_TABLE, *PRAS_TABLE; //--------------------------------------------------- // struct: SOCKET_EVENT_ENTRY //--------------------------------------------------- typedef struct _SOCKET_EVENT_ENTRY { LIST_ENTRY LinkBySocketEvents; LIST_ENTRY ListOfInterfaces; DWORD NumInterfaces; HANDLE InputWaitEvent; HANDLE InputEvent; } SOCKET_EVENT_ENTRY, *PSOCKET_EVENT_ENTRY; //--------------------------------------------------- // struct: SOCKET_ENTRY //--------------------------------------------------- typedef struct _SOCKET_ENTRY { LIST_ENTRY LinkByInterfaces; SOCKET Socket; PSOCKET_EVENT_ENTRY pSocketEventsEntry; } SOCKET_ENTRY, *PSOCKET_ENTRY; //------------------------------------------------------------------------------ // struct: IF_TABLE_ENTRY // // IF-table:Table_RWL protects LinkByAddr, LinkByIndex, HTLinkByIndex // IpAddr, Status, pBinding // IF-table:IfTableBucketCS protects ListOfSameIfGroups // Interlocked operations protect Info, Config //------------------------------------------------------------------------------ typedef struct _IF_TABLE_ENTRY { LIST_ENTRY LinkByAddr; // sorted by Ipaddr.only activated interfaces LIST_ENTRY LinkByIndex; // sorted by Index. all interfaces LIST_ENTRY HTLinkByIndex; // not sorted within bucket LIST_ENTRY ListOfSameIfGroups; // sorted by GroupAddr. GI entries for IF (all GIs of Ras clients) LIST_ENTRY ListOfSameIfGroupsNew; // unmerged list. sorted by GroupAddr. GI entries same as above DWORD NumGIEntriesInNewList; // used to decide if lists should be merged UCHAR IfType; // IGMP_IF_ (NOT_RAS,RAS_ROUTER,RAS_SERVER). for external calls, IGMP_IF_PROXY might be set // set when interface is created. cannot be changed again. DWORD IfIndex; IPADDR IpAddr; // set when IF is bound. ==0 for un-numbered IFs. DWORD Status; // IF_(CREATED/BOUND/ENABLED/ACTIVATED), // IF_DEACTIVATE_DELETE_FLAG, // MGM_ENABLED_IGMPRTR_FLAG, IGMPRTR_MPROTOCOL_PRESENT_FLAG PRAS_TABLE pRasTable; // null if not IGMP_IF_RAS_SERVER. created in _AddIfEntry() PLIST_ENTRY pProxyHashTable; // g_pProxyHashTable: contains the proxy entries. They are also linked in // order using the LinkBySameIfGroups field accessed through pite. IGMP_IF_CONFIG Config; PIGMP_IF_BINDING pBinding; // null if not bound or unNumbered interface. IF_INFO Info; SOCKET_ENTRY SocketEntry; // used by igmpRouter for getting input, and binding to waitEvent // used by proxy to join the igmp groups as a host. IGMP_TIMER_ENTRY QueryTimer; // Querier mode: used for sending general query. IGMP_TIMER_ENTRY NonQueryTimer; // used when in NonQuerier mode: used for detecting other queriers HANDLE pPrevIfGroupEnumPtr; // points to the next GI entry to be enumerated. USHORT PrevIfGroupEnumSignature;//used in enumerating interface GI list in order SOCKET StaticGroupSocket; // used only by igmp Router. created in _CreateIfSockets and // closed in _DeleteIfSockets. // Static groups in proxy are joined on SocketEntry. DWORD CreationFlags; // see below. } IF_TABLE_ENTRY, *PIF_TABLE_ENTRY; // // values for CreationFlags // #define REGISTERED_PROTOCOL_WITH_MGM 0x0001 #define TAKEN_INTERFACE_OWNERSHIP_WITH_MGM 0x0002 #define DONE_STAR_STAR_JOIN 0x0004 #define SOCKETS_CREATED 0x0008 // the above flags are cleared during deactivation, while below flags // are retained across deactivations. #define CREATION_FLAGS_DEACTIVATION_CLEAR 0x00FF #define CREATED_PROXY_HASH_TABLE 0x0100 // expand the table if the number of interface is greater than 16 #define IF_HASHTABLE_SZ1 256 #define IF_EXPAND_THRESHOLD1 256 #define IF_HASHTABLE_SZ2 512 //--------------------------------------------------- // struct: IGMP_IF_TABLE //--------------------------------------------------- typedef struct _IF_TABLE { LIST_ENTRY ListByAddr; LIST_ENTRY ListByIndex; DWORD Status; DWORD NumBuckets; DWORD NumInterfaces; PLIST_ENTRY HashTableByIndex; PDYNAMIC_CS_LOCK *aIfBucketDCS; PDYNAMIC_RW_LOCK *aIfBucketDRWL; CRITICAL_SECTION IfLists_CS; // CS protecting the 1st two lists } IGMP_IF_TABLE, *PIGMP_IF_TABLE; //--------------------------------------------------- // struct: GI_INFO //--------------------------------------------------- typedef struct _GROUP_INFO { DWORD LastReporter; LONGLONG GroupUpTime; LONGLONG GroupExpiryTime; LONGLONG V1HostPresentTimeLeft; // version 3 fields LONGLONG V2HostPresentTimeLeft; } GI_INFO, *PGROUP_INFO; //--------------------------------------------------- // struct: GI_ENTRY (group-Interface entry) //--------------------------------------------------- typedef struct _GI_ENTRY { LIST_ENTRY LinkByGI; LIST_ENTRY LinkBySameIfGroups; LIST_ENTRY LinkBySameClientGroups; //links all ras client groups DWORD IfIndex; DWORD Status; //bound,enabled,deleted,activated BOOL bRasClient; //rasclient or not BOOL bStaticGroup; PIF_TABLE_ENTRY pIfTableEntry; struct _GROUP_TABLE_ENTRY *pGroupTableEntry; //below two fields valid only for ras DWORD NHAddr; PRAS_TABLE_ENTRY pRasTableEntry; IGMP_TIMER_ENTRY GroupMembershipTimer; /*timerlock*///LastMemQueryCount left to be sent DWORD LastMemQueryCount; IGMP_TIMER_ENTRY LastMemQueryTimer; IGMP_TIMER_ENTRY LastVer1ReportTimer;/*timelock*/ BYTE Version; //ver1, ver2, ver3 GI_INFO Info; // igmpv3 fields. ignored for rest. IGMP_TIMER_ENTRY LastVer2ReportTimer;/*timelock*/ DWORD FilterType; DWORD NumSources; LIST_ENTRY *V3InclusionList; LIST_ENTRY V3InclusionListSorted; LIST_ENTRY V3ExclusionList; //query sources LIST_ENTRY V3SourcesQueryList; DWORD V3SourcesQueryCount; BOOL bV3SourcesQueryNow; IGMP_TIMER_ENTRY V3SourcesQueryTimer; #if DEBUG_FLAGS_SIGNATURE DWORD Signature;//0xfadfad02 #endif } GI_ENTRY, *PGI_ENTRY; //kslksl1 10 #define SOURCES_BUCKET_SZ 1 //--------------------------------------------------- // struct: GI_SOURCE_ENTRY //--------------------------------------------------- typedef struct _GI_SOURCE_ENTRY { LIST_ENTRY LinkSources; LIST_ENTRY LinkSourcesInclListSorted; LIST_ENTRY V3SourcesQueryList; PGI_ENTRY pGIEntry; BOOL bInclusionList; IPADDR IpAddr; //how many more src queries left to be sent DWORD V3SourcesQueryLeft; BOOL bInV3SourcesQueryList; //timeout sources in inc list IGMP_TIMER_ENTRY SourceExpTimer; LONGLONG SourceInListTime; BOOL bStaticSource; } GI_SOURCE_ENTRY, *PGI_SOURCE_ENTRY; #define GET_IF_CONFIG_FOR_SOURCE(pSourceEntry) \ pSourceEntry->pGIEntry->pIfTableEntry->Config #define GET_IF_ENTRY_FOR_SOURCE(pSourceEntry) \ pSourceEntry->pGIEntry->pIfTableEntry //--------------------------------------------------- // struct: GROUP_TABLE_ENTRY //--------------------------------------------------- typedef struct _GROUP_TABLE_ENTRY { LIST_ENTRY HTLinkByGroup; LIST_ENTRY LinkByGroup; //ordered list of groups LIST_ENTRY ListOfGIs; DWORD Group; DWORD GroupLittleEndian; DWORD NumVifs; DWORD Status; LONGLONG GroupUpTime; #if DEBUG_FLAGS_SIGNATURE DWORD Signature; //0xfadfad01 #endif } GROUP_TABLE_ENTRY, *PGROUP_TABLE_ENTRY; #define GROUP_HASH_TABLE_SZ 256 //--------------------------------------------------- // struct: GROUP_TABLE //--------------------------------------------------- typedef struct _GROUP_TABLE { LOCKED_LIST ListByGroup; LIST_ENTRY ListByGroupNew; DWORD NumGroupsInNewList; DWORD Status; LONG NumIfs; //Interlocked Operations DYNAMIC_CS_LOCKED_LIST HashTableByGroup[GROUP_HASH_TABLE_SZ]; } GROUP_TABLE, *PGROUP_TABLE; //------------------------------------------------- // Proxy group entry //------------------------------------------------- typedef struct _PROXY_GROUP_ENTRY { LIST_ENTRY HT_Link; LIST_ENTRY LinkBySameIfGroups; //v3 LIST_ENTRY ListSources; DWORD Group; DWORD GroupLittleEndian; DWORD RefCount; LONGLONG InitTime; BOOL bStaticGroup; //v3 DWORD NumSources; DWORD FilterType; } PROXY_GROUP_ENTRY, *PPROXY_GROUP_ENTRY; typedef struct _PROXY_SOURCE_ENTRY { LIST_ENTRY LinkSources; IPADDR IpAddr; DWORD RefCount; BOOL bStaticSource; DWORD JoinMode;//ALLOW,BLOCK, NO_STATE DWORD JoinModeIntended; } PROXY_SOURCE_ENTRY, *PPROXY_SOURCE_ENTRY; //------------------------------------------------- // prototypes //------------------------------------------------- DWORD CreateIfSockets ( PIF_TABLE_ENTRY pite ); VOID DeleteIfSockets ( PIF_TABLE_ENTRY pite ); VOID DeleteAllTimers ( PLIST_ENTRY pHead, DWORD bEntryType //RAS_CLIENT, NOT_RAS_CLIENT ); DWORD DeleteGIEntry ( PGI_ENTRY pgie, //group interface entry BOOL bUpdateStats, BOOL bCallMgm ); VOID DeleteAllGIEntries( PIF_TABLE_ENTRY pite ); VOID DeleteGIEntryFromIf ( PGI_ENTRY pgie //group interface entry ); VOID MergeGroupLists( ); VOID MergeIfGroupsLists( PIF_TABLE_ENTRY pite ); VOID MergeProxyLists( PIF_TABLE_ENTRY pite ); DWORD CopyinIfConfig ( PIGMP_IF_CONFIG pConfig, PIGMP_MIB_IF_CONFIG pConfigExt, DWORD IfIndex ); DWORD CopyinIfConfigAndUpdate ( PIF_TABLE_ENTRY pite, PIGMP_MIB_IF_CONFIG pConfigExt, ULONG IfIndex ); VOID CopyoutIfConfig ( PIGMP_MIB_IF_CONFIG pConfigExt, PIF_TABLE_ENTRY pite ); DWORD ValidateIfConfig ( PIGMP_MIB_IF_CONFIG pConfigExt, DWORD IfIndex, DWORD IfType, ULONG StructureVersion, ULONG StructureSize ); DWORD InitializeIfTable ( ); VOID DeInitializeIfTable ( ); DWORD InitializeGroupTable ( ); VOID DeInitializeGroupTable ( ); DWORD InitializeRasTable( DWORD IfIndex, PIF_TABLE_ENTRY pite ); VOID DeInitializeRasTable ( PIF_TABLE_ENTRY pite, BOOL bFullCleanup ); #endif // _IGMP_TABLE_H_