net-snmp 5.7
|
00001 /* 00002 * Simple Network Management Protocol (RFC 1067). 00003 * 00004 */ 00005 /********************************************************************** 00006 Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University 00007 00008 All Rights Reserved 00009 00010 Permission to use, copy, modify, and distribute this software and its 00011 documentation for any purpose and without fee is hereby granted, 00012 provided that the above copyright notice appear in all copies and that 00013 both that copyright notice and this permission notice appear in 00014 supporting documentation, and that the name of CMU not be 00015 used in advertising or publicity pertaining to distribution of the 00016 software without specific, written prior permission. 00017 00018 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 00019 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 00020 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 00021 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 00022 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 00023 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 00024 SOFTWARE. 00025 ******************************************************************/ 00026 00027 #include <net-snmp/net-snmp-config.h> 00028 #include <ctype.h> 00029 00030 #ifdef KINETICS 00031 #include "gw.h" 00032 #include "ab.h" 00033 #include "inet.h" 00034 #include "fp4/cmdmacro.h" 00035 #include "fp4/pbuf.h" 00036 #include "glob.h" 00037 #endif 00038 00039 #include <stdio.h> 00040 #include <stdlib.h> 00041 00042 #include <sys/types.h> 00043 #ifdef HAVE_STRING_H 00044 #include <string.h> 00045 #else 00046 #include <strings.h> 00047 #endif 00048 #if HAVE_NETINET_IN_H 00049 #include <netinet/in.h> 00050 #endif 00051 #ifdef HAVE_SYS_SELECT_H 00052 #include <sys/select.h> 00053 #endif 00054 #ifndef NULL 00055 #define NULL 0 00056 #endif 00057 00058 #if HAVE_DMALLOC_H 00059 #include <dmalloc.h> 00060 #endif 00061 00062 #ifdef vms 00063 #include <in.h> 00064 #endif 00065 00066 #include <net-snmp/types.h> 00067 #include <net-snmp/output_api.h> 00068 00069 #include <net-snmp/library/asn1.h> 00070 #include <net-snmp/library/snmp.h> /* for "internal" definitions */ 00071 #include <net-snmp/library/snmp_api.h> 00072 #include <net-snmp/library/mib.h> 00073 00089 void 00090 xdump(const void * data, size_t length, const char *prefix) 00091 { 00092 const u_char * const cp = (const u_char*)data; 00093 int col, count; 00094 char *buffer; 00095 00096 buffer = (char *) malloc(strlen(prefix) + 80); 00097 if (!buffer) { 00098 snmp_log(LOG_NOTICE, 00099 "xdump: malloc failed. packet-dump skipped\n"); 00100 return; 00101 } 00102 00103 count = 0; 00104 while (count < (int) length) { 00105 strcpy(buffer, prefix); 00106 sprintf(buffer + strlen(buffer), "%.4d: ", count); 00107 00108 for (col = 0; ((count + col) < (int) length) && col < 16; col++) { 00109 sprintf(buffer + strlen(buffer), "%02X ", cp[count + col]); 00110 if (col % 4 == 3) 00111 strcat(buffer, " "); 00112 } 00113 for (; col < 16; col++) { /* pad end of buffer with zeros */ 00114 strcat(buffer, " "); 00115 if (col % 4 == 3) 00116 strcat(buffer, " "); 00117 } 00118 strcat(buffer, " "); 00119 for (col = 0; ((count + col) < (int) length) && col < 16; col++) { 00120 buffer[col + 60] = 00121 isprint(cp[count + col]) ? cp[count + col] : '.'; 00122 } 00123 buffer[col + 60] = '\n'; 00124 buffer[col + 60 + 1] = 0; 00125 snmp_log(LOG_DEBUG, "%s", buffer); 00126 count += col; 00127 } 00128 snmp_log(LOG_DEBUG, "\n"); 00129 free(buffer); 00130 00131 } /* end xdump() */ 00132 00133 /* 00134 * u_char * snmp_parse_var_op( 00135 * u_char *data IN - pointer to the start of object 00136 * oid *var_name OUT - object id of variable 00137 * int *var_name_len IN/OUT - length of variable name 00138 * u_char *var_val_type OUT - type of variable (int or octet string) (one byte) 00139 * int *var_val_len OUT - length of variable 00140 * u_char **var_val OUT - pointer to ASN1 encoded value of variable 00141 * int *listlength IN/OUT - number of valid bytes left in var_op_list 00142 */ 00143 00144 u_char * 00145 snmp_parse_var_op(u_char * data, 00146 oid * var_name, 00147 size_t * var_name_len, 00148 u_char * var_val_type, 00149 size_t * var_val_len, 00150 u_char ** var_val, size_t * listlength) 00151 { 00152 u_char var_op_type; 00153 size_t var_op_len = *listlength; 00154 u_char *var_op_start = data; 00155 00156 data = asn_parse_sequence(data, &var_op_len, &var_op_type, 00157 (ASN_SEQUENCE | ASN_CONSTRUCTOR), "var_op"); 00158 if (data == NULL) { 00159 /* 00160 * msg detail is set 00161 */ 00162 return NULL; 00163 } 00164 DEBUGDUMPHEADER("recv", "Name"); 00165 data = 00166 asn_parse_objid(data, &var_op_len, &var_op_type, var_name, 00167 var_name_len); 00168 DEBUGINDENTLESS(); 00169 if (data == NULL) { 00170 ERROR_MSG("No OID for variable"); 00171 return NULL; 00172 } 00173 if (var_op_type != 00174 (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID)) 00175 return NULL; 00176 *var_val = data; /* save pointer to this object */ 00177 /* 00178 * find out what type of object this is 00179 */ 00180 data = asn_parse_header(data, &var_op_len, var_val_type); 00181 if (data == NULL) { 00182 ERROR_MSG("No header for value"); 00183 return NULL; 00184 } 00185 /* 00186 * XXX no check for type! 00187 */ 00188 *var_val_len = var_op_len; 00189 data += var_op_len; 00190 *listlength -= (int) (data - var_op_start); 00191 return data; 00192 } 00193 00194 /* 00195 * u_char * snmp_build_var_op( 00196 * u_char *data IN - pointer to the beginning of the output buffer 00197 * oid *var_name IN - object id of variable 00198 * int *var_name_len IN - length of object id 00199 * u_char var_val_type IN - type of variable 00200 * int var_val_len IN - length of variable 00201 * u_char *var_val IN - value of variable 00202 * int *listlength IN/OUT - number of valid bytes left in 00203 * output buffer 00204 */ 00205 00206 u_char * 00207 snmp_build_var_op(u_char * data, 00208 oid * var_name, 00209 size_t * var_name_len, 00210 u_char var_val_type, 00211 size_t var_val_len, 00212 u_char * var_val, size_t * listlength) 00213 { 00214 size_t dummyLen, headerLen; 00215 u_char *dataPtr; 00216 00217 dummyLen = *listlength; 00218 dataPtr = data; 00219 #if 0 00220 data = asn_build_sequence(data, &dummyLen, 00221 (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), 00222 0); 00223 if (data == NULL) { 00224 return NULL; 00225 } 00226 #endif 00227 if (dummyLen < 4) 00228 return NULL; 00229 data += 4; 00230 dummyLen -= 4; 00231 00232 headerLen = data - dataPtr; 00233 *listlength -= headerLen; 00234 DEBUGDUMPHEADER("send", "Name"); 00235 data = asn_build_objid(data, listlength, 00236 (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | 00237 ASN_OBJECT_ID), var_name, 00238 *var_name_len); 00239 DEBUGINDENTLESS(); 00240 if (data == NULL) { 00241 ERROR_MSG("Can't build OID for variable"); 00242 return NULL; 00243 } 00244 DEBUGDUMPHEADER("send", "Value"); 00245 switch (var_val_type) { 00246 case ASN_INTEGER: 00247 data = asn_build_int(data, listlength, var_val_type, 00248 (long *) var_val, var_val_len); 00249 break; 00250 case ASN_GAUGE: 00251 case ASN_COUNTER: 00252 case ASN_TIMETICKS: 00253 case ASN_UINTEGER: 00254 data = asn_build_unsigned_int(data, listlength, var_val_type, 00255 (u_long *) var_val, var_val_len); 00256 break; 00257 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00258 case ASN_OPAQUE_COUNTER64: 00259 case ASN_OPAQUE_U64: 00260 #endif 00261 case ASN_COUNTER64: 00262 data = asn_build_unsigned_int64(data, listlength, var_val_type, 00263 (struct counter64 *) var_val, 00264 var_val_len); 00265 break; 00266 case ASN_OCTET_STR: 00267 case ASN_IPADDRESS: 00268 case ASN_OPAQUE: 00269 case ASN_NSAP: 00270 data = asn_build_string(data, listlength, var_val_type, 00271 var_val, var_val_len); 00272 break; 00273 case ASN_OBJECT_ID: 00274 data = asn_build_objid(data, listlength, var_val_type, 00275 (oid *) var_val, var_val_len / sizeof(oid)); 00276 break; 00277 case ASN_NULL: 00278 data = asn_build_null(data, listlength, var_val_type); 00279 break; 00280 case ASN_BIT_STR: 00281 data = asn_build_bitstring(data, listlength, var_val_type, 00282 var_val, var_val_len); 00283 break; 00284 case SNMP_NOSUCHOBJECT: 00285 case SNMP_NOSUCHINSTANCE: 00286 case SNMP_ENDOFMIBVIEW: 00287 data = asn_build_null(data, listlength, var_val_type); 00288 break; 00289 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00290 case ASN_OPAQUE_FLOAT: 00291 data = asn_build_float(data, listlength, var_val_type, 00292 (float *) var_val, var_val_len); 00293 break; 00294 case ASN_OPAQUE_DOUBLE: 00295 data = asn_build_double(data, listlength, var_val_type, 00296 (double *) var_val, var_val_len); 00297 break; 00298 case ASN_OPAQUE_I64: 00299 data = asn_build_signed_int64(data, listlength, var_val_type, 00300 (struct counter64 *) var_val, 00301 var_val_len); 00302 break; 00303 #endif /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */ 00304 default: 00305 { 00306 char error_buf[64]; 00307 snprintf(error_buf, sizeof(error_buf), 00308 "wrong type in snmp_build_var_op: %d", var_val_type); 00309 ERROR_MSG(error_buf); 00310 data = NULL; 00311 } 00312 } 00313 DEBUGINDENTLESS(); 00314 if (data == NULL) { 00315 return NULL; 00316 } 00317 dummyLen = (data - dataPtr) - headerLen; 00318 00319 asn_build_sequence(dataPtr, &dummyLen, 00320 (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), 00321 dummyLen); 00322 return data; 00323 } 00324 00325 #ifdef NETSNMP_USE_REVERSE_ASNENCODING 00326 int 00327 snmp_realloc_rbuild_var_op(u_char ** pkt, size_t * pkt_len, 00328 size_t * offset, int allow_realloc, 00329 const oid * var_name, size_t * var_name_len, 00330 u_char var_val_type, 00331 u_char * var_val, size_t var_val_len) 00332 { 00333 size_t start_offset = *offset; 00334 int rc = 0; 00335 00336 /* 00337 * Encode the value. 00338 */ 00339 DEBUGDUMPHEADER("send", "Value"); 00340 00341 switch (var_val_type) { 00342 case ASN_INTEGER: 00343 rc = asn_realloc_rbuild_int(pkt, pkt_len, offset, allow_realloc, 00344 var_val_type, (long *) var_val, 00345 var_val_len); 00346 break; 00347 00348 case ASN_GAUGE: 00349 case ASN_COUNTER: 00350 case ASN_TIMETICKS: 00351 case ASN_UINTEGER: 00352 rc = asn_realloc_rbuild_unsigned_int(pkt, pkt_len, offset, 00353 allow_realloc, var_val_type, 00354 (u_long *) var_val, 00355 var_val_len); 00356 break; 00357 00358 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00359 case ASN_OPAQUE_COUNTER64: 00360 case ASN_OPAQUE_U64: 00361 #endif 00362 case ASN_COUNTER64: 00363 rc = asn_realloc_rbuild_unsigned_int64(pkt, pkt_len, offset, 00364 allow_realloc, var_val_type, 00365 (struct counter64 *) 00366 var_val, var_val_len); 00367 break; 00368 00369 case ASN_OCTET_STR: 00370 case ASN_IPADDRESS: 00371 case ASN_OPAQUE: 00372 case ASN_NSAP: 00373 rc = asn_realloc_rbuild_string(pkt, pkt_len, offset, allow_realloc, 00374 var_val_type, var_val, var_val_len); 00375 break; 00376 00377 case ASN_OBJECT_ID: 00378 rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc, 00379 var_val_type, (oid *) var_val, 00380 var_val_len / sizeof(oid)); 00381 break; 00382 00383 case ASN_NULL: 00384 rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc, 00385 var_val_type); 00386 break; 00387 00388 case ASN_BIT_STR: 00389 rc = asn_realloc_rbuild_bitstring(pkt, pkt_len, offset, 00390 allow_realloc, var_val_type, 00391 var_val, var_val_len); 00392 break; 00393 00394 case SNMP_NOSUCHOBJECT: 00395 case SNMP_NOSUCHINSTANCE: 00396 case SNMP_ENDOFMIBVIEW: 00397 rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc, 00398 var_val_type); 00399 break; 00400 00401 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00402 case ASN_OPAQUE_FLOAT: 00403 rc = asn_realloc_rbuild_float(pkt, pkt_len, offset, allow_realloc, 00404 var_val_type, (float *) var_val, 00405 var_val_len); 00406 break; 00407 00408 case ASN_OPAQUE_DOUBLE: 00409 rc = asn_realloc_rbuild_double(pkt, pkt_len, offset, allow_realloc, 00410 var_val_type, (double *) var_val, 00411 var_val_len); 00412 break; 00413 00414 case ASN_OPAQUE_I64: 00415 rc = asn_realloc_rbuild_signed_int64(pkt, pkt_len, offset, 00416 allow_realloc, var_val_type, 00417 (struct counter64 *) var_val, 00418 var_val_len); 00419 break; 00420 #endif /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */ 00421 default: 00422 { 00423 char error_buf[64]; 00424 snprintf(error_buf, sizeof(error_buf), 00425 "wrong type in snmp_realloc_rbuild_var_op: %d", var_val_type); 00426 ERROR_MSG(error_buf); 00427 rc = 0; 00428 } 00429 } 00430 DEBUGINDENTLESS(); 00431 00432 if (rc == 0) { 00433 return 0; 00434 } 00435 00436 /* 00437 * Build the OID. 00438 */ 00439 00440 DEBUGDUMPHEADER("send", "Name"); 00441 rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc, 00442 (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | 00443 ASN_OBJECT_ID), var_name, 00444 *var_name_len); 00445 DEBUGINDENTLESS(); 00446 if (rc == 0) { 00447 ERROR_MSG("Can't build OID for variable"); 00448 return 0; 00449 } 00450 00451 /* 00452 * Build the sequence header. 00453 */ 00454 00455 rc = asn_realloc_rbuild_sequence(pkt, pkt_len, offset, allow_realloc, 00456 (u_char) (ASN_SEQUENCE | 00457 ASN_CONSTRUCTOR), 00458 *offset - start_offset); 00459 return rc; 00460 } 00461 00462 #endif /* NETSNMP_USE_REVERSE_ASNENCODING */