Leaked source code of windows server 2003
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.

298 lines
7.4 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. Author:
  6. Revision History:
  7. --*/
  8. #include "allinc.h"
  9. static UINT rguiIfEntryIndexList[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 0};
  10. static AsnObjectIdentifier aoiIfLinkIndexOid = {sizeof(rguiIfEntryIndexList) / sizeof (UINT),
  11. rguiIfEntryIndexList};
  12. BOOL
  13. MibTrap(
  14. AsnInteger *paiGenericTrap,
  15. AsnInteger *paiSpecificTrap,
  16. RFC1157VarBindList *pr1157vblVariableBindings
  17. )
  18. /*++
  19. Routine Description
  20. Locks
  21. Arguments
  22. Return Value
  23. NO_ERROR
  24. --*/
  25. {
  26. AsnInteger NumberOfLinks;
  27. AsnInteger LinkNumber;
  28. AsnInteger errorStatus;
  29. RFC1157VarBind my_item;
  30. DWORD i, j, dwResult, dwIndex;
  31. BOOL bFound;
  32. TraceEnter("MibTrap");
  33. if(g_Cache.pRpcIfTable is NULL)
  34. {
  35. TRACE0("IF Cache not setup");
  36. UpdateCache(MIB_II_IF);
  37. TraceLeave("MibTrap");
  38. return FALSE;
  39. }
  40. EnterWriter(MIB_II_TRAP);
  41. if(g_dwValidStatusEntries is 0)
  42. {
  43. TRACE0("Status table is empty");
  44. //
  45. // This is the case where we are being polled for the first time ever, or
  46. // we have cycled once through all the interfaces and the poll timer has
  47. // fired again
  48. //
  49. //
  50. // We check the amount of memory needed and copy out the contents of
  51. // the current IF cache
  52. //
  53. EnterReader(MIB_II_IF);
  54. if((g_dwTotalStatusEntries < g_Cache.pRpcIfTable->dwNumEntries) or
  55. (g_dwTotalStatusEntries > g_Cache.pRpcIfTable->dwNumEntries + MAX_DIFF))
  56. {
  57. if(g_pisStatusTable isnot NULL)
  58. {
  59. HeapFree(g_hPrivateHeap,
  60. 0,
  61. g_pisStatusTable);
  62. }
  63. g_pisStatusTable =
  64. HeapAlloc(g_hPrivateHeap,
  65. 0,
  66. sizeof(MIB_IFSTATUS) * (g_Cache.pRpcIfTable->dwNumEntries + SPILLOVER));
  67. if(g_pisStatusTable is NULL)
  68. {
  69. TRACE2("Error %d allocating %d bytes for status table",
  70. GetLastError(),
  71. sizeof(MIB_IFSTATUS) * (g_Cache.pRpcIfTable->dwNumEntries + SPILLOVER));
  72. ReleaseLock(MIB_II_IF);
  73. ReleaseLock(MIB_II_TRAP);
  74. TraceLeave("MibTrap");
  75. return FALSE;
  76. }
  77. g_dwTotalStatusEntries = g_Cache.pRpcIfTable->dwNumEntries + SPILLOVER;
  78. }
  79. //
  80. // Copy out the oper status
  81. //
  82. for(i = 0; i < g_Cache.pRpcIfTable->dwNumEntries; i++)
  83. {
  84. g_pisStatusTable[i].dwIfIndex =
  85. g_Cache.pRpcIfTable->table[i].dwIndex;
  86. if(g_bFirstTime)
  87. {
  88. g_pisStatusTable[i].dwOperationalStatus =
  89. IF_OPER_STATUS_NON_OPERATIONAL;
  90. }
  91. else
  92. {
  93. g_pisStatusTable[i].dwOperationalStatus =
  94. g_Cache.pRpcIfTable->table[i].dwOperStatus;
  95. }
  96. }
  97. if(g_bFirstTime)
  98. {
  99. g_bFirstTime = FALSE;
  100. }
  101. g_dwValidStatusEntries = g_Cache.pRpcIfTable->dwNumEntries;
  102. ReleaseLock(MIB_II_IF);
  103. }
  104. dwResult = UpdateCache(MIB_II_IF);
  105. if(dwResult isnot NO_ERROR)
  106. {
  107. TRACE1("Error %d updating IF cache",
  108. dwResult);
  109. ReleaseLock(MIB_II_TRAP);
  110. return FALSE;
  111. }
  112. EnterReader(MIB_II_IF);
  113. bFound = FALSE;
  114. for(i = 0;
  115. (i < g_Cache.pRpcIfTable->dwNumEntries) and !bFound;
  116. i++)
  117. {
  118. //
  119. // Loop till we reach the end of the table or we find the first
  120. // I/F whose status is different
  121. //
  122. for(j = 0; j < g_dwValidStatusEntries; j++)
  123. {
  124. if(g_pisStatusTable[j].dwIfIndex > g_Cache.pRpcIfTable->table[i].dwIndex)
  125. {
  126. //
  127. // We have passed the index in the array. It cant be after this
  128. // point since the tables are ordered
  129. //
  130. dwIndex = i;
  131. bFound = TRUE;
  132. //
  133. // Since we have a new I/F we need to reread the StatusTable
  134. // If we dont then we will always hit this interface and get
  135. // stuck in a loop
  136. //
  137. g_dwValidStatusEntries = 0;
  138. TRACE1("IF index %d not found in status table",
  139. g_Cache.pRpcIfTable->table[i].dwIndex);
  140. break;
  141. }
  142. if(g_pisStatusTable[j].dwIfIndex is g_Cache.pRpcIfTable->table[i].dwIndex)
  143. {
  144. if(g_pisStatusTable[j].dwOperationalStatus isnot g_Cache.pRpcIfTable->table[i].dwOperStatus)
  145. {
  146. //
  147. // Its changed
  148. //
  149. TRACE2("Status changed for IF %d. New status is %d",
  150. g_Cache.pRpcIfTable->table[i].dwIndex,
  151. g_Cache.pRpcIfTable->table[i].dwOperStatus);
  152. g_pisStatusTable[j].dwOperationalStatus =
  153. g_Cache.pRpcIfTable->table[i].dwOperStatus;
  154. dwIndex = i;
  155. bFound = TRUE;
  156. }
  157. //
  158. // Try the next i/f or break out of outer loop depending
  159. // on bFound
  160. //
  161. break;
  162. }
  163. }
  164. }
  165. if(!bFound)
  166. {
  167. //
  168. // No i/f found whose status had changed. Set valid entries to 0 so that
  169. // next time around we reread the cache
  170. //
  171. g_dwValidStatusEntries = 0;
  172. ReleaseLock(MIB_II_IF);
  173. ReleaseLock(MIB_II_TRAP);
  174. TraceLeave("MibTrap");
  175. return FALSE;
  176. }
  177. if(g_Cache.pRpcIfTable->table[dwIndex].dwOperStatus is IF_ADMIN_STATUS_UP)
  178. {
  179. *paiGenericTrap = SNMP_GENERICTRAP_LINKUP;
  180. }
  181. else
  182. {
  183. *paiGenericTrap = SNMP_GENERICTRAP_LINKDOWN;
  184. }
  185. pr1157vblVariableBindings->list = (RFC1157VarBind *)SnmpUtilMemAlloc((sizeof(RFC1157VarBind)));
  186. if (pr1157vblVariableBindings->list is NULL)
  187. {
  188. ReleaseLock(MIB_II_IF);
  189. ReleaseLock(MIB_II_TRAP);
  190. TraceLeave("MibTrap");
  191. return FALSE;
  192. }
  193. pr1157vblVariableBindings->len = 1;
  194. SnmpUtilOidCpy(&((pr1157vblVariableBindings->list)->name),
  195. &aoiIfLinkIndexOid);
  196. (pr1157vblVariableBindings->list)->name.ids[10] =
  197. g_Cache.pRpcIfTable->table[dwIndex].dwIndex;
  198. (pr1157vblVariableBindings->list)->value.asnType = ASN_INTEGER;
  199. (pr1157vblVariableBindings->list)->value.asnValue.number = g_Cache.pRpcIfTable->table[dwIndex].dwIndex;
  200. *paiSpecificTrap = 0;
  201. ReleaseLock(MIB_II_IF);
  202. ReleaseLock(MIB_II_TRAP);
  203. TraceLeave("MibTrap");
  204. return TRUE;
  205. }