2 * Routines for SNMP (simple network management protocol)
5 * $Id: packet-snmp.c,v 1.15 1999/12/05 02:32:38 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@unicom.net>
9 * Copyright 1998 Didier Jorand
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #if defined(HAVE_UCD_SNMP_SNMP_H)
32 # define WITH_SNMP_UCD 1
33 #elif defined(HAVE_SNMP_SNMP_H)
34 # define WITH_SNMP_CMU 1
41 #ifdef HAVE_SYS_TYPES_H
42 # include <sys/types.h>
45 #ifdef HAVE_NETINET_IN_H
46 # include <netinet/in.h>
52 #include "packet-snmp.h"
54 static int proto_snmp = -1;
56 static gint ett_snmp = -1;
58 #if defined(WITH_SNMP_CMU) || defined(WITH_SNMP_UCD)
60 #define in_addr_t u_int
63 /* should be defined only if supported in ucd-snmp */
64 #define OPAQUE_SPECIAL_TYPES 1
65 #include <ucd-snmp/asn1.h>
66 #include <ucd-snmp/snmp.h>
67 #include <ucd-snmp/snmp_api.h>
68 #include <ucd-snmp/snmp_impl.h>
69 #include <ucd-snmp/mib.h>
71 typedef long SNMP_INT;
72 typedef unsigned long SNMP_UINT;
73 #define OID_FORMAT_STRING "%ld"
74 #define OID_FORMAT_STRING1 ".%ld"
78 #include <snmp/snmp.h>
79 #include <snmp/snmp_impl.h>
82 #define MAX_NAME_LEN SNMP_MAX_LEN
85 #define SNMP_MSG_GET GET_REQ_MSG
86 #define SNMP_MSG_GETNEXT GETNEXT_REQ_MSG
87 #define SNMP_MSG_RESPONSE GET_RSP_MSG
88 #define SNMP_MSG_SET SET_REQ_MSG
89 #define SNMP_MSG_TRAP TRP_REQ_MSG
91 #ifdef GETBULK_REQ_MSG
92 #define SNMP_MSG_GETBULK GETBULK_REQ_MSG
94 #define SNMP_MSG_GETBULK SNMP_PDU_GETBULK
98 #define SNMP_MSG_INFORM INFORM_REQ_MSG
100 #define SNMP_MSG_INFORM SNMP_PDU_INFORM
104 #define SNMP_MSG_TRAP2 TRP2_REQ_MSG
106 #define SNMP_MSG_TRAP2 SNMP_PDU_V2TRAP
110 #define SNMP_MSG_REPORT REPORT_MSG
112 #define SNMP_MSG_REPORT SNMP_PDU_REPORT
115 #ifndef SNMP_VERSION_2c
116 #define SNMP_VERSION_2c 1
118 #ifndef SNMP_VERSION_2u
119 #define SNMP_VERSION_2u 2
121 #ifndef SNMP_VERSION_3
122 #define SNMP_VERSION_3 3
125 #ifdef SNMP_TRAP_AUTHENTICATIONFAILURE
126 #define SNMP_TRAP_AUTHFAIL SNMP_TRAP_AUTHENTICATIONFAILURE
129 #ifndef COMMUNITY_MAX_LEN
130 #define COMMUNITY_MAX_LEN 256
134 #define ASN_INTEGER SMI_INTEGER
136 #ifndef ASN_OCTET_STR
137 #define ASN_OCTET_STR SMI_STRING
139 #ifndef ASN_OBJECT_ID
140 #define ASN_OBJECT_ID SMI_OBJID
143 #define ASN_NULL SMI_NULLOBJ
146 #ifndef ASN_IPADDRESS
148 #define ASN_IPADDRESS IPADDRESS
150 #define ASN_IPADDRESS SMI_IPADDRESS
156 #define ASN_COUNTER COUNTER
158 #define ASN_COUNTER SMI_COUNTER32
164 #define ASN_GAUGE GAUGE
166 #define ASN_GAUGE SMI_GAUGE32
170 #ifndef ASN_TIMETICKS
172 #define ASN_TIMETICKS TIMETICKS
174 #define ASN_TIMETICKS SMI_TIMETICKS
180 #define ASN_OPAQUE OPAQUE
182 #define ASN_OPAQUE SMI_OPAQUE
186 #ifndef ASN_COUNTER64
188 #define ASN_COUNTER64 COUNTER64
190 #define ASN_COUNTER64 SMI_COUNTER64
195 /* historic: should not be used! */
196 #define ASN_UINTEGER (ASN_APPLICATION | 7)
199 /* historic: should not be used! */
200 #define ASN_NSAP (ASN_APPLICATION | 5)
202 #ifndef SNMP_NOSUCHOBJECT
203 #define SNMP_NOSUCHOBJECT SMI_NOSUCHOBJECT
205 #ifndef SNMP_NOSUCHINSTANCE
206 #define SNMP_NOSUCHINSTANCE SMI_NOSUCHINSTANCE
208 #ifndef SNMP_ENDOFMIBVIEW
209 #define SNMP_ENDOFMIBVIEW SMI_ENDOFMIBVIEW
212 typedef int SNMP_INT;
213 typedef unsigned int SNMP_UINT;
214 #define OID_FORMAT_STRING "%d"
215 #define OID_FORMAT_STRING1 ".%d"
217 #endif /* WITH_SNMP_CMU */
219 static const value_string versions[] = {
220 { SNMP_VERSION_1, "VERSION 1" },
221 { SNMP_VERSION_2c, "VERSION 2C" },
222 { SNMP_VERSION_2u, "VERSION 2U" },
223 { SNMP_VERSION_3, "VERSION 3" },
227 static const value_string pdu_types[] = {
228 { SNMP_MSG_GET, "GET" },
229 { SNMP_MSG_GETNEXT, "GET-NEXT" },
230 { SNMP_MSG_SET, "SET" },
231 { SNMP_MSG_RESPONSE, "RESPONSE" },
232 { SNMP_MSG_TRAP, "TRAP-V1" },
233 { SNMP_MSG_GETBULK, "GETBULK" },
234 { SNMP_MSG_INFORM, "INFORM" },
235 { SNMP_MSG_TRAP2, "TRAP-V2" },
236 { SNMP_MSG_REPORT, "REPORT" },
240 static const value_string error_statuses[] = {
241 { SNMP_ERR_NOERROR, "NO ERROR" },
242 { SNMP_ERR_TOOBIG, "ERROR: TOOBIG" },
243 { SNMP_ERR_NOSUCHNAME, "ERROR: NO SUCH NAME" },
244 { SNMP_ERR_BADVALUE, "ERROR: BAD VALUE" },
245 { SNMP_ERR_READONLY, "ERROR: READ ONLY" },
246 { SNMP_ERR_GENERR, "ERROR: GENERIC ERROR" },
247 { SNMP_ERR_NOACCESS, "ERROR: NO ACCESS" },
248 { SNMP_ERR_WRONGTYPE, "ERROR: WRONG TYPE" },
249 { SNMP_ERR_WRONGLENGTH, "ERROR: WRONG LENGTH" },
250 { SNMP_ERR_WRONGENCODING, "ERROR: WRONG ENCODING" },
251 { SNMP_ERR_WRONGVALUE, "ERROR: WRONG VALUE" },
252 { SNMP_ERR_NOCREATION, "ERROR: NO CREATION" },
253 { SNMP_ERR_INCONSISTENTVALUE, "ERROR: INCONSISTENT VALUE" },
254 { SNMP_ERR_RESOURCEUNAVAILABLE, "ERROR: RESOURCE UNAVAILABLE" },
255 { SNMP_ERR_COMMITFAILED, "ERROR: COMMIT FAILED" },
256 { SNMP_ERR_UNDOFAILED, "ERROR: UNDO FAILED" },
257 { SNMP_ERR_AUTHORIZATIONERROR, "ERROR: AUTHORIZATION ERROR" },
258 { SNMP_ERR_NOTWRITABLE, "ERROR: NOT WRITABLE" },
259 { SNMP_ERR_INCONSISTENTNAME, "ERROR: INCONSISTENT NAME" },
263 static const value_string trap_types[] = {
264 { SNMP_TRAP_COLDSTART, "COLD START" },
265 { SNMP_TRAP_WARMSTART, "WARM START" },
266 { SNMP_TRAP_LINKDOWN, "LINK DOWN" },
267 { SNMP_TRAP_LINKUP, "LINK UP" },
268 { SNMP_TRAP_AUTHFAIL, "AUTHENTICATION FAILED" },
269 { SNMP_TRAP_EGPNEIGHBORLOSS, "EGP NEIGHBORLOSS" },
270 { SNMP_TRAP_ENTERPRISESPECIFIC, "ENTERPRISE SPECIFIC" },
275 dissect_snmp_error(const u_char *pd, int offset, frame_data *fd,
276 proto_tree *tree, const char *message)
278 if (check_col(fd, COL_INFO))
279 col_add_str(fd, COL_INFO, message);
281 dissect_data(pd, offset, fd, tree);
285 dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
286 proto_tree *tree, char *proto_name, int proto, gint ett)
288 int length=fd->pkt_len-offset;
289 u_char *data, *tmp_data;
291 int all_length, header_length;
292 u_char type, pdu_type;
294 SNMP_INT request_id, error_status, error_index;
295 int request_id_length, error_status_length, error_index_length;
298 u_char community[COMMUNITY_MAX_LEN];
299 int community_length = COMMUNITY_MAX_LEN;
301 oid enterprise[MAX_NAME_LEN];
302 int enterprise_length;
303 SNMP_INT trap_type, specific_type;
307 oid vb_name[MAX_NAME_LEN];
311 char vb_string[MAX_NAME_LEN*6]; /* TBC */
312 char vb_string2[2048]; /* TBC */
314 SNMP_INT vb_integer_value;
315 SNMP_UINT vb_unsigned_value;
317 struct counter64 vb_counter64_value;
319 oid vb_oid_value[MAX_NAME_LEN];
320 int vb_oid_value_length;
321 unsigned char vb_string_value[128];
322 int vb_string_value_length;
324 float vb_float_value;
325 double vb_double_value;
330 char *pdu_type_string;
332 proto_tree *snmp_tree=NULL;
333 proto_item *item=NULL;
335 if (check_col(fd, COL_PROTOCOL))
336 col_add_str(fd, COL_PROTOCOL, proto_name);
338 /* NOTE: we have to parse the message piece by piece, since the
339 * capture length may be less than the message length: a 'global'
340 * parsing is likely to fail.
344 /* parse the SNMP header */
345 if(NULL == asn_parse_header((u_char*)&pd[offset], &length, &type)) {
346 dissect_snmp_error(pd, offset, fd, tree,
347 "Couldn't parse SNMP header");
351 if (type != (ASN_SEQUENCE | ASN_CONSTRUCTOR)) {
352 dissect_snmp_error(pd, offset, fd, tree, "Not an SNMP PDU");
356 /* authenticates message */
357 length=fd->pkt_len-offset;
358 header_length=length;
359 data = snmp_comstr_parse((u_char*)&pd[offset], &length, community, &community_length, (long*)&version);
361 dissect_snmp_error(pd, offset, fd, tree,
362 "Couldn't parse authentication");
365 #endif /* WITH_SNMP_UCD */
367 /* initialize length variables */
368 /* length=fd->pkt_len-offset; */
369 header_length=length;
371 /* parse the SNMP header */
372 data = asn_parse_header((u_char*)&pd[offset], &length, &type);
374 dissect_snmp_error(pd, offset, fd, tree,
375 "Couldn't parse SNMP header");
379 if (type != (ASN_SEQUENCE | ASN_CONSTRUCTOR)) {
380 dissect_snmp_error(pd, offset, fd, tree, "Not an SNMP PDU");
384 data = asn_parse_int(data, &length, &type, &version, sizeof(SNMP_INT));
386 dissect_snmp_error(pd, offset, fd, tree,
387 "Couldn't parse SNMP version number");
390 data = asn_parse_string(data, &length, &type, community, &community_length);
392 dissect_snmp_error(pd, offset, fd, tree,
393 "Couldn't parse SNMP community");
396 community[community_length] = '\0';
397 #endif /* WITH_SNMP_CMU */
399 header_length-=length;
400 /* printf("Community is %s, version is %d (header length is %d)\n", community, version, header_length); */
401 if(version != SNMP_VERSION_1) {
402 dissect_snmp_error(pd, offset, fd, tree,
403 "Non-version-1 SNMP PDU");
407 pdu_type_length=length;
408 data = asn_parse_header(data, &length, &pdu_type);
410 dissect_snmp_error(pd, offset, fd, tree,
411 "Couldn't parse PDU type");
414 pdu_type_length-=length;
415 /* printf("pdu type is %#x (length is %d)\n", type, pdu_type_length); */
417 /* get the fields in the PDU preceeding the variable-bindings sequence */
418 if (pdu_type != SNMP_MSG_TRAP) {
421 request_id_length=length;
422 data = asn_parse_int(data, &length, &type, &request_id, sizeof(request_id));
424 dissect_snmp_error(pd, offset, fd, tree,
425 "Couldn't parse request ID");
428 request_id_length-=length;
429 /* printf("request id is %#lx (length is %d)\n", request_id, request_id_length); */
431 /* error status (getbulk non-repeaters) */
432 error_status_length=length;
433 data = asn_parse_int(data, &length, &type, &error_status, sizeof(error_status));
435 dissect_snmp_error(pd, offset, fd, tree,
436 "Couldn't parse error status");
439 error_status_length-=length;
441 /* error index (getbulk max-repetitions) */
442 error_index_length=length;
443 data = asn_parse_int(data, &length, &type, &error_index, sizeof(error_index));
445 dissect_snmp_error(pd, offset, fd, tree,
446 "Couldn't parse error index");
449 error_index_length-=length;
451 pdu_type_string = val_to_str(pdu_type, pdu_types,
452 "Unknown PDU type %#x");
453 if (check_col(fd, COL_INFO))
454 col_add_str(fd, COL_INFO, pdu_type_string);
456 /* all_length=header_length+pdu_type_length+request_id_length+error_status_length+error_index_length; */
457 all_length=fd->pkt_len-offset;
458 item = proto_tree_add_item(tree, proto, offset, all_length, NULL);
459 snmp_tree = proto_item_add_subtree(item, ett);
460 proto_tree_add_text(snmp_tree, offset, header_length, "Community: \"%s\", Version: %s", community, val_to_str(version, versions, "Unknown version %#x"));
461 offset+=header_length;
462 proto_tree_add_text(snmp_tree, offset, pdu_type_length, "%s", pdu_type_string);
463 offset+=pdu_type_length;
464 proto_tree_add_text(snmp_tree, offset, request_id_length, "Request Id.: %#x", (unsigned int)request_id);
465 offset+=request_id_length;
466 proto_tree_add_text(snmp_tree, offset, error_status_length, "Error Status: %s", val_to_str(error_status, error_statuses, "Unknown (%d)"));
467 offset+=error_status_length;
468 proto_tree_add_text(snmp_tree, offset, error_index_length, "Error Index: %d", (int)error_index);
469 offset+=error_index_length;
471 offset+=header_length;
472 offset+=pdu_type_length;
473 offset+=request_id_length;
474 offset+=error_status_length;
475 offset+=error_index_length;
479 /* an SNMPv1 trap PDU */
480 pdu_type_string = val_to_str(pdu_type, pdu_types,
481 "Unknown PDU type %#x");
482 if (check_col(fd, COL_INFO))
483 col_add_str(fd, COL_INFO, pdu_type_string);
485 all_length=fd->pkt_len-offset;
486 item = proto_tree_add_item(tree, proto, offset, all_length, NULL);
487 snmp_tree = proto_item_add_subtree(item, ett);
488 proto_tree_add_text(snmp_tree, offset, header_length, "Community: \"%s\", Version: %s", community, val_to_str(version, versions, "Unknown version %#x"));
489 offset+=header_length;
490 proto_tree_add_text(snmp_tree, offset, pdu_type_length, "Pdu type: %s", pdu_type_string);
491 offset+=pdu_type_length;
493 offset+=header_length;
494 offset+=pdu_type_length;
498 enterprise_length = MAX_NAME_LEN;
500 data = asn_parse_objid(data, &length, &type, enterprise, &enterprise_length);
502 dissect_snmp_error(pd, offset, fd, tree,
503 "Couldn't parse enterprise OID");
508 sprintf(vb_string, OID_FORMAT_STRING, enterprise[0]);
509 for(i=1; i<enterprise_length;i++) {
510 sprintf(tmp_string, OID_FORMAT_STRING1, enterprise[i]);
511 strcat(vb_string,tmp_string);
514 proto_tree_add_text(snmp_tree, offset, tmp_length, "Enterprise: %s", vb_string);
519 vb_string_value_length = 4;
521 data = asn_parse_string(data, &length, &type, vb_string_value, &vb_string_value_length);
523 dissect_snmp_error(pd, offset, fd, tree,
524 "Couldn't parse agent address");
529 proto_tree_add_text(snmp_tree, offset, tmp_length, "Agent address: %d.%d.%d.%d",
530 vb_string_value[0],vb_string_value[1],vb_string_value[2],vb_string_value[3]);
536 data = asn_parse_int(data, &length, &type, &trap_type, sizeof(trap_type));
538 dissect_snmp_error(pd, offset, fd, tree,
539 "Couldn't parse trap type");
544 proto_tree_add_text(snmp_tree, offset, tmp_length, "Trap type: %s", val_to_str(trap_type, trap_types, "Unknown (%d)"));
550 data = asn_parse_int(data, &length, &type, &specific_type, sizeof(specific_type));
552 dissect_snmp_error(pd, offset, fd, tree,
553 "Couldn't parse specific trap type");
558 proto_tree_add_text(snmp_tree, offset, tmp_length, "Specific trap type: %ld (%#lx)", (long)specific_type, (long)specific_type);
564 data = asn_parse_unsigned_int(data, &length, &type, ×tamp, sizeof(timestamp));
566 dissect_snmp_error(pd, offset, fd, tree,
567 "Couldn't parse time stamp");
572 proto_tree_add_text(snmp_tree, offset, tmp_length, "Timestamp: %lu", (unsigned long)timestamp);
577 /* variable bindings */
578 /* get header for variable-bindings sequence */
580 data = asn_parse_header(data, &length, &type);
582 dissect_snmp_error(pd, offset, fd, tree,
583 "Couldn't variable-bindings header");
587 if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR)) {
588 dissect_snmp_error(pd, offset, fd, tree,
589 "Bad type for variable-bindings header");
593 /* printf("VB header: offset is %d; length is %d.\n", offset, tmp_length); */
595 /* loop on variable bindings */
599 /* printf("VB index is %d (offset=%d; length=%d).\n", vb_index, offset, length); */
603 data = asn_parse_header(data, &tmp_length, &type);
605 dissect_snmp_error(pd, offset, fd, tree,
606 "Couldn't parse variable-binding header");
609 if (type != (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR)) {
610 dissect_snmp_error(pd, offset, fd, tree,
611 "Bad type for variable-binding header");
614 tmp_length=(int)(data-tmp_data);
618 /* parse object identifier */
619 vb_name_length=MAX_NAME_LEN;
621 data = asn_parse_objid(data, &length, &type, vb_name, &vb_name_length);
623 dissect_snmp_error(pd, offset, fd, tree,
624 "No object-identifier for variable-binding");
628 if (type != (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID)) {
629 dissect_snmp_error(pd, offset, fd, tree,
630 "Bad type for variable-binding");
636 sprintf(vb_string, OID_FORMAT_STRING, vb_name[0]);
637 for(i=1; i<vb_name_length;i++) {
638 sprintf(tmp_string, OID_FORMAT_STRING1, vb_name[i]);
639 strcat(vb_string,tmp_string);
642 sprint_objid(vb_string2, vb_name, vb_name_length);
644 proto_tree_add_text(snmp_tree, offset, tmp_length, "Object identifier %d: %s (%s)", vb_index, vb_string, vb_string2);
648 /* parse the type of the object */
650 if (NULL == asn_parse_header(data, &tmp_length, &vb_type)){
651 dissect_snmp_error(pd, offset, fd, tree,
652 "Bad type for variable-binding value");
656 /* parse the value */
660 data=asn_parse_null(data, &length, &type);
663 dissect_snmp_error(pd, offset, fd, tree,
664 "Couldn't parse null value");
668 proto_tree_add_text(snmp_tree, offset, tmp_length, "Value: NULL");
675 data=asn_parse_int(data, &length, &type, &vb_integer_value, sizeof(vb_integer_value));
678 dissect_snmp_error(pd, offset, fd, tree,
679 "Couldn't parse integer value");
683 proto_tree_add_text(snmp_tree, offset, tmp_length, "Value: <i> %ld (%#lx)", (long)vb_integer_value, (long)vb_integer_value);
693 data=asn_parse_unsigned_int(data, &length, &type, &vb_unsigned_value, sizeof(vb_unsigned_value));
696 dissect_snmp_error(pd, offset, fd, tree,
697 "Couldn't parse unsigned value");
701 proto_tree_add_text(snmp_tree, offset, tmp_length, "Value: <u> %lu (%#lx)", (unsigned long)vb_unsigned_value, (unsigned long)vb_unsigned_value);
707 /* only ucd support 64bits types */
709 #ifdef OPAQUE_SPECIAL_TYPES
710 case ASN_OPAQUE_COUNTER64:
712 #endif /* OPAQUE_SPECIAL_TYPES */
714 data=asn_parse_unsigned_int64(data, &length, &type, &vb_counter64_value, sizeof(vb_counter64_value));
717 dissect_snmp_error(pd, offset, fd, tree,
718 "Couldn't parse counter64 value");
722 proto_tree_add_text(snmp_tree, offset, tmp_length, "Value: <i64> %lu:%lu (%#lx:%lx)",
723 vb_counter64_value.high,
724 vb_counter64_value.low,
725 vb_counter64_value.high,
726 vb_counter64_value.low);
730 #endif /* WITH_SNMP_UCD */
733 vb_oid_value_length = MAX_NAME_LEN;
735 data=asn_parse_objid(data, &length, &type, vb_oid_value, &vb_oid_value_length);
738 dissect_snmp_error(pd, offset, fd, tree,
739 "Couldn't parse OID value");
743 sprintf(vb_string, OID_FORMAT_STRING, vb_oid_value[0]);
744 for(i=1; i<vb_oid_value_length;i++) {
745 sprintf(tmp_string, OID_FORMAT_STRING1, vb_oid_value[i]);
746 strcat(vb_string,tmp_string);
748 proto_tree_add_text(snmp_tree, offset, tmp_length, "Value: <oid> %s", vb_string);
756 vb_string_value_length=128;
758 data=asn_parse_string(data, &length, &type, vb_string_value, &vb_string_value_length);
761 dissect_snmp_error(pd, offset, fd, tree,
762 "Couldn't parse octet string value");
766 vb_string_value[vb_string_value_length]=0;
767 /* if some characters are not printable, display the string as
769 for(i=0; i<vb_string_value_length; i++) {
770 if(!(isprint(vb_string_value[i]) || isspace(vb_string_value[i]))) break;
772 if(i<vb_string_value_length) {
773 sprintf(vb_string, "%03d", (int)vb_string_value[0]);
774 for(i=1; i<vb_string_value_length; i++) {
775 sprintf(tmp_string, ".%03d", (int)vb_string_value[i]);
776 strcat(vb_string,tmp_string);
778 proto_tree_add_text(snmp_tree, offset, tmp_length, "Value: <str> %s", vb_string);
780 proto_tree_add_text(snmp_tree, offset, tmp_length, "Value: <str> %s", vb_string_value);
786 #ifdef OPAQUE_SPECIAL_TYPES
789 data=asn_parse_signed_int64(data, &length, &type, &vb_counter64_value, sizeof(vb_counter64_value));
792 dissect_snmp_error(pd, offset, fd, tree,
793 "Couldn't parse integer64 value");
797 proto_tree_add_text(snmp_tree, offset, tmp_length, "Value: <i64> %ld:%lu (%#lx:%lx)",
798 vb_counter64_value.high,
799 vb_counter64_value.low,
800 vb_counter64_value.high,
801 vb_counter64_value.low);
807 case ASN_OPAQUE_FLOAT:
809 data=asn_parse_float(data, &length, &type,&vb_float_value, sizeof(vb_float_value));
812 dissect_snmp_error(pd, offset, fd, tree,
813 "Couldn't parse float value");
817 proto_tree_add_text(snmp_tree, offset, tmp_length, "Value: <f> %f", (double)vb_float_value);
822 case ASN_OPAQUE_DOUBLE:
824 data=asn_parse_double(data, &length, &type,&vb_double_value, sizeof(vb_double_value));
827 dissect_snmp_error(pd, offset, fd, tree,
828 "Couldn't parse double value");
832 proto_tree_add_text(snmp_tree, offset, tmp_length, "Value: <d> %f", vb_double_value);
836 #endif /* OPAQUE_SPECIAL_TYPES */
838 case SNMP_NOSUCHOBJECT:
840 proto_tree_add_text(snmp_tree, offset, tmp_length, "Value: <err> no such object");
843 case SNMP_NOSUCHINSTANCE:
845 proto_tree_add_text(snmp_tree, offset, tmp_length, "Value: <err> no such instance");
848 case SNMP_ENDOFMIBVIEW:
850 proto_tree_add_text(snmp_tree, offset, tmp_length, "Value: <err> end of mib view");
855 dissect_snmp_error(pd, offset, fd, tree,
856 "Unsupported type for variable-binding value");
862 #else /* WITH_SNMP: CMU or UCD */
864 /* Stub dissector, for use when there's no SNMP library. */
866 dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
867 proto_tree *tree, char *proto_name, int proto, gint ett)
870 proto_tree *snmp_tree;
872 if (check_col(fd, COL_PROTOCOL))
873 col_add_str(fd, COL_PROTOCOL, proto_name);
874 if (check_col(fd, COL_INFO))
875 col_add_str(fd, COL_INFO, "SNMP request or reply");
877 item = proto_tree_add_item(tree, proto, offset, END_OF_FRAME,
879 snmp_tree = proto_item_add_subtree(item, ett);
880 dissect_data(pd, offset, fd, snmp_tree);
884 #endif /* WITH_SNMP: CMU or UCD */
887 dissect_snmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
889 dissect_snmp_pdu(pd, offset, fd, tree, "SNMP", proto_snmp, ett_snmp);
893 * Allow the stuff that builds "register.c" to scan "packet-snmp.c" even
894 * if we're not enabling SNMP decoding (for "canned" source distributions
895 * such as BSD ports, it may be a pain to arrange that it be scanned only
896 * if SNMP is being used), by having "proto_register_snmp()" always be
897 * defined, but not do anything if SNMP decoding isn't enabled.
900 proto_register_snmp(void)
902 #if defined(WITH_SNMP_CMU) || defined(WITH_SNMP_UCD)
903 /* static hf_register_info hf[] = {
905 { "Name", "snmp.abbreviation", TYPE, VALS_POINTER }},
907 #endif /* WITH_SNMP: CMU or UCD */
908 static gint *ett[] = {
912 #if defined(WITH_SNMP_CMU) || defined(WITH_SNMP_UCD)
914 #endif /* WITH_SNMP: CMU or UCD */
915 proto_snmp = proto_register_protocol("Simple Network Management Protocol", "snmp");
916 #if defined(WITH_SNMP_CMU) || defined(WITH_SNMP_UCD)
917 /* proto_register_field_array(proto_snmp, hf, array_length(hf));*/
918 #endif /* WITH_SNMP: CMU or UCD */
919 proto_register_subtree_array(ett, array_length(ett));