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.

1049 lines
27 KiB

  1. /*++
  2. Copyright (c) 1992-1997 Microsoft Corporation
  3. Module Name:
  4. varbinds.c
  5. Abstract:
  6. Contains routines for manipulating varbinds.
  7. Environment:
  8. User Mode - Win32
  9. Revision History:
  10. 10-Feb-1997 DonRyan
  11. Rewrote to implement SNMPv2 support.
  12. --*/
  13. ///////////////////////////////////////////////////////////////////////////////
  14. // //
  15. // Include files //
  16. // //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #include "globals.h"
  19. #include "varbinds.h"
  20. #include "query.h"
  21. #include "snmpmgmt.h"
  22. ///////////////////////////////////////////////////////////////////////////////
  23. // //
  24. // Private procedures //
  25. // //
  26. ///////////////////////////////////////////////////////////////////////////////
  27. BOOL
  28. LoadVarBind(
  29. PNETWORK_LIST_ENTRY pNLE,
  30. UINT iVb
  31. )
  32. /*++
  33. Routine Description:
  34. Creates varbind list entry from varbind structure.
  35. Arguments:
  36. pNLE - pointer to network list entry.
  37. iVb - index of variable binding.
  38. Return Values:
  39. Returns true if successful.
  40. --*/
  41. {
  42. SnmpVarBind * pVb;
  43. PVARBIND_LIST_ENTRY pVLE = NULL;
  44. PMIB_REGION_LIST_ENTRY pRLE = NULL;
  45. BOOL fAnyOk;
  46. BOOL fOk;
  47. // allocate list entry
  48. if (fOk = AllocVLE(&pVLE)) {
  49. // save varbind list index
  50. pVLE->nErrorIndex = iVb + 1;
  51. // retrieve varbind pointer
  52. pVb = &pNLE->Pdu.Vbl.list[iVb];
  53. SNMPDBG((
  54. SNMP_LOG_TRACE,
  55. "SNMP: SVC: variable %d name %s.\n",
  56. pVLE->nErrorIndex,
  57. SnmpUtilOidToA(&pVb->name)
  58. ));
  59. // initialize type of resolved variable
  60. pVLE->ResolvedVb.value.asnType = ASN_NULL;
  61. // copy varbind name to working structure
  62. if (SnmpUtilOidCpy(&pVLE->ResolvedVb.name, &pVb->name) == 0)
  63. {
  64. SNMPDBG((
  65. SNMP_LOG_ERROR,
  66. "SNMP: SVC: could not copy vb name to working structure.\n"
  67. ));
  68. // free allocated resources
  69. FreeVLE(pVLE);
  70. return FALSE;
  71. }
  72. // see if specific object asked for
  73. fAnyOk = ((pNLE->Pdu.nType == SNMP_PDU_GETNEXT) ||
  74. (pNLE->Pdu.nType == SNMP_PDU_GETBULK));
  75. // attempt to lookup variable name in supported regions
  76. if (FindSupportedRegion(&pRLE, &pVb->name, fAnyOk)) {
  77. // save pointer to region
  78. pVLE->pCurrentRLE = pRLE;
  79. // structure has been initialized
  80. pVLE->nState = VARBIND_INITIALIZED;
  81. SNMPDBG((
  82. SNMP_LOG_TRACE,
  83. "SNMP: SVC: variable %d assigned to %s.\n",
  84. pVLE->nErrorIndex,
  85. pVLE->pCurrentRLE->pSLE->pPathname
  86. ));
  87. SNMPDBG((
  88. SNMP_LOG_VERBOSE,
  89. "SNMP: SVC: variable %d state '%s'.\n",
  90. pVLE->nErrorIndex,
  91. VARBINDSTATESTRING(pVLE->nState)
  92. ));
  93. // see if this is a getnext request
  94. if (pNLE->Pdu.nType == SNMP_PDU_GETNEXT) {
  95. // only need single rep
  96. pVLE->nMaxRepetitions = 1;
  97. } else if (pNLE->Pdu.nType == SNMP_PDU_GETBULK) {
  98. // see if this non-repeater which is in bounds
  99. if (pNLE->Pdu.Pdu.BulkPdu.nNonRepeaters > (int)iVb) {
  100. // only need single rep
  101. pVLE->nMaxRepetitions = 1;
  102. SNMPDBG((
  103. SNMP_LOG_VERBOSE,
  104. "SNMP: SVC: variable %d max repetitions %d.\n",
  105. pVLE->nErrorIndex,
  106. pVLE->nMaxRepetitions
  107. ));
  108. // see if max-repetitions is non-zero
  109. } else if (pNLE->Pdu.Pdu.BulkPdu.nMaxRepetitions > 0) {
  110. // set max-repetitions to value in getbulk pdu
  111. pVLE->nMaxRepetitions = pNLE->Pdu.Pdu.BulkPdu.nMaxRepetitions;
  112. SNMPDBG((
  113. SNMP_LOG_VERBOSE,
  114. "SNMP: SVC: variable %d max repetitions %d.\n",
  115. pVLE->nErrorIndex,
  116. pVLE->nMaxRepetitions
  117. ));
  118. } else {
  119. // modify state to resolved
  120. pVLE->nState = VARBIND_RESOLVED;
  121. SNMPDBG((
  122. SNMP_LOG_VERBOSE,
  123. "SNMP: SVC: variable %d state '%s'.\n",
  124. pVLE->nErrorIndex,
  125. VARBINDSTATESTRING(pVLE->nState)
  126. ));
  127. SNMPDBG((
  128. SNMP_LOG_VERBOSE,
  129. "SNMP: SVC: variable %d value NULL.\n",
  130. pVLE->nErrorIndex
  131. ));
  132. }
  133. } else if (pNLE->Pdu.nType == SNMP_PDU_SET) {
  134. // copy varbind value to working structure
  135. if (SnmpUtilAsnAnyCpy(&pVLE->ResolvedVb.value, &pVb->value) == 0)
  136. {
  137. SNMPDBG((
  138. SNMP_LOG_ERROR,
  139. "SNMP: SVC: could not copy vb value to working structure.\n"
  140. ));
  141. // free allocated resources
  142. FreeVLE(pVLE);
  143. return FALSE;
  144. }
  145. SNMPDBG((
  146. SNMP_LOG_VERBOSE,
  147. "SNMP: SVC: variable %d value %s.\n",
  148. pVLE->nErrorIndex,
  149. "<TBD>"
  150. ));
  151. }
  152. } else {
  153. // null pointer to region
  154. pVLE->pCurrentRLE = NULL;
  155. SNMPDBG((
  156. SNMP_LOG_TRACE,
  157. "SNMP: SVC: variable %d unable to be assigned.\n",
  158. pVLE->nErrorIndex
  159. ));
  160. // getbulk
  161. if (fAnyOk) {
  162. // modify state to resolved
  163. pVLE->nState = VARBIND_RESOLVED;
  164. // set the exception in the variable's type field
  165. pVLE->ResolvedVb.value.asnType = SNMP_EXCEPTION_ENDOFMIBVIEW;
  166. SNMPDBG((
  167. SNMP_LOG_VERBOSE,
  168. "SNMP: SVC: variable %d state '%s'.\n",
  169. pVLE->nErrorIndex,
  170. VARBINDSTATESTRING(pVLE->nState)
  171. ));
  172. SNMPDBG((
  173. SNMP_LOG_VERBOSE,
  174. "SNMP: SVC: variable %d value ENDOFMIBVIEW.\n",
  175. pVLE->nErrorIndex
  176. ));
  177. } else if (pNLE->Pdu.nType == SNMP_PDU_GET) {
  178. // modify state to resolved
  179. pVLE->nState = VARBIND_RESOLVED;
  180. // set the exception in the variable's type field
  181. pVLE->ResolvedVb.value.asnType = SNMP_EXCEPTION_NOSUCHOBJECT;
  182. SNMPDBG((
  183. SNMP_LOG_VERBOSE,
  184. "SNMP: SVC: variable %d state '%s'.\n",
  185. pVLE->nErrorIndex,
  186. VARBINDSTATESTRING(pVLE->nState)
  187. ));
  188. SNMPDBG((
  189. SNMP_LOG_VERBOSE,
  190. "SNMP: SVC: variable %d value NOSUCHOBJECT.\n",
  191. pVLE->nErrorIndex
  192. ));
  193. } else {
  194. // modify state to resolved
  195. //pVLE->nState = VARBIND_ABORTED;
  196. pVLE->nState = VARBIND_RESOLVED;
  197. // save error status in network list entry
  198. pNLE->Pdu.Pdu.NormPdu.nErrorStatus = SNMP_ERRORSTATUS_NOTWRITABLE;
  199. pNLE->Pdu.Pdu.NormPdu.nErrorIndex = pVLE->nErrorIndex;
  200. SNMPDBG((
  201. SNMP_LOG_VERBOSE,
  202. "SNMP: SVC: variable %d state '%s'.\n",
  203. pVLE->nErrorIndex,
  204. VARBINDSTATESTRING(pVLE->nState)
  205. ));
  206. SNMPDBG((
  207. SNMP_LOG_VERBOSE,
  208. "SNMP: SVC: variable %d error %s.\n",
  209. pVLE->nErrorIndex,
  210. SNMPERRORSTRING(pNLE->Pdu.Pdu.NormPdu.nErrorStatus)
  211. ));
  212. // failure
  213. //fOk = FALSE;
  214. }
  215. }
  216. // add to existing varbind list
  217. InsertTailList(&pNLE->Bindings, &pVLE->Link);
  218. }
  219. return fOk;
  220. }
  221. BOOL
  222. LoadVarBinds(
  223. PNETWORK_LIST_ENTRY pNLE
  224. )
  225. /*++
  226. Routine Description:
  227. Creates list of varbind entries from varbind structure.
  228. Arguments:
  229. pNLE - pointer to network list entry.
  230. Return Values:
  231. Returns true if successful.
  232. --*/
  233. {
  234. UINT iVb;
  235. BOOL fOk = TRUE;
  236. // process each varbind in list
  237. for (iVb = 0; (fOk && (iVb < pNLE->Pdu.Vbl.len)); iVb++) {
  238. // load individual varbind
  239. fOk = LoadVarBind(pNLE, iVb);
  240. }
  241. return fOk;
  242. }
  243. BOOL
  244. UnloadVarBinds(
  245. PNETWORK_LIST_ENTRY pNLE
  246. )
  247. /*++
  248. Routine Description:
  249. Destroys list of varbind entries.
  250. Arguments:
  251. pNLE - pointer to network list entry.
  252. Return Values:
  253. Returns true if successful.
  254. --*/
  255. {
  256. PLIST_ENTRY pLE;
  257. PVARBIND_LIST_ENTRY pVLE;
  258. // process each varbind entry
  259. while (!IsListEmpty(&pNLE->Bindings)) {
  260. // point to first varbind
  261. pLE = RemoveHeadList(&pNLE->Bindings);
  262. // retrieve pointer to varbind entry from link
  263. pVLE = CONTAINING_RECORD(pLE, VARBIND_LIST_ENTRY, Link);
  264. // release
  265. FreeVLE(pVLE);
  266. }
  267. return TRUE;
  268. }
  269. BOOL
  270. ValidateVarBinds(
  271. PNETWORK_LIST_ENTRY pNLE
  272. )
  273. /*++
  274. Routine Description:
  275. Updates error status based on query results and version.
  276. Arguments:
  277. pNLE - pointer to network list entry.
  278. Return Values:
  279. Returns true if successful.
  280. --*/
  281. {
  282. PLIST_ENTRY pLE;
  283. PVARBIND_LIST_ENTRY pVLE;
  284. // see if error has already report during processing
  285. if (pNLE->Pdu.Pdu.NormPdu.nErrorStatus == SNMP_ERRORSTATUS_NOERROR) {
  286. // point to first varbind
  287. pLE = pNLE->Bindings.Flink;
  288. // process each varbind entry
  289. while (pLE != &pNLE->Bindings) {
  290. // retrieve pointer to varbind entry from link
  291. pVLE = CONTAINING_RECORD(pLE, VARBIND_LIST_ENTRY, Link);
  292. // see if varbind has been resolved
  293. if (pVLE->nState != VARBIND_RESOLVED) {
  294. SNMPDBG((
  295. SNMP_LOG_WARNING,
  296. "SNMP: SVC: variable %d unresolved.\n",
  297. pVLE->nErrorIndex
  298. ));
  299. // report internal error has occurred
  300. pNLE->Pdu.Pdu.NormPdu.nErrorStatus = SNMP_ERRORSTATUS_GENERR;
  301. pNLE->Pdu.Pdu.NormPdu.nErrorIndex = pVLE->nErrorIndex;
  302. break; // bail...
  303. } else if (pNLE->nVersion == SNMP_VERSION_1) {
  304. // report error if exceptions are present instead of values
  305. if ((pVLE->ResolvedVb.value.asnType == SNMP_EXCEPTION_NOSUCHOBJECT) ||
  306. (pVLE->ResolvedVb.value.asnType == SNMP_EXCEPTION_NOSUCHINSTANCE) ||
  307. (pVLE->ResolvedVb.value.asnType == SNMP_EXCEPTION_ENDOFMIBVIEW)) {
  308. SNMPDBG((
  309. SNMP_LOG_WARNING,
  310. "SNMP: SVC: variable %d unresolved in SNMPv1.\n",
  311. pVLE->nErrorIndex
  312. ));
  313. // report that variable could not be found
  314. pNLE->Pdu.Pdu.NormPdu.nErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
  315. pNLE->Pdu.Pdu.NormPdu.nErrorIndex = pVLE->nErrorIndex;
  316. break; // bail...
  317. }
  318. }
  319. // next entry
  320. pLE = pLE->Flink;
  321. }
  322. }
  323. // see if this is first version
  324. if (pNLE->nVersion == SNMP_VERSION_1) {
  325. // adjust status code
  326. switch (pNLE->Pdu.Pdu.NormPdu.nErrorStatus) {
  327. case SNMP_ERRORSTATUS_NOERROR:
  328. case SNMP_ERRORSTATUS_TOOBIG:
  329. case SNMP_ERRORSTATUS_NOSUCHNAME:
  330. case SNMP_ERRORSTATUS_BADVALUE:
  331. case SNMP_ERRORSTATUS_READONLY:
  332. case SNMP_ERRORSTATUS_GENERR:
  333. break;
  334. case SNMP_ERRORSTATUS_NOACCESS:
  335. case SNMP_ERRORSTATUS_NOCREATION:
  336. case SNMP_ERRORSTATUS_NOTWRITABLE:
  337. case SNMP_ERRORSTATUS_AUTHORIZATIONERROR:
  338. case SNMP_ERRORSTATUS_INCONSISTENTNAME:
  339. pNLE->Pdu.Pdu.NormPdu.nErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
  340. break;
  341. case SNMP_ERRORSTATUS_WRONGTYPE:
  342. case SNMP_ERRORSTATUS_WRONGLENGTH:
  343. case SNMP_ERRORSTATUS_WRONGENCODING:
  344. case SNMP_ERRORSTATUS_WRONGVALUE:
  345. case SNMP_ERRORSTATUS_INCONSISTENTVALUE:
  346. pNLE->Pdu.Pdu.NormPdu.nErrorStatus = SNMP_ERRORSTATUS_BADVALUE;
  347. break;
  348. case SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE:
  349. case SNMP_ERRORSTATUS_COMMITFAILED:
  350. case SNMP_ERRORSTATUS_UNDOFAILED:
  351. default:
  352. pNLE->Pdu.Pdu.NormPdu.nErrorStatus = SNMP_ERRORSTATUS_GENERR;
  353. break;
  354. }
  355. }
  356. return (pNLE->Pdu.Pdu.NormPdu.nErrorStatus == SNMP_ERRORSTATUS_NOERROR);
  357. }
  358. BOOL
  359. UpdateVarBindsFromResolvedVb(
  360. PNETWORK_LIST_ENTRY pNLE
  361. )
  362. /*++
  363. Routine Description:
  364. Updates varbinds with results containing single varbinds.
  365. Arguments:
  366. pNLE - pointer to network list entry.
  367. Return Values:
  368. Returns true if successful.
  369. --*/
  370. {
  371. PLIST_ENTRY pLE;
  372. PVARBIND_LIST_ENTRY pVLE;
  373. // point to first varbind
  374. pLE = pNLE->Bindings.Flink;
  375. // process each varbind entry
  376. while (pLE != &pNLE->Bindings) {
  377. // retrieve pointer to varbind entry from link
  378. pVLE = CONTAINING_RECORD(pLE, VARBIND_LIST_ENTRY, Link);
  379. SNMPDBG((
  380. SNMP_LOG_TRACE,
  381. "SNMP: SVC: variable %d resolved name %s.\n",
  382. pVLE->nErrorIndex,
  383. SnmpUtilOidToA(&pVLE->ResolvedVb.name)
  384. ));
  385. // release memory for original varbind
  386. SnmpUtilVarBindFree(&pNLE->Pdu.Vbl.list[pVLE->nErrorIndex - 1]);
  387. // copy resolved varbind structure into pdu varbindlist
  388. if (SnmpUtilVarBindCpy(&pNLE->Pdu.Vbl.list[pVLE->nErrorIndex - 1],
  389. &pVLE->ResolvedVb) == 0)
  390. {
  391. SNMPDBG((
  392. SNMP_LOG_ERROR,
  393. "SNMP: SVC: could not copy resolved vb struct into pdu vbl.\n"
  394. ));
  395. return FALSE;
  396. }
  397. // next entry
  398. pLE = pLE->Flink;
  399. }
  400. // success
  401. return TRUE;
  402. }
  403. BOOL
  404. UpdateVarBindsFromResolvedVbl(
  405. PNETWORK_LIST_ENTRY pNLE
  406. )
  407. /*++
  408. Routine Description:
  409. Updates varbinds with results containing multiple varbinds.
  410. Arguments:
  411. pNLE - pointer to network list entry.
  412. Return Values:
  413. Returns true if successful.
  414. --*/
  415. {
  416. UINT nRepeaters;
  417. UINT nNonRepeaters;
  418. UINT nMaxRepetitions;
  419. UINT nIterations;
  420. UINT nVarBindsLast;
  421. UINT nVarBinds = 0;
  422. SnmpVarBind * pVarBind;
  423. PVARBIND_LIST_ENTRY pVLE;
  424. PLIST_ENTRY pLE1;
  425. PLIST_ENTRY pLE2;
  426. // retrieve getbulk parameters from pdu
  427. nNonRepeaters = pNLE->Pdu.Pdu.BulkPdu.nNonRepeaters;
  428. nMaxRepetitions = pNLE->Pdu.Pdu.BulkPdu.nMaxRepetitions;
  429. nRepeaters = (pNLE->Pdu.Vbl.len >= nNonRepeaters)
  430. ? (pNLE->Pdu.Vbl.len - nNonRepeaters)
  431. : 0
  432. ;
  433. // see if we need to expand size of varbind list
  434. if ((nRepeaters > 0) && (nMaxRepetitions > 1)) {
  435. UINT nMaxVarBinds;
  436. SnmpVarBind * pVarBinds;
  437. if (nMaxRepetitions > (UINT_MAX/nRepeaters))
  438. {
  439. SNMPDBG((
  440. SNMP_LOG_ERROR,
  441. "SNMP: SVC: arithmetic overflow: nMaxRepetitions 0x%x, nRepeaters 0x%x.\n",
  442. nMaxRepetitions, nRepeaters
  443. ));
  444. return FALSE; // bail...
  445. }
  446. if ((nMaxRepetitions * nRepeaters) > (UINT_MAX - nNonRepeaters))
  447. {
  448. SNMPDBG((
  449. SNMP_LOG_ERROR,
  450. "SNMP: SVC: arithmetic overflow: nMaxRepetitions 0x%x, nRepeaters 0x%x, nNonRepeaters 0x%x.\n",
  451. nMaxRepetitions, nRepeaters, nNonRepeaters
  452. ));
  453. return FALSE; // bail...
  454. }
  455. // calculate maximum number of varbinds possible
  456. nMaxVarBinds = nNonRepeaters + (nMaxRepetitions * nRepeaters);
  457. if (sizeof(SnmpVarBind) > (UINT_MAX/nMaxVarBinds))
  458. {
  459. SNMPDBG((
  460. SNMP_LOG_ERROR,
  461. "SNMP: SVC: arithmetic overflow: sizeof(SnmpVarBind) 0x%x, nMaxVarBinds 0x%x.\n",
  462. sizeof(SnmpVarBind), nMaxVarBinds
  463. ));
  464. return FALSE; // bail...
  465. }
  466. // BTW, we might want to restrict
  467. // (nMaxVarBinds * sizeof(SnmpVarBind)) < 65535
  468. // because this vbl has to be less than the size of udp datagram.
  469. // reallocate varbind list to fit maximum
  470. pVarBinds = SnmpUtilMemReAlloc(pNLE->Pdu.Vbl.list,
  471. nMaxVarBinds * sizeof(SnmpVarBind)
  472. );
  473. // validate pointer
  474. if (pVarBinds == NULL) {
  475. SNMPDBG((
  476. SNMP_LOG_ERROR,
  477. "SNMP: SVC: Could not re-allocate varbind list.\n"
  478. ));
  479. return FALSE; // bail...
  480. }
  481. // restore varbind pointer
  482. pNLE->Pdu.Vbl.list = pVarBinds;
  483. }
  484. // point to first varbind
  485. pLE1 = pNLE->Bindings.Flink;
  486. // process each varbind entry
  487. while (pLE1 != &pNLE->Bindings) {
  488. // retrieve pointer to varbind entry from link
  489. pVLE = CONTAINING_RECORD(pLE1, VARBIND_LIST_ENTRY, Link);
  490. // see if this is non-repeater
  491. if (pVLE->nMaxRepetitions == 1) {
  492. // release memory for original varbind
  493. SnmpUtilVarBindFree(&pNLE->Pdu.Vbl.list[nVarBinds]);
  494. // copy resolved varbind into pdu structure
  495. if (SnmpUtilVarBindCpy(&pNLE->Pdu.Vbl.list[nVarBinds],
  496. &pVLE->ResolvedVb) == 0)
  497. {
  498. SNMPDBG((
  499. SNMP_LOG_ERROR,
  500. "SNMP: SVC: could not copy resolved vb into pdu struct at line %d.\n",
  501. __LINE__
  502. ));
  503. return FALSE;
  504. }
  505. // increment
  506. nVarBinds++;
  507. } else {
  508. //
  509. // finished processing non-repeaters
  510. //
  511. break;
  512. }
  513. // next entry
  514. pLE1 = pLE1->Flink;
  515. }
  516. // initialize
  517. nIterations = 0;
  518. // store
  519. pLE2 = pLE1;
  520. // process any repeaters until max
  521. while (nIterations < nMaxRepetitions) {
  522. // restore
  523. pLE1 = pLE2;
  524. // process each varbind entry
  525. while (pLE1 != &pNLE->Bindings) {
  526. // retrieve pointer to varbind entry from link
  527. pVLE = CONTAINING_RECORD(pLE1, VARBIND_LIST_ENTRY, Link);
  528. // see if value stored in default
  529. if (pVLE->ResolvedVbl.len == 0) {
  530. // release memory for original varbind
  531. SnmpUtilVarBindFree(&pNLE->Pdu.Vbl.list[nVarBinds]);
  532. // copy resolved varbind into pdu varbind list
  533. if (SnmpUtilVarBindCpy(&pNLE->Pdu.Vbl.list[nVarBinds],
  534. &pVLE->ResolvedVb) == 0)
  535. {
  536. SNMPDBG((
  537. SNMP_LOG_ERROR,
  538. "SNMP: SVC: could not copy resolved vb into pdu vbl at line %d.\n",
  539. __LINE__
  540. ));
  541. // save varbind count processed so far
  542. pNLE->Pdu.Vbl.len = nVarBinds;
  543. return FALSE;
  544. }
  545. // increment
  546. nVarBinds++;
  547. // see if value available in this iteration
  548. } else if (pVLE->ResolvedVbl.len > nIterations) {
  549. // release memory for original varbind
  550. SnmpUtilVarBindFree(&pNLE->Pdu.Vbl.list[nVarBinds]);
  551. // copy resolved varbind into pdu varbind list
  552. if (SnmpUtilVarBindCpy(&pNLE->Pdu.Vbl.list[nVarBinds],
  553. &pVLE->ResolvedVbl.list[nIterations]) == 0)
  554. {
  555. SNMPDBG((
  556. SNMP_LOG_ERROR,
  557. "SNMP: SVC: could not copy resolved vb into pdu vbl at line %d.\n",
  558. __LINE__
  559. ));
  560. // save varbind count processed so far
  561. pNLE->Pdu.Vbl.len = nVarBinds;
  562. return FALSE;
  563. }
  564. // increment
  565. nVarBinds++;
  566. }
  567. // next entry
  568. pLE1 = pLE1->Flink;
  569. }
  570. // increment
  571. nIterations++;
  572. }
  573. // save new varbind count
  574. pNLE->Pdu.Vbl.len = nVarBinds;
  575. // success
  576. return TRUE;
  577. }
  578. BOOL
  579. UpdatePdu(
  580. PNETWORK_LIST_ENTRY pNLE,
  581. BOOL fOk
  582. )
  583. /*++
  584. Routine Description:
  585. Updates pdu with query results.
  586. Arguments:
  587. pNLE - pointer to network list entry.
  588. fOk - true if process succeeded to this point.
  589. Return Values:
  590. Returns true if successful.
  591. --*/
  592. {
  593. PLIST_ENTRY pLE;
  594. PVARBIND_LIST_ENTRY pVLE;
  595. // validate
  596. if (fOk) {
  597. // make sure varbinds valid
  598. fOk = ValidateVarBinds(pNLE);
  599. // validate
  600. if (fOk) {
  601. // see if pdu type is getnext or getbulk
  602. if (pNLE->Pdu.nType != SNMP_PDU_GETBULK) {
  603. // update varbinds with single result
  604. fOk = UpdateVarBindsFromResolvedVb(pNLE);
  605. } else {
  606. // update varbinds with multiple results
  607. fOk = UpdateVarBindsFromResolvedVbl(pNLE);
  608. }
  609. }
  610. }
  611. // trap internal errors that have not been accounted for as of yet
  612. if (!fOk && (pNLE->Pdu.Pdu.NormPdu.nErrorStatus == SNMP_ERRORSTATUS_NOERROR)) {
  613. // report status that was determined above
  614. pNLE->Pdu.Pdu.NormPdu.nErrorStatus = SNMP_ERRORSTATUS_GENERR;
  615. pNLE->Pdu.Pdu.NormPdu.nErrorIndex = 0;
  616. }
  617. if (pNLE->Pdu.Pdu.NormPdu.nErrorStatus == SNMP_ERRORSTATUS_NOERROR)
  618. {
  619. switch(pNLE->Pdu.nType)
  620. {
  621. case SNMP_PDU_GETNEXT:
  622. case SNMP_PDU_GETBULK:
  623. case SNMP_PDU_GET:
  624. // update counter for successful GET-NEXT GET-BULK
  625. mgmtCAdd(CsnmpInTotalReqVars, pNLE->Pdu.Vbl.len);
  626. break;
  627. case SNMP_PDU_SET:
  628. // update counter for successful SET
  629. mgmtCAdd(CsnmpInTotalSetVars, pNLE->Pdu.Vbl.len);
  630. break;
  631. }
  632. }
  633. else
  634. {
  635. // update here counters for all OUT errors
  636. mgmtUtilUpdateErrStatus(OUT_errStatus, pNLE->Pdu.Pdu.NormPdu.nErrorStatus);
  637. }
  638. return TRUE;
  639. }
  640. ///////////////////////////////////////////////////////////////////////////////
  641. // //
  642. // Public procedures //
  643. // //
  644. ///////////////////////////////////////////////////////////////////////////////
  645. BOOL
  646. AllocVLE(
  647. PVARBIND_LIST_ENTRY * ppVLE
  648. )
  649. /*++
  650. Routine Description:
  651. Allocates varbind structure and initializes.
  652. Arguments:
  653. ppVLE - pointer to receive pointer to entry.
  654. Return Values:
  655. Returns true if successful.
  656. --*/
  657. {
  658. BOOL fOk = FALSE;
  659. PVARBIND_LIST_ENTRY pVLE = NULL;
  660. // attempt to allocate structure
  661. pVLE = AgentMemAlloc(sizeof(VARBIND_LIST_ENTRY));
  662. // validate
  663. if (pVLE != NULL) {
  664. // success
  665. fOk = TRUE;
  666. } else {
  667. SNMPDBG((
  668. SNMP_LOG_ERROR,
  669. "SNMP: SVC: could not allocate varbind entry.\n"
  670. ));
  671. }
  672. // transfer
  673. *ppVLE = pVLE;
  674. return fOk;
  675. }
  676. BOOL
  677. FreeVLE(
  678. PVARBIND_LIST_ENTRY pVLE
  679. )
  680. /*++
  681. Routine Description:
  682. Releases varbind structure.
  683. Arguments:
  684. pVLE - pointer to list entry to be freed.
  685. Return Values:
  686. Returns true if successful.
  687. --*/
  688. {
  689. BOOL fOk = TRUE;
  690. // validate pointer
  691. if (pVLE != NULL) {
  692. // release current varbind
  693. SnmpUtilVarBindFree(&pVLE->ResolvedVb);
  694. // release current varbind list
  695. SnmpUtilVarBindListFree(&pVLE->ResolvedVbl);
  696. // release structure
  697. AgentMemFree(pVLE);
  698. }
  699. return TRUE;
  700. }
  701. BOOL
  702. ProcessVarBinds(
  703. PNETWORK_LIST_ENTRY pNLE
  704. )
  705. /*++
  706. Routine Description:
  707. Creates list of varbind entries from varbind structure.
  708. Arguments:
  709. pNLE - pointer to network list entry.
  710. Return Values:
  711. Returns true if successful.
  712. --*/
  713. {
  714. BOOL fOk = FALSE;
  715. // validate type before processing
  716. if ((pNLE->Pdu.nType == SNMP_PDU_SET) ||
  717. (pNLE->Pdu.nType == SNMP_PDU_GET) ||
  718. (pNLE->Pdu.nType == SNMP_PDU_GETNEXT) ||
  719. (pNLE->Pdu.nType == SNMP_PDU_GETBULK)) {
  720. // initialize varbinds
  721. if (LoadVarBinds(pNLE)) {
  722. // process queries
  723. fOk = ProcessQueries(pNLE);
  724. }
  725. // transfer results
  726. UpdatePdu(pNLE, fOk);
  727. // unload varbinds
  728. UnloadVarBinds(pNLE);
  729. // update management counters for accepted and processed requests
  730. switch(pNLE->Pdu.nType)
  731. {
  732. case SNMP_PDU_GET:
  733. mgmtCTick(CsnmpInGetRequests);
  734. break;
  735. case SNMP_PDU_GETNEXT:
  736. case SNMP_PDU_GETBULK:
  737. mgmtCTick(CsnmpInGetNexts);
  738. break;
  739. case SNMP_PDU_SET:
  740. mgmtCTick(CsnmpInSetRequests);
  741. break;
  742. }
  743. } else {
  744. SNMPDBG((
  745. SNMP_LOG_ERROR,
  746. "SNMP: SVC: ignoring unknown pdu type %d.\n",
  747. pNLE->Pdu.nType
  748. ));
  749. }
  750. return fOk;
  751. }