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 #if HAVE_WINSOCK_H 00055 #include <winsock.h> 00056 #endif 00057 #ifndef NULL 00058 #define NULL 0 00059 #endif 00060 00061 #if HAVE_DMALLOC_H 00062 #include <dmalloc.h> 00063 #endif 00064 00065 #ifdef vms 00066 #include <in.h> 00067 #endif 00068 00069 #include <net-snmp/types.h> 00070 #include <net-snmp/output_api.h> 00071 00072 #include <net-snmp/library/asn1.h> 00073 #include <net-snmp/library/snmp.h> /* for "internal" definitions */ 00074 #include <net-snmp/library/snmp_api.h> 00075 #include <net-snmp/library/mib.h> 00076 00092 void 00093 xdump(const u_char * cp, size_t length, const char *prefix) 00094 { 00095 int col, count; 00096 char *buffer; 00097 00098 buffer = (char *) malloc(strlen(prefix) + 80); 00099 if (!buffer) { 00100 snmp_log(LOG_NOTICE, 00101 "xdump: malloc failed. packet-dump skipped\n"); 00102 return; 00103 } 00104 00105 count = 0; 00106 while (count < (int) length) { 00107 strcpy(buffer, prefix); 00108 sprintf(buffer + strlen(buffer), "%.4d: ", count); 00109 00110 for (col = 0; ((count + col) < (int) length) && col < 16; col++) { 00111 sprintf(buffer + strlen(buffer), "%02X ", cp[count + col]); 00112 if (col % 4 == 3) 00113 strcat(buffer, " "); 00114 } 00115 for (; col < 16; col++) { /* pad end of buffer with zeros */ 00116 strcat(buffer, " "); 00117 if (col % 4 == 3) 00118 strcat(buffer, " "); 00119 } 00120 strcat(buffer, " "); 00121 for (col = 0; ((count + col) < (int) length) && col < 16; col++) { 00122 buffer[col + 60] = 00123 isprint(cp[count + col]) ? cp[count + col] : '.'; 00124 } 00125 buffer[col + 60] = '\n'; 00126 buffer[col + 60 + 1] = 0; 00127 snmp_log(LOG_DEBUG, "%s", buffer); 00128 count += col; 00129 } 00130 snmp_log(LOG_DEBUG, "\n"); 00131 free(buffer); 00132 00133 } /* end xdump() */ 00134 00135 /* 00136 * u_char * snmp_parse_var_op( 00137 * u_char *data IN - pointer to the start of object 00138 * oid *var_name OUT - object id of variable 00139 * int *var_name_len IN/OUT - length of variable name 00140 * u_char *var_val_type OUT - type of variable (int or octet string) (one byte) 00141 * int *var_val_len OUT - length of variable 00142 * u_char **var_val OUT - pointer to ASN1 encoded value of variable 00143 * int *listlength IN/OUT - number of valid bytes left in var_op_list 00144 */ 00145 00146 u_char * 00147 snmp_parse_var_op(u_char * data, 00148 oid * var_name, 00149 size_t * var_name_len, 00150 u_char * var_val_type, 00151 size_t * var_val_len, 00152 u_char ** var_val, size_t * listlength) 00153 { 00154 u_char var_op_type; 00155 size_t var_op_len = *listlength; 00156 u_char *var_op_start = data; 00157 00158 data = asn_parse_sequence(data, &var_op_len, &var_op_type, 00159 (ASN_SEQUENCE | ASN_CONSTRUCTOR), "var_op"); 00160 if (data == NULL) { 00161 /* 00162 * msg detail is set 00163 */ 00164 return NULL; 00165 } 00166 DEBUGDUMPHEADER("recv", "Name"); 00167 data = 00168 asn_parse_objid(data, &var_op_len, &var_op_type, var_name, 00169 var_name_len); 00170 DEBUGINDENTLESS(); 00171 if (data == NULL) { 00172 ERROR_MSG("No OID for variable"); 00173 return NULL; 00174 } 00175 if (var_op_type != 00176 (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID)) 00177 return NULL; 00178 *var_val = data; /* save pointer to this object */ 00179 /* 00180 * find out what type of object this is 00181 */ 00182 data = asn_parse_header(data, &var_op_len, var_val_type); 00183 if (data == NULL) { 00184 ERROR_MSG("No header for value"); 00185 return NULL; 00186 } 00187 /* 00188 * XXX no check for type! 00189 */ 00190 *var_val_len = var_op_len; 00191 data += var_op_len; 00192 *listlength -= (int) (data - var_op_start); 00193 return data; 00194 } 00195 00196 /* 00197 * u_char * snmp_build_var_op( 00198 * u_char *data IN - pointer to the beginning of the output buffer 00199 * oid *var_name IN - object id of variable 00200 * int *var_name_len IN - length of object id 00201 * u_char var_val_type IN - type of variable 00202 * int var_val_len IN - length of variable 00203 * u_char *var_val IN - value of variable 00204 * int *listlength IN/OUT - number of valid bytes left in 00205 * output buffer 00206 */ 00207 00208 u_char * 00209 snmp_build_var_op(u_char * data, 00210 oid * var_name, 00211 size_t * var_name_len, 00212 u_char var_val_type, 00213 size_t var_val_len, 00214 u_char * var_val, size_t * listlength) 00215 { 00216 size_t dummyLen, headerLen; 00217 u_char *dataPtr; 00218 00219 dummyLen = *listlength; 00220 dataPtr = data; 00221 #if 0 00222 data = asn_build_sequence(data, &dummyLen, 00223 (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), 00224 0); 00225 if (data == NULL) { 00226 return NULL; 00227 } 00228 #endif 00229 if (dummyLen < 4) 00230 return NULL; 00231 data += 4; 00232 dummyLen -= 4; 00233 00234 headerLen = data - dataPtr; 00235 *listlength -= headerLen; 00236 DEBUGDUMPHEADER("send", "Name"); 00237 data = asn_build_objid(data, listlength, 00238 (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | 00239 ASN_OBJECT_ID), var_name, 00240 *var_name_len); 00241 DEBUGINDENTLESS(); 00242 if (data == NULL) { 00243 ERROR_MSG("Can't build OID for variable"); 00244 return NULL; 00245 } 00246 DEBUGDUMPHEADER("send", "Value"); 00247 switch (var_val_type) { 00248 case ASN_INTEGER: 00249 data = asn_build_int(data, listlength, var_val_type, 00250 (long *) var_val, var_val_len); 00251 break; 00252 case ASN_GAUGE: 00253 case ASN_COUNTER: 00254 case ASN_TIMETICKS: 00255 case ASN_UINTEGER: 00256 data = asn_build_unsigned_int(data, listlength, var_val_type, 00257 (u_long *) var_val, var_val_len); 00258 break; 00259 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00260 case ASN_OPAQUE_COUNTER64: 00261 case ASN_OPAQUE_U64: 00262 #endif 00263 case ASN_COUNTER64: 00264 data = asn_build_unsigned_int64(data, listlength, var_val_type, 00265 (struct counter64 *) var_val, 00266 var_val_len); 00267 break; 00268 case ASN_OCTET_STR: 00269 case ASN_IPADDRESS: 00270 case ASN_OPAQUE: 00271 case ASN_NSAP: 00272 data = asn_build_string(data, listlength, var_val_type, 00273 var_val, var_val_len); 00274 break; 00275 case ASN_OBJECT_ID: 00276 data = asn_build_objid(data, listlength, var_val_type, 00277 (oid *) var_val, var_val_len / sizeof(oid)); 00278 break; 00279 case ASN_NULL: 00280 data = asn_build_null(data, listlength, var_val_type); 00281 break; 00282 case ASN_BIT_STR: 00283 data = asn_build_bitstring(data, listlength, var_val_type, 00284 var_val, var_val_len); 00285 break; 00286 case SNMP_NOSUCHOBJECT: 00287 case SNMP_NOSUCHINSTANCE: 00288 case SNMP_ENDOFMIBVIEW: 00289 data = asn_build_null(data, listlength, var_val_type); 00290 break; 00291 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00292 case ASN_OPAQUE_FLOAT: 00293 data = asn_build_float(data, listlength, var_val_type, 00294 (float *) var_val, var_val_len); 00295 break; 00296 case ASN_OPAQUE_DOUBLE: 00297 data = asn_build_double(data, listlength, var_val_type, 00298 (double *) var_val, var_val_len); 00299 break; 00300 case ASN_OPAQUE_I64: 00301 data = asn_build_signed_int64(data, listlength, var_val_type, 00302 (struct counter64 *) var_val, 00303 var_val_len); 00304 break; 00305 #endif /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */ 00306 default: 00307 { 00308 char error_buf[64]; 00309 snprintf(error_buf, sizeof(error_buf), 00310 "wrong type in snmp_build_var_op: %d", var_val_type); 00311 ERROR_MSG(error_buf); 00312 data = NULL; 00313 } 00314 } 00315 DEBUGINDENTLESS(); 00316 if (data == NULL) { 00317 return NULL; 00318 } 00319 dummyLen = (data - dataPtr) - headerLen; 00320 00321 asn_build_sequence(dataPtr, &dummyLen, 00322 (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), 00323 dummyLen); 00324 return data; 00325 } 00326 00327 #ifdef NETSNMP_USE_REVERSE_ASNENCODING 00328 int 00329 snmp_realloc_rbuild_var_op(u_char ** pkt, size_t * pkt_len, 00330 size_t * offset, int allow_realloc, 00331 const oid * var_name, size_t * var_name_len, 00332 u_char var_val_type, 00333 u_char * var_val, size_t var_val_len) 00334 { 00335 size_t start_offset = *offset; 00336 int rc = 0; 00337 00338 /* 00339 * Encode the value. 00340 */ 00341 DEBUGDUMPHEADER("send", "Value"); 00342 00343 switch (var_val_type) { 00344 case ASN_INTEGER: 00345 rc = asn_realloc_rbuild_int(pkt, pkt_len, offset, allow_realloc, 00346 var_val_type, (long *) var_val, 00347 var_val_len); 00348 break; 00349 00350 case ASN_GAUGE: 00351 case ASN_COUNTER: 00352 case ASN_TIMETICKS: 00353 case ASN_UINTEGER: 00354 rc = asn_realloc_rbuild_unsigned_int(pkt, pkt_len, offset, 00355 allow_realloc, var_val_type, 00356 (u_long *) var_val, 00357 var_val_len); 00358 break; 00359 00360 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00361 case ASN_OPAQUE_COUNTER64: 00362 case ASN_OPAQUE_U64: 00363 #endif 00364 case ASN_COUNTER64: 00365 rc = asn_realloc_rbuild_unsigned_int64(pkt, pkt_len, offset, 00366 allow_realloc, var_val_type, 00367 (struct counter64 *) 00368 var_val, var_val_len); 00369 break; 00370 00371 case ASN_OCTET_STR: 00372 case ASN_IPADDRESS: 00373 case ASN_OPAQUE: 00374 case ASN_NSAP: 00375 rc = asn_realloc_rbuild_string(pkt, pkt_len, offset, allow_realloc, 00376 var_val_type, var_val, var_val_len); 00377 break; 00378 00379 case ASN_OBJECT_ID: 00380 rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc, 00381 var_val_type, (oid *) var_val, 00382 var_val_len / sizeof(oid)); 00383 break; 00384 00385 case ASN_NULL: 00386 rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc, 00387 var_val_type); 00388 break; 00389 00390 case ASN_BIT_STR: 00391 rc = asn_realloc_rbuild_bitstring(pkt, pkt_len, offset, 00392 allow_realloc, var_val_type, 00393 var_val, var_val_len); 00394 break; 00395 00396 case SNMP_NOSUCHOBJECT: 00397 case SNMP_NOSUCHINSTANCE: 00398 case SNMP_ENDOFMIBVIEW: 00399 rc = asn_realloc_rbuild_null(pkt, pkt_len, offset, allow_realloc, 00400 var_val_type); 00401 break; 00402 00403 #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES 00404 case ASN_OPAQUE_FLOAT: 00405 rc = asn_realloc_rbuild_float(pkt, pkt_len, offset, allow_realloc, 00406 var_val_type, (float *) var_val, 00407 var_val_len); 00408 break; 00409 00410 case ASN_OPAQUE_DOUBLE: 00411 rc = asn_realloc_rbuild_double(pkt, pkt_len, offset, allow_realloc, 00412 var_val_type, (double *) var_val, 00413 var_val_len); 00414 break; 00415 00416 case ASN_OPAQUE_I64: 00417 rc = asn_realloc_rbuild_signed_int64(pkt, pkt_len, offset, 00418 allow_realloc, var_val_type, 00419 (struct counter64 *) var_val, 00420 var_val_len); 00421 break; 00422 #endif /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */ 00423 default: 00424 { 00425 char error_buf[64]; 00426 snprintf(error_buf, sizeof(error_buf), 00427 "wrong type in snmp_realloc_rbuild_var_op: %d", var_val_type); 00428 ERROR_MSG(error_buf); 00429 rc = 0; 00430 } 00431 } 00432 DEBUGINDENTLESS(); 00433 00434 if (rc == 0) { 00435 return 0; 00436 } 00437 00438 /* 00439 * Build the OID. 00440 */ 00441 00442 DEBUGDUMPHEADER("send", "Name"); 00443 rc = asn_realloc_rbuild_objid(pkt, pkt_len, offset, allow_realloc, 00444 (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | 00445 ASN_OBJECT_ID), var_name, 00446 *var_name_len); 00447 DEBUGINDENTLESS(); 00448 if (rc == 0) { 00449 ERROR_MSG("Can't build OID for variable"); 00450 return 0; 00451 } 00452 00453 /* 00454 * Build the sequence header. 00455 */ 00456 00457 rc = asn_realloc_rbuild_sequence(pkt, pkt_len, offset, allow_realloc, 00458 (u_char) (ASN_SEQUENCE | 00459 ASN_CONSTRUCTOR), 00460 *offset - start_offset); 00461 return rc; 00462 } 00463 00464 #endif /* NETSNMP_USE_REVERSE_ASNENCODING */
Last modified: Wednesday, 01-Aug-2018 04:41:28 UTC
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.