v3.cpp
上传用户:cnryan
上传日期:2008-12-15
资源大小:260k
文件大小:10k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*_############################################################################
  2.   _## 
  3.   _##  v3.cpp  
  4.   _##
  5.   _##  SNMP++v3.2.21
  6.   _##  -----------------------------------------------
  7.   _##  Copyright (c) 2001-2006 Jochen Katz, Frank Fock
  8.   _##
  9.   _##  This software is based on SNMP++2.6 from Hewlett Packard:
  10.   _##  
  11.   _##    Copyright (c) 1996
  12.   _##    Hewlett-Packard Company
  13.   _##  
  14.   _##  ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  15.   _##  Permission to use, copy, modify, distribute and/or sell this software 
  16.   _##  and/or its documentation is hereby granted without fee. User agrees 
  17.   _##  to display the above copyright notice and this license notice in all 
  18.   _##  copies of the software and any documentation of the software. User 
  19.   _##  agrees to assume all liability for the use of the software; 
  20.   _##  Hewlett-Packard and Jochen Katz make no representations about the 
  21.   _##  suitability of this software for any purpose. It is provided 
  22.   _##  "AS-IS" without warranty of any kind, either express or implied. User 
  23.   _##  hereby grants a royalty-free license to any and all derivatives based
  24.   _##  upon this software code base. 
  25.   _##  
  26.   _##  Stuttgart, Germany, Fri Jun 16 17:48:57 CEST 2006 
  27.   _##  
  28.   _##########################################################################*/
  29. char v3_cpp_version[]="#(@) SNMP++ $Id: v3.cpp,v 1.8 2006/06/03 20:27:08 katz Exp $";
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <stdio.h>
  33. #include <string.h>
  34. #ifndef _MSC_VER
  35. #ifndef __BCPLUSPLUS__
  36. #include <unistd.h>
  37. #endif
  38. #endif
  39. #include "snmp_pp/log.h"
  40. #include "snmp_pp/v3.h"
  41. #include "snmp_pp/octet.h"
  42. #ifdef SNMP_PP_NAMESPACE
  43. namespace Snmp_pp {
  44. #endif
  45. #define MAX_LINE_LEN 100
  46. const char *logfilename = NULL;
  47. int debug_level = 19;
  48. // Set the amount of log messages you want to get.
  49. void debug_set_level(const int db_level)
  50. {
  51.   debug_level = db_level;
  52. }
  53. #ifdef _DEBUG
  54. void debughexcprintf(int db_level, const char *comment,
  55.                      const unsigned char *data, const unsigned int len)
  56. {
  57.     if (db_level > debug_level) return;
  58.     char *buf = new char[MAX_LOG_SIZE];
  59.     if (NULL == buf) return; // not good!
  60.     if (comment && (strlen(comment) < MAX_LOG_SIZE - 25))
  61.     {
  62. sprintf(buf, "%s (length %i): n", comment, len);
  63. LOG_BEGIN(DEBUG_LOG | 3);
  64. LOG(buf);
  65. LOG_END;
  66.     }
  67.     char *tmp = new char[4];
  68.     if (NULL == tmp) { delete [] buf ; return; }
  69.     buf[0] = '';
  70.     for (unsigned int i=0; i<len; i++)
  71.     {
  72. sprintf(tmp, "%02X ", data[i]);
  73. strcat(buf, tmp);
  74. if ((i+1)%4==0)
  75. {
  76.     sprintf(tmp, " ");
  77.     strcat(buf, tmp);
  78. }
  79. if ((i+1)%16==0)
  80. {
  81.     LOG_BEGIN(DEBUG_LOG | 3);
  82.     LOG(buf);
  83.     LOG_END;
  84.     // reset the buf
  85.     buf[0] = '';
  86. }
  87.     }
  88.     // and cleanup...
  89.     delete [] tmp;
  90.     delete [] buf;
  91. }
  92. void debugprintf(int db_level, const char *format, ...)
  93. {
  94.     if (db_level > debug_level) return;
  95.     va_list  args;
  96.     va_start(args, format);
  97. /////////////////////////////////////////////////////////////////
  98. // NOTE: This would be the best way to go (by using _vscprintf), 
  99. // but it is part of the VC7.0, and it can't be used in VC6.0
  100. /////////////////////////////////////////////////////////////////
  101. // _vscprintf doesn't count terminating '' so we add one more
  102. // int len = _vscprintf( format, args ) + 1;
  103.     char *buf = new char[MAX_LOG_SIZE];
  104.     if (NULL == buf) return; // not good!
  105.     vsprintf(buf, format, args);
  106.     va_end(args);
  107.     LOG_BEGIN(DEBUG_LOG | 1);
  108.     LOG(buf);
  109.     LOG_END;
  110.     // and cleanup...
  111.     delete [] buf;
  112. }
  113. #else
  114. #if (defined (__STRICT_ANSI__) || !defined (__GNUC__)) && !defined (_MSC_VER)
  115. void debugprintf(int, const char*, ...)
  116. {
  117. }
  118. #endif
  119. #endif
  120. #ifdef _SNMPv3
  121. unsigned char *v3strcpy(const unsigned char *src, const int srclen)
  122. {
  123.   unsigned char *res = new unsigned char[srclen+1];
  124.   if (!res) return NULL;
  125.   memcpy(res, src, srclen);
  126.   res[srclen] = '';
  127.   return res;
  128. }
  129. int unsignedCharCompare(const unsigned char *str1, const long int ptr1len,
  130.                         const unsigned char *str2, const long int ptr2len)
  131. {
  132.   if (ptr1len != ptr2len) return 0;
  133.   const unsigned char *ptr1 = str1;
  134.   const unsigned char *ptr2 = str2;
  135.   for (int i=0; i < ptr1len; ++i)
  136.     if (*ptr1++ != *ptr2++) return 0;
  137.   return 1;
  138. }
  139. // Encode the given string into the output buffer.
  140. void encodeString(const unsigned char* in, const int in_length, char* out)
  141. {
  142.   char* out_ptr = out;
  143.   const unsigned char* in_ptr = in;
  144.   for (int i=0; i<in_length; i++)
  145.   {
  146.     *out_ptr++ = 64 + ((*in_ptr >> 4) & 0xF);
  147.     *out_ptr++ = 64 + (*in_ptr++ & 0xF);
  148.   }
  149. }
  150. // Decode the given encoded string into the output buffer.
  151. void decodeString(const unsigned char* in, const int in_length, char* out)
  152. {
  153.   char* out_ptr = out;
  154.   const unsigned char* in_ptr = in;
  155.   if ((in_length % 2) || (in_length < 0))
  156.   {
  157.     LOG_BEGIN(WARNING_LOG | 3);
  158.     LOG("decodeString: Illegal input length (len)");
  159.     LOG(in_length);
  160.     LOG_END;
  161.     *out = 0;
  162.     return;
  163.   }
  164.   for (int i= in_length / 2; i > 0; i--)
  165.   {
  166.     *out_ptr = (*in_ptr++ & 0xF) << 4;
  167.     *out_ptr++ |= (*in_ptr++ & 0xF);
  168.   }
  169.   *out_ptr = 0; // make sure it is null terminated
  170. }
  171. // Read the bootCounter of the given engineID stored in the given file.
  172. int getBootCounter(const char *fileName,
  173.                    const OctetStr &engineId, unsigned int &boot)
  174. {
  175.   char line[MAX_LINE_LEN];
  176.   char encoded[MAXLENGTH_ENGINEID * 2 + 2];
  177.   int len = engineId.len();
  178.   FILE *file;
  179.   boot = 0;
  180.   file = fopen(fileName, "r");
  181.   if (!file)
  182.   {
  183.     LOG_BEGIN(ERROR_LOG | 1);
  184.     LOG("getBootCounter: Could not open (file)");
  185.     LOG(fileName);
  186.     LOG_END;
  187.     return SNMPv3_FILEOPEN_ERROR;
  188.   }
  189.   if (len > MAXLENGTH_ENGINEID)
  190.   {
  191.     LOG_BEGIN(ERROR_LOG | 3);
  192.     LOG("getBootCounter: engine id too long, ignoring last bytes (len) (max)");
  193.     LOG(len);
  194.     LOG(MAXLENGTH_ENGINEID);
  195.     LOG_END;
  196.     len = MAXLENGTH_ENGINEID;
  197.   }
  198.   encodeString(engineId.data(), len, encoded);
  199.   encoded[2*len]=' ';
  200.   encoded[2*len + 1] = 0;
  201.   while (fgets(line, MAX_LINE_LEN, file))
  202.   {
  203.     line[MAX_LINE_LEN - 1] = 0;
  204.     /* ignore comments */
  205.     if (line[0]=='#')
  206.       continue;
  207.     if (!strncmp(encoded, line, len*2 + 1))
  208.     {
  209.       /* line starts with engineId */
  210.       char* ptr = line;
  211.       /* skip until first space */
  212.       while (*ptr != 0 && *ptr != ' ')
  213.         ptr++;
  214.       if (*ptr == 0)
  215.       {
  216.         fclose(file);
  217.         LOG_BEGIN(ERROR_LOG | 3);
  218.         LOG("getBootCounter: Illegal line: (file) (line)");
  219.         LOG(fileName);
  220.         LOG(line);
  221.         LOG_END;
  222.         return SNMPv3_FILE_ERROR;
  223.       }
  224.       boot = atoi(ptr);
  225.       fclose(file);
  226.       LOG_BEGIN(DEBUG_LOG | 3);
  227.       LOG("getBootCounter: found entry (file) (engine id) (boot counter)");
  228.       LOG(fileName);
  229.       LOG(engineId.get_printable());
  230.       LOG(boot);
  231.       LOG_END;
  232.       return SNMPv3_OK;
  233.     }
  234.   }
  235.   fclose(file);
  236.   LOG_BEGIN(WARNING_LOG | 3);
  237.   LOG("getBootCounter: No entry found (file) (engine id)");
  238.   LOG(fileName);
  239.   LOG(engineId.get_printable());
  240.   LOG_END;
  241.   return SNMPv3_NO_ENTRY_ERROR;
  242. }
  243. // Store the bootCounter of the given engineID in the given file.
  244. int saveBootCounter(const char *fileName,
  245.                     const OctetStr &engineId, const unsigned int boot)
  246. {
  247.   char line[MAX_LINE_LEN];
  248.   char tmpFileName[MAXLENGTH_FILENAME];
  249.   char encoded[MAXLENGTH_ENGINEID * 2 + 2];
  250.   int found = FALSE;
  251.   int len = engineId.len();
  252.   FILE *file_in, *file_out;
  253.   tmpFileName[0] = 0;
  254.   sprintf(tmpFileName, "%s.tmp",fileName);
  255.   if (len > MAXLENGTH_ENGINEID)
  256.   {
  257.     LOG_BEGIN(ERROR_LOG | 3);
  258.     LOG("saveBootCounter: engine id too long, ignoring last bytes (len) (max)");
  259.     LOG(len);
  260.     LOG(MAXLENGTH_ENGINEID);
  261.     LOG_END;
  262.     len = MAXLENGTH_ENGINEID;
  263.   }
  264.   file_in = fopen(fileName, "r");
  265.   if (!file_in)
  266.   {
  267.     file_in = fopen(fileName, "w");
  268.     if (!file_in)
  269.     {
  270.       LOG_BEGIN(ERROR_LOG | 3);
  271.       LOG("saveBootCounter: could not create new file (file)");
  272.       LOG(fileName);
  273.       LOG_END;
  274.       return SNMPv3_FILECREATE_ERROR;
  275.     }
  276.     LOG_BEGIN(INFO_LOG | 3);
  277.     LOG("saveBootCounter: created new file (file)");
  278.     LOG(fileName);
  279.     LOG_END;
  280.     fputs("# n",file_in);
  281.     fputs("# This file was created by an SNMP++v3 application,n", file_in);
  282.     fputs("# it is used to store the snmpEngineBoots counters.n", file_in);
  283.     fputs("# n",file_in);
  284.     fputs("# Lines starting with '#' are comments.n", file_in);
  285.     fputs("# The snmpEngineBoots counters are stored asn", file_in);
  286.     fputs("# <encoded snmpEngineId> <bootCounter>n", file_in);
  287.     fputs("# n", file_in);
  288.     fclose(file_in);
  289.     file_in = fopen(fileName, "r");
  290.   }
  291.   file_out = fopen(tmpFileName, "w");
  292.   if ((file_in) && (file_out))
  293.   {
  294.     encodeString(engineId.data(), len, encoded);
  295.     encoded[len*2] = ' ';
  296.     encoded[len*2 + 1] = 0;
  297.     while (fgets(line, MAX_LINE_LEN, file_in))
  298.     {
  299.       line[MAX_LINE_LEN - 1] = 0;
  300.       if (!strncmp(encoded, line, len*2 + 1))
  301.       {
  302.         if (found)
  303.         {
  304.           LOG_BEGIN(WARNING_LOG | 3);
  305.           LOG("saveBootCounter: Removing doubled entry (file) (line)");
  306.           LOG(fileName);
  307.           LOG(line);
  308.           LOG_END;
  309.           continue;
  310.         }
  311.         sprintf(line,"%s%in", encoded, boot);
  312.         fputs(line, file_out);
  313.         found = TRUE;
  314.         continue;
  315.       }
  316.       fputs(line, file_out);
  317.     }
  318.     if (!found)
  319.     {
  320.       sprintf(line, "%s%in", encoded, boot);
  321.       fputs(line, file_out);
  322.     }
  323.     fclose(file_in);
  324.     fclose(file_out);
  325. #ifdef WIN32
  326.     _unlink(fileName);
  327. #endif
  328.     if (rename(tmpFileName, fileName))
  329.     {
  330.       LOG_BEGIN(ERROR_LOG | 1);
  331.       LOG("saveBootCounter: Failed to rename temporary file (tmp file) (file)");
  332.       LOG(tmpFileName);
  333.       LOG(fileName);
  334.       LOG_END;
  335.       return SNMPv3_FILERENAME_ERROR;
  336.     }
  337.     LOG_BEGIN(INFO_LOG | 5);
  338.     LOG("saveBootCounter: Saved counter (file) (engine id) (boot)");
  339.     LOG(fileName);
  340.     LOG(engineId.get_printable());
  341.     LOG(boot);
  342.     LOG_END;
  343.     return SNMPv3_OK;
  344.   }
  345.   LOG_BEGIN(ERROR_LOG | 1);
  346.   LOG("saveBootCounter: Failed to open both files (file) (tmp file)");
  347.   LOG(fileName);
  348.   LOG(tmpFileName);
  349.   LOG_END;
  350.   return SNMPv3_FILEOPEN_ERROR;
  351. }
  352. #endif
  353. #ifdef SNMP_PP_NAMESPACE
  354. }; // end of namespace Snmp_pp
  355. #endif