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.

407 lines
9.3 KiB

  1. /*++
  2. Copyright (c) 1992-1997 Microsoft Corporation
  3. Module Name:
  4. oid.c
  5. Abstract:
  6. Contains routines to manipulatee object identifiers.
  7. SnmpUtilOidCpy
  8. SnmpUtilOidAppend
  9. SnmpUtilOidNCmp
  10. SnmpUtilOidCmp
  11. SnmpUtilOidFree
  12. Environment:
  13. User Mode - Win32
  14. Revision History:
  15. --*/
  16. ///////////////////////////////////////////////////////////////////////////////
  17. // //
  18. // Include files //
  19. // //
  20. ///////////////////////////////////////////////////////////////////////////////
  21. #include <snmp.h>
  22. #include <snmputil.h>
  23. #include <limits.h>
  24. ///////////////////////////////////////////////////////////////////////////////
  25. // //
  26. // Public Procedures //
  27. // //
  28. ///////////////////////////////////////////////////////////////////////////////
  29. SNMPAPI
  30. SNMP_FUNC_TYPE
  31. SnmpUtilOidCpy(
  32. AsnObjectIdentifier * pOidDst,
  33. AsnObjectIdentifier * pOidSrc
  34. )
  35. /*++
  36. Routine Description:
  37. Copy an object identifier.
  38. Arguments:
  39. pOidDst - pointer to structure to receive OID.
  40. pOidSrc - pointer to OID to copy.
  41. Return Values:
  42. Returns SNMPAPI_NOERROR if successful.
  43. --*/
  44. {
  45. SNMPAPI nResult = SNMPAPI_ERROR;
  46. // validate pointers
  47. if (pOidDst != NULL) {
  48. // initialize
  49. pOidDst->ids = NULL;
  50. pOidDst->idLength = 0;
  51. // check for subids
  52. if ((pOidSrc != NULL) &&
  53. (pOidSrc->ids != NULL) &&
  54. (pOidSrc->idLength != 0)) {
  55. // check for arithmetic overflow
  56. if (pOidSrc->idLength > UINT_MAX/sizeof(UINT)) {
  57. SNMPDBG((
  58. SNMP_LOG_ERROR,
  59. "SNMP: API: pOidSrc->idLength 0x%x will overflow.\n",
  60. pOidSrc->idLength
  61. ));
  62. SetLastError(SNMP_MEM_ALLOC_ERROR);
  63. return nResult;
  64. }
  65. // attempt to allocate the subids
  66. pOidDst->ids = (UINT *)SnmpUtilMemAlloc(
  67. pOidSrc->idLength * sizeof(UINT)
  68. );
  69. // validate pointer
  70. if (pOidDst->ids != NULL) {
  71. // transfer the oid length
  72. pOidDst->idLength = pOidSrc->idLength;
  73. // transfer subids
  74. memcpy(pOidDst->ids,
  75. pOidSrc->ids,
  76. pOidSrc->idLength * sizeof(UINT)
  77. );
  78. nResult = SNMPAPI_NOERROR; // success...
  79. } else {
  80. SNMPDBG((
  81. SNMP_LOG_ERROR,
  82. "SNMP: API: could not allocate oid.\n"
  83. ));
  84. SetLastError(SNMP_MEM_ALLOC_ERROR);
  85. }
  86. } else {
  87. SNMPDBG((
  88. SNMP_LOG_WARNING,
  89. "SNMP: API: copying a null oid.\n"
  90. ));
  91. nResult = SNMPAPI_NOERROR; // success...
  92. }
  93. } else {
  94. SNMPDBG((
  95. SNMP_LOG_ERROR,
  96. "SNMP: API: null oid pointer during copy.\n"
  97. ));
  98. SetLastError(ERROR_INVALID_PARAMETER);
  99. }
  100. return nResult;
  101. }
  102. SNMPAPI
  103. SNMP_FUNC_TYPE
  104. SnmpUtilOidAppend(
  105. AsnObjectIdentifier * pOidDst,
  106. AsnObjectIdentifier * pOidSrc
  107. )
  108. /*++
  109. Routine Description:
  110. Append source OID to destination OID
  111. Arguments:
  112. pOidDst - pointer to structure to receive combined OID.
  113. pOidSrc - pointer to OID to append.
  114. Return Values:
  115. Returns SNMPAPI_NOERROR if successful.
  116. --*/
  117. {
  118. SNMPAPI nResult = SNMPAPI_ERROR;
  119. // validate pointers
  120. if (pOidDst != NULL) {
  121. // check if there are subids
  122. if ((pOidSrc != NULL) &&
  123. (pOidSrc->ids != NULL) &&
  124. (pOidSrc->idLength != 0)) {
  125. // calculate the total number of subidentifiers
  126. UINT nIds;
  127. // check for arithmetic overflow
  128. if (pOidDst->idLength > (UINT_MAX - pOidSrc->idLength)) {
  129. SNMPDBG((
  130. SNMP_LOG_ERROR,
  131. "SNMP: API: combined oid too large. Dst oid len 0x%x, Src oid len 0x%x.\n",
  132. pOidDst->idLength, pOidSrc->idLength
  133. ));
  134. SetLastError(SNMP_BERAPI_OVERFLOW);
  135. return nResult;
  136. }
  137. nIds = pOidDst->idLength + pOidSrc->idLength;
  138. // validate number of subids
  139. if (nIds <= SNMP_MAX_OID_LEN) {
  140. // attempt to allocate the subidentifiers
  141. UINT * pIds = (UINT *)SnmpUtilMemReAlloc(
  142. pOidDst->ids,
  143. nIds * sizeof(UINT)
  144. );
  145. // validate pointer
  146. if (pIds != NULL) {
  147. // transfer pointer
  148. pOidDst->ids = pIds;
  149. // transfer subids
  150. memcpy(&pOidDst->ids[pOidDst->idLength],
  151. pOidSrc->ids,
  152. pOidSrc->idLength * sizeof(UINT)
  153. );
  154. // transfer oid length
  155. pOidDst->idLength = nIds;
  156. nResult = SNMPAPI_NOERROR; // success...
  157. } else {
  158. SNMPDBG((
  159. SNMP_LOG_ERROR,
  160. "SNMP: API: could not allocate oid.\n"
  161. ));
  162. SetLastError(SNMP_MEM_ALLOC_ERROR);
  163. }
  164. } else {
  165. SNMPDBG((
  166. SNMP_LOG_ERROR,
  167. "SNMP: API: combined oid too large.\n"
  168. ));
  169. SetLastError(SNMP_BERAPI_OVERFLOW);
  170. }
  171. } else {
  172. SNMPDBG((
  173. SNMP_LOG_WARNING,
  174. "SNMP: API: appending a null oid.\n"
  175. ));
  176. nResult = SNMPAPI_NOERROR; // success...
  177. }
  178. } else {
  179. SNMPDBG((
  180. SNMP_LOG_ERROR,
  181. "SNMP: API: null oid pointer during copy.\n"
  182. ));
  183. SetLastError(ERROR_INVALID_PARAMETER);
  184. }
  185. return nResult;
  186. }
  187. SNMPAPI
  188. SNMP_FUNC_TYPE
  189. SnmpUtilOidNCmp(
  190. AsnObjectIdentifier * pOid1,
  191. AsnObjectIdentifier * pOid2,
  192. UINT nSubIds
  193. )
  194. /*++
  195. Routine Description:
  196. Compares two OIDs up to a certain subidentifier.
  197. Arguments:
  198. pOid1 - pointer to first OID.
  199. pOid2 - pointer to second OID.
  200. nSubIds - maximum subidentifiers to compare.
  201. Return Values:
  202. < 0 first parameter is 'less than' second.
  203. 0 first parameter is 'equal to' second.
  204. > 0 first parameter is 'greater than' second.
  205. --*/
  206. {
  207. UINT i = 0;
  208. // INT nResult = 0;
  209. // validate pointers
  210. if ((pOid1 != NULL) &&
  211. (pOid2 != NULL)) {
  212. // calculate maximum number of subidentifiers to compare
  213. UINT nMaxIds = min(nSubIds, min(pOid1->idLength, pOid2->idLength));
  214. while(i < nMaxIds)
  215. {
  216. if (pOid1->ids[i] != pOid2->ids[i])
  217. break;
  218. i++;
  219. }
  220. // comparision length less than either OID lengths; components equals
  221. if (i == nSubIds)
  222. return 0;
  223. // difference encountered before either OID endings and before the
  224. // requested comparision length
  225. if (i < nMaxIds)
  226. return (pOid1->ids[i] < pOid2->ids[i])? -1 : 1;
  227. // one OID is shorter than the requested comparision length
  228. return pOid1->idLength - pOid2->idLength;
  229. }
  230. return 0;
  231. }
  232. SNMPAPI
  233. SNMP_FUNC_TYPE
  234. SnmpUtilOidCmp(
  235. AsnObjectIdentifier * pOid1,
  236. AsnObjectIdentifier * pOid2
  237. )
  238. /*++
  239. Routine Description:
  240. Compares two OIDs.
  241. Arguments:
  242. pOid1 - pointer to first OID.
  243. pOid2 - pointer to second OID.
  244. Return Values:
  245. < 0 first parameter is 'less than' second.
  246. 0 first parameter is 'equal to' second.
  247. > 0 first parameter is 'greater than' second.
  248. --*/
  249. {
  250. // forward request to the function above
  251. return SnmpUtilOidNCmp(pOid1,pOid2,max(pOid1->idLength,pOid2->idLength));
  252. }
  253. VOID
  254. SNMP_FUNC_TYPE
  255. SnmpUtilOidFree(
  256. AsnObjectIdentifier * pOid
  257. )
  258. /*++
  259. Routine Description:
  260. Releases memory associated with OID.
  261. Arguments:
  262. pOid - pointer to OID to free.
  263. Return Values:
  264. None.
  265. --*/
  266. {
  267. // validate
  268. if (pOid != NULL) {
  269. // release subids memory
  270. SnmpUtilMemFree(pOid->ids);
  271. // re-initialize
  272. pOid->idLength = 0;
  273. pOid->ids = NULL;
  274. }
  275. }