1 /*_############################################################################
6 _## -----------------------------------------------
7 _## Copyright (c) 2001-2010 Jochen Katz, Frank Fock
9 _## This software is based on SNMP++2.6 from Hewlett Packard:
11 _## Copyright (c) 1996
12 _## Hewlett-Packard Company
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.
26 _## Stuttgart, Germany, Thu Sep 2 00:07:47 CEST 2010
28 _##########################################################################*/
30 char v3_cpp_version[]="#(@) SNMP++ $Id: v3.cpp 274 2006-11-03 19:21:16Z katz $";
37 #ifndef __BCPLUSPLUS__
42 #include "snmp_pp/log.h"
43 #include "snmp_pp/v3.h"
44 #include "snmp_pp/octet.h"
46 #ifdef SNMP_PP_NAMESPACE
50 #define MAX_LINE_LEN 100
52 const char *logfilename = NULL;
55 // Set the amount of log messages you want to get.
56 void debug_set_level(const int db_level)
58 debug_level = db_level;
63 void debughexcprintf(int db_level, const char *comment,
64 const unsigned char *data, const unsigned int len)
66 if (db_level > debug_level) return;
68 char *buf = new char[MAX_LOG_SIZE];
70 if (NULL == buf) return; // not good!
72 if (comment && (strlen(comment) < MAX_LOG_SIZE - 25))
74 sprintf(buf, "%s (length %i): \n", comment, len);
75 LOG_BEGIN(DEBUG_LOG | 3);
80 char *tmp = new char[4];
82 if (NULL == tmp) { delete [] buf ; return; }
85 for (unsigned int i=0; i<len; i++)
87 sprintf(tmp, "%02X ", data[i]);
98 LOG_BEGIN(DEBUG_LOG | 3);
109 // print the last part of the message
110 LOG_BEGIN(DEBUG_LOG | 3);
120 void debugprintf(int db_level, const char *format, ...)
122 if (db_level > debug_level) return;
126 va_start(args, format);
128 /////////////////////////////////////////////////////////////////
129 // NOTE: This would be the best way to go (by using _vscprintf),
130 // but it is part of the VC7.0, and it can't be used in VC6.0
131 /////////////////////////////////////////////////////////////////
132 // _vscprintf doesn't count terminating '\0' so we add one more
133 // int len = _vscprintf( format, args ) + 1;
135 char *buf = new char[MAX_LOG_SIZE];
137 if (NULL == buf) return; // not good!
139 vsprintf(buf, format, args);
143 LOG_BEGIN(DEBUG_LOG | 1);
152 #if (defined (__STRICT_ANSI__) || !defined (__GNUC__)) && !defined (_MSC_VER)
153 void debugprintf(int, const char*, ...)
162 unsigned char *v3strcpy(const unsigned char *src, const int srclen)
164 unsigned char *res = new unsigned char[srclen+1];
165 if (!res) return NULL;
166 memcpy(res, src, srclen);
172 int unsignedCharCompare(const unsigned char *str1, const long int ptr1len,
173 const unsigned char *str2, const long int ptr2len)
175 if (ptr1len != ptr2len) return 0;
177 const unsigned char *ptr1 = str1;
178 const unsigned char *ptr2 = str2;
180 for (int i=0; i < ptr1len; ++i)
181 if (*ptr1++ != *ptr2++) return 0;
186 // Encode the given string into the output buffer.
187 void encodeString(const unsigned char* in, const int in_length, char* out)
190 const unsigned char* in_ptr = in;
192 for (int i=0; i<in_length; i++)
194 *out_ptr++ = 64 + ((*in_ptr >> 4) & 0xF);
195 *out_ptr++ = 64 + (*in_ptr++ & 0xF);
199 // Decode the given encoded string into the output buffer.
200 void decodeString(const unsigned char* in, const int in_length, char* out)
203 const unsigned char* in_ptr = in;
205 if ((in_length % 2) || (in_length < 0))
207 LOG_BEGIN(WARNING_LOG | 3);
208 LOG("decodeString: Illegal input length (len)");
216 for (int i= in_length / 2; i > 0; i--)
218 *out_ptr = (*in_ptr++ & 0xF) << 4;
219 *out_ptr++ |= (*in_ptr++ & 0xF);
221 *out_ptr = 0; // make sure it is null terminated
224 // Read the bootCounter of the given engineID stored in the given file.
225 int getBootCounter(const char *fileName,
226 const OctetStr &engineId, unsigned int &boot)
228 char line[MAX_LINE_LEN];
229 char encoded[MAXLENGTH_ENGINEID * 2 + 2];
230 int len = engineId.len();
235 file = fopen(fileName, "r");
239 LOG_BEGIN(ERROR_LOG | 1);
240 LOG("getBootCounter: Could not open (file)");
244 return SNMPv3_FILEOPEN_ERROR;
247 if (len > MAXLENGTH_ENGINEID)
249 LOG_BEGIN(ERROR_LOG | 3);
250 LOG("getBootCounter: engine id too long, ignoring last bytes (len) (max)");
252 LOG(MAXLENGTH_ENGINEID);
255 len = MAXLENGTH_ENGINEID;
258 encodeString(engineId.data(), len, encoded);
260 encoded[2*len + 1] = 0;
262 while (fgets(line, MAX_LINE_LEN, file))
264 line[MAX_LINE_LEN - 1] = 0;
265 /* ignore comments */
269 if (!strncmp(encoded, line, len*2 + 1))
271 /* line starts with engineId */
273 /* skip until first space */
274 while (*ptr != 0 && *ptr != ' ')
281 LOG_BEGIN(ERROR_LOG | 3);
282 LOG("getBootCounter: Illegal line: (file) (line)");
287 return SNMPv3_FILE_ERROR;
292 LOG_BEGIN(DEBUG_LOG | 3);
293 LOG("getBootCounter: found entry (file) (engine id) (boot counter)");
295 LOG(engineId.get_printable());
304 LOG_BEGIN(WARNING_LOG | 3);
305 LOG("getBootCounter: No entry found (file) (engine id)");
307 LOG(engineId.get_printable());
310 return SNMPv3_NO_ENTRY_ERROR;
313 // Store the bootCounter of the given engineID in the given file.
314 int saveBootCounter(const char *fileName,
315 const OctetStr &engineId, const unsigned int boot)
317 char line[MAX_LINE_LEN];
318 char tmpFileName[MAXLENGTH_FILENAME];
319 char encoded[MAXLENGTH_ENGINEID * 2 + 2];
321 int len = engineId.len();
322 FILE *file_in, *file_out;
325 sprintf(tmpFileName, "%s.tmp",fileName);
326 if (len > MAXLENGTH_ENGINEID)
328 LOG_BEGIN(ERROR_LOG | 3);
329 LOG("saveBootCounter: engine id too long, ignoring last bytes (len) (max)");
331 LOG(MAXLENGTH_ENGINEID);
334 len = MAXLENGTH_ENGINEID;
337 file_in = fopen(fileName, "r");
340 file_in = fopen(fileName, "w");
343 LOG_BEGIN(ERROR_LOG | 3);
344 LOG("saveBootCounter: could not create new file (file)");
348 return SNMPv3_FILECREATE_ERROR;
351 LOG_BEGIN(INFO_LOG | 3);
352 LOG("saveBootCounter: created new file (file)");
356 fputs("# \n",file_in);
357 fputs("# This file was created by an SNMP++v3 application,\n", file_in);
358 fputs("# it is used to store the snmpEngineBoots counters.\n", file_in);
359 fputs("# \n",file_in);
360 fputs("# Lines starting with '#' are comments.\n", file_in);
361 fputs("# The snmpEngineBoots counters are stored as\n", file_in);
362 fputs("# <encoded snmpEngineId> <bootCounter>\n", file_in);
363 fputs("# \n", file_in);
365 file_in = fopen(fileName, "r");
368 file_out = fopen(tmpFileName, "w");
370 if ((file_in) && (file_out))
372 encodeString(engineId.data(), len, encoded);
373 encoded[len*2] = ' ';
374 encoded[len*2 + 1] = 0;
376 while (fgets(line, MAX_LINE_LEN, file_in))
378 line[MAX_LINE_LEN - 1] = 0;
379 if (!strncmp(encoded, line, len*2 + 1))
383 LOG_BEGIN(WARNING_LOG | 3);
384 LOG("saveBootCounter: Removing doubled entry (file) (line)");
391 sprintf(line,"%s%i\n", encoded, boot);
392 fputs(line, file_out);
396 fputs(line, file_out);
400 sprintf(line, "%s%i\n", encoded, boot);
401 fputs(line, file_out);
408 if (rename(tmpFileName, fileName))
410 LOG_BEGIN(ERROR_LOG | 1);
411 LOG("saveBootCounter: Failed to rename temporary file (tmp file) (file)");
416 return SNMPv3_FILERENAME_ERROR;
419 LOG_BEGIN(INFO_LOG | 5);
420 LOG("saveBootCounter: Saved counter (file) (engine id) (boot)");
422 LOG(engineId.get_printable());
429 LOG_BEGIN(ERROR_LOG | 1);
430 LOG("saveBootCounter: Failed to open both files (file) (tmp file)");
435 return SNMPv3_FILEOPEN_ERROR;
440 #ifdef SNMP_PP_NAMESPACE
441 }; // end of namespace Snmp_pp