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.

594 lines
14 KiB

  1. //============================================================================
  2. // Copyright (c) 1995, Microsoft Corporation
  3. //
  4. // File: table.h
  5. //
  6. // History:
  7. // Abolade Gbadegesin Aug-8-1995 Created.
  8. //
  9. // V Raman Oct-3-1996
  10. // Added Deactivate Event to IF_TABLE_ENTRY
  11. //
  12. // V Raman Oct-27-1996
  13. // Removed Deactivate Event in IF_TABLE_ENTRY
  14. // and made interface deactivation synchronous
  15. //
  16. // Contains structures and macros used for table management.
  17. //============================================================================
  18. #ifndef _TABLE_H_
  19. #define _TABLE_H_
  20. #define GETMODE_EXACT 0
  21. #define GETMODE_FIRST 1
  22. #define GETMODE_NEXT 2
  23. //
  24. // TYPE DEFINITIONS FOR INTERFACE MANAGEMENT
  25. //
  26. //
  27. // struct: IF_TABLE_ENTRY
  28. //
  29. // declares the components of an interface table entry
  30. //
  31. //
  32. typedef struct _IF_TABLE_ENTRY {
  33. LIST_ENTRY ITE_LinkByAddress;
  34. LIST_ENTRY ITE_LinkByIndex;
  35. LIST_ENTRY ITE_HTLinkByIndex;
  36. NET_INTERFACE_TYPE ITE_Type;
  37. DWORD ITE_Index;
  38. DWORD ITE_Flags;
  39. HANDLE ITE_FullOrDemandUpdateTimer;
  40. IPRIP_IF_STATS ITE_Stats;
  41. PIPRIP_IF_CONFIG ITE_Config;
  42. PIPRIP_IF_BINDING ITE_Binding;
  43. SOCKET *ITE_Sockets;
  44. } IF_TABLE_ENTRY, *PIF_TABLE_ENTRY;
  45. #define ITEFLAG_ENABLED ((DWORD)0x00000001)
  46. #define ITEFLAG_BOUND ((DWORD)0x00000002)
  47. #define ITEFLAG_FULL_UPDATE_PENDING ((DWORD)0x00000004)
  48. #define ITEFLAG_FULL_UPDATE_INQUEUE ((DWORD)0x00000008)
  49. #define IF_IS_ENABLED(i) \
  50. ((i)->ITE_Flags & ITEFLAG_ENABLED)
  51. #define IF_IS_BOUND(i) \
  52. ((i)->ITE_Flags & ITEFLAG_BOUND)
  53. #define IF_IS_ACTIVE(i) \
  54. (IF_IS_BOUND(i) && IF_IS_ENABLED(i))
  55. #define IF_IS_DISABLED(i) !IF_IS_ENABLED(i)
  56. #define IF_IS_UNBOUND(i) !IF_IS_BOUND(i)
  57. #define IF_IS_INACTIVE(i) !IF_IS_ACTIVE(i)
  58. #define IF_FULL_UPDATE_PENDING(i) \
  59. ((i)->ITE_Flags & ITEFLAG_FULL_UPDATE_PENDING)
  60. #define IF_FULL_UPDATE_INQUEUE(i) \
  61. ((i)->ITE_Flags & ITEFLAG_FULL_UPDATE_INQUEUE)
  62. //
  63. // macros and definitions used by interface tables
  64. //
  65. #define IF_HASHTABLE_SIZE 29
  66. #define IF_HASHVALUE(i) ((i) % IF_HASHTABLE_SIZE)
  67. //
  68. // struct: IF_TABLE
  69. //
  70. // declares the structure of an interface table. consists of a hash-table
  71. // of IF_TABLE_ENTRY structures hashed on interface index, and a list
  72. // of all activated interfaces ordered by IP address
  73. //
  74. // The IT_CS section is used to synchronize the generation of updates;
  75. // it is acquired when updates are started and finished on interfaces
  76. // in this table, and thus it protects the flags field.
  77. //
  78. // The IT_RWL section is used to synchronize modifications to the table;
  79. // it must be acquired exclusively when entries are being added or deleted
  80. // from the table, and when the states of entries are being changed.
  81. // (e.g. binding, unbinding, enabling and disabling entries).
  82. //
  83. // IT_RWL must be acquired non-exclusively on all other acceses.
  84. //
  85. // When IT_RWL and IT_CS must both be acquired, IT_RWL must be acquired first.
  86. //
  87. typedef struct _IF_TABLE {
  88. DWORD IT_Created;
  89. DWORD IT_Flags;
  90. LARGE_INTEGER IT_LastUpdateTime;
  91. HANDLE IT_FinishTriggeredUpdateTimer;
  92. HANDLE IT_FinishFullUpdateTimer;
  93. CRITICAL_SECTION IT_CS;
  94. READ_WRITE_LOCK IT_RWL;
  95. LIST_ENTRY IT_ListByAddress;
  96. LIST_ENTRY IT_ListByIndex;
  97. LIST_ENTRY IT_HashTableByIndex[IF_HASHTABLE_SIZE];
  98. } IF_TABLE, *PIF_TABLE;
  99. //
  100. // constants and macros used for the flags field
  101. //
  102. #define IPRIP_FLAG_FULL_UPDATE_PENDING ((DWORD)0x00000001)
  103. #define IPRIP_FLAG_TRIGGERED_UPDATE_PENDING ((DWORD)0x00000002)
  104. #define IPRIP_FULL_UPDATE_PENDING(t) \
  105. ((t)->IT_Flags & IPRIP_FLAG_FULL_UPDATE_PENDING)
  106. #define IPRIP_TRIGGERED_UPDATE_PENDING(t) \
  107. ((t)->IT_Flags & IPRIP_FLAG_TRIGGERED_UPDATE_PENDING)
  108. DWORD
  109. CreateIfTable(
  110. PIF_TABLE pTable
  111. );
  112. DWORD
  113. DeleteIfTable(
  114. PIF_TABLE pTable
  115. );
  116. DWORD
  117. CreateIfEntry(
  118. PIF_TABLE pTable,
  119. DWORD dwIndex,
  120. NET_INTERFACE_TYPE dwIfType,
  121. PIPRIP_IF_CONFIG pConfig,
  122. PIF_TABLE_ENTRY *ppEntry
  123. );
  124. DWORD
  125. DeleteIfEntry(
  126. PIF_TABLE pIfTable,
  127. DWORD dwIndex
  128. );
  129. DWORD
  130. ValidateIfConfig(
  131. PIPRIP_IF_CONFIG pic
  132. );
  133. DWORD
  134. CreateIfSocket(
  135. PIF_TABLE_ENTRY pITE
  136. );
  137. DWORD
  138. DeleteIfSocket(
  139. PIF_TABLE_ENTRY pITE
  140. );
  141. DWORD
  142. BindIfEntry(
  143. PIF_TABLE pTable,
  144. DWORD dwIndex,
  145. PIP_ADAPTER_BINDING_INFO pBinding
  146. );
  147. DWORD
  148. UnBindIfEntry(
  149. PIF_TABLE pTable,
  150. DWORD dwIndex
  151. );
  152. DWORD
  153. EnableIfEntry(
  154. PIF_TABLE pTable,
  155. DWORD dwIndex
  156. );
  157. DWORD
  158. ConfigureIfEntry(
  159. PIF_TABLE pTable,
  160. DWORD dwIndex,
  161. PIPRIP_IF_CONFIG pConfig
  162. );
  163. DWORD
  164. DisableIfEntry(
  165. PIF_TABLE pTable,
  166. DWORD dwIndex
  167. );
  168. PIF_TABLE_ENTRY
  169. GetIfByIndex(
  170. PIF_TABLE pTable,
  171. DWORD dwIndex
  172. );
  173. PIF_TABLE_ENTRY
  174. GetIfByAddress(
  175. PIF_TABLE pTable,
  176. DWORD dwAddress,
  177. DWORD dwGetMode,
  178. PDWORD pdwErr
  179. );
  180. PIF_TABLE_ENTRY
  181. GetIfByListIndex(
  182. PIF_TABLE pTable,
  183. DWORD dwAddress,
  184. DWORD dwGetMode,
  185. PDWORD pdwErr
  186. );
  187. #define IF_TABLE_CREATED(pTable) ((pTable)->IT_Created == 0x12345678)
  188. //
  189. // TYPE DEFINITIONS FOR THE PEER STATISTICS HASH TABLE
  190. //
  191. //
  192. // struct: PEER_TABLE_ENTRY
  193. //
  194. // declares the structure of each entry in the peer table
  195. //
  196. typedef struct _PEER_TABLE_ENTRY {
  197. LIST_ENTRY PTE_LinkByAddress;
  198. LIST_ENTRY PTE_HTLinkByAddress;
  199. DWORD PTE_Address;
  200. IPRIP_PEER_STATS PTE_Stats;
  201. } PEER_TABLE_ENTRY, *PPEER_TABLE_ENTRY;
  202. //
  203. // macros and definitions used by peer statistics tables
  204. //
  205. #define PEER_HASHTABLE_SIZE 29
  206. #define PEER_HASHVALUE(a) \
  207. (((a) + \
  208. ((a) >> 8) + \
  209. ((a) >> 16) + \
  210. ((a) >> 24)) % PEER_HASHTABLE_SIZE)
  211. //
  212. // struct: PEER_TABLE
  213. //
  214. // this table contains the entries for keeping statistics about each peer.
  215. // it consists of a hash-table of peer stats (for fast direct access to
  216. // a specific entry) and a list of peer stats entries ordered by address
  217. // (for easy enumeration via MibGetNext)
  218. //
  219. typedef struct _PEER_TABLE {
  220. READ_WRITE_LOCK PT_RWL;
  221. DWORD PT_Created;
  222. LIST_ENTRY PT_ListByAddress;
  223. LIST_ENTRY PT_HashTableByAddress[PEER_HASHTABLE_SIZE];
  224. } PEER_TABLE, *PPEER_TABLE;
  225. DWORD
  226. CreatePeerTable(
  227. PPEER_TABLE pTable
  228. );
  229. DWORD
  230. DeletePeerTable(
  231. PPEER_TABLE pTable
  232. );
  233. DWORD
  234. CreatePeerEntry(
  235. PPEER_TABLE pTable,
  236. DWORD dwAddress,
  237. PPEER_TABLE_ENTRY *ppEntry
  238. );
  239. DWORD
  240. DeletePeerEntry(
  241. PPEER_TABLE pTable,
  242. DWORD dwAddress
  243. );
  244. PPEER_TABLE_ENTRY
  245. GetPeerByAddress(
  246. PPEER_TABLE pTable,
  247. DWORD dwAddress,
  248. DWORD dwGetMode,
  249. PDWORD pdwErr
  250. );
  251. #define PEER_TABLE_CREATED(pTable) ((pTable)->PT_Created == 0x12345678)
  252. //
  253. // TYPE DEFINITIONS FOR THE ROUTE TABLE USED FOR NETWORK SUMMARY
  254. //
  255. //
  256. // struct: ROUTE_TABLE_ENTRY
  257. //
  258. // declares the structure of each entry in the route table
  259. //
  260. typedef struct _ROUTE_TABLE_ENTRY {
  261. LIST_ENTRY RTE_Link;
  262. DWORD RTE_TTL;
  263. DWORD RTE_HoldTTL;
  264. RIP_IP_ROUTE RTE_Route;
  265. } ROUTE_TABLE_ENTRY, *PROUTE_TABLE_ENTRY;
  266. //
  267. // declares the structure of the protocol specific data
  268. //
  269. //
  270. // macros and definitions used by the route table
  271. //
  272. //
  273. // These flags are used in the ProtocolSpecificData array
  274. // to distinguish routes pending expiration from routes pending removal,
  275. // and to store the route tag for each route.
  276. // The first DWORD in the PSD_Data array is treated here as a byte-array;
  277. // the first two bytes are used to store the route tag;
  278. // the third byte is used to store the route flag
  279. //
  280. #define PSD(route) (route)->RR_ProtocolSpecificData.PSD_Data
  281. #define PSD_TAG0 0
  282. #define PSD_TAG1 1
  283. #define PSD_FLAG 2
  284. #define ROUTEFLAG_SUMMARY ((BYTE)0x03)
  285. #define SETROUTEFLAG(route, flag) (((PBYTE)&PSD(route))[PSD_FLAG] = (flag))
  286. #define GETROUTEFLAG(route) ((PBYTE)&PSD(route))[PSD_FLAG]
  287. #define SETROUTETAG(route, tag) \
  288. ((PBYTE)&PSD(route))[PSD_TAG0] = LOBYTE(tag), \
  289. ((PBYTE)&PSD(route))[PSD_TAG1] = HIBYTE(tag)
  290. #define GETROUTETAG(route) \
  291. MAKEWORD(((PBYTE)&PSD(route))[PSD_TAG0],((PBYTE)&PSD(route))[PSD_TAG1])
  292. #define SETROUTEMETRIC(route, metric) \
  293. (route)->RR_FamilySpecificData.FSD_Metric1 = (metric)
  294. #define GETROUTEMETRIC(route) \
  295. (route)->RR_FamilySpecificData.FSD_Metric1
  296. #define COMPUTE_ROUTE_METRIC(route) \
  297. (route)->RR_FamilySpecificData.FSD_Metric = \
  298. (route)->RR_FamilySpecificData.FSD_Metric1
  299. //
  300. // Macros to manipulate entity specific info in RTMv2 routes
  301. //
  302. #define ESD(route) (route)->EntitySpecificInfo
  303. #define ESD_TAG0 0
  304. #define ESD_TAG1 1
  305. #define ESD_FLAG 2
  306. #define SETRIPFLAG(route, flag) (((PBYTE)&ESD(route))[ESD_FLAG] = (flag))
  307. #define GETRIPFLAG(route) ((PBYTE)&ESD(route))[ESD_FLAG]
  308. #define SETRIPTAG(route, tag) \
  309. ((PBYTE)&ESD(route))[ESD_TAG0] = LOBYTE(tag), \
  310. ((PBYTE)&ESD(route))[ESD_TAG1] = HIBYTE(tag)
  311. #define GETRIPTAG(route) \
  312. MAKEWORD(((PBYTE)&ESD(route))[ESD_TAG0],((PBYTE)&ESD(route))[ESD_TAG1])
  313. #define ROUTE_HASHTABLE_SIZE 29
  314. #define ROUTE_HASHVALUE(a) \
  315. (((a) + \
  316. ((a) >> 8) + \
  317. ((a) >> 16) + \
  318. ((a) >> 24)) % ROUTE_HASHTABLE_SIZE)
  319. //
  320. // struct: ROUTE_TABLE
  321. //
  322. // declares the structure of a route table, which consists of a hash-table
  323. // of routes hashed on the destination network. Note that no synchronization
  324. // is included since this structure is only used during full-updates, to
  325. // store summary routes, and at most one thread may be sending a full-update
  326. // at any given time.
  327. //
  328. typedef struct _ROUTE_TABLE {
  329. DWORD RT_Created;
  330. LIST_ENTRY RT_HashTableByNetwork[ROUTE_HASHTABLE_SIZE];
  331. } ROUTE_TABLE, *PROUTE_TABLE;
  332. DWORD
  333. CreateRouteTable(
  334. PROUTE_TABLE pTable
  335. );
  336. DWORD
  337. DeleteRouteTable(
  338. PROUTE_TABLE pTable
  339. );
  340. DWORD
  341. WriteSummaryRoutes(
  342. PROUTE_TABLE pTable,
  343. HANDLE hRtmHandle
  344. );
  345. DWORD
  346. CreateRouteEntry(
  347. PROUTE_TABLE pTable,
  348. PRIP_IP_ROUTE pRoute,
  349. DWORD dwTTL,
  350. DWORD dwHoldTTL
  351. );
  352. DWORD
  353. DeleteRouteEntry(
  354. PROUTE_TABLE pTable,
  355. PRIP_IP_ROUTE pRoute
  356. );
  357. PROUTE_TABLE_ENTRY
  358. GetRouteByRoute(
  359. PROUTE_TABLE pTable,
  360. PRIP_IP_ROUTE pRoute
  361. );
  362. #define ROUTE_TABLE_CREATED(pTable) ((pTable)->RT_Created == 0x12345678)
  363. //
  364. // TYPE DEFINITIONS FOR BINDING TABLE
  365. //
  366. //
  367. // struct: BINDING_TABLE_ENTRY
  368. //
  369. // this entry contains a single binding.
  370. // a binding entry consists of an IP address, a network number (found
  371. // using the network class mask, not the subnet mask),
  372. // and a subnet mask.
  373. // All of the above are available when an interface is bound.
  374. // When a route arrives and its mask is to be guessed, its network number
  375. // can be computed (using the routes network class mask); we then search
  376. // the binding table for matching networks, and for each one we compare
  377. // (stored subnet mask) AND (interface IP address)
  378. // to
  379. // (stored subnet mask) AND (incoming route IP address).
  380. // When we find a match, (stored subnet mask) is our guess.
  381. //
  382. typedef struct _BINDING_TABLE_ENTRY {
  383. DWORD BTE_Address;
  384. DWORD BTE_Network;
  385. DWORD BTE_Netmask;
  386. LIST_ENTRY BTE_Link;
  387. } BINDING_TABLE_ENTRY, *PBINDING_TABLE_ENTRY;
  388. #define BINDING_HASHTABLE_SIZE 29
  389. #define BINDING_HASHVALUE(a) \
  390. (((a) + \
  391. ((a) >> 8) + \
  392. ((a) >> 16) + \
  393. ((a) >> 24)) % BINDING_HASHTABLE_SIZE)
  394. //
  395. // struct: BINDING_TABLE
  396. //
  397. // this table is used to store binding information that is used to guess
  398. // the subnet masks of incoming routes. it contains the bindings of all
  399. // interfaces which have been added to IPRIP, in an array to speed up access
  400. //
  401. typedef struct _BINDING_TABLE {
  402. READ_WRITE_LOCK BT_RWL;
  403. DWORD BT_Created;
  404. LIST_ENTRY BT_HashTableByNetwork[BINDING_HASHTABLE_SIZE];
  405. } BINDING_TABLE, *PBINDING_TABLE;
  406. #define BINDING_TABLE_CREATED(b) ((b)->BT_Created == 0x12345678)
  407. DWORD
  408. CreateBindingTable(
  409. PBINDING_TABLE pTable
  410. );
  411. DWORD
  412. DeleteBindingTable(
  413. PBINDING_TABLE pTable
  414. );
  415. DWORD
  416. CreateBindingEntry(
  417. PBINDING_TABLE pTable,
  418. PIPRIP_IF_BINDING pib
  419. );
  420. DWORD
  421. DeleteBindingEntry(
  422. PBINDING_TABLE pTable,
  423. PIPRIP_IF_BINDING pib
  424. );
  425. DWORD
  426. GuessSubnetMask(
  427. DWORD dwAddress,
  428. PDWORD pdwNetclassMask
  429. );
  430. DWORD
  431. AddRtmRoute(
  432. RTM_ENTITY_HANDLE hRtmHandle,
  433. PRIP_IP_ROUTE prir,
  434. RTM_NEXTHOP_HANDLE hNextHop OPTIONAL,
  435. DWORD dwTimeOut,
  436. DWORD dwHoldTime,
  437. BOOL bActive
  438. );
  439. DWORD
  440. GetRouteInfo(
  441. IN RTM_ROUTE_HANDLE hRoute,
  442. IN PRTM_ROUTE_INFO pInRouteInfo OPTIONAL,
  443. IN PRTM_DEST_INFO pInDestInfo OPTIONAL,
  444. OUT PRIP_IP_ROUTE pRoute
  445. );
  446. #endif // _TABLE_H_