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.

574 lines
17 KiB

  1. // wsnmp_ec.c
  2. //
  3. // WinSNMP Entity/Context 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. // 980424 - BobN
  10. // - Mods to SnmpStrToEntity() to support corresponding
  11. // - mods to SnmpStrToIpxAddress() to permit '.' char as
  12. // - netnum/nodenum separator
  13. // 970310 - Typographical changes
  14. //
  15. #include "winsnmp.inc"
  16. SNMPAPI_STATUS SNMPAPI_CALL SnmpStrToIpxAddress (LPCSTR, LPBYTE, LPBYTE);
  17. // SnmpStrToEntity
  18. HSNMP_ENTITY SNMPAPI_CALL
  19. SnmpStrToEntity (IN HSNMP_SESSION hSession,
  20. IN LPCSTR entityString)
  21. {
  22. DWORD strLen;
  23. LPCSTR tstStr;
  24. LPSTR profilePtr;
  25. LPSTR comma = ",";
  26. DWORD nEntity;
  27. SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
  28. HSNMP_SESSION lSession = 0;
  29. char profileBuf[MAX_PATH];
  30. LPENTITY pEntity;
  31. if (TaskData.hTask == 0)
  32. {
  33. lError = SNMPAPI_NOT_INITIALIZED;
  34. goto ERROR_OUT;
  35. }
  36. if (!snmpValidTableEntry(&SessDescr, HandleToUlong(hSession)-1))
  37. {
  38. lError = SNMPAPI_SESSION_INVALID;
  39. goto ERROR_OUT;
  40. }
  41. // We have a valid session at this point...
  42. lSession = hSession; // save it for possible error return
  43. if (!entityString || (strLen = lstrlen(entityString)) == 0)
  44. {
  45. lError = SNMPAPI_ALLOC_ERROR;
  46. goto ERROR_OUT;
  47. }
  48. // Must go through ERROR_PRECHECK label after next statement...
  49. EnterCriticalSection (&cs_ENTITY);
  50. // Search for Entity table entry to use
  51. lError = snmpAllocTableEntry(&EntsDescr, &nEntity);
  52. if (lError != SNMPAPI_SUCCESS)
  53. goto ERROR_PRECHECK;
  54. pEntity = snmpGetTableEntry(&EntsDescr, nEntity);
  55. pEntity->version = 0;
  56. pEntity->nPolicyTimeout = DEFTIMEOUT;
  57. pEntity->nPolicyRetry = DEFRETRY;
  58. if (strLen > MAX_FRIEND_NAME_LEN)
  59. strLen = MAX_FRIEND_NAME_LEN;
  60. switch (TaskData.nTranslateMode)
  61. {
  62. case SNMPAPI_TRANSLATED:
  63. // the entity is picked up from NP_WSNMP.INI, from [Entities] section:
  64. // [Entities]
  65. // EntityFriendlyName = ver#, ipaddr, timeout#, retries#, port#[,]
  66. // ------
  67. // Get the whole buffer
  68. if (!GetPrivateProfileString ("Entities", entityString, "",
  69. profileBuf, sizeof(profileBuf)/sizeof(profileBuf[0]), "NP_WSNMP.INI"))
  70. {
  71. snmpFreeTableEntry(&EntsDescr, nEntity);
  72. lError = SNMPAPI_ENTITY_UNKNOWN;
  73. goto ERROR_PRECHECK;
  74. }
  75. // pick up the ver# first (mandatory)
  76. profilePtr = strtok (profileBuf, comma);
  77. // if no token, is like we have a key with no value
  78. // bail out with SNMPAPI_NOOP
  79. if (profilePtr == NULL)
  80. {
  81. snmpFreeTableEntry(&EntsDescr, nEntity);
  82. lError = SNMPAPI_NOOP;
  83. goto ERROR_PRECHECK;
  84. }
  85. pEntity->version = atoi (profilePtr);
  86. // pick up the dotted ip address (mandatory)
  87. tstStr = strtok (NULL, comma); // Save real address string
  88. // if no address is specified, we don't have the vital info, so there's nothing to do
  89. // bail with SNMPAPI_NOOP
  90. if (tstStr == NULL)
  91. {
  92. snmpFreeTableEntry(&EntsDescr, nEntity);
  93. lError = SNMPAPI_NOOP;
  94. goto ERROR_PRECHECK;
  95. }
  96. // pick up the timeout# (optional)
  97. if (profilePtr = strtok (NULL, comma))
  98. {
  99. // The local database entry uses milliseconds for the timeout interval
  100. pEntity->nPolicyTimeout = atol (profilePtr);
  101. // Adjust for centiseconds, as used by the WinSNMP API
  102. pEntity->nPolicyTimeout /= 10;
  103. // pick up the retry# (optional)
  104. if (profilePtr = strtok (NULL, comma))
  105. {
  106. pEntity->nPolicyRetry = atol (profilePtr);
  107. // pick up the port# (optional)
  108. if (profilePtr = strtok (NULL, comma))
  109. pEntity->addr.inet.sin_port = htons ((short)atoi (profilePtr));
  110. }
  111. }
  112. break;
  113. // "version" was set to 0 above
  114. // if _V2, it will be incremented twice
  115. // if _V1, it will be incremented only once
  116. case SNMPAPI_UNTRANSLATED_V2:
  117. pEntity->version++;
  118. case SNMPAPI_UNTRANSLATED_V1:
  119. pEntity->version++;
  120. tstStr = entityString; // Save real address string
  121. break;
  122. default:
  123. snmpFreeTableEntry(&EntsDescr, nEntity);
  124. lError = SNMPAPI_MODE_INVALID;
  125. goto ERROR_PRECHECK;
  126. } // end_switch
  127. CopyMemory (pEntity->name, entityString, strLen);
  128. pEntity->name[strLen] = '\0'; // null terminated, name has size of MAX_FRIEND_NAME_LEN+1
  129. if (strncmp(tstStr, "255.255.255.255", 15) && inet_addr (tstStr) == INADDR_NONE)
  130. { // Not AF_INET, try AF_IPX
  131. if (SnmpStrToIpxAddress (tstStr,
  132. pEntity->addr.ipx.sa_netnum,
  133. pEntity->addr.ipx.sa_nodenum) == SNMPAPI_FAILURE)
  134. {
  135. snmpFreeTableEntry(&EntsDescr, nEntity);
  136. LeaveCriticalSection (&cs_ENTITY);
  137. return ((HSNMP_ENTITY) ULongToPtr(SaveError (hSession, SNMPAPI_ENTITY_UNKNOWN)));
  138. }
  139. pEntity->addr.ipx.sa_family = AF_IPX;
  140. if (pEntity->addr.ipx.sa_socket == 0)
  141. pEntity->addr.ipx.sa_socket = htons (IPX_SNMP_PORT);
  142. }
  143. else
  144. { // AF_INET
  145. pEntity->addr.inet.sin_family = AF_INET;
  146. if (pEntity->addr.inet.sin_port == 0)
  147. pEntity->addr.inet.sin_port = htons (IP_SNMP_PORT);
  148. pEntity->addr.inet.sin_addr.s_addr = inet_addr (tstStr);
  149. }
  150. // Record the creating session
  151. pEntity->Session = hSession;
  152. // Initialize refCount for SnmpFreeEntity garbage collection
  153. pEntity->refCount = 1;
  154. ERROR_PRECHECK:
  155. LeaveCriticalSection (&cs_ENTITY);
  156. ERROR_OUT:
  157. if (lError == SNMPAPI_SUCCESS)
  158. return ((HSNMP_ENTITY) ULongToPtr(nEntity+1));
  159. else // Failure cases
  160. return ((HSNMP_ENTITY) ULongToPtr(SaveError (lSession, lError)));
  161. } //end_SnmpStrToEntity
  162. // SnmpEntityToStr
  163. SNMPAPI_STATUS SNMPAPI_CALL
  164. SnmpEntityToStr (IN HSNMP_ENTITY hEntity,
  165. IN smiUINT32 size,
  166. OUT LPSTR string)
  167. {
  168. DWORD nEntity = HandleToUlong(hEntity) - 1;
  169. SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
  170. HSNMP_SESSION lSession = 0;
  171. LPSTR str;
  172. smiUINT32 len;
  173. char tmpStr[24];
  174. LPENTITY pEntity;
  175. if (TaskData.hTask == 0)
  176. {
  177. lError = SNMPAPI_NOT_INITIALIZED;
  178. goto ERROR_OUT;
  179. }
  180. if (!snmpValidTableEntry(&EntsDescr, nEntity))
  181. {
  182. lError = SNMPAPI_ENTITY_UNKNOWN;
  183. goto ERROR_OUT;
  184. }
  185. pEntity = snmpGetTableEntry(&EntsDescr, nEntity);
  186. lSession = pEntity->Session;
  187. if (size == 0)
  188. {
  189. lError = SNMPAPI_SIZE_INVALID;
  190. goto ERROR_OUT;
  191. }
  192. if (IsBadWritePtr(string, size))
  193. {
  194. lError = SNMPAPI_ALLOC_ERROR;
  195. goto ERROR_OUT;
  196. }
  197. len = 0;
  198. if (TaskData.nTranslateMode == SNMPAPI_TRANSLATED)
  199. {
  200. str = pEntity->name;
  201. len = lstrlen (str);
  202. }
  203. else
  204. {
  205. if (pEntity->addr.inet.sin_family == AF_INET)
  206. {
  207. // prefix bug 445174
  208. if ((str = inet_ntoa (pEntity->addr.inet.sin_addr)) != NULL)
  209. len = lstrlen (str);
  210. else
  211. {
  212. lError = SNMPAPI_OTHER_ERROR; // error in inet_ntoa call
  213. goto ERROR_OUT;
  214. }
  215. }
  216. else if (pEntity->addr.ipx.sa_family == AF_IPX)
  217. {
  218. SnmpIpxAddressToStr (pEntity->addr.ipx.sa_netnum,
  219. pEntity->addr.ipx.sa_nodenum,
  220. tmpStr);
  221. str = tmpStr;
  222. len = lstrlen (str);
  223. }
  224. else
  225. {
  226. lError = SNMPAPI_ENTITY_INVALID;
  227. goto ERROR_OUT;
  228. }
  229. }
  230. if (len >= size)
  231. {
  232. CopyMemory (string, str, size);
  233. string[size-1] = '\0';
  234. lError = SNMPAPI_OUTPUT_TRUNCATED;
  235. goto ERROR_OUT;
  236. }
  237. else
  238. {
  239. lstrcpy (string, str);
  240. return (len+1);
  241. }
  242. // Failure cases
  243. ERROR_OUT:
  244. return (SaveError (lSession, lError));
  245. } // End_SnmpEntityToStr
  246. // SnmpFreeEntity
  247. SNMPAPI_STATUS SNMPAPI_CALL
  248. SnmpFreeEntity (IN HSNMP_ENTITY hEntity)
  249. {
  250. DWORD nEntity;
  251. SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
  252. LPENTITY pEntity;
  253. if (TaskData.hTask == 0)
  254. {
  255. lError = SNMPAPI_NOT_INITIALIZED;
  256. goto ERROR_OUT;
  257. }
  258. nEntity = HandleToUlong(hEntity) - 1;
  259. if (!snmpValidTableEntry(&EntsDescr, nEntity))
  260. {
  261. lError = SNMPAPI_ENTITY_INVALID;
  262. goto ERROR_OUT;
  263. }
  264. pEntity = snmpGetTableEntry(&EntsDescr, nEntity);
  265. EnterCriticalSection (&cs_ENTITY);
  266. // Decrement refCount (unless already 0 [error])
  267. if (pEntity->refCount)
  268. pEntity->refCount--;
  269. // Now actually free it...
  270. if (pEntity->Agent == 0 && // but not if it's an Agent
  271. pEntity->refCount == 0) // nor if other references exist
  272. snmpFreeTableEntry(&EntsDescr, nEntity);
  273. LeaveCriticalSection (&cs_ENTITY);
  274. return (SNMPAPI_SUCCESS);
  275. ERROR_OUT:
  276. return (SaveError (0, lError));
  277. }
  278. // SnmpStrToContext
  279. // Allow for zero-length/NULL context...BN 3/12/96
  280. HSNMP_CONTEXT SNMPAPI_CALL
  281. SnmpStrToContext (IN HSNMP_SESSION hSession,
  282. IN smiLPCOCTETS contextString)
  283. {
  284. DWORD strLen;
  285. DWORD nContext;
  286. SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
  287. HSNMP_SESSION lSession = 0;
  288. char profileBuf[MAX_PATH];
  289. LPSTR profilePtr;
  290. LPSTR comma = ",";
  291. LPCTXT pCtxt;
  292. smiOCTETS tmpContextString;
  293. tmpContextString.len = 0;
  294. tmpContextString.ptr = NULL;
  295. if (TaskData.hTask == 0)
  296. {
  297. lError = SNMPAPI_NOT_INITIALIZED;
  298. goto ERROR_OUT;
  299. }
  300. if (!snmpValidTableEntry(&SessDescr, HandleToUlong(hSession)-1))
  301. {
  302. lError = SNMPAPI_SESSION_INVALID;
  303. goto ERROR_OUT;
  304. }
  305. lSession = hSession; // Save for possible error return
  306. if (IsBadReadPtr (contextString, sizeof(smiOCTETS)))
  307. {
  308. lError = SNMPAPI_ALLOC_ERROR;
  309. goto ERROR_OUT;
  310. }
  311. if (IsBadReadPtr (contextString->ptr, contextString->len))
  312. {
  313. lError = SNMPAPI_CONTEXT_INVALID;
  314. goto ERROR_OUT;
  315. }
  316. // Remember to allow for 0-len contexts (as above does)
  317. EnterCriticalSection (&cs_CONTEXT);
  318. // Search for Entity table entry to use
  319. lError = snmpAllocTableEntry(&CntxDescr, &nContext);
  320. if (lError != SNMPAPI_SUCCESS)
  321. goto ERROR_PRECHECK;
  322. pCtxt = snmpGetTableEntry(&CntxDescr, nContext);
  323. pCtxt->version = 0; // just to be sure
  324. pCtxt->name[0] = pCtxt->commStr[0] = '\0';
  325. // Following "if" test allows for zero-length/NULL community string
  326. // (deliberate assignment in conditional...)
  327. if (pCtxt->commLen = contextString->len)
  328. {
  329. switch (TaskData.nTranslateMode)
  330. {
  331. case SNMPAPI_TRANSLATED:
  332. // make a copy of input parameter to make sure the raw data is null terminated
  333. tmpContextString.ptr = (smiLPBYTE) GlobalAlloc(GPTR, contextString->len + 2);
  334. if (tmpContextString.ptr == NULL)
  335. {
  336. snmpFreeTableEntry(&CntxDescr, nContext);
  337. lError = SNMPAPI_ALLOC_ERROR;
  338. goto ERROR_PRECHECK;
  339. }
  340. tmpContextString.len = contextString->len;
  341. CopyMemory(tmpContextString.ptr, contextString->ptr, contextString->len);
  342. if (!GetPrivateProfileString ("Contexts", tmpContextString.ptr, "",
  343. profileBuf, sizeof(profileBuf)/sizeof(profileBuf[0]), "NP_WSNMP.INI"))
  344. {
  345. snmpFreeTableEntry(&CntxDescr, nContext);
  346. lError = SNMPAPI_CONTEXT_UNKNOWN;
  347. goto ERROR_PRECHECK;
  348. }
  349. strLen = min(contextString->len, MAX_FRIEND_NAME_LEN);
  350. CopyMemory (pCtxt->name, contextString->ptr, strLen);
  351. pCtxt->name[strLen] = '\0'; // name is size of MAX_FRIEND_NAME_LEN+1
  352. // pick up the version# for this context (mandatory)
  353. profilePtr = strtok (profileBuf, comma);
  354. // if there is no such version# is like we have a INI key without its value,
  355. // so bail out with SNMPAPI_NOOP
  356. if (profilePtr == NULL)
  357. {
  358. snmpFreeTableEntry(&CntxDescr, nContext);
  359. lError = SNMPAPI_NOOP;
  360. goto ERROR_PRECHECK;
  361. }
  362. pCtxt->version = (DWORD) atoi (profilePtr);
  363. // pick up the actual context value (mandatory)
  364. profilePtr = strtok (NULL, comma);
  365. // if there is no such value, is like we have the friendly name but this is malformed
  366. // and doesn't point to any actual context.
  367. // bail out with SNMPAPI_NOOP
  368. if (profilePtr == NULL)
  369. {
  370. snmpFreeTableEntry(&CntxDescr, nContext);
  371. lError = SNMPAPI_NOOP;
  372. goto ERROR_PRECHECK;
  373. }
  374. strLen = min(lstrlen (profilePtr), MAX_CONTEXT_LEN);
  375. pCtxt->commLen = strLen;
  376. CopyMemory (pCtxt->commStr, profilePtr, strLen);
  377. break;
  378. // "version" was set to 0 above
  379. // if _V2, it will be incremented twice
  380. // if _V1, it will be incremented only once
  381. case SNMPAPI_UNTRANSLATED_V2:
  382. pCtxt->version++;
  383. case SNMPAPI_UNTRANSLATED_V1:
  384. pCtxt->version++;
  385. strLen = min(contextString->len, MAX_CONTEXT_LEN);
  386. pCtxt->commLen = strLen; // updates the len of the commStr
  387. CopyMemory (pCtxt->commStr, contextString->ptr, strLen);
  388. break;
  389. default:
  390. snmpFreeTableEntry(&CntxDescr, nContext);
  391. lError = SNMPAPI_MODE_INVALID;
  392. goto ERROR_PRECHECK;
  393. } // end_switch
  394. // Remember that NULL community strings are allowed!
  395. } // end_if (on len)
  396. // Record the creating session value
  397. pCtxt->Session = hSession;
  398. // Initialize refCount for SnmpFreeContext garbage collection
  399. pCtxt->refCount = 1;
  400. ERROR_PRECHECK:
  401. LeaveCriticalSection (&cs_CONTEXT);
  402. if (tmpContextString.ptr)
  403. GlobalFree(tmpContextString.ptr);
  404. if (lError == SNMPAPI_SUCCESS)
  405. return ((HSNMP_CONTEXT) ULongToPtr(nContext+1));
  406. ERROR_OUT:
  407. return ((HSNMP_CONTEXT) ULongToPtr(SaveError(lSession, lError)));
  408. } // end_SnmpStrToContext
  409. // SnmpContextToStr
  410. // Revised to allow for zero-length/NULL context...BN 3/12/96
  411. SNMPAPI_STATUS SNMPAPI_CALL
  412. SnmpContextToStr (IN HSNMP_CONTEXT hContext,
  413. OUT smiLPOCTETS string)
  414. {
  415. smiUINT32 len;
  416. smiLPBYTE str;
  417. DWORD nCtx;
  418. SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
  419. HSNMP_SESSION lSession = 0;
  420. LPCTXT pCtxt;
  421. if (TaskData.hTask == 0)
  422. {
  423. lError = SNMPAPI_NOT_INITIALIZED;
  424. goto ERROR_OUT;
  425. }
  426. nCtx = HandleToUlong(hContext) - 1;
  427. if (!snmpValidTableEntry(&CntxDescr, nCtx))
  428. {
  429. lError = SNMPAPI_CONTEXT_INVALID;
  430. goto ERROR_OUT;
  431. }
  432. pCtxt = snmpGetTableEntry(&CntxDescr, nCtx);
  433. // save session for possible error return
  434. lSession = pCtxt->Session;
  435. if (IsBadWritePtr(string, sizeof(smiLPOCTETS)))
  436. {
  437. lError = string == NULL ? SNMPAPI_NOOP : SNMPAPI_ALLOC_ERROR;
  438. goto ERROR_OUT;
  439. }
  440. switch (TaskData.nTranslateMode)
  441. {
  442. case SNMPAPI_TRANSLATED:
  443. str = pCtxt->name;
  444. len = lstrlen (str);
  445. // If calling mode is TRANSLATED, and friendly value was stored,
  446. if (len)
  447. // then we are done here.
  448. break;
  449. // If calling mode is TRANSLATED, but no value stored,
  450. // then fall through to UNTRANSLATED default...
  451. case SNMPAPI_UNTRANSLATED_V1:
  452. case SNMPAPI_UNTRANSLATED_V2:
  453. str = pCtxt->commStr;
  454. len = pCtxt->commLen;
  455. break;
  456. default:
  457. lError = SNMPAPI_MODE_INVALID;
  458. goto ERROR_OUT;
  459. }
  460. // Setup for possible zero-length/NULL context return
  461. string->ptr = NULL;
  462. // (deliberate assignment in conditional...)
  463. if (string->len = len)
  464. {
  465. // App must free following alloc via SnmpFreeDescriptor()
  466. if (!(string->ptr = (smiLPBYTE)GlobalAlloc (GPTR, len)))
  467. {
  468. lError = SNMPAPI_ALLOC_ERROR;
  469. goto ERROR_OUT;
  470. }
  471. CopyMemory (string->ptr, str, len);
  472. }
  473. return (SNMPAPI_SUCCESS);
  474. ERROR_OUT:
  475. return (SaveError (lSession, lError));
  476. } // end_SnmpContextToStr()
  477. // SnmpFreeContext
  478. SNMPAPI_STATUS SNMPAPI_CALL
  479. SnmpFreeContext (IN HSNMP_CONTEXT hContext)
  480. {
  481. DWORD nCtx;
  482. SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
  483. LPCTXT pCtxt;
  484. if (TaskData.hTask == 0)
  485. {
  486. lError = SNMPAPI_NOT_INITIALIZED;
  487. goto ERROR_OUT;
  488. }
  489. nCtx = HandleToUlong(hContext) - 1;
  490. if (!snmpValidTableEntry(&CntxDescr, nCtx))
  491. {
  492. lError = SNMPAPI_CONTEXT_INVALID;
  493. goto ERROR_OUT;
  494. }
  495. pCtxt = snmpGetTableEntry(&CntxDescr, nCtx);
  496. EnterCriticalSection (&cs_CONTEXT);
  497. // Decrement refCount (unless already 0 [error])
  498. if (pCtxt->refCount)
  499. pCtxt->refCount--;
  500. // Now test refCount again
  501. if (pCtxt->refCount == 0)
  502. snmpFreeTableEntry(&CntxDescr, nCtx);
  503. LeaveCriticalSection (&cs_CONTEXT);
  504. return (SNMPAPI_SUCCESS);
  505. ERROR_OUT:
  506. return (SaveError (0, lError));
  507. }
  508. // SnmpSetPort
  509. SNMPAPI_STATUS SNMPAPI_CALL
  510. SnmpSetPort (IN HSNMP_ENTITY hEntity,
  511. IN UINT port)
  512. {
  513. DWORD nEntity;
  514. SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
  515. LPENTITY pEntity;
  516. if (TaskData.hTask == 0)
  517. {
  518. lError = SNMPAPI_NOT_INITIALIZED;
  519. goto ERROR_OUT;
  520. }
  521. nEntity = HandleToUlong(hEntity) - 1;
  522. if (!snmpValidTableEntry(&EntsDescr, nEntity))
  523. {
  524. lError = SNMPAPI_ENTITY_INVALID;
  525. goto ERROR_OUT;
  526. }
  527. pEntity = snmpGetTableEntry(&EntsDescr, nEntity);
  528. EnterCriticalSection (&cs_ENTITY);
  529. if (pEntity->Agent)
  530. { // Entity running as agent, cannot change port now
  531. lError = SNMPAPI_OPERATION_INVALID;
  532. goto ERROR_PRECHECK;
  533. }
  534. pEntity->addr.inet.sin_port = htons ((WORD)port);
  535. ERROR_PRECHECK:
  536. LeaveCriticalSection (&cs_ENTITY);
  537. if (lError == SNMPAPI_SUCCESS)
  538. return (SNMPAPI_SUCCESS);
  539. ERROR_OUT:
  540. return (SaveError (0, lError));
  541. } // end_SnmpSetPort()