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.

854 lines
19 KiB

  1. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  2. /*---------------------------------------------------------
  3. Filename: value.cpp
  4. Written By: B.Rajeev
  5. ----------------------------------------------------------*/
  6. #include "precomp.h"
  7. #include <typeinfo.h>
  8. #include "common.h"
  9. #include "address.h"
  10. #include "value.h"
  11. #define MAX_FIELDS 100
  12. #define FIELD_SEPARATOR '.'
  13. BOOL SnmpNull :: Equivalent (IN const SnmpValue &value) const
  14. {
  15. BOOL bResult = FALSE;
  16. if (typeid(*this) == typeid(value))
  17. {
  18. bResult = TRUE;
  19. }
  20. return bResult;
  21. }
  22. // Copy constructor
  23. SnmpInteger::SnmpInteger ( IN const SnmpInteger &value )
  24. {
  25. val = value.GetValue();
  26. }
  27. BOOL SnmpInteger :: Equivalent (IN const SnmpValue &value) const
  28. {
  29. BOOL bResult = FALSE;
  30. if (typeid(*this) == typeid(value))
  31. {
  32. bResult = Equivalent((const SnmpInteger &)value);
  33. }
  34. return bResult;
  35. }
  36. LONG SnmpInteger::GetValue () const
  37. {
  38. return val;
  39. }
  40. void SnmpInteger::SetValue ( IN const LONG value )
  41. {
  42. val = value;
  43. }
  44. SnmpValue *SnmpInteger::Copy () const
  45. {
  46. return new SnmpInteger(val);
  47. }
  48. // Copy constructor
  49. SnmpGauge::SnmpGauge ( IN const SnmpGauge &value )
  50. {
  51. val = value.GetValue();
  52. }
  53. BOOL SnmpGauge :: Equivalent (IN const SnmpValue &value) const
  54. {
  55. BOOL bResult = FALSE;
  56. if (typeid(*this) == typeid(value))
  57. {
  58. bResult = Equivalent((const SnmpGauge &)value);
  59. }
  60. return bResult;
  61. }
  62. ULONG SnmpGauge::GetValue () const
  63. {
  64. return val;
  65. }
  66. void SnmpGauge::SetValue ( IN const ULONG value )
  67. {
  68. val = value;
  69. }
  70. SnmpValue *SnmpGauge::Copy () const
  71. {
  72. return new SnmpGauge(val);
  73. }
  74. // Copy constructor
  75. SnmpCounter::SnmpCounter ( IN const SnmpCounter &value )
  76. {
  77. val = value.GetValue();
  78. }
  79. BOOL SnmpCounter :: Equivalent (IN const SnmpValue &value) const
  80. {
  81. BOOL bResult = FALSE;
  82. if (typeid(*this) == typeid(value))
  83. {
  84. bResult = Equivalent((const SnmpCounter &)value);
  85. }
  86. return bResult;
  87. }
  88. ULONG SnmpCounter::GetValue () const
  89. {
  90. return val;
  91. }
  92. void SnmpCounter::SetValue ( IN const ULONG value )
  93. {
  94. val = value;
  95. }
  96. SnmpValue *SnmpCounter::Copy () const
  97. {
  98. return new SnmpCounter(val);
  99. }
  100. // Copy constructor
  101. SnmpTimeTicks::SnmpTimeTicks ( IN const SnmpTimeTicks &value )
  102. {
  103. val = value.GetValue();
  104. }
  105. BOOL SnmpTimeTicks :: Equivalent (IN const SnmpValue &value) const
  106. {
  107. BOOL bResult = FALSE;
  108. if (typeid(*this) == typeid(value))
  109. {
  110. bResult = Equivalent((const SnmpTimeTicks &)value);
  111. }
  112. return bResult;
  113. }
  114. ULONG SnmpTimeTicks::GetValue () const
  115. {
  116. return val;
  117. }
  118. void SnmpTimeTicks::SetValue ( IN const ULONG value )
  119. {
  120. val = value;
  121. }
  122. SnmpValue *SnmpTimeTicks::Copy () const
  123. {
  124. return new SnmpTimeTicks(val);
  125. }
  126. void SnmpOctetString::OverWrite(IN const UCHAR *value)
  127. {
  128. if ( value && length )
  129. {
  130. memcpy(val, value, sizeof(UCHAR)*length);
  131. }
  132. }
  133. void SnmpOctetString::Initialize(IN const UCHAR *value, IN const ULONG valueLength)
  134. {
  135. is_valid = FALSE;
  136. if ( (value == NULL) && (valueLength != 0) )
  137. return;
  138. length = valueLength;
  139. val = Replicate(value, valueLength);
  140. is_valid = TRUE;
  141. }
  142. void SnmpOctetString::UnReplicate(UCHAR *value)
  143. {
  144. if ( is_valid == TRUE )
  145. delete[] val;
  146. }
  147. SnmpOctetString::SnmpOctetString ( IN const UCHAR *value , IN const ULONG valueLength ) : is_valid ( FALSE )
  148. {
  149. Initialize(value, valueLength);
  150. }
  151. SnmpOctetString::SnmpOctetString ( IN const SnmpOctetString &value ) : is_valid ( FALSE )
  152. {
  153. Initialize(value.GetValue(), value.GetValueLength());
  154. }
  155. SnmpOctetString::~SnmpOctetString ()
  156. {
  157. UnReplicate(val);
  158. }
  159. ULONG SnmpOctetString::GetValueLength () const
  160. {
  161. return length;
  162. }
  163. UCHAR *SnmpOctetString::GetValue () const
  164. {
  165. return val;
  166. }
  167. SnmpValue *SnmpOctetString::Copy () const
  168. {
  169. return new SnmpOctetString(val, length);
  170. }
  171. UCHAR *SnmpOctetString::Replicate(IN const UCHAR *value, IN const ULONG valueLength)
  172. {
  173. if ( value )
  174. {
  175. UCHAR *temp = new UCHAR[valueLength];
  176. memcpy(temp, value, sizeof(UCHAR)*valueLength);
  177. return temp;
  178. }
  179. else
  180. {
  181. return NULL ;
  182. }
  183. }
  184. void SnmpOctetString::SetValue ( IN const UCHAR *value , IN const ULONG valueLength )
  185. {
  186. if (length != valueLength)
  187. {
  188. UnReplicate(val);
  189. Initialize(value, valueLength);
  190. }
  191. else
  192. OverWrite(value);
  193. }
  194. BOOL SnmpOctetString :: Equivalent (IN const SnmpValue &value) const
  195. {
  196. BOOL bResult = FALSE;
  197. if (typeid(*this) == typeid(value))
  198. {
  199. bResult = Equivalent((const SnmpOctetString &)value);
  200. }
  201. return bResult;
  202. }
  203. BOOL SnmpOctetString::Equivalent(IN const SnmpOctetString &snmp_octet_string) const
  204. {
  205. if ( is_valid && snmp_octet_string() )
  206. {
  207. if ( length != snmp_octet_string.GetValueLength() )
  208. return FALSE;
  209. UCHAR *octet_values = snmp_octet_string.GetValue();
  210. for( UINT i=0; i < length; i++)
  211. {
  212. if ( val[i] != octet_values[i] )
  213. return FALSE;
  214. }
  215. return TRUE;
  216. }
  217. else
  218. return FALSE;
  219. }
  220. void SnmpObjectIdentifier::OverWrite(IN const ULONG *value)
  221. {
  222. if ( value )
  223. {
  224. memcpy(val, value, sizeof(ULONG)*length);
  225. }
  226. }
  227. void SnmpObjectIdentifier::Initialize(IN const ULONG *value, IN const ULONG valueLength)
  228. {
  229. if ( ( (value == NULL) && (valueLength != 0) ) || ( valueLength == 0 ) )
  230. {
  231. length = 0 ;
  232. val = NULL ;
  233. return;
  234. }
  235. length = valueLength;
  236. if ( length <= DEFAULT_OBJECTIDENTIFIER_LENGTH )
  237. {
  238. val = m_value ;
  239. memcpy(val , value, sizeof(ULONG)*length);
  240. is_valid = TRUE;
  241. }
  242. else
  243. {
  244. val = new ULONG[length];
  245. memcpy(val , value, sizeof(ULONG)*length);
  246. is_valid = TRUE;
  247. }
  248. }
  249. void SnmpObjectIdentifier::UnReplicate(ULONG *value)
  250. {
  251. if ( ( is_valid == TRUE ) & ( length > DEFAULT_OBJECTIDENTIFIER_LENGTH ) )
  252. {
  253. delete[] val;
  254. }
  255. }
  256. SnmpObjectIdentifier::SnmpObjectIdentifier ( IN const ULONG *value , IN const ULONG valueLength ) : val ( NULL ) , length ( 0 ) , is_valid ( TRUE )
  257. {
  258. Initialize(value, valueLength);
  259. }
  260. SnmpObjectIdentifier::SnmpObjectIdentifier ( IN const SnmpObjectIdentifier &value ) : val ( NULL ) , length ( 0 ) , is_valid ( TRUE )
  261. {
  262. Initialize(value.GetValue(), value.GetValueLength());
  263. }
  264. SnmpObjectIdentifier::~SnmpObjectIdentifier ()
  265. {
  266. UnReplicate(val);
  267. }
  268. ULONG SnmpObjectIdentifier::GetValueLength () const
  269. {
  270. return length;
  271. }
  272. ULONG *SnmpObjectIdentifier::GetValue () const
  273. {
  274. return val;
  275. }
  276. SnmpValue *SnmpObjectIdentifier::Copy () const
  277. {
  278. return new SnmpObjectIdentifier(val, length);
  279. }
  280. ULONG *SnmpObjectIdentifier::Replicate(IN const ULONG *value, IN const ULONG valueLength) const
  281. {
  282. if ( value )
  283. {
  284. ULONG *temp = new ULONG[valueLength];
  285. memcpy(temp, value, sizeof(ULONG)*valueLength);
  286. return temp;
  287. }
  288. else
  289. {
  290. return NULL ;
  291. }
  292. }
  293. ULONG *SnmpObjectIdentifier::Replicate(IN const ULONG *first_value,
  294. IN const ULONG first_length,
  295. IN const ULONG *second_value,
  296. IN const ULONG second_length) const
  297. {
  298. if ( first_value && second_value )
  299. {
  300. ULONG new_length = first_length + second_length;
  301. ULONG *temp = new ULONG[new_length];
  302. int first_value_size = sizeof(ULONG)*first_length;
  303. memcpy(temp, first_value, first_value_size);
  304. memcpy(temp + first_length, second_value,
  305. sizeof(ULONG)*second_length);
  306. return temp;
  307. }
  308. else if ( first_value )
  309. {
  310. ULONG *temp = new ULONG [ first_length];
  311. memcpy(temp, first_value, sizeof(ULONG)*first_length);
  312. return temp;
  313. }
  314. else if ( second_value )
  315. {
  316. ULONG *temp = new ULONG [ second_length];
  317. memcpy(temp, second_value, sizeof(ULONG)*second_length);
  318. return temp;
  319. }
  320. else
  321. {
  322. return NULL ;
  323. }
  324. }
  325. SnmpObjectIdentifier::Comparison SnmpObjectIdentifier::Compare(IN const SnmpObjectIdentifier &first,
  326. IN const SnmpObjectIdentifier &second) const
  327. {
  328. ULONG *first_string = first.GetValue();
  329. ULONG *second_string = second.GetValue();
  330. int first_length = first.GetValueLength();
  331. int second_length = second.GetValueLength();
  332. int min_length = MIN(first_length,second_length);
  333. for(int i=0; i < min_length; i++)
  334. {
  335. if ( first_string[i] < second_string[i] )
  336. return LESS_THAN;
  337. else if ( first_string[i] > second_string[i] )
  338. return GREATER_THAN;
  339. else
  340. continue;
  341. }
  342. if ( first_length < second_length )
  343. return LESS_THAN;
  344. else if ( first_length > second_length )
  345. return GREATER_THAN;
  346. else
  347. return EQUAL_TO;
  348. }
  349. void SnmpObjectIdentifier::SetValue ( IN const ULONG *value , IN const ULONG valueLength )
  350. {
  351. if (valueLength)
  352. {
  353. if ( length != valueLength)
  354. {
  355. UnReplicate(val);
  356. Initialize(value, valueLength);
  357. }
  358. else
  359. {
  360. OverWrite(value);
  361. }
  362. }
  363. else
  364. {
  365. UnReplicate(val);
  366. val = NULL ;
  367. length = 0 ;
  368. }
  369. }
  370. // A null terminated dot-separated string representing the
  371. // object identifer value is passed and the private fields
  372. // and length are set from it
  373. SnmpObjectIdentifier::SnmpObjectIdentifier(IN const char *value)
  374. {
  375. is_valid = FALSE;
  376. UINT str_len = strlen(value);
  377. if ( str_len <= 0 )
  378. return;
  379. ULONG temp_field[MAX_FIELDS];
  380. // create an input stream from the string
  381. istrstream input_stream((char *)value);
  382. // consecutive fields must be separated by a
  383. // FIELD_SEPARATOR
  384. char separator;
  385. input_stream >> temp_field[0];
  386. if ( input_stream.bad() || input_stream.fail() )
  387. return;
  388. // while the stream still has something,
  389. // read (FIELD_SEPARATOR, ULONG) pairs from the input stream
  390. // and set the temp_fields
  391. // check if the read was bad or failed after the event
  392. for( int i = 1 ; (i < MAX_FIELDS) && (!input_stream.eof()); i++)
  393. {
  394. input_stream >> separator;
  395. if ( input_stream.bad() || input_stream.fail() )
  396. return;
  397. if ( separator != FIELD_SEPARATOR )
  398. return;
  399. input_stream >> temp_field[i];
  400. if ( input_stream.bad() || input_stream.fail() )
  401. return;
  402. }
  403. is_valid = TRUE;
  404. // set the length
  405. length = i;
  406. val = NULL ;
  407. // create memory for the fields and copy temp_fields into it
  408. Initialize(temp_field, length);
  409. }
  410. BOOL SnmpObjectIdentifier::Equivalent(IN const SnmpObjectIdentifier &value,
  411. IN ULONG max_length) const
  412. {
  413. if ( (!is_valid) || (!value()) )
  414. return FALSE;
  415. if ( (length < max_length) || (value.GetValueLength() < max_length) )
  416. return FALSE;
  417. ULONG *value_string = value.GetValue();
  418. for( UINT i=0; i < max_length; i++ )
  419. if ( val[i] != value_string[i] )
  420. return FALSE;
  421. return TRUE;
  422. }
  423. BOOL SnmpObjectIdentifier::Equivalent(IN const SnmpObjectIdentifier &value) const
  424. {
  425. if ( (!is_valid) || (!value()) )
  426. return FALSE;
  427. ULONG *value_string = value.GetValue();
  428. for( UINT i=length; i ; i-- )
  429. {
  430. if ( val[i-1] != value_string[i-1] )
  431. return FALSE;
  432. }
  433. return TRUE;
  434. }
  435. BOOL SnmpObjectIdentifier :: Equivalent (IN const SnmpValue &value) const
  436. {
  437. BOOL bResult = FALSE;
  438. if (typeid(*this) == typeid(value))
  439. {
  440. bResult = Equivalent((const SnmpObjectIdentifier &)value);
  441. }
  442. return bResult;
  443. }
  444. SnmpObjectIdentifier SnmpObjectIdentifier::operator+ ( IN const SnmpObjectIdentifier &value ) const
  445. {
  446. ULONG *temp_plus_array = Replicate(val, length, value.GetValue(), value.GetValueLength());
  447. SnmpObjectIdentifier local_identifier(temp_plus_array, length+value.GetValueLength());
  448. delete[] temp_plus_array;
  449. return SnmpObjectIdentifier(local_identifier);
  450. }
  451. // Determines the fields (starting from left), common to the
  452. // two object identifiers and returns a new object identifier
  453. // with only these fields. If nothing is shared, NULL is returned
  454. SnmpObjectIdentifier *SnmpObjectIdentifier::Cut( SnmpObjectIdentifier &value ) const
  455. {
  456. // determine the smaller of the two lengths
  457. int min_length = MIN(length, value.GetValueLength());
  458. ULONG *other_field = value.GetValue();
  459. // compare the fields
  460. for(int index=0; index < min_length; index++)
  461. if ( val[index] != other_field[index] )
  462. break;
  463. // if nothing in common - return NULL
  464. if ( index == 0 )
  465. return NULL;
  466. // they must have the fields in the range [0..(index-1)] common
  467. // therefore, a common length of "index"
  468. return new SnmpObjectIdentifier(other_field, index);
  469. }
  470. ULONG &SnmpObjectIdentifier::operator [] ( IN const ULONG index ) const
  471. {
  472. if ( index < length )
  473. return val[index];
  474. // should never reach here if the user checks the
  475. // index value before
  476. return val[0];
  477. }
  478. //returns an allocated char* representation of the OID.
  479. //The return value must be freed by the caller i.e. delete []
  480. char *SnmpObjectIdentifier::GetAllocatedString() const
  481. {
  482. char * retVal = NULL ;
  483. if (length)
  484. {
  485. retVal = new char [ length * 18 ] ;
  486. ostrstream s ( retVal , length * 18 ) ;
  487. s << val[0];
  488. UINT i = 1;
  489. char dot = '.';
  490. while (i < length)
  491. {
  492. s << dot << val[i++] ;
  493. }
  494. s << ends ;
  495. }
  496. return retVal;
  497. }
  498. SnmpIpAddress::SnmpIpAddress ( IN const char *value )
  499. {
  500. // create a stream to read the fields from
  501. istrstream address_stream((char *)value);
  502. // store the values [0..255] separated by FIELD_SEPARATORs
  503. // in the value string
  504. UCHAR field[SNMP_IP_ADDR_LEN];
  505. // contains the maximum value for a UCHAR. used
  506. // for comparison with the field values read
  507. const UCHAR max_uchar = -1;
  508. // consecutive fields must be separated by a
  509. // FIELD_SEPARATOR
  510. char separator;
  511. // a field is first read into this for comparison
  512. // with max_uchar
  513. ULONG temp_field;
  514. is_valid = FALSE;
  515. // read the first three (UCHAR,FIELD_SEPARATOR) pairs
  516. // check if the stream is good before each read
  517. for(int i=0; i < (SNMP_IP_ADDR_LEN-1); i++)
  518. {
  519. if ( !address_stream.good() )
  520. return;
  521. address_stream >> temp_field;
  522. if ( temp_field > max_uchar )
  523. return;
  524. field[i] = (UCHAR)temp_field;
  525. if ( !address_stream.good() )
  526. return;
  527. address_stream >> separator;
  528. if ( separator != FIELD_SEPARATOR )
  529. return;
  530. }
  531. if ( !address_stream.good() )
  532. return;
  533. address_stream >> temp_field;
  534. if (temp_field > max_uchar)
  535. return;
  536. field[SNMP_IP_ADDR_LEN-1] = (UCHAR)temp_field;
  537. // make sure that there are is nothing more left in the
  538. // stream
  539. if ( !address_stream.eof() )
  540. return;
  541. ULONG byteA = field [ 0 ] ;
  542. ULONG byteB = field [ 1 ] ;
  543. ULONG byteC = field [ 2 ] ;
  544. ULONG byteD = field [ 3 ] ;
  545. val = ( byteA << 24 ) + ( byteB << 16 ) + ( byteC << 8 ) + byteD ;
  546. is_valid = TRUE;
  547. }
  548. // Copy constructor
  549. SnmpIpAddress::SnmpIpAddress ( IN const SnmpIpAddress &value )
  550. {
  551. if ( value() )
  552. {
  553. val = value.GetValue();
  554. is_valid = TRUE;
  555. }
  556. else
  557. is_valid = FALSE;
  558. }
  559. BOOL SnmpIpAddress :: Equivalent (IN const SnmpValue &value) const
  560. {
  561. BOOL bResult = FALSE;
  562. if (typeid(*this) == typeid(value))
  563. {
  564. bResult = Equivalent((const SnmpIpAddress &)value);
  565. }
  566. return bResult;
  567. }
  568. ULONG SnmpIpAddress::GetValue () const
  569. {
  570. return val;
  571. }
  572. void SnmpIpAddress::SetValue ( IN const ULONG value )
  573. {
  574. val = value;
  575. is_valid = TRUE;
  576. }
  577. SnmpValue *SnmpIpAddress::Copy () const
  578. {
  579. return new SnmpIpAddress(val);
  580. }
  581. // Copy constructor
  582. SnmpUInteger32::SnmpUInteger32 ( IN const SnmpUInteger32 &value )
  583. {
  584. val = value.GetValue();
  585. }
  586. ULONG SnmpUInteger32::GetValue () const
  587. {
  588. return val;
  589. }
  590. void SnmpUInteger32::SetValue ( IN const ULONG value )
  591. {
  592. val = value;
  593. }
  594. SnmpValue *SnmpUInteger32::Copy () const
  595. {
  596. return new SnmpUInteger32(val);
  597. }
  598. BOOL SnmpUInteger32 :: Equivalent (IN const SnmpValue &value) const
  599. {
  600. BOOL bResult = FALSE;
  601. if (typeid(*this) == typeid(value))
  602. {
  603. bResult = Equivalent((const SnmpUInteger32 &)value);
  604. }
  605. return bResult;
  606. }
  607. // Copy constructor
  608. SnmpCounter64::SnmpCounter64( IN const SnmpCounter64 &value )
  609. {
  610. lval = value.GetLowValue();
  611. hval = value.GetHighValue();
  612. }
  613. ULONG SnmpCounter64::GetLowValue () const
  614. {
  615. return lval;
  616. }
  617. ULONG SnmpCounter64::GetHighValue () const
  618. {
  619. return hval;
  620. }
  621. void SnmpCounter64::SetValue ( IN const ULONG lvalue , IN const ULONG hvalue )
  622. {
  623. lval = lvalue;
  624. hval = hvalue ;
  625. }
  626. SnmpValue *SnmpCounter64::Copy () const
  627. {
  628. return new SnmpCounter64(lval,hval);
  629. }
  630. BOOL SnmpCounter64 :: Equivalent (IN const SnmpValue &value) const
  631. {
  632. BOOL bResult = FALSE;
  633. if (typeid(*this) == typeid(value))
  634. {
  635. bResult = Equivalent((const SnmpCounter64 &)value);
  636. }
  637. return bResult;
  638. }
  639. BOOL SnmpNoSuchInstance :: Equivalent (IN const SnmpValue &value) const
  640. {
  641. BOOL bResult = FALSE;
  642. if (typeid(*this) == typeid(value))
  643. {
  644. bResult = TRUE;
  645. }
  646. return bResult;
  647. }
  648. BOOL SnmpNoSuchObject :: Equivalent (IN const SnmpValue &value) const
  649. {
  650. BOOL bResult = FALSE;
  651. if (typeid(*this) == typeid(value))
  652. {
  653. bResult = TRUE;
  654. }
  655. return bResult;
  656. }
  657. BOOL SnmpEndOfMibView :: Equivalent (IN const SnmpValue &value) const
  658. {
  659. BOOL bResult = FALSE;
  660. if (typeid(*this) == typeid(value))
  661. {
  662. bResult = TRUE;
  663. }
  664. return bResult;
  665. }
  666. BOOL SnmpOpaque :: Equivalent (IN const SnmpValue &value) const
  667. {
  668. BOOL bResult = FALSE;
  669. if (typeid(*this) == typeid(value))
  670. {
  671. bResult = Equivalent((const SnmpOpaque &)value);
  672. }
  673. return bResult;
  674. }