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.

371 lines
10 KiB

  1. // wsnmp_pd.c
  2. //
  3. // WinSNMP PDU Functions and helpers
  4. // Copyright 1995-1997 ACE*COMM Corp
  5. // Rleased to Microsoft under Contract
  6. // Beta 1 version, 970228
  7. // Bob Natale ([email protected])
  8. //
  9. // Removed extraneous functions
  10. //
  11. #include "winsnmp.inc"
  12. LPVARBIND SnmpCopyVbl (LPVARBIND);
  13. // PDU Functions
  14. // SnmpCreatePdu
  15. HSNMP_PDU SNMPAPI_CALL
  16. SnmpCreatePdu (IN HSNMP_SESSION hSession,
  17. IN smiINT PDU_type,
  18. IN smiINT32 request_id,
  19. IN smiINT error_status,
  20. IN smiINT error_index,
  21. IN HSNMP_VBL hVbl)
  22. {
  23. DWORD nPdu;
  24. SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
  25. HSNMP_SESSION lSession = 0;
  26. LPPDUS pPdu;
  27. if (TaskData.hTask == 0)
  28. {
  29. lError = SNMPAPI_NOT_INITIALIZED;
  30. goto ERROR_OUT;
  31. }
  32. if (!snmpValidTableEntry(&SessDescr, HandleToUlong(hSession)-1))
  33. {
  34. lError = SNMPAPI_SESSION_INVALID;
  35. goto ERROR_OUT;
  36. }
  37. // We have a valid session at this point...
  38. lSession = hSession; // save it for possible error return
  39. if (hVbl)
  40. {
  41. if (!snmpValidTableEntry(&VBLsDescr, HandleToUlong(hVbl)-1))
  42. {
  43. lError = SNMPAPI_VBL_INVALID;
  44. goto ERROR_OUT;
  45. }
  46. }
  47. if (!PDU_type) // NULL is allowed and defaults to SNMP_PDU_GETNEXT
  48. PDU_type = SNMP_PDU_GETNEXT;
  49. switch (PDU_type)
  50. {
  51. case SNMP_PDU_GET:
  52. case SNMP_PDU_GETNEXT:
  53. case SNMP_PDU_RESPONSE:
  54. case SNMP_PDU_SET:
  55. case SNMP_PDU_INFORM:
  56. case SNMP_PDU_TRAP:
  57. case SNMP_PDU_GETBULK:
  58. break;
  59. case SNMP_PDU_V1TRAP:
  60. default:
  61. lError = SNMPAPI_PDU_INVALID;
  62. goto ERROR_OUT;
  63. }
  64. EnterCriticalSection (&cs_PDU);
  65. lError = snmpAllocTableEntry(&PDUsDescr, &nPdu);
  66. if (lError != SNMPAPI_SUCCESS)
  67. goto ERROR_PRECHECK;
  68. pPdu = snmpGetTableEntry(&PDUsDescr, nPdu);
  69. // Initialize new PDU components
  70. pPdu->Session = hSession;
  71. pPdu->type = PDU_type;
  72. pPdu->errStatus = error_status;
  73. pPdu->errIndex = error_index;
  74. // If RequestID=0 at this point, assign one (which may be 0)
  75. pPdu->appReqId = (request_id) ? request_id : ++(TaskData.nLastReqId);
  76. pPdu->VBL_addr = NULL;
  77. pPdu->VBL = (hVbl) ? hVbl : 0;
  78. ERROR_PRECHECK:
  79. LeaveCriticalSection (&cs_PDU);
  80. if (lError == SNMPAPI_SUCCESS)
  81. return ((HSNMP_PDU) ULongToPtr(nPdu+1));
  82. else
  83. ERROR_OUT:
  84. return ((HSNMP_PDU) ULongToPtr(SaveError(lSession, lError)));
  85. } // end_SnmpCreatePdu
  86. // SnmpGetPduData
  87. SNMPAPI_STATUS SNMPAPI_CALL
  88. SnmpGetPduData (IN HSNMP_PDU hPdu,
  89. OUT smiLPINT PDU_type,
  90. OUT smiLPINT32 request_id,
  91. OUT smiLPINT error_status,
  92. OUT smiLPINT error_index,
  93. OUT LPHSNMP_VBL hVbl)
  94. {
  95. DWORD nPdu = HandleToUlong(hPdu) - 1;
  96. DWORD done = 0;
  97. HSNMP_SESSION hSession;
  98. SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
  99. HSNMP_SESSION lSession = 0;
  100. LPPDUS pPdu;
  101. LPVBLS pVbl;
  102. if (TaskData.hTask == 0)
  103. {
  104. lError = SNMPAPI_NOT_INITIALIZED;
  105. goto ERROR_OUT;
  106. }
  107. if (!snmpValidTableEntry(&PDUsDescr, nPdu))
  108. {
  109. lError = SNMPAPI_PDU_INVALID;
  110. goto ERROR_OUT;
  111. }
  112. pPdu = snmpGetTableEntry(&PDUsDescr, nPdu);
  113. // Use PDU's session for (possibly) creating hVbl later
  114. hSession = pPdu->Session;
  115. if (!snmpValidTableEntry(&SessDescr, HandleToUlong(hSession)-1))
  116. {
  117. lError = SNMPAPI_SESSION_INVALID;
  118. goto ERROR_OUT;
  119. }
  120. lSession = hSession; // Save for possible error return
  121. if (PDU_type)
  122. {
  123. *PDU_type = pPdu->type;
  124. done++;
  125. }
  126. if (request_id)
  127. {
  128. *request_id = pPdu->appReqId;
  129. done++;
  130. }
  131. if (error_status)
  132. {
  133. *error_status = pPdu->errStatus;
  134. done++;
  135. }
  136. if (error_index)
  137. {
  138. *error_index = pPdu->errIndex;
  139. done++;
  140. }
  141. if (hVbl)
  142. {
  143. DWORD nVbl; // Important control variable
  144. *hVbl = 0;
  145. EnterCriticalSection (&cs_VBL);
  146. // First case is on a created (not received) PDU
  147. // which has not yet been assigned a VBL
  148. if ((!pPdu->VBL) && (!pPdu->VBL_addr))
  149. goto DONE_VBL;
  150. // If there is a VBL already assinged to the PDU,
  151. // then duplicate it
  152. if (pPdu->VBL)
  153. { // Per policy, create a new hVbl resource for the calling app
  154. if (!(*hVbl = SnmpDuplicateVbl (hSession, pPdu->VBL)))
  155. {
  156. lError = SNMPAPI_VBL_INVALID;
  157. goto ERROR_PRECHECK;
  158. }
  159. goto DONE_VBL;
  160. }
  161. // This must be a received PDU and
  162. // the first call to extract the VBL
  163. lError = snmpAllocTableEntry(&VBLsDescr, &nVbl);
  164. if (lError != SNMPAPI_SUCCESS)
  165. goto ERROR_PRECHECK;
  166. pVbl = snmpGetTableEntry(&VBLsDescr, nVbl);
  167. pVbl->Session = hSession;
  168. pVbl->vbList = pPdu->VBL_addr;
  169. // Clear received vbList address...IMPORTANT!
  170. pPdu->VBL_addr = NULL;
  171. *hVbl = pPdu->VBL = (HSNMP_VBL) ULongToPtr(nVbl+1);
  172. DONE_VBL:
  173. done++;
  174. ERROR_PRECHECK:
  175. LeaveCriticalSection (&cs_VBL);
  176. } // end_if vbl
  177. if (done == 0)
  178. lError = SNMPAPI_NOOP;
  179. if (lError == SNMPAPI_SUCCESS)
  180. return (SNMPAPI_SUCCESS);
  181. ERROR_OUT:
  182. return (SaveError (lSession, lError));
  183. } // end_SnmpGetPduData
  184. // SnmpSetPduData
  185. SNMPAPI_STATUS SNMPAPI_CALL
  186. SnmpSetPduData (IN HSNMP_PDU hPdu,
  187. IN const smiINT FAR *PDU_type,
  188. IN const smiINT32 FAR *request_id,
  189. IN const smiINT FAR *non_repeaters,
  190. IN const smiINT FAR *max_repetitions,
  191. IN const HSNMP_VBL FAR *hVbl)
  192. {
  193. DWORD nPdu = HandleToUlong(hPdu) - 1;
  194. DWORD done = 0;
  195. SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
  196. HSNMP_SESSION lSession = 0;
  197. LPPDUS pPdu;
  198. if (TaskData.hTask == 0)
  199. {
  200. lError = SNMPAPI_NOT_INITIALIZED;
  201. goto ERROR_OUT;
  202. }
  203. if (!snmpValidTableEntry(&PDUsDescr, nPdu))
  204. {
  205. lError = SNMPAPI_PDU_INVALID;
  206. goto ERROR_OUT;
  207. }
  208. pPdu = snmpGetTableEntry(&PDUsDescr, nPdu);
  209. lSession = pPdu->Session; // Save for possible error return
  210. EnterCriticalSection (&cs_PDU);
  211. if (!IsBadReadPtr((LPVOID)PDU_type, sizeof(smiINT)))
  212. {
  213. if (*PDU_type == SNMP_PDU_V1TRAP)
  214. {
  215. lError = SNMPAPI_PDU_INVALID;
  216. goto ERROR_OUT;
  217. }
  218. pPdu->type = *PDU_type;
  219. done++;
  220. }
  221. if (!IsBadReadPtr((LPVOID)request_id, sizeof(smiINT32)))
  222. {
  223. pPdu->appReqId = *request_id;
  224. done++;
  225. }
  226. if (!IsBadReadPtr((LPVOID)non_repeaters, sizeof(smiINT)))
  227. {
  228. pPdu->errStatus = *non_repeaters;
  229. done++;
  230. }
  231. if (!IsBadReadPtr((LPVOID)max_repetitions, sizeof(smiINT)))
  232. {
  233. pPdu->errIndex = *max_repetitions;
  234. done++;
  235. }
  236. if (!IsBadReadPtr((LPVOID)hVbl, sizeof(HSNMP_VBL)))
  237. { // Assign new vbl
  238. HSNMP_VBL tVbl = *hVbl;
  239. // Check for validity
  240. if (!snmpValidTableEntry(&VBLsDescr, HandleToUlong(tVbl)-1))
  241. { // If not, disallow operation
  242. lError = SNMPAPI_VBL_INVALID;
  243. goto ERROR_PRECHECK;
  244. }
  245. pPdu->VBL = tVbl;
  246. // Following case can happen if a a vbl is assigned to a
  247. // response pdu which never had its vbl dereferenced...
  248. if (pPdu->VBL_addr) //...then is must be freed
  249. FreeVarBindList (pPdu->VBL_addr);
  250. pPdu->VBL_addr = NULL;
  251. done++;
  252. } // end_if vbl
  253. ERROR_PRECHECK:
  254. LeaveCriticalSection (&cs_PDU);
  255. if (done == 0)
  256. lError = ((PDU_type == NULL) &&
  257. (request_id == NULL) &&
  258. (non_repeaters == NULL) &&
  259. (max_repetitions == NULL) &&
  260. (hVbl == NULL)) ? SNMPAPI_NOOP : SNMPAPI_ALLOC_ERROR;
  261. if (lError == SNMPAPI_SUCCESS)
  262. return (SNMPAPI_SUCCESS);
  263. ERROR_OUT:
  264. return (SaveError (lSession, lError));
  265. } // end_SnmpSetPduData
  266. // SnmpDuplicatePdu
  267. HSNMP_PDU SNMPAPI_CALL
  268. SnmpDuplicatePdu (IN HSNMP_SESSION hSession,
  269. IN HSNMP_PDU hPdu)
  270. {
  271. DWORD lPdu = HandleToUlong(hPdu) - 1;
  272. DWORD nPdu;
  273. SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
  274. HSNMP_SESSION lSession = 0;
  275. LPPDUS pOldPdu, pNewPdu;
  276. if (TaskData.hTask == 0)
  277. {
  278. lError = SNMPAPI_NOT_INITIALIZED;
  279. goto ERROR_OUT;
  280. }
  281. if (!snmpValidTableEntry(&SessDescr, HandleToUlong(hSession)-1))
  282. {
  283. lError = SNMPAPI_SESSION_INVALID;
  284. goto ERROR_OUT;
  285. }
  286. lSession = hSession; // save for possible error return
  287. if (!snmpValidTableEntry(&PDUsDescr, lPdu) ||
  288. (pOldPdu = snmpGetTableEntry(&PDUsDescr, lPdu))->type == SNMP_PDU_V1TRAP)
  289. {
  290. lError = SNMPAPI_PDU_INVALID;
  291. goto ERROR_OUT;
  292. }
  293. EnterCriticalSection (&cs_PDU);
  294. lError = snmpAllocTableEntry(&PDUsDescr, &nPdu);
  295. if (lError != SNMPAPI_SUCCESS)
  296. goto ERROR_PRECHECK;
  297. pNewPdu = snmpGetTableEntry(&PDUsDescr, nPdu);
  298. CopyMemory (pNewPdu, pOldPdu, sizeof(PDUS));
  299. pNewPdu->Session = hSession; // Can be different
  300. // Setting the VBL value in the duplicated PDU is "tricky"...
  301. // If there is a VBL value, just replicate it and that's that.
  302. // If VBL = 0 and there is no VBL_addr attached to the pdu_ptr,
  303. // then the VBL value is 0 and is already set from the original PDU.
  304. // Otherwise, this is a received PDU from which the varbindlist has
  305. // not yet been extracted and must, therefore, be re-produced.
  306. // This third case is covered in the next *2* lines.
  307. if ((!pOldPdu->VBL) && pOldPdu->VBL_addr)
  308. {
  309. if (!(pNewPdu->VBL_addr = SnmpCopyVbl (pOldPdu->VBL_addr)))
  310. {
  311. lError = SNMPAPI_ALLOC_ERROR;
  312. }
  313. }
  314. ERROR_PRECHECK:
  315. LeaveCriticalSection (&cs_PDU);
  316. if (lError == SNMPAPI_SUCCESS)
  317. return ((HSNMP_PDU) ULongToPtr(nPdu+1));
  318. ERROR_OUT:
  319. return ((HSNMP_PDU) ULongToPtr(SaveError(lSession, lError)));
  320. } // end_SnmpDuplicatePdu
  321. // SnmpFreePdu
  322. SNMPAPI_STATUS SNMPAPI_CALL
  323. SnmpFreePdu (IN HSNMP_PDU hPdu)
  324. {
  325. DWORD nPdu = HandleToUlong(hPdu) - 1;
  326. SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
  327. LPPDUS pPdu;
  328. if (TaskData.hTask == 0)
  329. {
  330. lError = SNMPAPI_NOT_INITIALIZED;
  331. goto ERROR_OUT;
  332. }
  333. if (!snmpValidTableEntry(&PDUsDescr, nPdu))
  334. {
  335. lError = SNMPAPI_PDU_INVALID;
  336. goto ERROR_OUT;
  337. }
  338. pPdu = snmpGetTableEntry(&PDUsDescr, nPdu);
  339. EnterCriticalSection (&cs_PDU);
  340. if (pPdu->VBL_addr)
  341. FreeVarBindList (pPdu->VBL_addr);
  342. if (pPdu->v1Trap)
  343. FreeV1Trap (pPdu->v1Trap);
  344. snmpFreeTableEntry(&PDUsDescr, nPdu);
  345. LeaveCriticalSection (&cs_PDU);
  346. return (SNMPAPI_SUCCESS);
  347. ERROR_OUT:
  348. return (SaveError (0, lError));
  349. } // end_SnmpfreePdu