Source code of Windows XP (NT5)
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.

662 lines
18 KiB

  1. //=============================================================================
  2. // Copyright (c) 1997 Microsoft Corporation
  3. //
  4. // File: table.h
  5. //
  6. // Abstract:
  7. // This module contains declarations for interface and group table
  8. // structures, related macros, and function prototypes.
  9. //
  10. // Author: K.S.Lokesh (lokeshs@) 11-1-97
  11. //
  12. // Revision History:
  13. //=============================================================================
  14. #ifndef _IGMP_TABLE_H_
  15. #define _IGMP_TABLE_H_
  16. //
  17. // forward declarations
  18. //
  19. struct _IF_TABLE_ENTRY;
  20. struct _GROUP_TABLE_ENTRY;
  21. struct _GI_ENTRY;
  22. //
  23. // struct: GLOBAL_CONFIG (same as mib structs in igmprm.h)
  24. //
  25. typedef IGMP_MIB_GLOBAL_CONFIG GLOBAL_CONFIG;
  26. typedef PIGMP_MIB_GLOBAL_CONFIG PGLOBAL_CONFIG;
  27. //---------------------------------------------------
  28. // struct: IGMP_GLOBAL_STATS
  29. //---------------------------------------------------
  30. typedef struct _GLOBAL_STATS {
  31. DWORD CurrentGroupMemberships;
  32. DWORD GroupMembershipsAdded;
  33. LARGE_INTEGER TimeWhenRtrStarted;
  34. } IGMP_GLOBAL_STATS, *PIGMP_GLOBAL_STATS;
  35. //-------------------------------------------------
  36. // static group structures(external)
  37. //-------------------------------------------------
  38. typedef struct _STATIC_GROUP_V3 {
  39. IGMP_STATIC_GROUP_V3;
  40. DWORD Sources[0];
  41. } STATIC_GROUP_V3, *PSTATIC_GROUP_V3;
  42. typedef struct _MIB_GROUP_INFO_V3 {
  43. IGMP_MIB_GROUP_INFO_V3;
  44. IGMP_MIB_GROUP_SOURCE_INFO_V3 Sources[0];
  45. } MIB_GROUP_INFO_V3, *PMIB_GROUP_INFO_V3;
  46. typedef PIGMP_MIB_GROUP_INFO PMIB_GROUP_INFO;
  47. typedef IGMP_MIB_GROUP_INFO MIB_GROUP_INFO;
  48. #define GET_FIRST_STATIC_GROUP_V3(pConfig) \
  49. ((PSTATIC_GROUP_V3)((PIGMP_MIB_IF_CONFIG)(pConfig)+1))
  50. #define GET_NEXT_STATIC_GROUP_V3(pStaticGroupV3) \
  51. ((PSTATIC_GROUP_V3) ((PCHAR)pStaticGroupV3+sizeof(IGMP_STATIC_GROUP_V3) \
  52. +sizeof(IPADDR)*pStaticGroupV3->NumSources))
  53. //----------------------------------------------------------------------------
  54. // struct: IF_STATIC_GROUP
  55. //----------------------------------------------------------------------------
  56. typedef struct _IF_STATIC_GROUP {
  57. LIST_ENTRY Link;
  58. STATIC_GROUP_V3;
  59. } IF_STATIC_GROUP, *PIF_STATIC_GROUP;
  60. //---------------------------------------------------------------
  61. // struct: IGMP_IF_CONFIG (same as mib structs in igmprm.h)
  62. //
  63. // if they are made different, then CopyMemory should not be used
  64. //---------------------------------------------------------------
  65. typedef struct _IGMP_IF_CONFIG {
  66. IGMP_MIB_IF_CONFIG;
  67. //v3: NonQuerier saves old values
  68. DWORD RobustnessVariableOld;
  69. DWORD GenQueryIntervalOld;
  70. DWORD OtherQuerierPresentIntervalOld;
  71. DWORD GroupMembershipTimeoutOld;
  72. DWORD ExtSize;
  73. LIST_ENTRY ListOfStaticGroups;
  74. } IGMP_IF_CONFIG, *PIGMP_IF_CONFIG;
  75. //---------------------------------------------------
  76. // struct: IF_INFO
  77. //---------------------------------------------------
  78. typedef struct _IF_INFO {
  79. UCHAR QuerierState; //if made DWORD, then change to interlocked operations
  80. DWORD QuerierIpAddr;
  81. LONGLONG QuerierPresentTimeout; //when the last query was heard. only if I am not querier
  82. LONGLONG LastQuerierChangeTime; // when the last querier was changed
  83. LONGLONG V1QuerierPresentTime; //when the last v1 query was heard
  84. LONGLONG OtherVerPresentTimeWarn; //when the last warning was given
  85. DWORD StartupQueryCountCurrent;
  86. DWORD GroupQueriesSent;
  87. DWORD GroupQueriesReceived;
  88. LONGLONG TimeWhenActivated;
  89. DWORD TotalIgmpPacketsReceived;
  90. DWORD TotalIgmpPacketsForRouter;
  91. DWORD GenQueriesSent;
  92. DWORD GenQueriesReceived;
  93. DWORD WrongVersionQueries;
  94. DWORD JoinsReceived;
  95. DWORD LeavesReceived;
  96. DWORD CurrentGroupMemberships;
  97. DWORD GroupMembershipsAdded;
  98. DWORD WrongChecksumPackets;
  99. DWORD ShortPacketsReceived;
  100. DWORD LongPacketsReceived;
  101. DWORD PacketsWithoutRtrAlert;
  102. DWORD PacketSize;
  103. } IF_INFO, *PIF_INFO;
  104. //---------------------------------------------------
  105. // struct RAS_CLIENT_INFO
  106. //---------------------------------------------------
  107. typedef struct _RAS_CLIENT_INFO {
  108. DWORD SendFailures;
  109. DWORD TotalIgmpPacketsReceived;
  110. DWORD TotalIgmpPacketsForRouter;
  111. DWORD GenQueriesReceived;
  112. DWORD JoinsReceived;
  113. DWORD LeavesReceived;
  114. DWORD CurrentGroupMemberships;
  115. DWORD GroupMembershipsAdded;
  116. DWORD GroupMembershipsRemoved;
  117. DWORD WrongChecksumPackets;
  118. DWORD ShortPacketsReceived;
  119. DWORD LongPacketsReceived;
  120. DWORD WrongVersionQueries;
  121. } RAS_CLIENT_INFO, *PRAS_CLIENT_INFO;
  122. //---------------------------------------------------
  123. // struct: RAS_TABLE_ENTRY
  124. //---------------------------------------------------
  125. typedef struct _RAS_TABLE_ENTRY {
  126. LIST_ENTRY LinkByAddr;
  127. LIST_ENTRY HTLinkByAddr;
  128. LIST_ENTRY ListOfSameClientGroups;
  129. DWORD NHAddr;
  130. struct _IF_TABLE_ENTRY *IfTableEntry;
  131. DWORD Status;
  132. RAS_CLIENT_INFO Info;
  133. } RAS_TABLE_ENTRY, *PRAS_TABLE_ENTRY;
  134. //---------------------------------------------------
  135. // struct: RAS_TABLE
  136. //---------------------------------------------------
  137. #define RAS_HASH_TABLE_SZ 256
  138. typedef struct _RAS_TABLE {
  139. LIST_ENTRY ListByAddr; //links ras clients
  140. LIST_ENTRY HashTableByAddr[RAS_HASH_TABLE_SZ];
  141. struct _IF_TABLE_ENTRY *pIfTable; //ptr to interface table entry
  142. DWORD RefCount;
  143. DWORD Status;
  144. } RAS_TABLE, *PRAS_TABLE;
  145. //---------------------------------------------------
  146. // struct: SOCKET_EVENT_ENTRY
  147. //---------------------------------------------------
  148. typedef struct _SOCKET_EVENT_ENTRY {
  149. LIST_ENTRY LinkBySocketEvents;
  150. LIST_ENTRY ListOfInterfaces;
  151. DWORD NumInterfaces;
  152. HANDLE InputWaitEvent;
  153. HANDLE InputEvent;
  154. } SOCKET_EVENT_ENTRY, *PSOCKET_EVENT_ENTRY;
  155. //---------------------------------------------------
  156. // struct: SOCKET_ENTRY
  157. //---------------------------------------------------
  158. typedef struct _SOCKET_ENTRY {
  159. LIST_ENTRY LinkByInterfaces;
  160. SOCKET Socket;
  161. PSOCKET_EVENT_ENTRY pSocketEventsEntry;
  162. } SOCKET_ENTRY, *PSOCKET_ENTRY;
  163. //------------------------------------------------------------------------------
  164. // struct: IF_TABLE_ENTRY
  165. //
  166. // IF-table:Table_RWL protects LinkByAddr, LinkByIndex, HTLinkByIndex
  167. // IpAddr, Status, pBinding
  168. // IF-table:IfTableBucketCS protects ListOfSameIfGroups
  169. // Interlocked operations protect Info, Config
  170. //------------------------------------------------------------------------------
  171. typedef struct _IF_TABLE_ENTRY {
  172. LIST_ENTRY LinkByAddr; // sorted by Ipaddr.only activated interfaces
  173. LIST_ENTRY LinkByIndex; // sorted by Index. all interfaces
  174. LIST_ENTRY HTLinkByIndex; // not sorted within bucket
  175. LIST_ENTRY ListOfSameIfGroups; // sorted by GroupAddr. GI entries for IF (all GIs of Ras clients)
  176. LIST_ENTRY ListOfSameIfGroupsNew; // unmerged list. sorted by GroupAddr. GI entries same as above
  177. DWORD NumGIEntriesInNewList; // used to decide if lists should be merged
  178. UCHAR IfType; // IGMP_IF_ (NOT_RAS,RAS_ROUTER,RAS_SERVER). for external calls, IGMP_IF_PROXY might be set
  179. // set when interface is created. cannot be changed again.
  180. DWORD IfIndex;
  181. IPADDR IpAddr; // set when IF is bound. ==0 for un-numbered IFs.
  182. DWORD Status; // IF_(CREATED/BOUND/ENABLED/ACTIVATED),
  183. // IF_DEACTIVATE_DELETE_FLAG,
  184. // MGM_ENABLED_IGMPRTR_FLAG, IGMPRTR_MPROTOCOL_PRESENT_FLAG
  185. PRAS_TABLE pRasTable; // null if not IGMP_IF_RAS_SERVER. created in _AddIfEntry()
  186. PLIST_ENTRY pProxyHashTable; // g_pProxyHashTable: contains the proxy entries. They are also linked in
  187. // order using the LinkBySameIfGroups field accessed through pite.
  188. IGMP_IF_CONFIG Config;
  189. PIGMP_IF_BINDING pBinding; // null if not bound or unNumbered interface.
  190. IF_INFO Info;
  191. SOCKET_ENTRY SocketEntry; // used by igmpRouter for getting input, and binding to waitEvent
  192. // used by proxy to join the igmp groups as a host.
  193. IGMP_TIMER_ENTRY QueryTimer; // Querier mode: used for sending general query.
  194. IGMP_TIMER_ENTRY NonQueryTimer; // used when in NonQuerier mode: used for detecting other queriers
  195. HANDLE pPrevIfGroupEnumPtr; // points to the next GI entry to be enumerated.
  196. USHORT PrevIfGroupEnumSignature;//used in enumerating interface GI list in order
  197. SOCKET StaticGroupSocket; // used only by igmp Router. created in _CreateIfSockets and
  198. // closed in _DeleteIfSockets.
  199. // Static groups in proxy are joined on SocketEntry.
  200. DWORD CreationFlags; // see below.
  201. } IF_TABLE_ENTRY, *PIF_TABLE_ENTRY;
  202. //
  203. // values for CreationFlags
  204. //
  205. #define REGISTERED_PROTOCOL_WITH_MGM 0x0001
  206. #define TAKEN_INTERFACE_OWNERSHIP_WITH_MGM 0x0002
  207. #define DONE_STAR_STAR_JOIN 0x0004
  208. #define SOCKETS_CREATED 0x0008
  209. // the above flags are cleared during deactivation, while below flags
  210. // are retained across deactivations.
  211. #define CREATION_FLAGS_DEACTIVATION_CLEAR 0x00FF
  212. #define CREATED_PROXY_HASH_TABLE 0x0100
  213. // expand the table if the number of interface is greater than 16
  214. #define IF_HASHTABLE_SZ1 256
  215. #define IF_EXPAND_THRESHOLD1 256
  216. #define IF_HASHTABLE_SZ2 512
  217. //---------------------------------------------------
  218. // struct: IGMP_IF_TABLE
  219. //---------------------------------------------------
  220. typedef struct _IF_TABLE {
  221. LIST_ENTRY ListByAddr;
  222. LIST_ENTRY ListByIndex;
  223. DWORD Status;
  224. DWORD NumBuckets;
  225. DWORD NumInterfaces;
  226. PLIST_ENTRY HashTableByIndex;
  227. PDYNAMIC_CS_LOCK *aIfBucketDCS;
  228. PDYNAMIC_RW_LOCK *aIfBucketDRWL;
  229. CRITICAL_SECTION IfLists_CS; // CS protecting the 1st two lists
  230. } IGMP_IF_TABLE, *PIGMP_IF_TABLE;
  231. //---------------------------------------------------
  232. // struct: GI_INFO
  233. //---------------------------------------------------
  234. typedef struct _GROUP_INFO {
  235. DWORD LastReporter;
  236. LONGLONG GroupUpTime;
  237. LONGLONG GroupExpiryTime;
  238. LONGLONG V1HostPresentTimeLeft;
  239. // version 3 fields
  240. LONGLONG V2HostPresentTimeLeft;
  241. } GI_INFO, *PGROUP_INFO;
  242. //---------------------------------------------------
  243. // struct: GI_ENTRY (group-Interface entry)
  244. //---------------------------------------------------
  245. typedef struct _GI_ENTRY {
  246. LIST_ENTRY LinkByGI;
  247. LIST_ENTRY LinkBySameIfGroups;
  248. LIST_ENTRY LinkBySameClientGroups; //links all ras client groups
  249. DWORD IfIndex;
  250. DWORD Status; //bound,enabled,deleted,activated
  251. BOOL bRasClient; //rasclient or not
  252. BOOL bStaticGroup;
  253. PIF_TABLE_ENTRY pIfTableEntry;
  254. struct _GROUP_TABLE_ENTRY *pGroupTableEntry;
  255. //below two fields valid only for ras
  256. DWORD NHAddr;
  257. PRAS_TABLE_ENTRY pRasTableEntry;
  258. IGMP_TIMER_ENTRY GroupMembershipTimer;
  259. /*timerlock*///LastMemQueryCount left to be sent
  260. DWORD LastMemQueryCount;
  261. IGMP_TIMER_ENTRY LastMemQueryTimer;
  262. IGMP_TIMER_ENTRY LastVer1ReportTimer;/*timelock*/
  263. BYTE Version; //ver1, ver2, ver3
  264. GI_INFO Info;
  265. // igmpv3 fields. ignored for rest.
  266. IGMP_TIMER_ENTRY LastVer2ReportTimer;/*timelock*/
  267. DWORD FilterType;
  268. DWORD NumSources;
  269. LIST_ENTRY *V3InclusionList;
  270. LIST_ENTRY V3InclusionListSorted;
  271. LIST_ENTRY V3ExclusionList;
  272. //query sources
  273. LIST_ENTRY V3SourcesQueryList;
  274. DWORD V3SourcesQueryCount;
  275. BOOL bV3SourcesQueryNow;
  276. IGMP_TIMER_ENTRY V3SourcesQueryTimer;
  277. #if DEBUG_FLAGS_SIGNATURE
  278. DWORD Signature;//0xfadfad02
  279. #endif
  280. } GI_ENTRY, *PGI_ENTRY;
  281. //kslksl1 10
  282. #define SOURCES_BUCKET_SZ 1
  283. //---------------------------------------------------
  284. // struct: GI_SOURCE_ENTRY
  285. //---------------------------------------------------
  286. typedef struct _GI_SOURCE_ENTRY {
  287. LIST_ENTRY LinkSources;
  288. LIST_ENTRY LinkSourcesInclListSorted;
  289. LIST_ENTRY V3SourcesQueryList;
  290. PGI_ENTRY pGIEntry;
  291. BOOL bInclusionList;
  292. IPADDR IpAddr;
  293. //how many more src queries left to be sent
  294. DWORD V3SourcesQueryLeft;
  295. BOOL bInV3SourcesQueryList;
  296. //timeout sources in inc list
  297. IGMP_TIMER_ENTRY SourceExpTimer;
  298. LONGLONG SourceInListTime;
  299. BOOL bStaticSource;
  300. } GI_SOURCE_ENTRY, *PGI_SOURCE_ENTRY;
  301. #define GET_IF_CONFIG_FOR_SOURCE(pSourceEntry) \
  302. pSourceEntry->pGIEntry->pIfTableEntry->Config
  303. #define GET_IF_ENTRY_FOR_SOURCE(pSourceEntry) \
  304. pSourceEntry->pGIEntry->pIfTableEntry
  305. //---------------------------------------------------
  306. // struct: GROUP_TABLE_ENTRY
  307. //---------------------------------------------------
  308. typedef struct _GROUP_TABLE_ENTRY {
  309. LIST_ENTRY HTLinkByGroup;
  310. LIST_ENTRY LinkByGroup; //ordered list of groups
  311. LIST_ENTRY ListOfGIs;
  312. DWORD Group;
  313. DWORD GroupLittleEndian;
  314. DWORD NumVifs;
  315. DWORD Status;
  316. LONGLONG GroupUpTime;
  317. #if DEBUG_FLAGS_SIGNATURE
  318. DWORD Signature; //0xfadfad01
  319. #endif
  320. } GROUP_TABLE_ENTRY, *PGROUP_TABLE_ENTRY;
  321. #define GROUP_HASH_TABLE_SZ 256
  322. //---------------------------------------------------
  323. // struct: GROUP_TABLE
  324. //---------------------------------------------------
  325. typedef struct _GROUP_TABLE {
  326. LOCKED_LIST ListByGroup;
  327. LIST_ENTRY ListByGroupNew;
  328. DWORD NumGroupsInNewList;
  329. DWORD Status;
  330. LONG NumIfs; //Interlocked Operations
  331. DYNAMIC_CS_LOCKED_LIST HashTableByGroup[GROUP_HASH_TABLE_SZ];
  332. } GROUP_TABLE, *PGROUP_TABLE;
  333. //-------------------------------------------------
  334. // Proxy group entry
  335. //-------------------------------------------------
  336. typedef struct _PROXY_GROUP_ENTRY {
  337. LIST_ENTRY HT_Link;
  338. LIST_ENTRY LinkBySameIfGroups;
  339. //v3
  340. LIST_ENTRY ListSources;
  341. DWORD Group;
  342. DWORD GroupLittleEndian;
  343. DWORD RefCount;
  344. LONGLONG InitTime;
  345. BOOL bStaticGroup;
  346. //v3
  347. DWORD NumSources;
  348. DWORD FilterType;
  349. } PROXY_GROUP_ENTRY, *PPROXY_GROUP_ENTRY;
  350. typedef struct _PROXY_SOURCE_ENTRY {
  351. LIST_ENTRY LinkSources;
  352. IPADDR IpAddr;
  353. DWORD RefCount;
  354. BOOL bStaticSource;
  355. DWORD JoinMode;//ALLOW,BLOCK, NO_STATE
  356. DWORD JoinModeIntended;
  357. } PROXY_SOURCE_ENTRY, *PPROXY_SOURCE_ENTRY;
  358. //-------------------------------------------------
  359. // prototypes
  360. //-------------------------------------------------
  361. DWORD
  362. CreateIfSockets (
  363. PIF_TABLE_ENTRY pite
  364. );
  365. VOID
  366. DeleteIfSockets (
  367. PIF_TABLE_ENTRY pite
  368. );
  369. VOID
  370. DeleteAllTimers (
  371. PLIST_ENTRY pHead,
  372. DWORD bEntryType //RAS_CLIENT, NOT_RAS_CLIENT
  373. );
  374. DWORD
  375. DeleteGIEntry (
  376. PGI_ENTRY pgie, //group interface entry
  377. BOOL bUpdateStats,
  378. BOOL bCallMgm
  379. );
  380. VOID
  381. DeleteAllGIEntries(
  382. PIF_TABLE_ENTRY pite
  383. );
  384. VOID
  385. DeleteGIEntryFromIf (
  386. PGI_ENTRY pgie //group interface entry
  387. );
  388. VOID
  389. MergeGroupLists(
  390. );
  391. VOID
  392. MergeIfGroupsLists(
  393. PIF_TABLE_ENTRY pite
  394. );
  395. VOID
  396. MergeProxyLists(
  397. PIF_TABLE_ENTRY pite
  398. );
  399. DWORD
  400. CopyinIfConfig (
  401. PIGMP_IF_CONFIG pConfig,
  402. PIGMP_MIB_IF_CONFIG pConfigExt,
  403. DWORD IfIndex
  404. );
  405. DWORD
  406. CopyinIfConfigAndUpdate (
  407. PIF_TABLE_ENTRY pite,
  408. PIGMP_MIB_IF_CONFIG pConfigExt,
  409. ULONG IfIndex
  410. );
  411. VOID
  412. CopyoutIfConfig (
  413. PIGMP_MIB_IF_CONFIG pConfigExt,
  414. PIF_TABLE_ENTRY pite
  415. );
  416. DWORD
  417. ValidateIfConfig (
  418. PIGMP_MIB_IF_CONFIG pConfigExt,
  419. DWORD IfIndex,
  420. DWORD IfType,
  421. ULONG StructureVersion,
  422. ULONG StructureSize
  423. );
  424. DWORD
  425. InitializeIfTable (
  426. );
  427. VOID
  428. DeInitializeIfTable (
  429. );
  430. DWORD
  431. InitializeGroupTable (
  432. );
  433. VOID
  434. DeInitializeGroupTable (
  435. );
  436. DWORD
  437. InitializeRasTable(
  438. DWORD IfIndex,
  439. PIF_TABLE_ENTRY pite
  440. );
  441. VOID
  442. DeInitializeRasTable (
  443. PIF_TABLE_ENTRY pite,
  444. BOOL bFullCleanup
  445. );
  446. #endif // _IGMP_TABLE_H_