1 /* Do not modify this file. Changes will be overwritten.                      */
2 /* Generated automatically by the ASN.1 to Wireshark dissector compiler       */
3 /* packet-snmp.c                                                              */
4 /* asn2wrs.py -b -p snmp -c ./snmp.cnf -s ./packet-snmp-template -D . -O ../.. snmp.asn */
5 
6 /* Input file: packet-snmp-template.c */
7 
8 #line 1 "./asn1/snmp/packet-snmp-template.c"
9 /* packet-snmp.c
10  * Routines for SNMP (simple network management protocol)
11  * Copyright (C) 1998 Didier Jorand
12  *
13  * See RFC 1157 for SNMPv1.
14  *
15  * See RFCs 1901, 1905, and 1906 for SNMPv2c.
16  *
17  * See RFCs 1905, 1906, 1909, and 1910 for SNMPv2u [historic].
18  *
19  * See RFCs 2570-2576 for SNMPv3
20  * Updated to use the asn2wrs compiler made by Tomas Kukosa
21  * Copyright (C) 2005 - 2006 Anders Broman [AT] ericsson.com
22  *
23  * See RFC 3414 for User-based Security Model for SNMPv3
24  * See RFC 3826 for  (AES) Cipher Algorithm in the SNMP USM
25  * See RFC 2578 for Structure of Management Information Version 2 (SMIv2)
26  * Copyright (C) 2007 Luis E. Garcia Ontanon <luis@ontanon.org>
27  *
28  * Wireshark - Network traffic analyzer
29  * By Gerald Combs <gerald@wireshark.org>
30  * Copyright 1998 Gerald Combs
31  *
32  * Some stuff from:
33  *
34  * GXSNMP -- An snmp mangament application
35  * Copyright (C) 1998 Gregory McLean & Jochen Friedrich
36  * Beholder RMON ethernet network monitor,Copyright (C) 1993 DNPAP group
37  *
38  * SPDX-License-Identifier: GPL-2.0-or-later
39  */
40 
41 #if 0
42 #include <stdio.h>
43 #define D(args) do {printf args; fflush(stdout); } while(0)
44 #endif
45 
46 #include "config.h"
47 
48 #include <epan/packet.h>
49 #include <epan/strutil.h>
50 #include <epan/conversation.h>
51 #include <epan/etypes.h>
52 #include <epan/prefs.h>
53 #include <epan/addr_resolv.h>
54 #include <epan/next_tvb.h>
55 #include <epan/uat.h>
56 #include <epan/asn1.h>
57 #include <epan/expert.h>
58 #include <epan/oids.h>
59 #include <epan/srt_table.h>
60 #include <epan/tap.h>
61 #include "packet-ipx.h"
62 #include "packet-hpext.h"
63 #include "packet-ber.h"
64 #include "packet-snmp.h"
65 #include <wsutil/wsgcrypt.h>
66 
67 #define PNAME  "Simple Network Management Protocol"
68 #define PSNAME "SNMP"
69 #define PFNAME "snmp"
70 
71 #define UDP_PORT_SNMP		161
72 #define UDP_PORT_SNMP_TRAP	162
73 #define TCP_PORT_SNMP		161
74 #define TCP_PORT_SNMP_TRAP	162
75 #define TCP_PORT_SMUX		199
76 #define UDP_PORT_SNMP_PATROL 8161
77 #define SNMP_NUM_PROCEDURES 8
78 
79 /* Initialize the protocol and registered fields */
80 static int snmp_tap = -1;
81 static int proto_snmp = -1;
82 static int proto_smux = -1;
83 
84 static gboolean display_oid = TRUE;
85 static gboolean snmp_var_in_tree = TRUE;
86 
87 void proto_register_snmp(void);
88 void proto_reg_handoff_snmp(void);
89 void proto_register_smux(void);
90 void proto_reg_handoff_smux(void);
91 
92 static void snmp_usm_password_to_key(const snmp_usm_auth_model_t model, const guint8 *password, guint passwordlen,
93 	const guint8 *engineID, guint engineLength, guint8 *key);
94 
95 static tvbuff_t* snmp_usm_priv_des(snmp_usm_params_t*, tvbuff_t*, packet_info *pinfo, gchar const**);
96 static tvbuff_t* snmp_usm_priv_aes128(snmp_usm_params_t*, tvbuff_t*, packet_info *pinfo, gchar const**);
97 static tvbuff_t* snmp_usm_priv_aes192(snmp_usm_params_t*, tvbuff_t*, packet_info *pinfo, gchar const**);
98 static tvbuff_t* snmp_usm_priv_aes256(snmp_usm_params_t*, tvbuff_t*, packet_info *pinfo, gchar const**);
99 
100 static gboolean snmp_usm_auth(const packet_info *pinfo, const snmp_usm_auth_model_t model, snmp_usm_params_t* p, guint8**, guint*, gchar const**);
101 
102 static const value_string auth_types[] = {
103 	{SNMP_USM_AUTH_MD5,"MD5"},
104 	{SNMP_USM_AUTH_SHA1,"SHA1"},
105 	{SNMP_USM_AUTH_SHA2_224,"SHA2-224"},
106 	{SNMP_USM_AUTH_SHA2_256,"SHA2-256"},
107 	{SNMP_USM_AUTH_SHA2_384,"SHA2-384"},
108 	{SNMP_USM_AUTH_SHA2_512,"SHA2-512"},
109 	{0,NULL}
110 };
111 
112 static const guint auth_hash_len[] = {
113 	HASH_MD5_LENGTH,
114 	HASH_SHA1_LENGTH,
115 	HASH_SHA2_224_LENGTH,
116 	HASH_SHA2_256_LENGTH,
117 	HASH_SHA2_384_LENGTH,
118 	HASH_SHA2_512_LENGTH
119 };
120 
121 static const guint auth_tag_len[] = {
122 	12,
123 	12,
124 	16,
125 	24,
126 	32,
127 	48
128 };
129 
130 static const enum gcry_md_algos auth_hash_algo[] = {
131 	GCRY_MD_MD5,
132 	GCRY_MD_SHA1,
133 	GCRY_MD_SHA224,
134 	GCRY_MD_SHA256,
135 	GCRY_MD_SHA384,
136 	GCRY_MD_SHA512
137 };
138 
139 #define PRIV_DES	0
140 #define PRIV_AES128	1
141 #define PRIV_AES192	2
142 #define PRIV_AES256	3
143 
144 static const value_string priv_types[] = {
145 	{ PRIV_DES,    "DES" },
146 	{ PRIV_AES128, "AES" },
147 	{ PRIV_AES192, "AES192" },
148 	{ PRIV_AES256, "AES256" },
149 	{ 0, NULL}
150 };
151 static snmp_usm_decoder_t priv_protos[] = {
152 	snmp_usm_priv_des,
153 	snmp_usm_priv_aes128,
154 	snmp_usm_priv_aes192,
155 	snmp_usm_priv_aes256
156 };
157 
158 static snmp_ue_assoc_t* ueas = NULL;
159 static guint num_ueas = 0;
160 static snmp_ue_assoc_t* localized_ues = NULL;
161 static snmp_ue_assoc_t* unlocalized_ues = NULL;
162 /****/
163 
164 /* Variables used for handling enterprise specific trap types */
165 typedef struct _snmp_st_assoc_t {
166 	char *enterprise;
167 	guint trap;
168 	char *desc;
169 } snmp_st_assoc_t;
170 static guint num_specific_traps = 0;
171 static snmp_st_assoc_t *specific_traps = NULL;
172 static const char *enterprise_oid = NULL;
173 static guint generic_trap = 0;
174 static guint32 snmp_version = 0;
175 static guint32 RequestID = -1;
176 
177 static snmp_usm_params_t usm_p = {FALSE,FALSE,0,0,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,FALSE};
178 
179 #define TH_AUTH   0x01
180 #define TH_CRYPT  0x02
181 #define TH_REPORT 0x04
182 
183 /* desegmentation of SNMP-over-TCP */
184 static gboolean snmp_desegment = TRUE;
185 
186 /* Global variables */
187 
188 guint32 MsgSecurityModel;
189 tvbuff_t *oid_tvb=NULL;
190 tvbuff_t *value_tvb=NULL;
191 
192 static dissector_handle_t snmp_handle;
193 static dissector_handle_t data_handle;
194 
195 static next_tvb_list_t *var_list;
196 
197 static int hf_snmp_response_in = -1;
198 static int hf_snmp_response_to = -1;
199 static int hf_snmp_time = -1;
200 
201 static int hf_snmp_v3_flags_auth = -1;
202 static int hf_snmp_v3_flags_crypt = -1;
203 static int hf_snmp_v3_flags_report = -1;
204 
205 static int hf_snmp_engineid_conform = -1;
206 static int hf_snmp_engineid_enterprise = -1;
207 static int hf_snmp_engineid_format = -1;
208 static int hf_snmp_engineid_ipv4 = -1;
209 static int hf_snmp_engineid_ipv6 = -1;
210 static int hf_snmp_engineid_cisco_type = -1;
211 static int hf_snmp_engineid_mac = -1;
212 static int hf_snmp_engineid_text = -1;
213 static int hf_snmp_engineid_time = -1;
214 static int hf_snmp_engineid_data = -1;
215 static int hf_snmp_decryptedPDU = -1;
216 static int hf_snmp_msgAuthentication = -1;
217 
218 static int hf_snmp_noSuchObject = -1;
219 static int hf_snmp_noSuchInstance = -1;
220 static int hf_snmp_endOfMibView = -1;
221 static int hf_snmp_unSpecified = -1;
222 
223 static int hf_snmp_integer32_value = -1;
224 static int hf_snmp_octetstring_value = -1;
225 static int hf_snmp_oid_value = -1;
226 static int hf_snmp_null_value = -1;
227 static int hf_snmp_ipv4_value = -1;
228 static int hf_snmp_ipv6_value = -1;
229 static int hf_snmp_anyaddress_value = -1;
230 static int hf_snmp_unsigned32_value = -1;
231 static int hf_snmp_unknown_value = -1;
232 static int hf_snmp_opaque_value = -1;
233 static int hf_snmp_nsap_value = -1;
234 static int hf_snmp_counter_value = -1;
235 static int hf_snmp_timeticks_value = -1;
236 static int hf_snmp_big_counter_value = -1;
237 static int hf_snmp_gauge32_value = -1;
238 
239 static int hf_snmp_objectname = -1;
240 static int hf_snmp_scalar_instance_index = -1;
241 
242 static int hf_snmp_var_bind_str = -1;
243 static int hf_snmp_agentid_trailer = -1;
244 
245 
246 /*--- Included file: packet-snmp-hf.c ---*/
247 #line 1 "./asn1/snmp/packet-snmp-hf.c"
248 static int hf_snmp_SMUX_PDUs_PDU = -1;            /* SMUX_PDUs */
249 static int hf_snmp_version = -1;                  /* Version */
250 static int hf_snmp_community = -1;                /* Community */
251 static int hf_snmp_data = -1;                     /* PDUs */
252 static int hf_snmp_parameters = -1;               /* OCTET_STRING */
253 static int hf_snmp_datav2u = -1;                  /* T_datav2u */
254 static int hf_snmp_v2u_plaintext = -1;            /* PDUs */
255 static int hf_snmp_encrypted = -1;                /* OCTET_STRING */
256 static int hf_snmp_msgAuthoritativeEngineID = -1;  /* T_msgAuthoritativeEngineID */
257 static int hf_snmp_msgAuthoritativeEngineBoots = -1;  /* T_msgAuthoritativeEngineBoots */
258 static int hf_snmp_msgAuthoritativeEngineTime = -1;  /* T_msgAuthoritativeEngineTime */
259 static int hf_snmp_msgUserName = -1;              /* T_msgUserName */
260 static int hf_snmp_msgAuthenticationParameters = -1;  /* T_msgAuthenticationParameters */
261 static int hf_snmp_msgPrivacyParameters = -1;     /* T_msgPrivacyParameters */
262 static int hf_snmp_msgVersion = -1;               /* Version */
263 static int hf_snmp_msgGlobalData = -1;            /* HeaderData */
264 static int hf_snmp_msgSecurityParameters = -1;    /* T_msgSecurityParameters */
265 static int hf_snmp_msgData = -1;                  /* ScopedPduData */
266 static int hf_snmp_msgID = -1;                    /* INTEGER_0_2147483647 */
267 static int hf_snmp_msgMaxSize = -1;               /* INTEGER_484_2147483647 */
268 static int hf_snmp_msgFlags = -1;                 /* T_msgFlags */
269 static int hf_snmp_msgSecurityModel = -1;         /* T_msgSecurityModel */
270 static int hf_snmp_plaintext = -1;                /* ScopedPDU */
271 static int hf_snmp_encryptedPDU = -1;             /* T_encryptedPDU */
272 static int hf_snmp_contextEngineID = -1;          /* SnmpEngineID */
273 static int hf_snmp_contextName = -1;              /* OCTET_STRING */
274 static int hf_snmp_get_request = -1;              /* GetRequest_PDU */
275 static int hf_snmp_get_next_request = -1;         /* GetNextRequest_PDU */
276 static int hf_snmp_get_response = -1;             /* GetResponse_PDU */
277 static int hf_snmp_set_request = -1;              /* SetRequest_PDU */
278 static int hf_snmp_trap = -1;                     /* Trap_PDU */
279 static int hf_snmp_getBulkRequest = -1;           /* GetBulkRequest_PDU */
280 static int hf_snmp_informRequest = -1;            /* InformRequest_PDU */
281 static int hf_snmp_snmpV2_trap = -1;              /* SNMPv2_Trap_PDU */
282 static int hf_snmp_report = -1;                   /* Report_PDU */
283 static int hf_snmp_request_id = -1;               /* T_request_id */
284 static int hf_snmp_error_status = -1;             /* T_error_status */
285 static int hf_snmp_error_index = -1;              /* INTEGER */
286 static int hf_snmp_variable_bindings = -1;        /* VarBindList */
287 static int hf_snmp_bulkPDU_request_id = -1;       /* Integer32 */
288 static int hf_snmp_non_repeaters = -1;            /* INTEGER_0_2147483647 */
289 static int hf_snmp_max_repetitions = -1;          /* INTEGER_0_2147483647 */
290 static int hf_snmp_enterprise = -1;               /* EnterpriseOID */
291 static int hf_snmp_agent_addr = -1;               /* NetworkAddress */
292 static int hf_snmp_generic_trap = -1;             /* GenericTrap */
293 static int hf_snmp_specific_trap = -1;            /* SpecificTrap */
294 static int hf_snmp_time_stamp = -1;               /* TimeTicks */
295 static int hf_snmp_name = -1;                     /* ObjectName */
296 static int hf_snmp_valueType = -1;                /* ValueType */
297 static int hf_snmp_VarBindList_item = -1;         /* VarBind */
298 static int hf_snmp_open = -1;                     /* OpenPDU */
299 static int hf_snmp_close = -1;                    /* ClosePDU */
300 static int hf_snmp_registerRequest = -1;          /* RReqPDU */
301 static int hf_snmp_registerResponse = -1;         /* RegisterResponse */
302 static int hf_snmp_commitOrRollback = -1;         /* SOutPDU */
303 static int hf_snmp_rRspPDU = -1;                  /* RRspPDU */
304 static int hf_snmp_pDUs = -1;                     /* PDUs */
305 static int hf_snmp_smux_simple = -1;              /* SimpleOpen */
306 static int hf_snmp_smux_version = -1;             /* T_smux_version */
307 static int hf_snmp_identity = -1;                 /* OBJECT_IDENTIFIER */
308 static int hf_snmp_description = -1;              /* DisplayString */
309 static int hf_snmp_password = -1;                 /* OCTET_STRING */
310 static int hf_snmp_subtree = -1;                  /* ObjectName */
311 static int hf_snmp_priority = -1;                 /* INTEGER_M1_2147483647 */
312 static int hf_snmp_operation = -1;                /* T_operation */
313 
314 /*--- End of included file: packet-snmp-hf.c ---*/
315 #line 238 "./asn1/snmp/packet-snmp-template.c"
316 
317 /* Initialize the subtree pointers */
318 static gint ett_smux = -1;
319 static gint ett_snmp = -1;
320 static gint ett_engineid = -1;
321 static gint ett_msgFlags = -1;
322 static gint ett_encryptedPDU = -1;
323 static gint ett_decrypted = -1;
324 static gint ett_authParameters = -1;
325 static gint ett_internet = -1;
326 static gint ett_varbind = -1;
327 static gint ett_name = -1;
328 static gint ett_value = -1;
329 static gint ett_decoding_error = -1;
330 
331 
332 /*--- Included file: packet-snmp-ett.c ---*/
333 #line 1 "./asn1/snmp/packet-snmp-ett.c"
334 static gint ett_snmp_Message = -1;
335 static gint ett_snmp_Messagev2u = -1;
336 static gint ett_snmp_T_datav2u = -1;
337 static gint ett_snmp_UsmSecurityParameters = -1;
338 static gint ett_snmp_SNMPv3Message = -1;
339 static gint ett_snmp_HeaderData = -1;
340 static gint ett_snmp_ScopedPduData = -1;
341 static gint ett_snmp_ScopedPDU = -1;
342 static gint ett_snmp_PDUs = -1;
343 static gint ett_snmp_PDU = -1;
344 static gint ett_snmp_BulkPDU = -1;
345 static gint ett_snmp_Trap_PDU_U = -1;
346 static gint ett_snmp_VarBind = -1;
347 static gint ett_snmp_VarBindList = -1;
348 static gint ett_snmp_SMUX_PDUs = -1;
349 static gint ett_snmp_RegisterResponse = -1;
350 static gint ett_snmp_OpenPDU = -1;
351 static gint ett_snmp_SimpleOpen_U = -1;
352 static gint ett_snmp_RReqPDU_U = -1;
353 
354 /*--- End of included file: packet-snmp-ett.c ---*/
355 #line 254 "./asn1/snmp/packet-snmp-template.c"
356 
357 static expert_field ei_snmp_failed_decrypted_data_pdu = EI_INIT;
358 static expert_field ei_snmp_decrypted_data_bad_formatted = EI_INIT;
359 static expert_field ei_snmp_verify_authentication_error = EI_INIT;
360 static expert_field ei_snmp_authentication_ok = EI_INIT;
361 static expert_field ei_snmp_authentication_error = EI_INIT;
362 static expert_field ei_snmp_varbind_not_uni_class_seq = EI_INIT;
363 static expert_field ei_snmp_varbind_has_indicator = EI_INIT;
364 static expert_field ei_snmp_objectname_not_oid = EI_INIT;
365 static expert_field ei_snmp_objectname_has_indicator = EI_INIT;
366 static expert_field ei_snmp_value_not_primitive_encoding = EI_INIT;
367 static expert_field ei_snmp_invalid_oid = EI_INIT;
368 static expert_field ei_snmp_varbind_wrong_tag = EI_INIT;
369 static expert_field ei_snmp_varbind_response = EI_INIT;
370 static expert_field ei_snmp_no_instance_subid = EI_INIT;
371 static expert_field ei_snmp_wrong_num_of_subids = EI_INIT;
372 static expert_field ei_snmp_index_suboid_too_short = EI_INIT;
373 static expert_field ei_snmp_unimplemented_instance_index = EI_INIT;
374 static expert_field ei_snmp_index_suboid_len0 = EI_INIT;
375 static expert_field ei_snmp_index_suboid_too_long = EI_INIT;
376 static expert_field ei_snmp_index_string_too_long = EI_INIT;
377 static expert_field ei_snmp_column_parent_not_row = EI_INIT;
378 static expert_field ei_snmp_uint_too_large = EI_INIT;
379 static expert_field ei_snmp_int_too_large = EI_INIT;
380 static expert_field ei_snmp_integral_value0 = EI_INIT;
381 static expert_field ei_snmp_missing_mib = EI_INIT;
382 static expert_field ei_snmp_varbind_wrong_length_value = EI_INIT;
383 static expert_field ei_snmp_varbind_wrong_class_tag = EI_INIT;
384 static expert_field ei_snmp_rfc1910_non_conformant = EI_INIT;
385 static expert_field ei_snmp_rfc3411_non_conformant = EI_INIT;
386 static expert_field ei_snmp_version_unknown = EI_INIT;
387 static expert_field ei_snmp_trap_pdu_obsolete = EI_INIT;
388 
389 static const true_false_string auth_flags = {
390 	"OK",
391 	"Failed"
392 };
393 
394 /* Security Models */
395 
396 #define SNMP_SEC_ANY			0
397 #define SNMP_SEC_V1			1
398 #define SNMP_SEC_V2C			2
399 #define SNMP_SEC_USM			3
400 
401 static const value_string sec_models[] = {
402 	{ SNMP_SEC_ANY,			"Any" },
403 	{ SNMP_SEC_V1,			"V1" },
404 	{ SNMP_SEC_V2C,			"V2C" },
405 	{ SNMP_SEC_USM,			"USM" },
406 	{ 0,				NULL }
407 };
408 
409 #if 0
410 /* SMUX PDU types */
411 #define SMUX_MSG_OPEN 		0
412 #define SMUX_MSG_CLOSE		1
413 #define SMUX_MSG_RREQ		2
414 #define SMUX_MSG_RRSP		3
415 #define SMUX_MSG_SOUT		4
416 
417 static const value_string smux_types[] = {
418 	{ SMUX_MSG_OPEN,	"Open" },
419 	{ SMUX_MSG_CLOSE,	"Close" },
420 	{ SMUX_MSG_RREQ,	"Registration Request" },
421 	{ SMUX_MSG_RRSP,	"Registration Response" },
422 	{ SMUX_MSG_SOUT,	"Commit Or Rollback" },
423 	{ 0,			NULL }
424 };
425 #endif
426 
427 /* Procedure names (used in Service Response Time) */
428 const value_string snmp_procedure_names[] = {
429 	{ 0,	"Get" },
430 	{ 1,	"GetNext" },
431 	{ 3,	"Set" },
432 	{ 4,	"Register" },
433 	{ 5,	"Bulk" },
434 	{ 6,	"Inform" },
435 	{ 0,	NULL }
436 };
437 
438 #define SNMP_IPA    0		/* IP Address */
439 #define SNMP_CNT    1		/* Counter (Counter32) */
440 #define SNMP_GGE    2		/* Gauge (Gauge32) */
441 #define SNMP_TIT    3		/* TimeTicks */
442 #define SNMP_OPQ    4		/* Opaque */
443 #define SNMP_NSP    5		/* NsapAddress */
444 #define SNMP_C64    6		/* Counter64 */
445 #define SNMP_U32    7		/* Uinteger32 */
446 
447 #define SERR_NSO    0
448 #define SERR_NSI    1
449 #define SERR_EOM    2
450 
451 
452 dissector_table_t value_sub_dissectors_table;
453 
454 /*
455  * Data structure attached to a conversation, request/response information
456  */
457 typedef struct snmp_conv_info_t {
458 	wmem_map_t *request_response;
459 } snmp_conv_info_t;
460 
461 static snmp_request_response_t *
snmp_get_request_response_pointer(wmem_map_t * map,guint32 requestId)462 snmp_get_request_response_pointer(wmem_map_t *map, guint32 requestId)
463 {
464 	snmp_request_response_t *srrp=(snmp_request_response_t *)wmem_map_lookup(map, &requestId);
465 	if (!srrp) {
466 		srrp=wmem_new0(wmem_file_scope(), snmp_request_response_t);
467 		srrp->requestId=requestId;
468 		wmem_map_insert(map, &(srrp->requestId), (void *)srrp);
469 	}
470 
471 	return srrp;
472 }
473 
474 static snmp_request_response_t*
snmp_match_request_response(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint requestId,guint procedure_id,snmp_conv_info_t * snmp_info)475 snmp_match_request_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint requestId, guint procedure_id, snmp_conv_info_t *snmp_info)
476 {
477 	snmp_request_response_t *srrp=NULL;
478 
479 	DISSECTOR_ASSERT_HINT(snmp_info, "No SNMP info from ASN1 context");
480 
481 	/* get or create request/response pointer based on request id */
482 	srrp=(snmp_request_response_t *)snmp_get_request_response_pointer(snmp_info->request_response, requestId);
483 
484 	// if not visited fill the request/response data
485 	if (!PINFO_FD_VISITED(pinfo)) {
486 		switch(procedure_id)
487 		{
488 			case SNMP_REQ_GET:
489 			case SNMP_REQ_GETNEXT:
490 			case SNMP_REQ_SET:
491 			case SNMP_REQ_GETBULK:
492 			case SNMP_REQ_INFORM:
493 				srrp->request_frame_id=pinfo->fd->num;
494 				srrp->response_frame_id=0;
495 				srrp->request_time=pinfo->abs_ts;
496 				srrp->request_procedure_id=procedure_id;
497 				break;
498 			case SNMP_RES_GET:
499 				srrp->response_frame_id=pinfo->fd->num;
500 				break;
501 			default:
502 				return NULL;
503 		}
504 	}
505 
506 	/* if request and response was matched */
507 	if (srrp->request_frame_id!=0 && srrp->response_frame_id!=0)
508 	{
509 		proto_item *it;
510 
511 		// if it is a request
512 		if (srrp->request_frame_id == pinfo->fd->num)
513 		{
514 			it=proto_tree_add_uint(tree, hf_snmp_response_in, tvb, 0, 0, srrp->response_frame_id);
515 			proto_item_set_generated(it);
516 		} else {
517 			nstime_t ns;
518 			it=proto_tree_add_uint(tree, hf_snmp_response_to, tvb, 0, 0, srrp->request_frame_id);
519 			proto_item_set_generated(it);
520 			nstime_delta(&ns, &pinfo->abs_ts, &srrp->request_time);
521 			it=proto_tree_add_time(tree, hf_snmp_time, tvb, 0, 0, &ns);
522 			proto_item_set_generated(it);
523 
524 			return srrp;
525 		}
526 	}
527 
528 	return NULL;
529 }
530 
531 static void
snmpstat_init(struct register_srt * srt _U_,GArray * srt_array)532 snmpstat_init(struct register_srt* srt _U_, GArray* srt_array)
533 {
534 	srt_stat_table *snmp_srt_table;
535 	guint32 i;
536 
537 	snmp_srt_table = init_srt_table("SNMP Commands", NULL, srt_array, SNMP_NUM_PROCEDURES, NULL, "snmp.data", NULL);
538 	for (i = 0; i < SNMP_NUM_PROCEDURES; i++)
539 	{
540 		init_srt_table_row(snmp_srt_table, i, val_to_str_const(i, snmp_procedure_names, "<unknown>"));
541 	}
542 }
543 
544 /* This is called only if request and response was matched -> no need to return anything than TAP_PACKET_REDRAW */
545 static tap_packet_status
snmpstat_packet(void * psnmp,packet_info * pinfo,epan_dissect_t * edt _U_,const void * psi)546 snmpstat_packet(void *psnmp, packet_info *pinfo, epan_dissect_t *edt _U_, const void *psi)
547 {
548 	guint i = 0;
549 	srt_stat_table *snmp_srt_table;
550 	const snmp_request_response_t *snmp=(const snmp_request_response_t *)psi;
551 	srt_data_t *data = (srt_data_t *)psnmp;
552 
553 	snmp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
554 
555 	add_srt_table_data(snmp_srt_table, snmp->request_procedure_id, &snmp->request_time, pinfo);
556 	return TAP_PACKET_REDRAW;
557 }
558 
559 static const gchar *
snmp_lookup_specific_trap(guint specific_trap)560 snmp_lookup_specific_trap (guint specific_trap)
561 {
562 	guint i;
563 
564 	for (i = 0; i < num_specific_traps; i++) {
565 		snmp_st_assoc_t *u = &(specific_traps[i]);
566 
567 		if ((u->trap == specific_trap) &&
568 		    (strcmp (u->enterprise, enterprise_oid) == 0))
569 		{
570 			return u->desc;
571 		}
572 	}
573 
574 	return NULL;
575 }
576 
577 static int
dissect_snmp_variable_string(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)578 dissect_snmp_variable_string(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
579 {
580 
581 	proto_tree_add_item(tree, hf_snmp_var_bind_str, tvb, 0, -1, ENC_ASCII|ENC_NA);
582 
583 	return tvb_captured_length(tvb);
584 }
585 
586 /*
587 DateAndTime ::= TEXTUAL-CONVENTION
588     DISPLAY-HINT "2d-1d-1d,1d:1d:1d.1d,1a1d:1d"
589     STATUS       current
590     DESCRIPTION
591             "A date-time specification.
592 
593             field  octets  contents                  range
594             -----  ------  --------                  -----
595               1      1-2   year*                     0..65536
596               2       3    month                     1..12
597               3       4    day                       1..31
598               4       5    hour                      0..23
599               5       6    minutes                   0..59
600               6       7    seconds                   0..60
601                            (use 60 for leap-second)
602               7       8    deci-seconds              0..9
603               8       9    direction from UTC        '+' / '-'
604               9      10    hours from UTC*           0..13
605              10      11    minutes from UTC          0..59
606 
607             * Notes:
608             - the value of year is in network-byte order
609             - daylight saving time in New Zealand is +13
610 
611             For example, Tuesday May 26, 1992 at 1:30:15 PM EDT would be
612             displayed as:
613 
614                              1992-5-26,13:30:15.0,-4:0
615 
616             Note that if only local time is known, then timezone
617             information (fields 8-10) is not present."
618     SYNTAX       OCTET STRING (SIZE (8 | 11))
619 */
620 static proto_item *
dissect_snmp_variable_date_and_time(proto_tree * tree,packet_info * pinfo,int hfid,tvbuff_t * tvb,int offset,int length)621 dissect_snmp_variable_date_and_time(proto_tree *tree, packet_info *pinfo, int hfid, tvbuff_t *tvb, int offset, int length)
622 {
623 	guint16 year;
624 	guint8 month;
625 	guint8 day;
626 	guint8 hour;
627 	guint8 minutes;
628 	guint8 seconds;
629 	guint8 deci_seconds;
630 	guint8 hour_from_utc;
631 	guint8 min_from_utc;
632 	gchar *str;
633 
634 	year			= tvb_get_ntohs(tvb,offset);
635 	month			= tvb_get_guint8(tvb,offset+2);
636 	day			= tvb_get_guint8(tvb,offset+3);
637 	hour			= tvb_get_guint8(tvb,offset+4);
638 	minutes			= tvb_get_guint8(tvb,offset+5);
639 	seconds			= tvb_get_guint8(tvb,offset+6);
640 	deci_seconds		= tvb_get_guint8(tvb,offset+7);
641 	if(length > 8){
642 		hour_from_utc	= tvb_get_guint8(tvb,offset+9);
643 		min_from_utc	= tvb_get_guint8(tvb,offset+10);
644 
645 		str = wmem_strdup_printf(pinfo->pool,
646 			 "%u-%u-%u, %u:%u:%u.%u UTC %s%u:%u",
647 			 year,
648 			 month,
649 			 day,
650 			 hour,
651 			 minutes,
652 			 seconds,
653 			 deci_seconds,
654 			 tvb_get_string_enc(pinfo->pool,tvb,offset+8,1,ENC_ASCII|ENC_NA),
655 			 hour_from_utc,
656 			 min_from_utc);
657 	}else{
658 		 str = wmem_strdup_printf(pinfo->pool,
659 			 "%u-%u-%u, %u:%u:%u.%u",
660 			 year,
661 			 month,
662 			 day,
663 			 hour,
664 			 minutes,
665 			 seconds,
666 			 deci_seconds);
667 	}
668 
669 	return proto_tree_add_string(tree, hfid, tvb, offset, length, str);
670 
671 }
672 
673 /*
674  *  dissect_snmp_VarBind
675  *  this routine dissects variable bindings, looking for the oid information in our oid reporsitory
676  *  to format and add the value adequatelly.
677  *
678  * The choice to handwrite this code instead of using the asn compiler is to avoid having tons
679  * of uses of global variables distributed in very different parts of the code.
680  * Other than that there's a cosmetic thing: the tree from ASN generated code would be so
681  * convoluted due to the nesting of CHOICEs in the definition of VarBind/value.
682  *
683  * XXX: the length of this function (~400 lines) is an aberration!
684  *  oid_key_t:key_type could become a series of callbacks instead of an enum
685  *  the (! oid_info_is_ok) switch could be made into an array (would be slower)
686  *
687 
688 	NetworkAddress ::=  CHOICE { internet IpAddress }
689 	IpAddress ::= [APPLICATION 0] IMPLICIT OCTET STRING (SIZE (4))
690 	TimeTicks ::= [APPLICATION 3] IMPLICIT INTEGER (0..4294967295)
691 	Integer32 ::= INTEGER (-2147483648..2147483647)
692 	ObjectName ::= OBJECT IDENTIFIER
693 	Counter32 ::= [APPLICATION 1] IMPLICIT INTEGER (0..4294967295)
694 	Gauge32 ::= [APPLICATION 2] IMPLICIT INTEGER (0..4294967295)
695 	Unsigned32 ::= [APPLICATION 2] IMPLICIT INTEGER (0..4294967295)
696 	Integer-value ::=  INTEGER (-2147483648..2147483647)
697 	Integer32 ::= INTEGER (-2147483648..2147483647)
698 	ObjectID-value ::= OBJECT IDENTIFIER
699 	Empty ::= NULL
700 	TimeTicks ::= [APPLICATION 3] IMPLICIT INTEGER (0..4294967295)
701 	Opaque ::= [APPLICATION 4] IMPLICIT OCTET STRING
702 	Counter64 ::= [APPLICATION 6] IMPLICIT INTEGER (0..18446744073709551615)
703 
704 	ObjectSyntax ::= CHOICE {
705 		 simple SimpleSyntax,
706 		 application-wide ApplicationSyntax
707 	}
708 
709 	SimpleSyntax ::= CHOICE {
710 	   integer-value Integer-value,
711 	   string-value String-value,
712 	   objectID-value ObjectID-value,
713 	   empty  Empty
714 	}
715 
716 	ApplicationSyntax ::= CHOICE {
717 	   ipAddress-value IpAddress,
718 	   counter-value Counter32,
719 	   timeticks-value TimeTicks,
720 	   arbitrary-value Opaque,
721 	   big-counter-value Counter64,
722 	   unsigned-integer-value Unsigned32
723 	}
724 
725 	ValueType ::=  CHOICE {
726 	   value ObjectSyntax,
727 	   unSpecified NULL,
728 	   noSuchObject[0] IMPLICIT NULL,
729 	   noSuchInstance[1] IMPLICIT NULL,
730 	   endOfMibView[2] IMPLICIT NULL
731 	}
732 
733 	VarBind ::= SEQUENCE {
734 	   name ObjectName,
735 	   valueType ValueType
736 	}
737 
738  */
739 
740 static int
dissect_snmp_VarBind(gboolean implicit_tag _U_,tvbuff_t * tvb,int offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index _U_)741 dissect_snmp_VarBind(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,
742 		     asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_)
743 {
744 	int seq_offset, name_offset, value_offset, value_start;
745 	guint32 seq_len, name_len, value_len;
746 	gint8 ber_class;
747 	gboolean pc;
748 	gint32 tag;
749 	gboolean ind;
750 	guint32* subids;
751 	guint8* oid_bytes;
752 	oid_info_t* oid_info = NULL;
753 	guint oid_matched, oid_left;
754 	proto_item *pi_name, *pi_varbind, *pi_value = NULL;
755 	proto_tree *pt, *pt_varbind, *pt_name, *pt_value;
756 	char label[ITEM_LABEL_LENGTH];
757 	const char* repr = NULL;
758 	const char* info_oid = NULL;
759 	char* valstr;
760 	int hfid = -1;
761 	int min_len = 0, max_len = 0;
762 	gboolean oid_info_is_ok;
763 	const char* oid_string = NULL;
764 	enum {BER_NO_ERROR, BER_WRONG_LENGTH, BER_WRONG_TAG} format_error = BER_NO_ERROR;
765 
766 	seq_offset = offset;
767 
768 	/* first have the VarBind's sequence header */
769 	offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag);
770 	offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &seq_len, &ind);
771 
772 	if (!pc && ber_class==BER_CLASS_UNI && tag==BER_UNI_TAG_SEQUENCE) {
773 		proto_item* pi;
774 		pt = proto_tree_add_subtree(tree, tvb, seq_offset, seq_len + (offset - seq_offset),
775 				ett_decoding_error, &pi, "VarBind must be an universal class sequence");
776 		expert_add_info(actx->pinfo, pi, &ei_snmp_varbind_not_uni_class_seq);
777 		return dissect_unknown_ber(actx->pinfo, tvb, seq_offset, pt);
778 	}
779 
780 	if (ind) {
781 		proto_item* pi;
782 		pt = proto_tree_add_subtree(tree, tvb, seq_offset, seq_len + (offset - seq_offset),
783 					ett_decoding_error, &pi, "Indicator must be clear in VarBind");
784 		expert_add_info(actx->pinfo, pi, &ei_snmp_varbind_has_indicator);
785 		return dissect_unknown_ber(actx->pinfo, tvb, seq_offset, pt);
786 	}
787 
788 	/* we add the varbind tree root with a dummy label we'll fill later on */
789 	pt_varbind = proto_tree_add_subtree(tree,tvb,offset,seq_len,ett_varbind,&pi_varbind,"VarBind");
790 	*label = '\0';
791 
792 	seq_len += offset - seq_offset;
793 
794 	/* then we have the ObjectName's header */
795 
796 	offset = dissect_ber_identifier(actx->pinfo, pt_varbind, tvb, offset, &ber_class, &pc, &tag);
797 	name_offset = offset = dissect_ber_length(actx->pinfo, pt_varbind, tvb, offset, &name_len, &ind);
798 
799 	if (! ( !pc && ber_class==BER_CLASS_UNI && tag==BER_UNI_TAG_OID) ) {
800 		proto_item* pi;
801 		pt = proto_tree_add_subtree(tree, tvb, seq_offset, seq_len,
802 				ett_decoding_error, &pi, "ObjectName must be an OID in primitive encoding");
803 		expert_add_info(actx->pinfo, pi, &ei_snmp_objectname_not_oid);
804 		return dissect_unknown_ber(actx->pinfo, tvb, seq_offset, pt);
805 	}
806 
807 	if (ind) {
808 		proto_item* pi;
809 		pt = proto_tree_add_subtree(tree, tvb, seq_offset, seq_len,
810 				ett_decoding_error, &pi, "Indicator must be clear in ObjectName");
811 		expert_add_info(actx->pinfo, pi, &ei_snmp_objectname_has_indicator);
812 		return dissect_unknown_ber(actx->pinfo, tvb, seq_offset, pt);
813 	}
814 
815 	pi_name = proto_tree_add_item(pt_varbind,hf_snmp_objectname,tvb,name_offset,name_len,ENC_NA);
816 	pt_name = proto_item_add_subtree(pi_name,ett_name);
817 
818 	offset += name_len;
819 	value_start = offset;
820 	/* then we have the value's header */
821 	offset = dissect_ber_identifier(actx->pinfo, pt_varbind, tvb, offset, &ber_class, &pc, &tag);
822 	value_offset = dissect_ber_length(actx->pinfo, pt_varbind, tvb, offset, &value_len, &ind);
823 
824 	if (! (!pc) ) {
825 		proto_item* pi;
826 		pt = proto_tree_add_subtree(pt_varbind, tvb, value_start, value_len,
827 				ett_decoding_error, &pi, "the value must be in primitive encoding");
828 		expert_add_info(actx->pinfo, pi, &ei_snmp_value_not_primitive_encoding);
829 		return dissect_unknown_ber(actx->pinfo, tvb, value_start, pt);
830 	}
831 
832 	/* Now, we know where everithing is */
833 
834 	/* fetch ObjectName and its relative oid_info */
835 	oid_bytes = (guint8*)tvb_memdup(actx->pinfo->pool, tvb, name_offset, name_len);
836 	oid_info = oid_get_from_encoded(actx->pinfo->pool, oid_bytes, name_len, &subids, &oid_matched, &oid_left);
837 
838 	add_oid_debug_subtree(oid_info,pt_name);
839 
840 	if (!subids) {
841 		proto_item* pi;
842 
843 		repr = oid_encoded2string(actx->pinfo->pool, oid_bytes, name_len);
844 		pt = proto_tree_add_subtree_format(pt_name,tvb, 0, 0, ett_decoding_error, &pi, "invalid oid: %s", repr);
845 		expert_add_info_format(actx->pinfo, pi, &ei_snmp_invalid_oid, "invalid oid: %s", repr);
846 		return dissect_unknown_ber(actx->pinfo, tvb, name_offset, pt);
847 	}
848 
849 	if (oid_matched+oid_left) {
850 		oid_string = oid_subid2string(actx->pinfo->pool, subids,oid_matched+oid_left);
851 	}
852 
853 	if (ber_class == BER_CLASS_CON) {
854 		/* if we have an error value just add it and get out the way ASAP */
855 		proto_item* pi;
856 		const char* note;
857 
858 		if (value_len != 0) {
859 			min_len = max_len = 0;
860 			format_error = BER_WRONG_LENGTH;
861 		}
862 
863 		switch (tag) {
864 			case SERR_NSO:
865 				hfid = hf_snmp_noSuchObject;
866 				note = "noSuchObject";
867 				break;
868 			case SERR_NSI:
869 				hfid = hf_snmp_noSuchInstance;
870 				note = "noSuchInstance";
871 				break;
872 			case SERR_EOM:
873 				hfid = hf_snmp_endOfMibView;
874 				note = "endOfMibView";
875 				break;
876 			default: {
877 				pt = proto_tree_add_subtree_format(pt_varbind,tvb,0,0,ett_decoding_error,&pi,
878 								"Wrong tag for Error Value: expected 0, 1, or 2 but got: %d",tag);
879 				expert_add_info(actx->pinfo, pi, &ei_snmp_varbind_wrong_tag);
880 				return dissect_unknown_ber(actx->pinfo, tvb, value_start, pt);
881 			}
882 		}
883 
884 		pi = proto_tree_add_item(pt_varbind,hfid,tvb,value_offset,value_len,ENC_BIG_ENDIAN);
885 		expert_add_info_format(actx->pinfo, pi, &ei_snmp_varbind_response, "%s",note);
886 		(void) g_strlcpy (label, note, ITEM_LABEL_LENGTH);
887 		goto set_label;
888 	}
889 
890 	/* now we'll try to figure out which are the indexing sub-oids and whether the oid we know about is the one oid we have to use */
891 	switch (oid_info->kind) {
892 		case OID_KIND_SCALAR:
893 			if (oid_left == 1) {
894 				/* OK: we got the instance sub-id */
895 				proto_tree_add_uint64(pt_name,hf_snmp_scalar_instance_index,tvb,name_offset,name_len,subids[oid_matched]);
896 				oid_info_is_ok = TRUE;
897 				goto indexing_done;
898 			} else if (oid_left == 0) {
899 				if (ber_class == BER_CLASS_UNI && tag == BER_UNI_TAG_NULL) {
900 					/* unSpecified  does not require an instance sub-id add the new value and get off the way! */
901 					pi_value = proto_tree_add_item(pt_varbind,hf_snmp_unSpecified,tvb,value_offset,value_len,ENC_NA);
902 					goto set_label;
903 				} else {
904 					proto_tree_add_expert(pt_name,actx->pinfo,&ei_snmp_no_instance_subid,tvb,0,0);
905 					oid_info_is_ok = FALSE;
906 					goto indexing_done;
907 				}
908 			} else {
909 				proto_tree_add_expert_format(pt_name,actx->pinfo,&ei_snmp_wrong_num_of_subids,tvb,0,0,"A scalar should have only one instance sub-id this has: %d",oid_left);
910 				oid_info_is_ok = FALSE;
911 				goto indexing_done;
912 			}
913 		break;
914 		case OID_KIND_COLUMN:
915 			if ( oid_info->parent->kind == OID_KIND_ROW) {
916 				oid_key_t* k = oid_info->parent->key;
917 				guint key_start = oid_matched;
918 				guint key_len = oid_left;
919 				oid_info_is_ok = TRUE;
920 
921 				if ( key_len == 0 && ber_class == BER_CLASS_UNI && tag == BER_UNI_TAG_NULL) {
922 					/* unSpecified  does not require an instance sub-id add the new value and get off the way! */
923 					pi_value = proto_tree_add_item(pt_varbind,hf_snmp_unSpecified,tvb,value_offset,value_len,ENC_NA);
924 					goto set_label;
925 				}
926 
927 				if (k) {
928 					for (;k;k = k->next) {
929 						guint suboid_len;
930 
931 						if (key_start >= oid_matched+oid_left) {
932 							proto_tree_add_expert(pt_name,actx->pinfo,&ei_snmp_index_suboid_too_short,tvb,0,0);
933 							oid_info_is_ok = FALSE;
934 							goto indexing_done;
935 						}
936 
937 						switch(k->key_type) {
938 							case OID_KEY_TYPE_WRONG: {
939 								proto_tree_add_expert(pt_name,actx->pinfo,&ei_snmp_unimplemented_instance_index,tvb,0,0);
940 								oid_info_is_ok = FALSE;
941 								goto indexing_done;
942 							}
943 							case OID_KEY_TYPE_INTEGER: {
944 								if (IS_FT_INT(k->ft_type)) {
945 									proto_tree_add_int(pt_name,k->hfid,tvb,name_offset,name_len,(guint)subids[key_start]);
946 								} else { /* if it's not an unsigned int let proto_tree_add_uint throw a warning */
947 									proto_tree_add_uint64(pt_name,k->hfid,tvb,name_offset,name_len,(guint)subids[key_start]);
948 								}
949 								key_start++;
950 								key_len--;
951 								continue; /* k->next */
952 							}
953 							case OID_KEY_TYPE_IMPLIED_OID:
954 								suboid_len = key_len;
955 
956 								goto show_oid_index;
957 
958 							case OID_KEY_TYPE_OID: {
959 								guint8* suboid_buf;
960 								guint suboid_buf_len;
961 								guint32* suboid;
962 
963 								suboid_len = subids[key_start++];
964 								key_len--;
965 
966 show_oid_index:
967 								suboid = &(subids[key_start]);
968 
969 								if( suboid_len == 0 ) {
970 									proto_tree_add_expert(pt_name,actx->pinfo,&ei_snmp_index_suboid_len0,tvb,0,0);
971 									oid_info_is_ok = FALSE;
972 									goto indexing_done;
973 								}
974 
975 								if( key_len < suboid_len ) {
976 									proto_tree_add_expert(pt_name,actx->pinfo,&ei_snmp_index_suboid_too_long,tvb,0,0);
977 									oid_info_is_ok = FALSE;
978 									goto indexing_done;
979 								}
980 
981 								suboid_buf_len = oid_subid2encoded(actx->pinfo->pool, suboid_len, suboid, &suboid_buf);
982 
983 								DISSECTOR_ASSERT(suboid_buf_len);
984 
985 								proto_tree_add_oid(pt_name,k->hfid,tvb,name_offset, suboid_buf_len, suboid_buf);
986 
987 								key_start += suboid_len;
988 								key_len -= suboid_len + 1;
989 								continue; /* k->next */
990 							}
991 							default: {
992 								guint8* buf;
993 								guint buf_len;
994 								guint32* suboid;
995 								guint i;
996 
997 
998 								switch (k->key_type) {
999 									case OID_KEY_TYPE_IPADDR:
1000 										suboid = &(subids[key_start]);
1001 										buf_len = 4;
1002 										break;
1003 									case OID_KEY_TYPE_IMPLIED_STRING:
1004 									case OID_KEY_TYPE_IMPLIED_BYTES:
1005 									case OID_KEY_TYPE_ETHER:
1006 										suboid = &(subids[key_start]);
1007 										buf_len = key_len;
1008 										break;
1009 									default:
1010 										buf_len = k->num_subids;
1011 										suboid = &(subids[key_start]);
1012 
1013 										if(!buf_len) {
1014 											buf_len = *suboid++;
1015 											key_len--;
1016 											key_start++;
1017 										}
1018 										break;
1019 								}
1020 
1021 								if( key_len < buf_len ) {
1022 									proto_tree_add_expert(pt_name,actx->pinfo,&ei_snmp_index_string_too_long,tvb,0,0);
1023 									oid_info_is_ok = FALSE;
1024 									goto indexing_done;
1025 								}
1026 
1027 								buf = (guint8*)wmem_alloc(actx->pinfo->pool, buf_len+1);
1028 								for (i = 0; i < buf_len; i++)
1029 									buf[i] = (guint8)suboid[i];
1030 								buf[i] = '\0';
1031 
1032 								switch(k->key_type) {
1033 									case OID_KEY_TYPE_STRING:
1034 									case OID_KEY_TYPE_IMPLIED_STRING:
1035 										proto_tree_add_string(pt_name,k->hfid,tvb,name_offset,buf_len, buf);
1036 										break;
1037 									case OID_KEY_TYPE_BYTES:
1038 									case OID_KEY_TYPE_NSAP:
1039 									case OID_KEY_TYPE_IMPLIED_BYTES:
1040 										proto_tree_add_bytes(pt_name,k->hfid,tvb,name_offset,buf_len, buf);
1041 										break;
1042 									case OID_KEY_TYPE_ETHER:
1043 										proto_tree_add_ether(pt_name,k->hfid,tvb,name_offset,buf_len, buf);
1044 										break;
1045 									case OID_KEY_TYPE_IPADDR: {
1046 										guint32* ipv4_p = (guint32*)buf;
1047 										proto_tree_add_ipv4(pt_name,k->hfid,tvb,name_offset,buf_len, *ipv4_p);
1048 										}
1049 										break;
1050 									default:
1051 										DISSECTOR_ASSERT_NOT_REACHED();
1052 										break;
1053 								}
1054 
1055 								key_start += buf_len;
1056 								key_len -= buf_len;
1057 								continue; /* k->next*/
1058 							}
1059 						}
1060 					}
1061 					goto indexing_done;
1062 				} else {
1063 					proto_tree_add_expert(pt_name,actx->pinfo,&ei_snmp_unimplemented_instance_index,tvb,0,0);
1064 					oid_info_is_ok = FALSE;
1065 					goto indexing_done;
1066 				}
1067 			} else {
1068 				proto_tree_add_expert(pt_name,actx->pinfo,&ei_snmp_column_parent_not_row,tvb,0,0);
1069 				oid_info_is_ok = FALSE;
1070 				goto indexing_done;
1071 			}
1072 		default: {
1073 /*			proto_tree_add_expert (pt_name,actx->pinfo,PI_MALFORMED, PI_WARN,tvb,0,0,"This kind OID should have no value"); */
1074 			oid_info_is_ok = FALSE;
1075 			goto indexing_done;
1076 		}
1077 	}
1078 indexing_done:
1079 
1080 	if (oid_info_is_ok && oid_info->value_type) {
1081 		if (ber_class == BER_CLASS_UNI && tag == BER_UNI_TAG_NULL) {
1082 			pi_value = proto_tree_add_item(pt_varbind,hf_snmp_unSpecified,tvb,value_offset,value_len,ENC_NA);
1083 		} else {
1084 			/* Provide a tree_item to attach errors to, if needed. */
1085 			pi_value = pi_name;
1086 
1087 			if ((oid_info->value_type->ber_class != BER_CLASS_ANY) &&
1088 				(ber_class != oid_info->value_type->ber_class))
1089 				format_error = BER_WRONG_TAG;
1090 			else if ((oid_info->value_type->ber_tag != BER_TAG_ANY) &&
1091 				(tag != oid_info->value_type->ber_tag))
1092 				format_error = BER_WRONG_TAG;
1093 			else {
1094 				max_len = oid_info->value_type->max_len == -1 ? 0xffffff : oid_info->value_type->max_len;
1095 				min_len = oid_info->value_type->min_len;
1096 
1097 				if ((int)value_len < min_len || (int)value_len > max_len)
1098 					format_error = BER_WRONG_LENGTH;
1099 			}
1100 
1101 			if (format_error == BER_NO_ERROR)
1102 				pi_value = proto_tree_add_item(pt_varbind,oid_info->value_hfid,tvb,value_offset,value_len,ENC_BIG_ENDIAN);
1103 		}
1104 	} else {
1105 		switch(ber_class|(tag<<4)) {
1106 			case BER_CLASS_UNI|(BER_UNI_TAG_INTEGER<<4):
1107 			{
1108 				gint64 val=0;
1109 				unsigned int int_val_offset = value_offset;
1110 				unsigned int i;
1111 
1112 				max_len = 4; min_len = 1;
1113 				if (value_len > (guint)max_len || value_len < (guint)min_len) {
1114 					hfid = hf_snmp_integer32_value;
1115 					format_error = BER_WRONG_LENGTH;
1116 					break;
1117 				}
1118 
1119 				if(value_len > 0) {
1120 					/* extend sign bit */
1121 					if(tvb_get_guint8(tvb, int_val_offset)&0x80) {
1122 						val=-1;
1123 					}
1124 					for(i=0;i<value_len;i++) {
1125 						val=(val<<8)|tvb_get_guint8(tvb, int_val_offset);
1126 						int_val_offset++;
1127 					}
1128 				}
1129 				pi_value = proto_tree_add_int64(pt_varbind, hf_snmp_integer32_value, tvb,value_offset,value_len, val);
1130 
1131 				goto already_added;
1132 			}
1133 			case BER_CLASS_UNI|(BER_UNI_TAG_OCTETSTRING<<4):
1134 				if(oid_info->value_hfid> -1){
1135 					hfid = oid_info->value_hfid;
1136 				}else{
1137 					hfid = hf_snmp_octetstring_value;
1138 				}
1139 				break;
1140 			case BER_CLASS_UNI|(BER_UNI_TAG_OID<<4):
1141 				max_len = -1; min_len = 1;
1142 				if (value_len < (guint)min_len) format_error = BER_WRONG_LENGTH;
1143 				hfid = hf_snmp_oid_value;
1144 				break;
1145 			case BER_CLASS_UNI|(BER_UNI_TAG_NULL<<4):
1146 				max_len = 0; min_len = 0;
1147 				if (value_len != 0) format_error = BER_WRONG_LENGTH;
1148 				hfid = hf_snmp_null_value;
1149 				break;
1150 			case BER_CLASS_APP: /* | (SNMP_IPA<<4)*/
1151 				switch(value_len) {
1152 					case 4: hfid = hf_snmp_ipv4_value; break;
1153 					case 16: hfid = hf_snmp_ipv6_value; break;
1154 					default: hfid = hf_snmp_anyaddress_value; break;
1155 				}
1156 				break;
1157 			case BER_CLASS_APP|(SNMP_U32<<4):
1158 				hfid = hf_snmp_unsigned32_value;
1159 				break;
1160 			case BER_CLASS_APP|(SNMP_GGE<<4):
1161 				hfid = hf_snmp_gauge32_value;
1162 				break;
1163 			case BER_CLASS_APP|(SNMP_CNT<<4):
1164 				hfid = hf_snmp_counter_value;
1165 				break;
1166 			case BER_CLASS_APP|(SNMP_TIT<<4):
1167 				hfid = hf_snmp_timeticks_value;
1168 				break;
1169 			case BER_CLASS_APP|(SNMP_OPQ<<4):
1170 				hfid = hf_snmp_opaque_value;
1171 				break;
1172 			case BER_CLASS_APP|(SNMP_NSP<<4):
1173 				hfid = hf_snmp_nsap_value;
1174 				break;
1175 			case BER_CLASS_APP|(SNMP_C64<<4):
1176 				hfid = hf_snmp_big_counter_value;
1177 				break;
1178 			default:
1179 				hfid = hf_snmp_unknown_value;
1180 				break;
1181 		}
1182 		if (value_len > 8) {
1183 			/*
1184 			 * Too long for an FT_UINT64 or an FT_INT64.
1185 			 */
1186 			header_field_info *hfinfo = proto_registrar_get_nth(hfid);
1187 			if (hfinfo->type == FT_UINT64) {
1188 				/*
1189 				 * Check if this is an unsigned int64 with
1190 				 * a big value.
1191 				 */
1192 				if (value_len > 9 || tvb_get_guint8(tvb, value_offset) != 0) {
1193 					/* It is.  Fail. */
1194 					proto_tree_add_expert_format(pt_varbind,actx->pinfo,&ei_snmp_uint_too_large,tvb,value_offset,value_len,"Integral value too large");
1195 					goto already_added;
1196 				}
1197 				/* Cheat and skip the leading 0 byte */
1198 				value_len--;
1199 				value_offset++;
1200 			} else if (hfinfo->type == FT_INT64) {
1201 				/*
1202 				 * For now, just reject these.
1203 				 */
1204 				proto_tree_add_expert_format(pt_varbind,actx->pinfo,&ei_snmp_int_too_large,tvb,value_offset,value_len,"Integral value too large or too small");
1205 				goto already_added;
1206 			}
1207 		} else if (value_len == 0) {
1208 			/*
1209 			 * X.690 section 8.3.1 "Encoding of an integer value":
1210 			 * "The encoding of an integer value shall be
1211 			 * primitive. The contents octets shall consist of
1212 			 * one or more octets."
1213 			 *
1214 			 * Zero is not "one or more".
1215 			 */
1216 			header_field_info *hfinfo = proto_registrar_get_nth(hfid);
1217 			if (hfinfo->type == FT_UINT64 || hfinfo->type == FT_INT64) {
1218 				proto_tree_add_expert_format(pt_varbind,actx->pinfo,&ei_snmp_integral_value0,tvb,value_offset,value_len,"Integral value is zero-length");
1219 				goto already_added;
1220 			}
1221 		}
1222 		/* Special case DATE AND TIME */
1223 		if((oid_info->value_type)&&(oid_info->value_type->keytype == OID_KEY_TYPE_DATE_AND_TIME)&&(value_len > 7)){
1224 			pi_value = dissect_snmp_variable_date_and_time(pt_varbind, actx->pinfo, hfid, tvb, value_offset, value_len);
1225 		}else{
1226 			pi_value = proto_tree_add_item(pt_varbind,hfid,tvb,value_offset,value_len,ENC_BIG_ENDIAN);
1227 		}
1228 		if (format_error != BER_NO_ERROR) {
1229 			expert_add_info(actx->pinfo, pi_value, &ei_snmp_missing_mib);
1230 		}
1231 
1232 	}
1233 already_added:
1234 	pt_value = proto_item_add_subtree(pi_value,ett_value);
1235 
1236 	if (value_len > 0 && oid_string) {
1237 		tvbuff_t* sub_tvb = tvb_new_subset_length(tvb, value_offset, value_len);
1238 
1239 		next_tvb_add_string(var_list, sub_tvb, (snmp_var_in_tree) ? pt_value : NULL, value_sub_dissectors_table, oid_string);
1240 	}
1241 
1242 
1243 set_label:
1244 	if (pi_value) proto_item_fill_label(PITEM_FINFO(pi_value), label);
1245 
1246 	if (oid_info && oid_info->name) {
1247 		if (oid_left >= 1) {
1248 			repr = wmem_strdup_printf(actx->pinfo->pool, "%s.%s (%s)", oid_info->name,
1249 						oid_subid2string(actx->pinfo->pool, &(subids[oid_matched]),oid_left),
1250 						oid_subid2string(actx->pinfo->pool, subids,oid_matched+oid_left));
1251 			info_oid = wmem_strdup_printf(actx->pinfo->pool, "%s.%s", oid_info->name,
1252 						oid_subid2string(actx->pinfo->pool, &(subids[oid_matched]),oid_left));
1253 		} else {
1254 			repr = wmem_strdup_printf(actx->pinfo->pool, "%s (%s)", oid_info->name,
1255 						oid_subid2string(actx->pinfo->pool, subids,oid_matched));
1256 			info_oid = oid_info->name;
1257 		}
1258 	} else if (oid_string) {
1259 		repr = wmem_strdup(actx->pinfo->pool, oid_string);
1260 		info_oid = oid_string;
1261 	} else {
1262 		repr = wmem_strdup(actx->pinfo->pool, "[Bad OID]");
1263 	}
1264 
1265 	valstr = strstr(label,": ");
1266 	valstr = valstr ? valstr+2 : label;
1267 
1268 	proto_item_set_text(pi_varbind,"%s: %s",repr,valstr);
1269 
1270 	if (display_oid && info_oid) {
1271 		col_append_fstr (actx->pinfo->cinfo, COL_INFO, " %s", info_oid);
1272 	}
1273 
1274 	switch (format_error) {
1275 		case BER_WRONG_LENGTH: {
1276 			proto_item* pi;
1277 			proto_tree* p_tree = proto_item_add_subtree(pi_value,ett_decoding_error);
1278 			pt = proto_tree_add_subtree_format(p_tree,tvb,0,0,ett_decoding_error,&pi,
1279 							     "Wrong value length: %u  expecting: %u <= len <= %u",
1280 							     value_len, min_len, max_len == -1 ? 0xFFFFFF : max_len);
1281 			expert_add_info(actx->pinfo, pi, &ei_snmp_varbind_wrong_length_value);
1282 			return dissect_unknown_ber(actx->pinfo, tvb, value_start, pt);
1283 		}
1284 		case BER_WRONG_TAG: {
1285 			proto_item* pi;
1286 			proto_tree* p_tree = proto_item_add_subtree(pi_value,ett_decoding_error);
1287 			pt = proto_tree_add_subtree_format(p_tree,tvb,0,0,ett_decoding_error,&pi,
1288 							     "Wrong class/tag for Value expected: %d,%d got: %d,%d",
1289 							     oid_info->value_type->ber_class, oid_info->value_type->ber_tag,
1290 							     ber_class, tag);
1291 			expert_add_info(actx->pinfo, pi, &ei_snmp_varbind_wrong_class_tag);
1292 			return dissect_unknown_ber(actx->pinfo, tvb, value_start, pt);
1293 		}
1294 		default:
1295 			break;
1296 	}
1297 
1298 	return seq_offset + seq_len;
1299 }
1300 
1301 
1302 #define F_SNMP_ENGINEID_CONFORM 0x80
1303 #define SNMP_ENGINEID_RFC1910 0x00
1304 #define SNMP_ENGINEID_RFC3411 0x01
1305 
1306 static const true_false_string tfs_snmp_engineid_conform = {
1307 	"RFC3411 (SNMPv3)",
1308 	"RFC1910 (Non-SNMPv3)"
1309 };
1310 
1311 #define SNMP_ENGINEID_FORMAT_IPV4 0x01
1312 #define SNMP_ENGINEID_FORMAT_IPV6 0x02
1313 #define SNMP_ENGINEID_FORMAT_MACADDRESS 0x03
1314 #define SNMP_ENGINEID_FORMAT_TEXT 0x04
1315 #define SNMP_ENGINEID_FORMAT_OCTETS 0x05
1316 
1317 static const value_string snmp_engineid_format_vals[] = {
1318 	{ SNMP_ENGINEID_FORMAT_IPV4,	"IPv4 address" },
1319 	{ SNMP_ENGINEID_FORMAT_IPV6,	"IPv6 address" },
1320 	{ SNMP_ENGINEID_FORMAT_MACADDRESS,	"MAC address" },
1321 	{ SNMP_ENGINEID_FORMAT_TEXT,	"Text, administratively assigned" },
1322 	{ SNMP_ENGINEID_FORMAT_OCTETS,	"Octets, administratively assigned" },
1323 	{ 0,	NULL }
1324 };
1325 
1326 #define SNMP_ENGINEID_CISCO_AGENT 0x00
1327 #define SNMP_ENGINEID_CISCO_MANAGER 0x01
1328 
1329 static const value_string snmp_engineid_cisco_type_vals[] = {
1330 	{ SNMP_ENGINEID_CISCO_AGENT,	"Agent" },
1331 	{ SNMP_ENGINEID_CISCO_MANAGER,	"Manager" },
1332 	{ 0,	NULL }
1333 };
1334 
1335 /*
1336  * SNMP Engine ID dissection according to RFC 3411 (SnmpEngineID TC)
1337  * or historic RFC 1910 (AgentID)
1338  */
1339 int
dissect_snmp_engineid(proto_tree * tree,packet_info * pinfo,tvbuff_t * tvb,int offset,int len)1340 dissect_snmp_engineid(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset, int len)
1341 {
1342 	proto_item *item = NULL;
1343 	guint8 conformance, format;
1344 	guint32 enterpriseid;
1345 	time_t seconds;
1346 	nstime_t ts;
1347 	int len_remain = len;
1348 
1349 	/* first bit: engine id conformance */
1350 	if (len_remain<1) return offset;
1351 	conformance = ((tvb_get_guint8(tvb, offset)>>7) & 0x01);
1352 	proto_tree_add_item(tree, hf_snmp_engineid_conform, tvb, offset, 1, ENC_BIG_ENDIAN);
1353 
1354 	/* 4-byte enterprise number/name */
1355 	if (len_remain<4) return offset;
1356 	enterpriseid = tvb_get_ntohl(tvb, offset);
1357 	if (conformance)
1358 		enterpriseid -= 0x80000000; /* ignore first bit */
1359 	proto_tree_add_uint(tree, hf_snmp_engineid_enterprise, tvb, offset, 4, enterpriseid);
1360 	offset+=4;
1361 	len_remain-=4;
1362 
1363 	switch(conformance) {
1364 
1365 	case SNMP_ENGINEID_RFC1910:
1366 		/* 12-byte AgentID w/ 8-byte trailer */
1367 		if (len_remain==8) {
1368 			proto_tree_add_item(tree, hf_snmp_agentid_trailer, tvb, offset, 8, ENC_NA);
1369 			offset+=8;
1370 			len_remain-=8;
1371 		} else {
1372 			proto_tree_add_expert(tree, pinfo, &ei_snmp_rfc1910_non_conformant, tvb, offset, len_remain);
1373 			return offset;
1374 		}
1375 		break;
1376 
1377 	case SNMP_ENGINEID_RFC3411: /* variable length: 5..32 */
1378 
1379 		/* 1-byte format specifier */
1380 		if (len_remain<1) return offset;
1381 		format = tvb_get_guint8(tvb, offset);
1382 		item = proto_tree_add_uint_format(tree, hf_snmp_engineid_format, tvb, offset, 1, format, "Engine ID Format: %s (%d)",
1383 						  val_to_str(format, snmp_engineid_format_vals, "Reserved/Enterprise-specific"), format);
1384 		offset+=1;
1385 		len_remain-=1;
1386 
1387 		switch(format) {
1388 		case SNMP_ENGINEID_FORMAT_IPV4:
1389 			/* 4-byte IPv4 address */
1390 			if (len_remain==4) {
1391 				proto_tree_add_item(tree, hf_snmp_engineid_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
1392 				offset+=4;
1393 				len_remain=0;
1394 			}
1395 			break;
1396 		case SNMP_ENGINEID_FORMAT_IPV6:
1397 			/* 16-byte IPv6 address */
1398 			if (len_remain==16) {
1399 				proto_tree_add_item(tree, hf_snmp_engineid_ipv6, tvb, offset, 16, ENC_NA);
1400 				offset+=16;
1401 				len_remain=0;
1402 			}
1403 			break;
1404 		case SNMP_ENGINEID_FORMAT_MACADDRESS:
1405 			/* See: https://supportforums.cisco.com/message/3010617#3010617 for details. */
1406 			if ((enterpriseid==9)&&(len_remain==7)) {
1407 				proto_tree_add_item(tree, hf_snmp_engineid_cisco_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1408 				offset++;
1409 				len_remain--;
1410 			}
1411 			/* 6-byte MAC address */
1412 			if (len_remain==6) {
1413 				proto_tree_add_item(tree, hf_snmp_engineid_mac, tvb, offset, 6, ENC_NA);
1414 				offset+=6;
1415 				len_remain=0;
1416 			}
1417 			break;
1418 		case SNMP_ENGINEID_FORMAT_TEXT:
1419 			/* max. 27-byte string, administratively assigned */
1420 			if (len_remain<=27) {
1421 				proto_tree_add_item(tree, hf_snmp_engineid_text, tvb, offset, len_remain, ENC_ASCII|ENC_NA);
1422 				offset+=len_remain;
1423 				len_remain=0;
1424 			}
1425 			break;
1426 		case 128:
1427 			/* most common enterprise-specific format: (ucd|net)-snmp random */
1428 			if ((enterpriseid==2021)||(enterpriseid==8072)) {
1429 				proto_item_append_text(item, (enterpriseid==2021) ? ": UCD-SNMP Random" : ": Net-SNMP Random");
1430 				/* demystify: 4B random, 4B/8B epoch seconds */
1431 				if ((len_remain==8) || (len_remain==12)) {
1432 					proto_tree_add_item(tree, hf_snmp_engineid_data, tvb, offset, 4, ENC_NA);
1433 					if (len_remain==8) {
1434 						seconds = (time_t)tvb_get_letohl(tvb, offset + 4);
1435 					} else {
1436 						seconds = (time_t)tvb_get_letohi64(tvb, offset + 4);
1437 					}
1438 					ts.secs = seconds;
1439 					ts.nsecs = 0;
1440 					proto_tree_add_time_format_value(tree, hf_snmp_engineid_time, tvb, offset + 4, len_remain - 4,
1441 									 &ts, "%s",
1442 									 abs_time_secs_to_str(pinfo->pool, seconds, ABSOLUTE_TIME_LOCAL, TRUE));
1443 					offset+=len_remain;
1444 					len_remain=0;
1445 				}
1446 			break;
1447 			}
1448 		/* fall through */
1449 		case SNMP_ENGINEID_FORMAT_OCTETS:
1450 		default:
1451 			/* max. 27 bytes, administratively assigned or unknown format */
1452 			if (len_remain<=27) {
1453 				proto_tree_add_item(tree, hf_snmp_engineid_data, tvb, offset, len_remain, ENC_NA);
1454 				offset+=len_remain;
1455 				len_remain=0;
1456 			}
1457 		break;
1458 		}
1459 	}
1460 
1461 	if (len_remain>0) {
1462 		proto_tree_add_expert(tree, pinfo, &ei_snmp_rfc3411_non_conformant, tvb, offset, len_remain);
1463 		offset+=len_remain;
1464 	}
1465 	return offset;
1466 }
1467 
1468 
set_ue_keys(snmp_ue_assoc_t * n)1469 static void set_ue_keys(snmp_ue_assoc_t* n ) {
1470 	guint key_size = auth_hash_len[n->user.authModel];
1471 
1472 	n->user.authKey.data = (guint8 *)g_malloc(key_size);
1473 	n->user.authKey.len = key_size;
1474 	snmp_usm_password_to_key(n->user.authModel,
1475 				 n->user.authPassword.data,
1476 				 n->user.authPassword.len,
1477 				 n->engine.data,
1478 				 n->engine.len,
1479 				 n->user.authKey.data);
1480 
1481 	if (n->priv_proto == PRIV_AES128 || n->priv_proto == PRIV_AES192 || n->priv_proto == PRIV_AES256) {
1482 		guint need_key_len =
1483 			(n->priv_proto == PRIV_AES128) ? 16 :
1484 			(n->priv_proto == PRIV_AES192) ? 24 :
1485 			(n->priv_proto == PRIV_AES256) ? 32 :
1486 			0;
1487 
1488 		guint key_len = key_size;
1489 
1490 		while (key_len < need_key_len)
1491 			key_len += key_size;
1492 
1493 		n->user.privKey.data = (guint8 *)g_malloc(key_len);
1494 		n->user.privKey.len  = need_key_len;
1495 
1496 		snmp_usm_password_to_key(n->user.authModel,
1497 					 n->user.privPassword.data,
1498 					 n->user.privPassword.len,
1499 					 n->engine.data,
1500 					 n->engine.len,
1501 					 n->user.privKey.data);
1502 
1503 		key_len = key_size;
1504 
1505 		/* extend key if needed */
1506 		while (key_len < need_key_len) {
1507 			snmp_usm_password_to_key(n->user.authModel,
1508 						 n->user.privKey.data,
1509 						 key_len,
1510 						 n->engine.data,
1511 						 n->engine.len,
1512 						 n->user.privKey.data + key_len);
1513 
1514 			key_len += key_size;
1515 		}
1516 
1517 	} else {
1518 		n->user.privKey.data = (guint8 *)g_malloc(key_size);
1519 		n->user.privKey.len = key_size;
1520 		snmp_usm_password_to_key(n->user.authModel,
1521 					 n->user.privPassword.data,
1522 					 n->user.privPassword.len,
1523 					 n->engine.data,
1524 					 n->engine.len,
1525 					 n->user.privKey.data);
1526 	}
1527 }
1528 
1529 static snmp_ue_assoc_t*
ue_dup(snmp_ue_assoc_t * o)1530 ue_dup(snmp_ue_assoc_t* o)
1531 {
1532 	snmp_ue_assoc_t* d = (snmp_ue_assoc_t*)g_memdup2(o,sizeof(snmp_ue_assoc_t));
1533 
1534 	d->user.authModel = o->user.authModel;
1535 
1536 	d->user.privProtocol = o->user.privProtocol;
1537 
1538 	d->user.userName.data = (guint8 *)g_memdup2(o->user.userName.data,o->user.userName.len);
1539 	d->user.userName.len = o->user.userName.len;
1540 
1541 	d->user.authPassword.data = o->user.authPassword.data ? (guint8 *)g_memdup2(o->user.authPassword.data,o->user.authPassword.len) : NULL;
1542 	d->user.authPassword.len = o->user.authPassword.len;
1543 
1544 	d->user.privPassword.data = o->user.privPassword.data ? (guint8 *)g_memdup2(o->user.privPassword.data,o->user.privPassword.len) : NULL;
1545 	d->user.privPassword.len = o->user.privPassword.len;
1546 
1547 	d->engine.len = o->engine.len;
1548 
1549 	if (d->engine.len) {
1550 		d->engine.data = (guint8 *)g_memdup2(o->engine.data,o->engine.len);
1551 		set_ue_keys(d);
1552 	}
1553 
1554 	return d;
1555 
1556 }
1557 
1558 static void*
snmp_users_copy_cb(void * dest,const void * orig,size_t len _U_)1559 snmp_users_copy_cb(void* dest, const void* orig, size_t len _U_)
1560 {
1561 	const snmp_ue_assoc_t* o = (const snmp_ue_assoc_t*)orig;
1562 	snmp_ue_assoc_t* d = (snmp_ue_assoc_t*)dest;
1563 
1564 	d->auth_model = o->auth_model;
1565 	d->user.authModel = (snmp_usm_auth_model_t) o->auth_model;
1566 
1567 	d->priv_proto = o->priv_proto;
1568 	d->user.privProtocol = priv_protos[o->priv_proto];
1569 
1570 	d->user.userName.data = (guint8*)g_memdup2(o->user.userName.data,o->user.userName.len);
1571 	d->user.userName.len = o->user.userName.len;
1572 
1573 	d->user.authPassword.data = o->user.authPassword.data ? (guint8*)g_memdup2(o->user.authPassword.data,o->user.authPassword.len) : NULL;
1574 	d->user.authPassword.len = o->user.authPassword.len;
1575 
1576 	d->user.privPassword.data = o->user.privPassword.data ? (guint8*)g_memdup2(o->user.privPassword.data,o->user.privPassword.len) : NULL;
1577 	d->user.privPassword.len = o->user.privPassword.len;
1578 
1579 	d->engine.len = o->engine.len;
1580 	if (o->engine.data) {
1581 		d->engine.data = (guint8*)g_memdup2(o->engine.data,o->engine.len);
1582 	}
1583 
1584 	d->user.authKey.data = o->user.authKey.data ? (guint8*)g_memdup2(o->user.authKey.data,o->user.authKey.len) : NULL;
1585 	d->user.authKey.len = o->user.authKey.len;
1586 
1587 	d->user.privKey.data = o->user.privKey.data ? (guint8*)g_memdup2(o->user.privKey.data,o->user.privKey.len) : NULL;
1588 	d->user.privKey.len = o->user.privKey.len;
1589 
1590 	return d;
1591 }
1592 
1593 static void
snmp_users_free_cb(void * p)1594 snmp_users_free_cb(void* p)
1595 {
1596 	snmp_ue_assoc_t* ue = (snmp_ue_assoc_t*)p;
1597 	g_free(ue->user.userName.data);
1598 	g_free(ue->user.authPassword.data);
1599 	g_free(ue->user.privPassword.data);
1600 	g_free(ue->user.authKey.data);
1601 	g_free(ue->user.privKey.data);
1602 	g_free(ue->engine.data);
1603 }
1604 
1605 static gboolean
snmp_users_update_cb(void * p _U_,char ** err)1606 snmp_users_update_cb(void* p _U_, char** err)
1607 {
1608 	snmp_ue_assoc_t* ue = (snmp_ue_assoc_t*)p;
1609 	GString* es = g_string_new("");
1610 	unsigned int i;
1611 
1612 	*err = NULL;
1613 
1614 	if (! ue->user.userName.len) {
1615 		g_string_append_printf(es,"no userName\n");
1616 	} else if ((ue->engine.len > 0) && (ue->engine.len < 5 || ue->engine.len > 32)) {
1617 		/* RFC 3411 section 5 */
1618 		g_string_append_printf(es, "Invalid engineId length (%u). Must be between 5 and 32 (10 and 64 hex digits)\n", ue->engine.len);
1619 	} else if (num_ueas) {
1620 		for (i=0; i<num_ueas-1; i++) {
1621 			snmp_ue_assoc_t* u = &(ueas[i]);
1622 
1623 			if ( u->user.userName.len == ue->user.userName.len
1624 				&& u->engine.len == ue->engine.len && (u != ue)) {
1625 
1626 				if (u->engine.len > 0 && memcmp( u->engine.data, ue->engine.data, u->engine.len ) == 0) {
1627 					if ( memcmp( u->user.userName.data, ue->user.userName.data, ue->user.userName.len ) == 0 ) {
1628 						/* XXX: make a string for the engineId */
1629 						g_string_append_printf(es,"Duplicate key (userName='%s')\n",ue->user.userName.data);
1630 						break;
1631 					}
1632 				}
1633 
1634 				if (u->engine.len == 0) {
1635 					if ( memcmp( u->user.userName.data, ue->user.userName.data, ue->user.userName.len ) == 0 ) {
1636 						g_string_append_printf(es,"Duplicate key (userName='%s' engineId=NONE)\n",ue->user.userName.data);
1637 						break;
1638 					}
1639 				}
1640 			}
1641 		}
1642 	}
1643 
1644 	if (es->len) {
1645 		es = g_string_truncate(es,es->len-1);
1646 		*err = g_string_free(es, FALSE);
1647 		return FALSE;
1648 	}
1649 
1650 	return TRUE;
1651 }
1652 
1653 static void
free_ue_cache(snmp_ue_assoc_t ** cache)1654 free_ue_cache(snmp_ue_assoc_t **cache)
1655 {
1656 	static snmp_ue_assoc_t *a, *nxt;
1657 
1658 	for (a = *cache; a; a = nxt) {
1659 		nxt = a->next;
1660 		snmp_users_free_cb(a);
1661 		g_free(a);
1662 	}
1663 
1664 	*cache = NULL;
1665 }
1666 
1667 #define CACHE_INSERT(c,a) if (c) { snmp_ue_assoc_t* t = c; c = a; c->next = t; } else { c = a; a->next = NULL; }
1668 
1669 static void
init_ue_cache(void)1670 init_ue_cache(void)
1671 {
1672 	guint i;
1673 
1674 	for (i = 0; i < num_ueas; i++) {
1675 		snmp_ue_assoc_t* a = ue_dup(&(ueas[i]));
1676 
1677 		if (a->engine.len) {
1678 			CACHE_INSERT(localized_ues,a);
1679 
1680 		} else {
1681 			CACHE_INSERT(unlocalized_ues,a);
1682 		}
1683 
1684 	}
1685 }
1686 
1687 static void
cleanup_ue_cache(void)1688 cleanup_ue_cache(void)
1689 {
1690 	free_ue_cache(&localized_ues);
1691 	free_ue_cache(&unlocalized_ues);
1692 }
1693 
1694 /* Called when the user applies changes to UAT preferences. */
1695 static void
renew_ue_cache(void)1696 renew_ue_cache(void)
1697 {
1698 	cleanup_ue_cache();
1699 	init_ue_cache();
1700 }
1701 
1702 
1703 static snmp_ue_assoc_t*
localize_ue(snmp_ue_assoc_t * o,const guint8 * engine,guint engine_len)1704 localize_ue( snmp_ue_assoc_t* o, const guint8* engine, guint engine_len )
1705 {
1706 	snmp_ue_assoc_t* n = (snmp_ue_assoc_t*)g_memdup2(o,sizeof(snmp_ue_assoc_t));
1707 
1708 	n->user.userName.data = (guint8*)g_memdup2(o->user.userName.data,o->user.userName.len);
1709 	n->user.authModel = o->user.authModel;
1710 	n->user.authPassword.data = (guint8*)g_memdup2(o->user.authPassword.data,o->user.authPassword.len);
1711 	n->user.authPassword.len = o->user.authPassword.len;
1712 	n->user.privPassword.data = (guint8*)g_memdup2(o->user.privPassword.data,o->user.privPassword.len);
1713 	n->user.privPassword.len = o->user.privPassword.len;
1714 	n->user.authKey.data = (guint8*)g_memdup2(o->user.authKey.data,o->user.authKey.len);
1715 	n->user.privKey.data = (guint8*)g_memdup2(o->user.privKey.data,o->user.privKey.len);
1716 	n->engine.data = (guint8*)g_memdup2(engine,engine_len);
1717 	n->engine.len = engine_len;
1718 	n->priv_proto = o->priv_proto;
1719 
1720 	set_ue_keys(n);
1721 
1722 	return n;
1723 }
1724 
1725 
1726 #define localized_match(a,u,ul,e,el) \
1727 	( a->user.userName.len == ul \
1728 	&& a->engine.len == el \
1729 	&& memcmp( a->user.userName.data, u, ul ) == 0 \
1730 	&& memcmp( a->engine.data,   e,  el ) == 0 )
1731 
1732 #define unlocalized_match(a,u,l) \
1733 	( a->user.userName.len == l && memcmp( a->user.userName.data, u, l) == 0 )
1734 
1735 static snmp_ue_assoc_t*
get_user_assoc(tvbuff_t * engine_tvb,tvbuff_t * user_tvb,packet_info * pinfo)1736 get_user_assoc(tvbuff_t* engine_tvb, tvbuff_t* user_tvb, packet_info *pinfo)
1737 {
1738 	static snmp_ue_assoc_t* a;
1739 	guint given_username_len;
1740 	guint8* given_username;
1741 	guint given_engine_len = 0;
1742 	guint8* given_engine = NULL;
1743 
1744 	if ( ! (localized_ues || unlocalized_ues ) ) return NULL;
1745 
1746 	if (! ( user_tvb && engine_tvb ) ) return NULL;
1747 
1748 	given_username_len = tvb_captured_length(user_tvb);
1749 	given_engine_len = tvb_captured_length(engine_tvb);
1750 	if (! ( given_engine_len && given_username_len ) ) return NULL;
1751 	given_username = (guint8*)tvb_memdup(pinfo->pool,user_tvb,0,-1);
1752 	given_engine = (guint8*)tvb_memdup(pinfo->pool,engine_tvb,0,-1);
1753 
1754 	for (a = localized_ues; a; a = a->next) {
1755 		if ( localized_match(a, given_username, given_username_len, given_engine, given_engine_len) ) {
1756 			return a;
1757 		}
1758 	}
1759 
1760 	for (a = unlocalized_ues; a; a = a->next) {
1761 		if ( unlocalized_match(a, given_username, given_username_len) ) {
1762 			snmp_ue_assoc_t* n = localize_ue( a, given_engine, given_engine_len );
1763 			CACHE_INSERT(localized_ues,n);
1764 			return n;
1765 		}
1766 	}
1767 
1768 	return NULL;
1769 }
1770 
1771 static gboolean
snmp_usm_auth(const packet_info * pinfo,const snmp_usm_auth_model_t model,snmp_usm_params_t * p,guint8 ** calc_auth_p,guint * calc_auth_len_p,gchar const ** error)1772 snmp_usm_auth(const packet_info *pinfo, const snmp_usm_auth_model_t model, snmp_usm_params_t* p, guint8** calc_auth_p,
1773 	guint* calc_auth_len_p, gchar const** error)
1774 {
1775 	gint msg_len;
1776 	guint8* msg;
1777 	guint auth_len;
1778 	guint8* auth;
1779 	guint8* key;
1780 	guint key_len;
1781 	guint8 *calc_auth;
1782 	guint start;
1783 	guint end;
1784 	guint i;
1785 
1786 	if (!p->auth_tvb) {
1787 		*error = "No Authenticator";
1788 		return FALSE;
1789 	}
1790 
1791 	key = p->user_assoc->user.authKey.data;
1792 	key_len = p->user_assoc->user.authKey.len;
1793 
1794 	if (! key ) {
1795 		*error = "User has no authKey";
1796 		return FALSE;
1797 	}
1798 
1799 	auth_len = tvb_captured_length(p->auth_tvb);
1800 
1801 	if (auth_len != auth_tag_len[model]) {
1802 		*error = "Authenticator length wrong";
1803 		return FALSE;
1804 	}
1805 
1806 	msg_len = tvb_captured_length(p->msg_tvb);
1807 	if (msg_len <= 0) {
1808 		*error = "Not enough data remaining";
1809 		return FALSE;
1810 	}
1811 	msg = (guint8*)tvb_memdup(pinfo->pool,p->msg_tvb,0,msg_len);
1812 
1813 	auth = (guint8*)tvb_memdup(pinfo->pool,p->auth_tvb,0,auth_len);
1814 
1815 	start = p->auth_offset - p->start_offset;
1816 	end =   start + auth_len;
1817 
1818 	/* fill the authenticator with zeros */
1819 	for ( i = start ; i < end ; i++ ) {
1820 		msg[i] = '\0';
1821 	}
1822 
1823 	calc_auth = (guint8*)wmem_alloc(pinfo->pool, auth_hash_len[model]);
1824 
1825 	if (ws_hmac_buffer(auth_hash_algo[model], calc_auth, msg, msg_len, key, key_len)) {
1826 		return FALSE;
1827 	}
1828 
1829 	if (calc_auth_p) *calc_auth_p = calc_auth;
1830 	if (calc_auth_len_p) *calc_auth_len_p = auth_len;
1831 
1832 	return ( memcmp(auth,calc_auth,auth_len) != 0 ) ? FALSE : TRUE;
1833 }
1834 
1835 static tvbuff_t*
snmp_usm_priv_des(snmp_usm_params_t * p,tvbuff_t * encryptedData,packet_info * pinfo,gchar const ** error)1836 snmp_usm_priv_des(snmp_usm_params_t* p, tvbuff_t* encryptedData, packet_info *pinfo, gchar const** error)
1837 {
1838 	gcry_error_t err;
1839 	gcry_cipher_hd_t hd = NULL;
1840 
1841 	guint8* cleartext;
1842 	guint8* des_key = p->user_assoc->user.privKey.data; /* first 8 bytes */
1843 	guint8* pre_iv = &(p->user_assoc->user.privKey.data[8]); /* last 8 bytes */
1844 	guint8* salt;
1845 	gint salt_len;
1846 	gint cryptgrm_len;
1847 	guint8* cryptgrm;
1848 	tvbuff_t* clear_tvb;
1849 	guint8 iv[8];
1850 	guint i;
1851 
1852 
1853 	salt_len = tvb_captured_length(p->priv_tvb);
1854 
1855 	if (salt_len != 8) {
1856 		*error = "decryptionError: msgPrivacyParameters length != 8";
1857 		return NULL;
1858 	}
1859 
1860 	salt = (guint8*)tvb_memdup(pinfo->pool,p->priv_tvb,0,salt_len);
1861 
1862 	/*
1863 	 The resulting "salt" is XOR-ed with the pre-IV to obtain the IV.
1864 	 */
1865 	for (i=0; i<8; i++) {
1866 		iv[i] = pre_iv[i] ^ salt[i];
1867 	}
1868 
1869 	cryptgrm_len = tvb_captured_length(encryptedData);
1870 
1871 	if ((cryptgrm_len <= 0) || (cryptgrm_len % 8)) {
1872 		*error = "decryptionError: the length of the encrypted data is not a multiple of 8 octets";
1873 		return NULL;
1874 	}
1875 
1876 	cryptgrm = (guint8*)tvb_memdup(pinfo->pool,encryptedData,0,-1);
1877 
1878 	cleartext = (guint8*)wmem_alloc(pinfo->pool, cryptgrm_len);
1879 
1880 	err = gcry_cipher_open(&hd, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC, 0);
1881 	if (err != GPG_ERR_NO_ERROR) goto on_gcry_error;
1882 
1883 	err = gcry_cipher_setiv(hd, iv, 8);
1884 	if (err != GPG_ERR_NO_ERROR) goto on_gcry_error;
1885 
1886 	err = gcry_cipher_setkey(hd,des_key,8);
1887 	if (err != GPG_ERR_NO_ERROR) goto on_gcry_error;
1888 
1889 	err = gcry_cipher_decrypt(hd, cleartext, cryptgrm_len, cryptgrm, cryptgrm_len);
1890 	if (err != GPG_ERR_NO_ERROR) goto on_gcry_error;
1891 
1892 	gcry_cipher_close(hd);
1893 
1894 	clear_tvb = tvb_new_child_real_data(encryptedData, cleartext, cryptgrm_len, cryptgrm_len);
1895 
1896 	return clear_tvb;
1897 
1898 on_gcry_error:
1899 	*error = (const gchar *)gcry_strerror(err);
1900 	if (hd) gcry_cipher_close(hd);
1901 	return NULL;
1902 }
1903 
1904 static tvbuff_t*
snmp_usm_priv_aes_common(snmp_usm_params_t * p,tvbuff_t * encryptedData,packet_info * pinfo,gchar const ** error,int algo)1905 snmp_usm_priv_aes_common(snmp_usm_params_t* p, tvbuff_t* encryptedData, packet_info *pinfo, gchar const** error, int algo)
1906 {
1907 	gcry_error_t err;
1908 	gcry_cipher_hd_t hd = NULL;
1909 
1910 	guint8* cleartext;
1911 	guint8* aes_key = p->user_assoc->user.privKey.data;
1912 	int aes_key_len = p->user_assoc->user.privKey.len;
1913 	guint8 iv[16];
1914 	gint priv_len;
1915 	gint cryptgrm_len;
1916 	guint8* cryptgrm;
1917 	tvbuff_t* clear_tvb;
1918 
1919 	priv_len = tvb_captured_length(p->priv_tvb);
1920 
1921 	if (priv_len != 8) {
1922 		*error = "decryptionError: msgPrivacyParameters length != 8";
1923 		return NULL;
1924 	}
1925 
1926 	iv[0] = (p->boots & 0xff000000) >> 24;
1927 	iv[1] = (p->boots & 0x00ff0000) >> 16;
1928 	iv[2] = (p->boots & 0x0000ff00) >> 8;
1929 	iv[3] = (p->boots & 0x000000ff);
1930 	iv[4] = (p->snmp_time & 0xff000000) >> 24;
1931 	iv[5] = (p->snmp_time & 0x00ff0000) >> 16;
1932 	iv[6] = (p->snmp_time & 0x0000ff00) >> 8;
1933 	iv[7] = (p->snmp_time & 0x000000ff);
1934 	tvb_memcpy(p->priv_tvb,&(iv[8]),0,8);
1935 
1936 	cryptgrm_len = tvb_captured_length(encryptedData);
1937 	if (cryptgrm_len <= 0) {
1938 		*error = "Not enough data remaining";
1939 		return NULL;
1940 	}
1941 	cryptgrm = (guint8*)tvb_memdup(pinfo->pool,encryptedData,0,-1);
1942 
1943 	cleartext = (guint8*)wmem_alloc(pinfo->pool, cryptgrm_len);
1944 
1945 	err = gcry_cipher_open(&hd, algo, GCRY_CIPHER_MODE_CFB, 0);
1946 	if (err != GPG_ERR_NO_ERROR) goto on_gcry_error;
1947 
1948 	err = gcry_cipher_setiv(hd, iv, 16);
1949 	if (err != GPG_ERR_NO_ERROR) goto on_gcry_error;
1950 
1951 	err = gcry_cipher_setkey(hd,aes_key,aes_key_len);
1952 	if (err != GPG_ERR_NO_ERROR) goto on_gcry_error;
1953 
1954 	err = gcry_cipher_decrypt(hd, cleartext, cryptgrm_len, cryptgrm, cryptgrm_len);
1955 	if (err != GPG_ERR_NO_ERROR) goto on_gcry_error;
1956 
1957 	gcry_cipher_close(hd);
1958 
1959 	clear_tvb = tvb_new_child_real_data(encryptedData, cleartext, cryptgrm_len, cryptgrm_len);
1960 
1961 	return clear_tvb;
1962 
1963 on_gcry_error:
1964 	*error = (const gchar *)gcry_strerror(err);
1965 	if (hd) gcry_cipher_close(hd);
1966 	return NULL;
1967 }
1968 
1969 static tvbuff_t*
snmp_usm_priv_aes128(snmp_usm_params_t * p,tvbuff_t * encryptedData,packet_info * pinfo,gchar const ** error)1970 snmp_usm_priv_aes128(snmp_usm_params_t* p, tvbuff_t* encryptedData, packet_info *pinfo, gchar const** error)
1971 {
1972 	return snmp_usm_priv_aes_common(p, encryptedData, pinfo, error, GCRY_CIPHER_AES);
1973 }
1974 
1975 static tvbuff_t*
snmp_usm_priv_aes192(snmp_usm_params_t * p,tvbuff_t * encryptedData,packet_info * pinfo,gchar const ** error)1976 snmp_usm_priv_aes192(snmp_usm_params_t* p, tvbuff_t* encryptedData, packet_info *pinfo, gchar const** error)
1977 {
1978 	return snmp_usm_priv_aes_common(p, encryptedData, pinfo, error, GCRY_CIPHER_AES192);
1979 }
1980 
1981 static tvbuff_t*
snmp_usm_priv_aes256(snmp_usm_params_t * p,tvbuff_t * encryptedData,packet_info * pinfo,gchar const ** error)1982 snmp_usm_priv_aes256(snmp_usm_params_t* p, tvbuff_t* encryptedData, packet_info *pinfo, gchar const** error)
1983 {
1984 	return snmp_usm_priv_aes_common(p, encryptedData, pinfo, error, GCRY_CIPHER_AES256);
1985 }
1986 
1987 static gboolean
check_ScopedPdu(tvbuff_t * tvb)1988 check_ScopedPdu(tvbuff_t* tvb)
1989 {
1990 	int offset;
1991 	gint8 ber_class;
1992 	gboolean pc;
1993 	gint32 tag;
1994 	int hoffset, eoffset;
1995 	guint32 len;
1996 
1997 	offset = get_ber_identifier(tvb, 0, &ber_class, &pc, &tag);
1998 	offset = get_ber_length(tvb, offset, NULL, NULL);
1999 
2000 	if ( ! (((ber_class!=BER_CLASS_APP) && (ber_class!=BER_CLASS_PRI) )
2001 			&& ( (!pc) || (ber_class!=BER_CLASS_UNI) || (tag!=BER_UNI_TAG_ENUMERATED) )
2002 			)) return FALSE;
2003 
2004 	if((tvb_get_guint8(tvb, offset)==0)&&(tvb_get_guint8(tvb, offset+1)==0))
2005 		return TRUE;
2006 
2007 	hoffset = offset;
2008 
2009 	offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
2010 	offset = get_ber_length(tvb, offset, &len, NULL);
2011 	eoffset = offset + len;
2012 
2013 	if (eoffset <= hoffset) return FALSE;
2014 
2015 	if ((ber_class!=BER_CLASS_APP)&&(ber_class!=BER_CLASS_PRI))
2016 		if( (ber_class!=BER_CLASS_UNI)
2017 			||((tag<BER_UNI_TAG_NumericString)&&(tag!=BER_UNI_TAG_OCTETSTRING)&&(tag!=BER_UNI_TAG_UTF8String)) )
2018 			return FALSE;
2019 
2020 	return TRUE;
2021 
2022 }
2023 
2024 
2025 /*--- Included file: packet-snmp-fn.c ---*/
2026 #line 1 "./asn1/snmp/packet-snmp-fn.c"
2027 
2028 
2029 
2030 static int
dissect_snmp_EnterpriseOID(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2031 dissect_snmp_EnterpriseOID(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2032 #line 88 "./asn1/snmp/snmp.cnf"
2033 	const gchar* name;
2034 
2035   offset = dissect_ber_object_identifier_str(implicit_tag, actx, tree, tvb, offset, hf_index, &enterprise_oid);
2036 
2037 
2038 	if (display_oid && enterprise_oid) {
2039 		name = oid_resolved_from_string(actx->pinfo->pool, enterprise_oid);
2040 		if (name) {
2041 		col_append_fstr (actx->pinfo->cinfo, COL_INFO, " %s", name);
2042 		}
2043 	}
2044 
2045 
2046 
2047   return offset;
2048 }
2049 
2050 
2051 
2052 static int
dissect_snmp_OCTET_STRING_SIZE_4(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2053 dissect_snmp_OCTET_STRING_SIZE_4(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2054   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
2055                                        NULL);
2056 
2057   return offset;
2058 }
2059 
2060 
2061 
2062 static int
dissect_snmp_NetworkAddress(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2063 dissect_snmp_NetworkAddress(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2064   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
2065                                       hf_index, BER_CLASS_APP, 0, TRUE, dissect_snmp_OCTET_STRING_SIZE_4);
2066 
2067   return offset;
2068 }
2069 
2070 
2071 
2072 static int
dissect_snmp_INTEGER_0_4294967295(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2073 dissect_snmp_INTEGER_0_4294967295(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2074   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2075                                                 NULL);
2076 
2077   return offset;
2078 }
2079 
2080 
2081 
2082 static int
dissect_snmp_TimeTicks(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2083 dissect_snmp_TimeTicks(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2084   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
2085                                       hf_index, BER_CLASS_APP, 3, TRUE, dissect_snmp_INTEGER_0_4294967295);
2086 
2087   return offset;
2088 }
2089 
2090 
2091 
2092 static int
dissect_snmp_Integer32(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2093 dissect_snmp_Integer32(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2094 #line 56 "./asn1/snmp/snmp.cnf"
2095 
2096   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2097                                                 &RequestID);
2098 
2099 
2100 
2101 
2102   return offset;
2103 }
2104 
2105 
2106 
2107 static int
dissect_snmp_ObjectName(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2108 dissect_snmp_ObjectName(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2109   offset = dissect_ber_object_identifier(implicit_tag, actx, tree, tvb, offset, hf_index, NULL);
2110 
2111   return offset;
2112 }
2113 
2114 
2115 static const value_string snmp_Version_vals[] = {
2116   {   0, "version-1" },
2117   {   1, "v2c" },
2118   {   2, "v2u" },
2119   {   3, "snmpv3" },
2120   { 0, NULL }
2121 };
2122 
2123 
2124 static int
dissect_snmp_Version(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2125 dissect_snmp_Version(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2126   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2127                                                 &snmp_version);
2128 
2129   return offset;
2130 }
2131 
2132 
2133 
2134 static int
dissect_snmp_Community(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2135 dissect_snmp_Community(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2136   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
2137                                        NULL);
2138 
2139   return offset;
2140 }
2141 
2142 
2143 
2144 static int
dissect_snmp_T_request_id(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2145 dissect_snmp_T_request_id(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2146 #line 52 "./asn1/snmp/snmp.cnf"
2147 
2148   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2149                                                 &RequestID);
2150 
2151 
2152 
2153 
2154   return offset;
2155 }
2156 
2157 
2158 static const value_string snmp_T_error_status_vals[] = {
2159   {   0, "noError" },
2160   {   1, "tooBig" },
2161   {   2, "noSuchName" },
2162   {   3, "badValue" },
2163   {   4, "readOnly" },
2164   {   5, "genErr" },
2165   {   6, "noAccess" },
2166   {   7, "wrongType" },
2167   {   8, "wrongLength" },
2168   {   9, "wrongEncoding" },
2169   {  10, "wrongValue" },
2170   {  11, "noCreation" },
2171   {  12, "inconsistentValue" },
2172   {  13, "resourceUnavailable" },
2173   {  14, "commitFailed" },
2174   {  15, "undoFailed" },
2175   {  16, "authorizationError" },
2176   {  17, "notWritable" },
2177   {  18, "inconsistentName" },
2178   { 0, NULL }
2179 };
2180 
2181 
2182 static int
dissect_snmp_T_error_status(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2183 dissect_snmp_T_error_status(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2184   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2185                                                 NULL);
2186 
2187   return offset;
2188 }
2189 
2190 
2191 
2192 static int
dissect_snmp_INTEGER(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2193 dissect_snmp_INTEGER(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2194   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2195                                                 NULL);
2196 
2197   return offset;
2198 }
2199 
2200 
2201 
2202 static const ber_sequence_t VarBindList_sequence_of[1] = {
2203   { &hf_snmp_VarBindList_item, BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_snmp_VarBind },
2204 };
2205 
2206 static int
dissect_snmp_VarBindList(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2207 dissect_snmp_VarBindList(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2208   offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
2209                                       VarBindList_sequence_of, hf_index, ett_snmp_VarBindList);
2210 
2211   return offset;
2212 }
2213 
2214 
2215 static const ber_sequence_t PDU_sequence[] = {
2216   { &hf_snmp_request_id     , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_T_request_id },
2217   { &hf_snmp_error_status   , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_T_error_status },
2218   { &hf_snmp_error_index    , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_INTEGER },
2219   { &hf_snmp_variable_bindings, BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_snmp_VarBindList },
2220   { NULL, 0, 0, 0, NULL }
2221 };
2222 
2223 static int
dissect_snmp_PDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2224 dissect_snmp_PDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2225   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2226                                    PDU_sequence, hf_index, ett_snmp_PDU);
2227 
2228   return offset;
2229 }
2230 
2231 
2232 
2233 static int
dissect_snmp_GetRequest_PDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2234 dissect_snmp_GetRequest_PDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2235   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
2236                                       hf_index, BER_CLASS_CON, 0, TRUE, dissect_snmp_PDU);
2237 
2238   return offset;
2239 }
2240 
2241 
2242 
2243 static int
dissect_snmp_GetNextRequest_PDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2244 dissect_snmp_GetNextRequest_PDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2245   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
2246                                       hf_index, BER_CLASS_CON, 1, TRUE, dissect_snmp_PDU);
2247 
2248   return offset;
2249 }
2250 
2251 
2252 
2253 static int
dissect_snmp_GetResponse_PDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2254 dissect_snmp_GetResponse_PDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2255   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
2256                                       hf_index, BER_CLASS_CON, 2, TRUE, dissect_snmp_PDU);
2257 
2258   return offset;
2259 }
2260 
2261 
2262 
2263 static int
dissect_snmp_SetRequest_PDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2264 dissect_snmp_SetRequest_PDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2265   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
2266                                       hf_index, BER_CLASS_CON, 3, TRUE, dissect_snmp_PDU);
2267 
2268   return offset;
2269 }
2270 
2271 
2272 static const value_string snmp_GenericTrap_vals[] = {
2273   {   0, "coldStart" },
2274   {   1, "warmStart" },
2275   {   2, "linkDown" },
2276   {   3, "linkUp" },
2277   {   4, "authenticationFailure" },
2278   {   5, "egpNeighborLoss" },
2279   {   6, "enterpriseSpecific" },
2280   { 0, NULL }
2281 };
2282 
2283 
2284 static int
dissect_snmp_GenericTrap(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2285 dissect_snmp_GenericTrap(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2286   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2287                                                 &generic_trap);
2288 
2289   return offset;
2290 }
2291 
2292 
2293 
2294 static int
dissect_snmp_SpecificTrap(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2295 dissect_snmp_SpecificTrap(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2296 #line 72 "./asn1/snmp/snmp.cnf"
2297   guint specific_trap;
2298 
2299   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2300                                                 &specific_trap);
2301 
2302 
2303 	if (generic_trap == 6) { /* enterprise specific */
2304 		const gchar *specific_str = snmp_lookup_specific_trap (specific_trap);
2305 		if (specific_str) {
2306 		proto_item_append_text(actx->created_item, " (%s)", specific_str);
2307 		}
2308 	}
2309 
2310 
2311   return offset;
2312 }
2313 
2314 
2315 static const ber_sequence_t Trap_PDU_U_sequence[] = {
2316   { &hf_snmp_enterprise     , BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_NOOWNTAG, dissect_snmp_EnterpriseOID },
2317   { &hf_snmp_agent_addr     , BER_CLASS_APP, 0, BER_FLAGS_NOOWNTAG, dissect_snmp_NetworkAddress },
2318   { &hf_snmp_generic_trap   , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_GenericTrap },
2319   { &hf_snmp_specific_trap  , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_SpecificTrap },
2320   { &hf_snmp_time_stamp     , BER_CLASS_APP, 3, BER_FLAGS_NOOWNTAG, dissect_snmp_TimeTicks },
2321   { &hf_snmp_variable_bindings, BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_snmp_VarBindList },
2322   { NULL, 0, 0, 0, NULL }
2323 };
2324 
2325 static int
dissect_snmp_Trap_PDU_U(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2326 dissect_snmp_Trap_PDU_U(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2327 #line 60 "./asn1/snmp/snmp.cnf"
2328 	generic_trap = 0;
2329 	enterprise_oid = NULL;
2330 
2331   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2332                                    Trap_PDU_U_sequence, hf_index, ett_snmp_Trap_PDU_U);
2333 
2334 
2335   if (snmp_version != 0) {
2336     expert_add_info(actx->pinfo, tree, &ei_snmp_trap_pdu_obsolete);
2337   }
2338 
2339 
2340 
2341   return offset;
2342 }
2343 
2344 
2345 
2346 static int
dissect_snmp_Trap_PDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2347 dissect_snmp_Trap_PDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2348   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
2349                                       hf_index, BER_CLASS_CON, 4, TRUE, dissect_snmp_Trap_PDU_U);
2350 
2351   return offset;
2352 }
2353 
2354 
2355 
2356 static int
dissect_snmp_INTEGER_0_2147483647(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2357 dissect_snmp_INTEGER_0_2147483647(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2358   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2359                                                 NULL);
2360 
2361   return offset;
2362 }
2363 
2364 
2365 static const ber_sequence_t BulkPDU_sequence[] = {
2366   { &hf_snmp_bulkPDU_request_id, BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_Integer32 },
2367   { &hf_snmp_non_repeaters  , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_INTEGER_0_2147483647 },
2368   { &hf_snmp_max_repetitions, BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_INTEGER_0_2147483647 },
2369   { &hf_snmp_variable_bindings, BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_snmp_VarBindList },
2370   { NULL, 0, 0, 0, NULL }
2371 };
2372 
2373 static int
dissect_snmp_BulkPDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2374 dissect_snmp_BulkPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2375   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2376                                    BulkPDU_sequence, hf_index, ett_snmp_BulkPDU);
2377 
2378   return offset;
2379 }
2380 
2381 
2382 
2383 static int
dissect_snmp_GetBulkRequest_PDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2384 dissect_snmp_GetBulkRequest_PDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2385   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
2386                                       hf_index, BER_CLASS_CON, 5, TRUE, dissect_snmp_BulkPDU);
2387 
2388   return offset;
2389 }
2390 
2391 
2392 
2393 static int
dissect_snmp_InformRequest_PDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2394 dissect_snmp_InformRequest_PDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2395   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
2396                                       hf_index, BER_CLASS_CON, 6, TRUE, dissect_snmp_PDU);
2397 
2398   return offset;
2399 }
2400 
2401 
2402 
2403 static int
dissect_snmp_SNMPv2_Trap_PDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2404 dissect_snmp_SNMPv2_Trap_PDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2405   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
2406                                       hf_index, BER_CLASS_CON, 7, TRUE, dissect_snmp_PDU);
2407 
2408   return offset;
2409 }
2410 
2411 
2412 
2413 static int
dissect_snmp_Report_PDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2414 dissect_snmp_Report_PDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2415   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
2416                                       hf_index, BER_CLASS_CON, 8, TRUE, dissect_snmp_PDU);
2417 
2418   return offset;
2419 }
2420 
2421 
2422 static const value_string snmp_PDUs_vals[] = {
2423   {   0, "get-request" },
2424   {   1, "get-next-request" },
2425   {   2, "get-response" },
2426   {   3, "set-request" },
2427   {   4, "trap" },
2428   {   5, "getBulkRequest" },
2429   {   6, "informRequest" },
2430   {   7, "snmpV2-trap" },
2431   {   8, "report" },
2432   { 0, NULL }
2433 };
2434 
2435 static const ber_choice_t PDUs_choice[] = {
2436   {   0, &hf_snmp_get_request    , BER_CLASS_CON, 0, BER_FLAGS_NOOWNTAG, dissect_snmp_GetRequest_PDU },
2437   {   1, &hf_snmp_get_next_request, BER_CLASS_CON, 1, BER_FLAGS_NOOWNTAG, dissect_snmp_GetNextRequest_PDU },
2438   {   2, &hf_snmp_get_response   , BER_CLASS_CON, 2, BER_FLAGS_NOOWNTAG, dissect_snmp_GetResponse_PDU },
2439   {   3, &hf_snmp_set_request    , BER_CLASS_CON, 3, BER_FLAGS_NOOWNTAG, dissect_snmp_SetRequest_PDU },
2440   {   4, &hf_snmp_trap           , BER_CLASS_CON, 4, BER_FLAGS_NOOWNTAG, dissect_snmp_Trap_PDU },
2441   {   5, &hf_snmp_getBulkRequest , BER_CLASS_CON, 5, BER_FLAGS_NOOWNTAG, dissect_snmp_GetBulkRequest_PDU },
2442   {   6, &hf_snmp_informRequest  , BER_CLASS_CON, 6, BER_FLAGS_NOOWNTAG, dissect_snmp_InformRequest_PDU },
2443   {   7, &hf_snmp_snmpV2_trap    , BER_CLASS_CON, 7, BER_FLAGS_NOOWNTAG, dissect_snmp_SNMPv2_Trap_PDU },
2444   {   8, &hf_snmp_report         , BER_CLASS_CON, 8, BER_FLAGS_NOOWNTAG, dissect_snmp_Report_PDU },
2445   { 0, NULL, 0, 0, 0, NULL }
2446 };
2447 
2448 static int
dissect_snmp_PDUs(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2449 dissect_snmp_PDUs(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2450 #line 28 "./asn1/snmp/snmp.cnf"
2451 	gint pdu_type=-1;
2452 
2453 	snmp_request_response_t *srrp;
2454 	snmp_conv_info_t *snmp_info = (snmp_conv_info_t *)actx->private_data;
2455 
2456 	col_clear(actx->pinfo->cinfo, COL_INFO);
2457 
2458   offset = dissect_ber_choice(actx, tree, tvb, offset,
2459                                  PDUs_choice, hf_index, ett_snmp_PDUs,
2460                                  &pdu_type);
2461 
2462 	if( (pdu_type!=-1) && snmp_PDUs_vals[pdu_type].strptr ){
2463 		col_prepend_fstr(actx->pinfo->cinfo, COL_INFO, "%s", snmp_PDUs_vals[pdu_type].strptr);
2464 
2465 		/* pdu_type is the index, not the tag so convert it to the tag value */
2466 		pdu_type = snmp_PDUs_vals[pdu_type].value;
2467 
2468 		srrp=snmp_match_request_response(tvb, actx->pinfo, tree, RequestID, pdu_type, snmp_info);
2469 		if (srrp) {
2470 			tap_queue_packet(snmp_tap, actx->pinfo, srrp);
2471 		}
2472 	}
2473 
2474 
2475 
2476 
2477   return offset;
2478 }
2479 
2480 
2481 static const ber_sequence_t Message_sequence[] = {
2482   { &hf_snmp_version        , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_Version },
2483   { &hf_snmp_community      , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_snmp_Community },
2484   { &hf_snmp_data           , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_snmp_PDUs },
2485   { NULL, 0, 0, 0, NULL }
2486 };
2487 
2488 static int
dissect_snmp_Message(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2489 dissect_snmp_Message(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2490   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2491                                    Message_sequence, hf_index, ett_snmp_Message);
2492 
2493   return offset;
2494 }
2495 
2496 
2497 
2498 static int
dissect_snmp_OCTET_STRING(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2499 dissect_snmp_OCTET_STRING(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2500   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
2501                                        NULL);
2502 
2503   return offset;
2504 }
2505 
2506 
2507 static const value_string snmp_T_datav2u_vals[] = {
2508   {   0, "plaintext" },
2509   {   1, "encrypted" },
2510   { 0, NULL }
2511 };
2512 
2513 static const ber_choice_t T_datav2u_choice[] = {
2514   {   0, &hf_snmp_v2u_plaintext  , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG, dissect_snmp_PDUs },
2515   {   1, &hf_snmp_encrypted      , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_snmp_OCTET_STRING },
2516   { 0, NULL, 0, 0, 0, NULL }
2517 };
2518 
2519 static int
dissect_snmp_T_datav2u(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2520 dissect_snmp_T_datav2u(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2521   offset = dissect_ber_choice(actx, tree, tvb, offset,
2522                                  T_datav2u_choice, hf_index, ett_snmp_T_datav2u,
2523                                  NULL);
2524 
2525   return offset;
2526 }
2527 
2528 
2529 static const ber_sequence_t Messagev2u_sequence[] = {
2530   { &hf_snmp_version        , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_Version },
2531   { &hf_snmp_parameters     , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_snmp_OCTET_STRING },
2532   { &hf_snmp_datav2u        , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_snmp_T_datav2u },
2533   { NULL, 0, 0, 0, NULL }
2534 };
2535 
2536 static int
dissect_snmp_Messagev2u(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2537 dissect_snmp_Messagev2u(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2538   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2539                                    Messagev2u_sequence, hf_index, ett_snmp_Messagev2u);
2540 
2541   return offset;
2542 }
2543 
2544 
2545 
2546 static int
dissect_snmp_SnmpEngineID(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2547 dissect_snmp_SnmpEngineID(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2548 #line 122 "./asn1/snmp/snmp.cnf"
2549 	tvbuff_t* param_tvb = NULL;
2550 
2551 	offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &param_tvb);
2552 	 if (param_tvb) {
2553 		proto_tree* engine_tree = proto_item_add_subtree(actx->created_item,ett_engineid);
2554 		dissect_snmp_engineid(engine_tree, actx->pinfo, param_tvb, 0, tvb_reported_length_remaining(param_tvb,0));
2555 	}
2556 
2557 
2558 
2559   return offset;
2560 }
2561 
2562 
2563 
2564 static int
dissect_snmp_T_msgAuthoritativeEngineID(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2565 dissect_snmp_T_msgAuthoritativeEngineID(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2566 #line 114 "./asn1/snmp/snmp.cnf"
2567 
2568 	offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &usm_p.engine_tvb);
2569 	 if (usm_p.engine_tvb) {
2570 		proto_tree* engine_tree = proto_item_add_subtree(actx->created_item,ett_engineid);
2571 		dissect_snmp_engineid(engine_tree, actx->pinfo, usm_p.engine_tvb, 0, tvb_reported_length_remaining(usm_p.engine_tvb,0));
2572 	}
2573 
2574 
2575 
2576   return offset;
2577 }
2578 
2579 
2580 
2581 static int
dissect_snmp_T_msgAuthoritativeEngineBoots(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2582 dissect_snmp_T_msgAuthoritativeEngineBoots(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2583   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2584                                                 &usm_p.boots);
2585 
2586   return offset;
2587 }
2588 
2589 
2590 
2591 static int
dissect_snmp_T_msgAuthoritativeEngineTime(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2592 dissect_snmp_T_msgAuthoritativeEngineTime(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2593   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2594                                                 &usm_p.snmp_time);
2595 
2596   return offset;
2597 }
2598 
2599 
2600 
2601 static int
dissect_snmp_T_msgUserName(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2602 dissect_snmp_T_msgUserName(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2603   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
2604                                        &usm_p.user_tvb);
2605 
2606   return offset;
2607 }
2608 
2609 
2610 
2611 static int
dissect_snmp_T_msgAuthenticationParameters(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2612 dissect_snmp_T_msgAuthenticationParameters(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2613 #line 134 "./asn1/snmp/snmp.cnf"
2614 	offset = dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_index, &usm_p.auth_tvb);
2615 	if (usm_p.auth_tvb) {
2616 		usm_p.auth_item = actx->created_item;
2617 		usm_p.auth_offset = tvb_offset_from_real_beginning(usm_p.auth_tvb);
2618 	}
2619 
2620 
2621   return offset;
2622 }
2623 
2624 
2625 
2626 static int
dissect_snmp_T_msgPrivacyParameters(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2627 dissect_snmp_T_msgPrivacyParameters(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2628   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
2629                                        &usm_p.priv_tvb);
2630 
2631   return offset;
2632 }
2633 
2634 
2635 static const ber_sequence_t UsmSecurityParameters_sequence[] = {
2636   { &hf_snmp_msgAuthoritativeEngineID, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_snmp_T_msgAuthoritativeEngineID },
2637   { &hf_snmp_msgAuthoritativeEngineBoots, BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_T_msgAuthoritativeEngineBoots },
2638   { &hf_snmp_msgAuthoritativeEngineTime, BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_T_msgAuthoritativeEngineTime },
2639   { &hf_snmp_msgUserName    , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_snmp_T_msgUserName },
2640   { &hf_snmp_msgAuthenticationParameters, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_snmp_T_msgAuthenticationParameters },
2641   { &hf_snmp_msgPrivacyParameters, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_snmp_T_msgPrivacyParameters },
2642   { NULL, 0, 0, 0, NULL }
2643 };
2644 
2645 static int
dissect_snmp_UsmSecurityParameters(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2646 dissect_snmp_UsmSecurityParameters(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2647   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2648                                    UsmSecurityParameters_sequence, hf_index, ett_snmp_UsmSecurityParameters);
2649 
2650   return offset;
2651 }
2652 
2653 
2654 
2655 static int
dissect_snmp_INTEGER_484_2147483647(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2656 dissect_snmp_INTEGER_484_2147483647(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2657   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2658                                                 NULL);
2659 
2660   return offset;
2661 }
2662 
2663 
2664 
2665 static int
dissect_snmp_T_msgFlags(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2666 dissect_snmp_T_msgFlags(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2667 #line 238 "./asn1/snmp/snmp.cnf"
2668 	tvbuff_t *parameter_tvb = NULL;
2669 
2670    offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
2671                                        &parameter_tvb);
2672 
2673 	if (parameter_tvb){
2674 		guint8 v3_flags = tvb_get_guint8(parameter_tvb, 0);
2675 		proto_tree* flags_tree = proto_item_add_subtree(actx->created_item,ett_msgFlags);
2676 
2677 		proto_tree_add_item(flags_tree, hf_snmp_v3_flags_report, parameter_tvb, 0, 1, ENC_BIG_ENDIAN);
2678 		proto_tree_add_item(flags_tree, hf_snmp_v3_flags_crypt, parameter_tvb, 0, 1, ENC_BIG_ENDIAN);
2679 		proto_tree_add_item(flags_tree, hf_snmp_v3_flags_auth, parameter_tvb, 0, 1, ENC_BIG_ENDIAN);
2680 
2681 		usm_p.encrypted = v3_flags & TH_CRYPT ? TRUE : FALSE;
2682 		usm_p.authenticated = v3_flags & TH_AUTH ? TRUE : FALSE;
2683 	}
2684 
2685 
2686 
2687 
2688   return offset;
2689 }
2690 
2691 
2692 
2693 static int
dissect_snmp_T_msgSecurityModel(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2694 dissect_snmp_T_msgSecurityModel(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2695   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2696                                                 &MsgSecurityModel);
2697 
2698   return offset;
2699 }
2700 
2701 
2702 static const ber_sequence_t HeaderData_sequence[] = {
2703   { &hf_snmp_msgID          , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_INTEGER_0_2147483647 },
2704   { &hf_snmp_msgMaxSize     , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_INTEGER_484_2147483647 },
2705   { &hf_snmp_msgFlags       , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_snmp_T_msgFlags },
2706   { &hf_snmp_msgSecurityModel, BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_T_msgSecurityModel },
2707   { NULL, 0, 0, 0, NULL }
2708 };
2709 
2710 static int
dissect_snmp_HeaderData(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2711 dissect_snmp_HeaderData(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2712   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2713                                    HeaderData_sequence, hf_index, ett_snmp_HeaderData);
2714 
2715   return offset;
2716 }
2717 
2718 
2719 
2720 static int
dissect_snmp_T_msgSecurityParameters(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2721 dissect_snmp_T_msgSecurityParameters(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2722 #line 185 "./asn1/snmp/snmp.cnf"
2723 
2724 	switch(MsgSecurityModel){
2725 		case SNMP_SEC_USM:	/* 3 */
2726 			offset = get_ber_identifier(tvb, offset, NULL, NULL, NULL);
2727 			offset = get_ber_length(tvb, offset, NULL, NULL);
2728 			offset = dissect_snmp_UsmSecurityParameters(FALSE, tvb, offset, actx, tree, -1);
2729 			usm_p.user_assoc = get_user_assoc(usm_p.engine_tvb, usm_p.user_tvb, actx->pinfo);
2730 			break;
2731 		case SNMP_SEC_ANY:	/* 0 */
2732 		case SNMP_SEC_V1:	/* 1 */
2733 		case SNMP_SEC_V2C:	/* 2 */
2734 		default:
2735 			  offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
2736                                        NULL);
2737 
2738 			break;
2739 	}
2740 
2741 
2742 
2743   return offset;
2744 }
2745 
2746 
2747 static const ber_sequence_t ScopedPDU_sequence[] = {
2748   { &hf_snmp_contextEngineID, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_snmp_SnmpEngineID },
2749   { &hf_snmp_contextName    , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_snmp_OCTET_STRING },
2750   { &hf_snmp_data           , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_snmp_PDUs },
2751   { NULL, 0, 0, 0, NULL }
2752 };
2753 
2754 static int
dissect_snmp_ScopedPDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2755 dissect_snmp_ScopedPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2756   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2757                                    ScopedPDU_sequence, hf_index, ett_snmp_ScopedPDU);
2758 
2759   return offset;
2760 }
2761 
2762 
2763 
2764 static int
dissect_snmp_T_encryptedPDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2765 dissect_snmp_T_encryptedPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2766 #line 143 "./asn1/snmp/snmp.cnf"
2767 	tvbuff_t* crypt_tvb;
2768 	offset = dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_snmp_encryptedPDU, &crypt_tvb);
2769 
2770 	if( usm_p.encrypted && crypt_tvb
2771 		&& usm_p.user_assoc
2772 		&& usm_p.user_assoc->user.privProtocol ) {
2773 
2774 		const gchar* error = NULL;
2775 		proto_tree* encryptedpdu_tree = proto_item_add_subtree(actx->created_item,ett_encryptedPDU);
2776 		tvbuff_t* cleartext_tvb = usm_p.user_assoc->user.privProtocol(&usm_p, crypt_tvb, actx->pinfo, &error );
2777 
2778 		if (! cleartext_tvb) {
2779 			proto_tree_add_expert_format(encryptedpdu_tree, actx->pinfo, &ei_snmp_failed_decrypted_data_pdu,
2780 				crypt_tvb, 0, -1, "Failed to decrypt encryptedPDU: %s", error);
2781 
2782 			col_set_str(actx->pinfo->cinfo, COL_INFO, "encryptedPDU: Failed to decrypt");
2783 
2784 			return offset;
2785 		} else {
2786 			proto_item* decrypted_item;
2787 			proto_tree* decrypted_tree;
2788 
2789 			if (! check_ScopedPdu(cleartext_tvb)) {
2790 				proto_tree_add_expert(encryptedpdu_tree, actx->pinfo, &ei_snmp_decrypted_data_bad_formatted, cleartext_tvb, 0, -1);
2791 
2792 				col_set_str(actx->pinfo->cinfo, COL_INFO, "encryptedPDU: Decrypted data not formatted as expected");
2793 
2794 				return offset;
2795 			}
2796 
2797 
2798 			add_new_data_source(actx->pinfo, cleartext_tvb, "Decrypted ScopedPDU");
2799 
2800 			decrypted_item = proto_tree_add_item(encryptedpdu_tree, hf_snmp_decryptedPDU,cleartext_tvb,0,-1,ENC_NA);
2801 			decrypted_tree = proto_item_add_subtree(decrypted_item,ett_decrypted);
2802 			dissect_snmp_ScopedPDU(FALSE, cleartext_tvb, 0, actx, decrypted_tree, -1);
2803 			}
2804 	} else {
2805 			col_set_str(actx->pinfo->cinfo, COL_INFO, "encryptedPDU: privKey Unknown");
2806 	}
2807 
2808 
2809 
2810   return offset;
2811 }
2812 
2813 
2814 static const value_string snmp_ScopedPduData_vals[] = {
2815   {   0, "plaintext" },
2816   {   1, "encryptedPDU" },
2817   { 0, NULL }
2818 };
2819 
2820 static const ber_choice_t ScopedPduData_choice[] = {
2821   {   0, &hf_snmp_plaintext      , BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_snmp_ScopedPDU },
2822   {   1, &hf_snmp_encryptedPDU   , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_snmp_T_encryptedPDU },
2823   { 0, NULL, 0, 0, 0, NULL }
2824 };
2825 
2826 static int
dissect_snmp_ScopedPduData(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2827 dissect_snmp_ScopedPduData(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2828   offset = dissect_ber_choice(actx, tree, tvb, offset,
2829                                  ScopedPduData_choice, hf_index, ett_snmp_ScopedPduData,
2830                                  NULL);
2831 
2832   return offset;
2833 }
2834 
2835 
2836 static const ber_sequence_t SNMPv3Message_sequence[] = {
2837   { &hf_snmp_msgVersion     , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_Version },
2838   { &hf_snmp_msgGlobalData  , BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_snmp_HeaderData },
2839   { &hf_snmp_msgSecurityParameters, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_snmp_T_msgSecurityParameters },
2840   { &hf_snmp_msgData        , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_snmp_ScopedPduData },
2841   { NULL, 0, 0, 0, NULL }
2842 };
2843 
2844 static int
dissect_snmp_SNMPv3Message(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2845 dissect_snmp_SNMPv3Message(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2846   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2847                                    SNMPv3Message_sequence, hf_index, ett_snmp_SNMPv3Message);
2848 
2849 #line 202 "./asn1/snmp/snmp.cnf"
2850 
2851 	if( usm_p.authenticated
2852 		&& usm_p.user_assoc ) {
2853 		const gchar* error = NULL;
2854 		proto_item* authen_item;
2855 		proto_tree* authen_tree = proto_item_add_subtree(usm_p.auth_item,ett_authParameters);
2856 		guint8* calc_auth = NULL;
2857 		guint calc_auth_len = 0;
2858 
2859 		usm_p.authOK = snmp_usm_auth(actx->pinfo, usm_p.user_assoc->user.authModel, &usm_p, &calc_auth, &calc_auth_len, &error );
2860 
2861 		if (error) {
2862 			expert_add_info_format( actx->pinfo, usm_p.auth_item, &ei_snmp_verify_authentication_error, "Error while verifying Message authenticity: %s", error );
2863 		} else {
2864 			expert_field* expert;
2865 
2866 			authen_item = proto_tree_add_boolean(authen_tree, hf_snmp_msgAuthentication, tvb, 0, 0, usm_p.authOK);
2867 			proto_item_set_generated(authen_item);
2868 
2869 			if (usm_p.authOK) {
2870 				expert = &ei_snmp_authentication_ok;
2871 			} else {
2872 				const gchar* calc_auth_str = bytes_to_str_punct(actx->pinfo->pool, calc_auth,calc_auth_len,' ');
2873 				proto_item_append_text(authen_item, " calculated = %s", calc_auth_str);
2874 				expert = &ei_snmp_authentication_error;
2875 			}
2876 
2877 			expert_add_info( actx->pinfo, authen_item, expert);
2878 		}
2879 	}
2880 
2881 
2882   return offset;
2883 }
2884 
2885 
2886 static const value_string snmp_T_smux_version_vals[] = {
2887   {   0, "version-1" },
2888   { 0, NULL }
2889 };
2890 
2891 
2892 static int
dissect_snmp_T_smux_version(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2893 dissect_snmp_T_smux_version(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2894   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2895                                                 NULL);
2896 
2897   return offset;
2898 }
2899 
2900 
2901 
2902 static int
dissect_snmp_OBJECT_IDENTIFIER(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2903 dissect_snmp_OBJECT_IDENTIFIER(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2904   offset = dissect_ber_object_identifier(implicit_tag, actx, tree, tvb, offset, hf_index, NULL);
2905 
2906   return offset;
2907 }
2908 
2909 
2910 
2911 static int
dissect_snmp_DisplayString(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2912 dissect_snmp_DisplayString(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2913   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
2914                                        NULL);
2915 
2916   return offset;
2917 }
2918 
2919 
2920 static const ber_sequence_t SimpleOpen_U_sequence[] = {
2921   { &hf_snmp_smux_version   , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_T_smux_version },
2922   { &hf_snmp_identity       , BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_NOOWNTAG, dissect_snmp_OBJECT_IDENTIFIER },
2923   { &hf_snmp_description    , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_snmp_DisplayString },
2924   { &hf_snmp_password       , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_snmp_OCTET_STRING },
2925   { NULL, 0, 0, 0, NULL }
2926 };
2927 
2928 static int
dissect_snmp_SimpleOpen_U(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2929 dissect_snmp_SimpleOpen_U(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2930   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2931                                    SimpleOpen_U_sequence, hf_index, ett_snmp_SimpleOpen_U);
2932 
2933   return offset;
2934 }
2935 
2936 
2937 
2938 static int
dissect_snmp_SimpleOpen(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2939 dissect_snmp_SimpleOpen(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2940   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
2941                                       hf_index, BER_CLASS_APP, 0, TRUE, dissect_snmp_SimpleOpen_U);
2942 
2943   return offset;
2944 }
2945 
2946 
2947 static const value_string snmp_OpenPDU_vals[] = {
2948   {   0, "smux-simple" },
2949   { 0, NULL }
2950 };
2951 
2952 static const ber_choice_t OpenPDU_choice[] = {
2953   {   0, &hf_snmp_smux_simple    , BER_CLASS_APP, 0, BER_FLAGS_NOOWNTAG, dissect_snmp_SimpleOpen },
2954   { 0, NULL, 0, 0, 0, NULL }
2955 };
2956 
2957 static int
dissect_snmp_OpenPDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2958 dissect_snmp_OpenPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2959   offset = dissect_ber_choice(actx, tree, tvb, offset,
2960                                  OpenPDU_choice, hf_index, ett_snmp_OpenPDU,
2961                                  NULL);
2962 
2963   return offset;
2964 }
2965 
2966 
2967 static const value_string snmp_ClosePDU_U_vals[] = {
2968   {   0, "goingDown" },
2969   {   1, "unsupportedVersion" },
2970   {   2, "packetFormat" },
2971   {   3, "protocolError" },
2972   {   4, "internalError" },
2973   {   5, "authenticationFailure" },
2974   { 0, NULL }
2975 };
2976 
2977 
2978 static int
dissect_snmp_ClosePDU_U(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2979 dissect_snmp_ClosePDU_U(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2980   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2981                                                 NULL);
2982 
2983   return offset;
2984 }
2985 
2986 
2987 
2988 static int
dissect_snmp_ClosePDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2989 dissect_snmp_ClosePDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2990   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
2991                                       hf_index, BER_CLASS_APP, 1, TRUE, dissect_snmp_ClosePDU_U);
2992 
2993   return offset;
2994 }
2995 
2996 
2997 
2998 static int
dissect_snmp_INTEGER_M1_2147483647(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2999 dissect_snmp_INTEGER_M1_2147483647(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
3000   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
3001                                                 NULL);
3002 
3003   return offset;
3004 }
3005 
3006 
3007 static const value_string snmp_T_operation_vals[] = {
3008   {   0, "delete" },
3009   {   1, "readOnly" },
3010   {   2, "readWrite" },
3011   { 0, NULL }
3012 };
3013 
3014 
3015 static int
dissect_snmp_T_operation(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)3016 dissect_snmp_T_operation(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
3017   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
3018                                                 NULL);
3019 
3020   return offset;
3021 }
3022 
3023 
3024 static const ber_sequence_t RReqPDU_U_sequence[] = {
3025   { &hf_snmp_subtree        , BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_NOOWNTAG, dissect_snmp_ObjectName },
3026   { &hf_snmp_priority       , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_INTEGER_M1_2147483647 },
3027   { &hf_snmp_operation      , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_snmp_T_operation },
3028   { NULL, 0, 0, 0, NULL }
3029 };
3030 
3031 static int
dissect_snmp_RReqPDU_U(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)3032 dissect_snmp_RReqPDU_U(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
3033   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
3034                                    RReqPDU_U_sequence, hf_index, ett_snmp_RReqPDU_U);
3035 
3036   return offset;
3037 }
3038 
3039 
3040 
3041 static int
dissect_snmp_RReqPDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)3042 dissect_snmp_RReqPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
3043   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
3044                                       hf_index, BER_CLASS_APP, 2, TRUE, dissect_snmp_RReqPDU_U);
3045 
3046   return offset;
3047 }
3048 
3049 
3050 static const value_string snmp_RRspPDU_U_vals[] = {
3051   {  -1, "failure" },
3052   { 0, NULL }
3053 };
3054 
3055 
3056 static int
dissect_snmp_RRspPDU_U(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)3057 dissect_snmp_RRspPDU_U(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
3058   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
3059                                                 NULL);
3060 
3061   return offset;
3062 }
3063 
3064 
3065 
3066 static int
dissect_snmp_RRspPDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)3067 dissect_snmp_RRspPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
3068   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
3069                                       hf_index, BER_CLASS_APP, 3, TRUE, dissect_snmp_RRspPDU_U);
3070 
3071   return offset;
3072 }
3073 
3074 
3075 static const value_string snmp_RegisterResponse_vals[] = {
3076   {   0, "rRspPDU" },
3077   {   1, "pDUs" },
3078   { 0, NULL }
3079 };
3080 
3081 static const ber_choice_t RegisterResponse_choice[] = {
3082   {   0, &hf_snmp_rRspPDU        , BER_CLASS_APP, 3, BER_FLAGS_NOOWNTAG, dissect_snmp_RRspPDU },
3083   {   1, &hf_snmp_pDUs           , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG, dissect_snmp_PDUs },
3084   { 0, NULL, 0, 0, 0, NULL }
3085 };
3086 
3087 static int
dissect_snmp_RegisterResponse(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)3088 dissect_snmp_RegisterResponse(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
3089   offset = dissect_ber_choice(actx, tree, tvb, offset,
3090                                  RegisterResponse_choice, hf_index, ett_snmp_RegisterResponse,
3091                                  NULL);
3092 
3093   return offset;
3094 }
3095 
3096 
3097 static const value_string snmp_SOutPDU_U_vals[] = {
3098   {   0, "commit" },
3099   {   1, "rollback" },
3100   { 0, NULL }
3101 };
3102 
3103 
3104 static int
dissect_snmp_SOutPDU_U(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)3105 dissect_snmp_SOutPDU_U(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
3106   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
3107                                                 NULL);
3108 
3109   return offset;
3110 }
3111 
3112 
3113 
3114 static int
dissect_snmp_SOutPDU(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)3115 dissect_snmp_SOutPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
3116   offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
3117                                       hf_index, BER_CLASS_APP, 4, TRUE, dissect_snmp_SOutPDU_U);
3118 
3119   return offset;
3120 }
3121 
3122 
3123 static const value_string snmp_SMUX_PDUs_vals[] = {
3124   {   0, "open" },
3125   {   1, "close" },
3126   {   2, "registerRequest" },
3127   {   3, "registerResponse" },
3128   {   4, "commitOrRollback" },
3129   { 0, NULL }
3130 };
3131 
3132 static const ber_choice_t SMUX_PDUs_choice[] = {
3133   {   0, &hf_snmp_open           , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG, dissect_snmp_OpenPDU },
3134   {   1, &hf_snmp_close          , BER_CLASS_APP, 1, BER_FLAGS_NOOWNTAG, dissect_snmp_ClosePDU },
3135   {   2, &hf_snmp_registerRequest, BER_CLASS_APP, 2, BER_FLAGS_NOOWNTAG, dissect_snmp_RReqPDU },
3136   {   3, &hf_snmp_registerResponse, BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG, dissect_snmp_RegisterResponse },
3137   {   4, &hf_snmp_commitOrRollback, BER_CLASS_APP, 4, BER_FLAGS_NOOWNTAG, dissect_snmp_SOutPDU },
3138   { 0, NULL, 0, 0, 0, NULL }
3139 };
3140 
3141 static int
dissect_snmp_SMUX_PDUs(gboolean implicit_tag _U_,tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)3142 dissect_snmp_SMUX_PDUs(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
3143   offset = dissect_ber_choice(actx, tree, tvb, offset,
3144                                  SMUX_PDUs_choice, hf_index, ett_snmp_SMUX_PDUs,
3145                                  NULL);
3146 
3147   return offset;
3148 }
3149 
3150 /*--- PDUs ---*/
3151 
dissect_SMUX_PDUs_PDU(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,void * data _U_)3152 static int dissect_SMUX_PDUs_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_) {
3153   int offset = 0;
3154   asn1_ctx_t asn1_ctx;
3155   asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
3156   offset = dissect_snmp_SMUX_PDUs(FALSE, tvb, offset, &asn1_ctx, tree, hf_snmp_SMUX_PDUs_PDU);
3157   return offset;
3158 }
3159 
3160 
3161 /*--- End of included file: packet-snmp-fn.c ---*/
3162 #line 1923 "./asn1/snmp/packet-snmp-template.c"
3163 
3164 static snmp_conv_info_t*
snmp_find_conversation_and_get_conv_data(packet_info * pinfo)3165 snmp_find_conversation_and_get_conv_data(packet_info *pinfo) {
3166 
3167 	conversation_t *conversation;
3168 	snmp_conv_info_t *snmp_info = NULL;
3169 
3170 	conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, conversation_pt_to_endpoint_type(pinfo->ptype),
3171 		pinfo->srcport, pinfo->destport, 0);
3172 
3173 	if( (conversation == NULL) || (conversation_get_dissector(conversation, pinfo->num)!=snmp_handle) ) {
3174 		conversation = conversation_new(pinfo->num, &pinfo->src, &pinfo->dst, conversation_pt_to_endpoint_type(pinfo->ptype),
3175 			pinfo->srcport, pinfo->destport, 0);
3176 		conversation_set_dissector(conversation, snmp_handle);
3177 	}
3178 
3179 	snmp_info = (snmp_conv_info_t *)conversation_get_proto_data(conversation, proto_snmp);
3180 	if (snmp_info == NULL) {
3181 		snmp_info = wmem_new0(wmem_file_scope(), snmp_conv_info_t);
3182 		snmp_info->request_response=wmem_map_new(wmem_file_scope(), g_int_hash, g_int_equal);
3183 
3184 		conversation_add_proto_data(conversation, proto_snmp, snmp_info);
3185 	}
3186 	return snmp_info;
3187 }
3188 
3189 guint
dissect_snmp_pdu(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,int proto,gint ett,gboolean is_tcp)3190 dissect_snmp_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo,
3191 		 proto_tree *tree, int proto, gint ett, gboolean is_tcp)
3192 {
3193 
3194 	guint length_remaining;
3195 	gint8 ber_class;
3196 	gboolean pc, ind = 0;
3197 	gint32 tag;
3198 	guint32 len;
3199 	guint message_length;
3200 	int start_offset = offset;
3201 	guint32 version = 0;
3202 	tvbuff_t	*next_tvb;
3203 
3204 	proto_tree *snmp_tree = NULL;
3205 	proto_item *item = NULL;
3206 
3207 	snmp_conv_info_t *snmp_info = snmp_find_conversation_and_get_conv_data(pinfo);
3208 
3209 	asn1_ctx_t asn1_ctx;
3210 	asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
3211 
3212 	asn1_ctx.private_data = snmp_info;
3213 
3214 	usm_p.msg_tvb = tvb;
3215 	usm_p.start_offset = tvb_offset_from_real_beginning(tvb);
3216 	usm_p.engine_tvb = NULL;
3217 	usm_p.user_tvb = NULL;
3218 	usm_p.auth_item = NULL;
3219 	usm_p.auth_tvb = NULL;
3220 	usm_p.auth_offset = 0;
3221 	usm_p.priv_tvb = NULL;
3222 	usm_p.user_assoc = NULL;
3223 	usm_p.authenticated = FALSE;
3224 	usm_p.encrypted = FALSE;
3225 	usm_p.boots = 0;
3226 	usm_p.snmp_time = 0;
3227 	usm_p.authOK = FALSE;
3228 
3229 	/*
3230 	 * This will throw an exception if we don't have any data left.
3231 	 * That's what we want.  (See "tcp_dissect_pdus()", which is
3232 	 * similar, but doesn't have to deal with ASN.1.
3233 	 * XXX - can we make "tcp_dissect_pdus()" provide enough
3234 	 * information to the "get_pdu_len" routine so that we could
3235 	 * have that routine deal with ASN.1, and just use
3236 	 * "tcp_dissect_pdus()"?)
3237 	 */
3238 	length_remaining = tvb_ensure_captured_length_remaining(tvb, offset);
3239 
3240 	/* NOTE: we have to parse the message piece by piece, since the
3241 	 * capture length may be less than the message length: a 'global'
3242 	 * parsing is likely to fail.
3243 	 */
3244 
3245 	/*
3246 	 * If this is SNMP-over-TCP, we might have to do reassembly
3247 	 * in order to read the "Sequence Of" header.
3248 	 */
3249 	if (is_tcp && snmp_desegment && pinfo->can_desegment) {
3250 		/*
3251 		 * This is TCP, and we should, and can, do reassembly.
3252 		 *
3253 		 * Is the "Sequence Of" header split across segment
3254 		 * boundaries?  We require at least 6 bytes for the
3255 		 * header, which allows for a 4-byte length (ASN.1
3256 		 * BER).
3257 		 */
3258 		if (length_remaining < 6) {
3259 			/*
3260 			 * Yes.  Tell the TCP dissector where the data
3261 			 * for this message starts in the data it handed
3262 			 * us and that we need "some more data."  Don't tell
3263 			 * it exactly how many bytes we need because if/when
3264 			 * we ask for even more (after the header) that will
3265 			 * break reassembly.
3266 			 */
3267 			pinfo->desegment_offset = offset;
3268 			pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
3269 			return -1;
3270 		}
3271 	}
3272 
3273 	/*
3274 	 * OK, try to read the "Sequence Of" header; this gets the total
3275 	 * length of the SNMP message.
3276 	 */
3277 	offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
3278 	/*Get the total octet length of the SNMP data*/
3279 	offset = get_ber_length(tvb, offset, &len, &ind);
3280 	message_length = len + offset;
3281 
3282 	/*Get the SNMP version data*/
3283 	/*offset =*/ dissect_ber_integer(FALSE, &asn1_ctx, 0, tvb, offset, -1, &version);
3284 
3285 
3286 	/*
3287 	 * If this is SNMP-over-TCP, we might have to do reassembly
3288 	 * to get all of this message.
3289 	 */
3290 	if (is_tcp && snmp_desegment && pinfo->can_desegment) {
3291 		/*
3292 		 * Yes - is the message split across segment boundaries?
3293 		 */
3294 		if (length_remaining < message_length) {
3295 			/*
3296 			 * Yes.  Tell the TCP dissector where the data
3297 			 * for this message starts in the data it handed
3298 			 * us, and how many more bytes we need, and
3299 			 * return.
3300 			 */
3301 			pinfo->desegment_offset = start_offset;
3302 			pinfo->desegment_len =
3303 			message_length - length_remaining;
3304 
3305 			/*
3306 			 * Return 0, which means "I didn't dissect anything
3307 			 * because I don't have enough data - we need
3308 			 * to desegment".
3309 			 */
3310 			return 0;
3311 		}
3312 	}
3313 
3314 	var_list = next_tvb_list_new(pinfo->pool);
3315 
3316 	col_set_str(pinfo->cinfo, COL_PROTOCOL, proto_get_protocol_short_name(find_protocol_by_id(proto)));
3317 
3318 	item = proto_tree_add_item(tree, proto, tvb, start_offset, message_length, ENC_BIG_ENDIAN);
3319 	snmp_tree = proto_item_add_subtree(item, ett);
3320 
3321 	switch (version) {
3322 	case 0: /* v1 */
3323 	case 1: /* v2c */
3324 		offset = dissect_snmp_Message(FALSE , tvb, start_offset, &asn1_ctx, snmp_tree, -1);
3325 		break;
3326 	case 2: /* v2u */
3327 		offset = dissect_snmp_Messagev2u(FALSE , tvb, start_offset, &asn1_ctx, snmp_tree, -1);
3328 		break;
3329 			/* v3 */
3330 	case 3:
3331 		offset = dissect_snmp_SNMPv3Message(FALSE , tvb, start_offset, &asn1_ctx, snmp_tree, -1);
3332 		break;
3333 	default:
3334 		/*
3335 		 * Return the length remaining in the tvbuff, so
3336 		 * if this is SNMP-over-TCP, our caller thinks there's
3337 		 * nothing left to dissect.
3338 		 */
3339 		expert_add_info(pinfo, item, &ei_snmp_version_unknown);
3340 		return length_remaining;
3341 		break;
3342 	}
3343 
3344 	/* There may be appended data after the SNMP data, so treat as raw
3345 	 * data which needs to be dissected in case of UDP as UDP is PDU oriented.
3346  	 */
3347 	if((!is_tcp) && (length_remaining > (guint)offset)) {
3348 		next_tvb = tvb_new_subset_remaining(tvb, offset);
3349 		call_dissector(data_handle, next_tvb, pinfo, tree);
3350 	} else {
3351 		next_tvb_call(var_list, pinfo, tree, NULL, data_handle);
3352 	}
3353 
3354 	return offset;
3355 }
3356 
3357 static gint
dissect_snmp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3358 dissect_snmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
3359 {
3360 	int offset;
3361 	gint8 tmp_class;
3362 	gboolean tmp_pc;
3363 	gint32 tmp_tag;
3364 	guint32 tmp_length;
3365 	gboolean tmp_ind;
3366 
3367 	/*
3368 	 * See if this looks like SNMP or not. if not, return 0 so
3369 	 * wireshark can try some other dissector instead.
3370 	 */
3371 	/* All SNMP packets are BER encoded and consist of a SEQUENCE
3372 	 * that spans the entire PDU. The first item is an INTEGER that
3373 	 * has the values 0-2 (version 1-3).
3374 	 * if not it is not snmp.
3375 	 */
3376 	/* SNMP starts with a SEQUENCE */
3377 	offset = get_ber_identifier(tvb, 0, &tmp_class, &tmp_pc, &tmp_tag);
3378 	if((tmp_class!=BER_CLASS_UNI)||(tmp_tag!=BER_UNI_TAG_SEQUENCE)) {
3379 		return 0;
3380 	}
3381 	/* then comes a length which spans the rest of the tvb */
3382 	offset = get_ber_length(tvb, offset, &tmp_length, &tmp_ind);
3383 	/* if(tmp_length!=(guint32)tvb_reported_length_remaining(tvb, offset)) {
3384 	 * Loosen the heuristic a bit to handle the case where data has intentionally
3385 	 * been added after the snmp PDU ( UDP case)
3386 	 */
3387 	if ( pinfo->ptype == PT_UDP ) {
3388 		if(tmp_length>(guint32)tvb_reported_length_remaining(tvb, offset)) {
3389 			return 0;
3390 		}
3391 	}else{
3392 		if(tmp_length!=(guint32)tvb_reported_length_remaining(tvb, offset)) {
3393 			return 0;
3394 		}
3395 	}
3396 	/* then comes an INTEGER (version)*/
3397 	get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
3398 	if((tmp_class!=BER_CLASS_UNI)||(tmp_tag!=BER_UNI_TAG_INTEGER)) {
3399 		return 0;
3400 	}
3401 	/* do we need to test that version is 0 - 2 (version1-3) ? */
3402 
3403 
3404 	/*
3405 	 * The first SNMP packet goes to the SNMP port; the second one
3406 	 * may come from some *other* port, but goes back to the same
3407 	 * IP address and port as the ones from which the first packet
3408 	 * came; all subsequent packets presumably go between those two
3409 	 * IP addresses and ports.
3410 	 *
3411 	 * If this packet went to the SNMP port, we check to see if
3412 	 * there's already a conversation with one address/port pair
3413 	 * matching the source IP address and port of this packet,
3414 	 * the other address matching the destination IP address of this
3415 	 * packet, and any destination port.
3416 	 *
3417 	 * If not, we create one, with its address 1/port 1 pair being
3418 	 * the source address/port of this packet, its address 2 being
3419 	 * the destination address of this packet, and its port 2 being
3420 	 * wildcarded, and give it the SNMP dissector as a dissector.
3421 	 */
3422 
3423 	return dissect_snmp_pdu(tvb, 0, pinfo, tree, proto_snmp, ett_snmp, FALSE);
3424 }
3425 
3426 static int
dissect_snmp_tcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3427 dissect_snmp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3428 {
3429 	int offset = 0;
3430 	guint message_len;
3431 
3432 	while (tvb_reported_length_remaining(tvb, offset) > 0) {
3433 		message_len = dissect_snmp_pdu(tvb, 0, pinfo, tree, proto_snmp, ett_snmp, TRUE);
3434 		if (message_len == 0) {
3435 			/*
3436 			 * We don't have all the data for that message,
3437 			 * so we need to do desegmentation;
3438 			 * "dissect_snmp_pdu()" has set that up.
3439 			 */
3440 			break;
3441 		}
3442 		offset += message_len;
3443 	}
3444 	return tvb_captured_length(tvb);
3445 }
3446 
3447 static int
dissect_smux(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3448 dissect_smux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3449 {
3450 	proto_tree *smux_tree = NULL;
3451 	proto_item *item = NULL;
3452 
3453 	var_list = next_tvb_list_new(pinfo->pool);
3454 
3455 	col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMUX");
3456 
3457 	item = proto_tree_add_item(tree, proto_smux, tvb, 0, -1, ENC_NA);
3458 	smux_tree = proto_item_add_subtree(item, ett_smux);
3459 
3460 	return dissect_SMUX_PDUs_PDU(tvb, pinfo, smux_tree, data);
3461 }
3462 
3463 /*
3464   MD5 Password to Key Algorithm from RFC 3414 A.2.1
3465   SHA1 Password to Key Algorithm from RFC 3414 A.2.2
3466   SHA2 Password to Key Algorithm from RFC 7860 9.3
3467 */
3468 static void
snmp_usm_password_to_key(const snmp_usm_auth_model_t model,const guint8 * password,guint passwordlen,const guint8 * engineID,guint engineLength,guint8 * key)3469 snmp_usm_password_to_key(const snmp_usm_auth_model_t model, const guint8 *password,
3470 	guint passwordlen, const guint8 *engineID, guint engineLength, guint8 *key)
3471 {
3472 	gcry_md_hd_t	hash_handle;
3473 	guint8	  *cp, password_buf[64];
3474 	guint32	 password_index = 0;
3475 	guint32	 count = 0, i;
3476 	guint	   hash_len;
3477 
3478 	if (gcry_md_open(&hash_handle, auth_hash_algo[model], 0)) {
3479 		return;
3480 	}
3481 
3482 	hash_len = auth_hash_len[model];
3483 
3484 	/**********************************************/
3485 	/* Use while loop until we've done 1 Megabyte */
3486 	/**********************************************/
3487 	while (count < 1048576) {
3488 		cp = password_buf;
3489 		if (passwordlen != 0) {
3490 			for (i = 0; i < 64; i++) {
3491 				/*************************************************/
3492 				/* Take the next octet of the password, wrapping */
3493 				/* to the beginning of the password as necessary.*/
3494 				/*************************************************/
3495 				*cp++ = password[password_index++ % passwordlen];
3496 			}
3497 		} else {
3498 			*cp = 0;
3499 		}
3500 		gcry_md_write(hash_handle, password_buf, 64);
3501 		count += 64;
3502 	}
3503 	memcpy(key, gcry_md_read(hash_handle, 0), hash_len);
3504 	gcry_md_close(hash_handle);
3505 
3506 	/*****************************************************/
3507 	/* Now localise the key with the engineID and pass   */
3508 	/* through hash function to produce final key        */
3509 	/* We ignore invalid engineLengths here. More strict */
3510 	/* checking is done in snmp_users_update_cb.         */
3511 	/*****************************************************/
3512 	if (gcry_md_open(&hash_handle, auth_hash_algo[model], 0)) {
3513 		return;
3514 	}
3515 	gcry_md_write(hash_handle, key, hash_len);
3516 	gcry_md_write(hash_handle, engineID, engineLength);
3517 	gcry_md_write(hash_handle, key, hash_len);
3518 	memcpy(key, gcry_md_read(hash_handle, 0), hash_len);
3519 	gcry_md_close(hash_handle);
3520 	return;
3521 }
3522 
3523 static void
process_prefs(void)3524 process_prefs(void)
3525 {
3526 }
3527 
3528 UAT_LSTRING_CB_DEF(snmp_users,userName,snmp_ue_assoc_t,user.userName.data,user.userName.len)
3529 UAT_LSTRING_CB_DEF(snmp_users,authPassword,snmp_ue_assoc_t,user.authPassword.data,user.authPassword.len)
3530 UAT_LSTRING_CB_DEF(snmp_users,privPassword,snmp_ue_assoc_t,user.privPassword.data,user.privPassword.len)
3531 UAT_BUFFER_CB_DEF(snmp_users,engine_id,snmp_ue_assoc_t,engine.data,engine.len)
3532 UAT_VS_DEF(snmp_users,auth_model,snmp_ue_assoc_t,guint,0,"MD5")
3533 UAT_VS_DEF(snmp_users,priv_proto,snmp_ue_assoc_t,guint,0,"DES")
3534 
3535 static void *
snmp_specific_trap_copy_cb(void * dest,const void * orig,size_t len _U_)3536 snmp_specific_trap_copy_cb(void *dest, const void *orig, size_t len _U_)
3537 {
3538 	snmp_st_assoc_t *u = (snmp_st_assoc_t *)dest;
3539 	const snmp_st_assoc_t *o = (const snmp_st_assoc_t *)orig;
3540 
3541 	u->enterprise = g_strdup(o->enterprise);
3542 	u->trap = o->trap;
3543 	u->desc = g_strdup(o->desc);
3544 
3545 	return dest;
3546 }
3547 
3548 static void
snmp_specific_trap_free_cb(void * r)3549 snmp_specific_trap_free_cb(void *r)
3550 {
3551 	snmp_st_assoc_t *u = (snmp_st_assoc_t *)r;
3552 
3553 	g_free(u->enterprise);
3554 	g_free(u->desc);
3555 }
3556 
UAT_CSTRING_CB_DEF(specific_traps,enterprise,snmp_st_assoc_t)3557 UAT_CSTRING_CB_DEF(specific_traps, enterprise, snmp_st_assoc_t)
3558 UAT_DEC_CB_DEF(specific_traps, trap, snmp_st_assoc_t)
3559 UAT_CSTRING_CB_DEF(specific_traps, desc, snmp_st_assoc_t)
3560 
3561 	/*--- proto_register_snmp -------------------------------------------*/
3562 void proto_register_snmp(void) {
3563 	/* List of fields */
3564 	static hf_register_info hf[] = {
3565 		{ &hf_snmp_response_in,
3566 		{ "Response In", "snmp.response_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3567 			"The response to this SNMP request is in this frame", HFILL }},
3568 		{ &hf_snmp_response_to,
3569 		{ "Response To", "snmp.response_to", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3570 			"This is a response to the SNMP request in this frame", HFILL }},
3571 		{ &hf_snmp_time,
3572 		{ "Time", "snmp.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3573 			"The time between the Request and the Response", HFILL }},
3574 		{ &hf_snmp_v3_flags_auth,
3575 		{ "Authenticated", "snmp.v3.flags.auth", FT_BOOLEAN, 8,
3576 		    TFS(&tfs_set_notset), TH_AUTH, NULL, HFILL }},
3577 		{ &hf_snmp_v3_flags_crypt,
3578 		{ "Encrypted", "snmp.v3.flags.crypt", FT_BOOLEAN, 8,
3579 		    TFS(&tfs_set_notset), TH_CRYPT, NULL, HFILL }},
3580 		{ &hf_snmp_v3_flags_report,
3581 		{ "Reportable", "snmp.v3.flags.report", FT_BOOLEAN, 8,
3582 		    TFS(&tfs_set_notset), TH_REPORT, NULL, HFILL }},
3583 		{ &hf_snmp_engineid_conform, {
3584 		    "Engine ID Conformance", "snmp.engineid.conform", FT_BOOLEAN, 8,
3585 		    TFS(&tfs_snmp_engineid_conform), F_SNMP_ENGINEID_CONFORM, "Engine ID RFC3411 Conformance", HFILL }},
3586 		{ &hf_snmp_engineid_enterprise, {
3587 		    "Engine Enterprise ID", "snmp.engineid.enterprise", FT_UINT32, BASE_ENTERPRISES,
3588 		    STRINGS_ENTERPRISES, 0, NULL, HFILL }},
3589 		{ &hf_snmp_engineid_format, {
3590 		    "Engine ID Format", "snmp.engineid.format", FT_UINT8, BASE_DEC,
3591 		    VALS(snmp_engineid_format_vals), 0, NULL, HFILL }},
3592 		{ &hf_snmp_engineid_ipv4, {
3593 		    "Engine ID Data: IPv4 address", "snmp.engineid.ipv4", FT_IPv4, BASE_NONE,
3594 		    NULL, 0, NULL, HFILL }},
3595 		{ &hf_snmp_engineid_ipv6, {
3596 		    "Engine ID Data: IPv6 address", "snmp.engineid.ipv6", FT_IPv6, BASE_NONE,
3597 		    NULL, 0, NULL, HFILL }},
3598 		{ &hf_snmp_engineid_cisco_type, {
3599 		    "Engine ID Data: Cisco type", "snmp.engineid.cisco.type", FT_UINT8, BASE_HEX,
3600 		    VALS(snmp_engineid_cisco_type_vals), 0, NULL, HFILL }},
3601 		{ &hf_snmp_engineid_mac, {
3602 		    "Engine ID Data: MAC address", "snmp.engineid.mac", FT_ETHER, BASE_NONE,
3603 		    NULL, 0, NULL, HFILL }},
3604 		{ &hf_snmp_engineid_text, {
3605 		    "Engine ID Data: Text", "snmp.engineid.text", FT_STRING, BASE_NONE,
3606 		    NULL, 0, NULL, HFILL }},
3607 		{ &hf_snmp_engineid_time, {
3608 		    "Engine ID Data: Creation Time", "snmp.engineid.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3609 		    NULL, 0, NULL, HFILL }},
3610 		{ &hf_snmp_engineid_data, {
3611 		    "Engine ID Data", "snmp.engineid.data", FT_BYTES, BASE_NONE,
3612 		    NULL, 0, NULL, HFILL }},
3613 		{ &hf_snmp_msgAuthentication, {
3614 		    "Authentication", "snmp.v3.auth", FT_BOOLEAN, BASE_NONE,
3615 		    TFS(&auth_flags), 0, NULL, HFILL }},
3616 		{ &hf_snmp_decryptedPDU, {
3617 		    "Decrypted ScopedPDU", "snmp.decrypted_pdu", FT_BYTES, BASE_NONE,
3618 		    NULL, 0, "Decrypted PDU", HFILL }},
3619 		{ &hf_snmp_noSuchObject, {
3620 		    "noSuchObject", "snmp.noSuchObject", FT_NONE, BASE_NONE,
3621 		    NULL, 0, NULL, HFILL }},
3622 		{ &hf_snmp_noSuchInstance, {
3623 		    "noSuchInstance", "snmp.noSuchInstance", FT_NONE, BASE_NONE,
3624 		    NULL, 0, NULL, HFILL }},
3625 		{ &hf_snmp_endOfMibView, {
3626 		    "endOfMibView", "snmp.endOfMibView", FT_NONE, BASE_NONE,
3627 		    NULL, 0, NULL, HFILL }},
3628 		{ &hf_snmp_unSpecified, {
3629 		    "unSpecified", "snmp.unSpecified", FT_NONE, BASE_NONE,
3630 		    NULL, 0, NULL, HFILL }},
3631 
3632 		{ &hf_snmp_integer32_value, {
3633 		    "Value (Integer32)", "snmp.value.int", FT_INT64, BASE_DEC,
3634 		    NULL, 0, NULL, HFILL }},
3635 		{ &hf_snmp_octetstring_value, {
3636 		    "Value (OctetString)", "snmp.value.octets", FT_BYTES, BASE_SHOW_ASCII_PRINTABLE,
3637 		    NULL, 0, NULL, HFILL }},
3638 		{ &hf_snmp_oid_value, {
3639 		    "Value (OID)", "snmp.value.oid", FT_OID, BASE_NONE,
3640 		    NULL, 0, NULL, HFILL }},
3641 		{ &hf_snmp_null_value, {
3642 		    "Value (Null)", "snmp.value.null", FT_NONE, BASE_NONE,
3643 		    NULL, 0, NULL, HFILL }},
3644 		{ &hf_snmp_ipv4_value, {
3645 		    "Value (IpAddress)", "snmp.value.ipv4", FT_IPv4, BASE_NONE,
3646 		    NULL, 0, NULL, HFILL }},
3647 		{ &hf_snmp_ipv6_value, {
3648 		    "Value (IpAddress)", "snmp.value.ipv6", FT_IPv6, BASE_NONE,
3649 		    NULL, 0, NULL, HFILL }},
3650 		{ &hf_snmp_anyaddress_value, {
3651 		    "Value (IpAddress)", "snmp.value.addr", FT_BYTES, BASE_NONE,
3652 		    NULL, 0, NULL, HFILL }},
3653 		{ &hf_snmp_unsigned32_value, {
3654 		    "Value (Unsigned32)", "snmp.value.u32", FT_INT64, BASE_DEC,
3655 		    NULL, 0, NULL, HFILL }},
3656 		{ &hf_snmp_gauge32_value, {
3657 		    "Value (Gauge32)", "snmp.value.g32", FT_INT64, BASE_DEC,
3658 		    NULL, 0, NULL, HFILL }},
3659 		{ &hf_snmp_unknown_value, {
3660 		    "Value (Unknown)", "snmp.value.unk", FT_BYTES, BASE_NONE,
3661 		    NULL, 0, NULL, HFILL }},
3662 		{ &hf_snmp_counter_value, {
3663 		    "Value (Counter32)", "snmp.value.counter", FT_UINT64, BASE_DEC,
3664 		    NULL, 0, NULL, HFILL }},
3665 		{ &hf_snmp_big_counter_value, {
3666 		    "Value (Counter64)", "snmp.value.counter", FT_UINT64, BASE_DEC,
3667 		    NULL, 0, NULL, HFILL }},
3668 		{ &hf_snmp_nsap_value, {
3669 		    "Value (NSAP)", "snmp.value.nsap", FT_UINT64, BASE_DEC,
3670 		    NULL, 0, NULL, HFILL }},
3671 		{ &hf_snmp_timeticks_value, {
3672 		    "Value (Timeticks)", "snmp.value.timeticks", FT_UINT64, BASE_DEC,
3673 		    NULL, 0, NULL, HFILL }},
3674 		{ &hf_snmp_opaque_value, {
3675 		    "Value (Opaque)", "snmp.value.opaque", FT_BYTES, BASE_NONE,
3676 		    NULL, 0, NULL, HFILL }},
3677 		{ &hf_snmp_objectname, {
3678 		    "Object Name", "snmp.name", FT_OID, BASE_NONE,
3679 		    NULL, 0, NULL, HFILL }},
3680 		{ &hf_snmp_scalar_instance_index, {
3681 		    "Scalar Instance Index", "snmp.name.index", FT_UINT64, BASE_DEC,
3682 		    NULL, 0, NULL, HFILL }},
3683 		{ &hf_snmp_var_bind_str, {
3684 		    "Variable-binding-string", "snmp.var-bind_str", FT_STRING, BASE_NONE,
3685 		    NULL, 0, NULL, HFILL }},
3686 		{ &hf_snmp_agentid_trailer, {
3687 		    "AgentID Trailer", "snmp.agentid_trailer", FT_BYTES, BASE_NONE,
3688 		    NULL, 0, NULL, HFILL }},
3689 
3690 
3691 
3692 /*--- Included file: packet-snmp-hfarr.c ---*/
3693 #line 1 "./asn1/snmp/packet-snmp-hfarr.c"
3694     { &hf_snmp_SMUX_PDUs_PDU,
3695       { "SMUX-PDUs", "snmp.SMUX_PDUs",
3696         FT_UINT32, BASE_DEC, VALS(snmp_SMUX_PDUs_vals), 0,
3697         NULL, HFILL }},
3698     { &hf_snmp_version,
3699       { "version", "snmp.version",
3700         FT_INT32, BASE_DEC, VALS(snmp_Version_vals), 0,
3701         NULL, HFILL }},
3702     { &hf_snmp_community,
3703       { "community", "snmp.community",
3704         FT_STRING, BASE_NONE, NULL, 0,
3705         NULL, HFILL }},
3706     { &hf_snmp_data,
3707       { "data", "snmp.data",
3708         FT_UINT32, BASE_DEC, VALS(snmp_PDUs_vals), 0,
3709         "PDUs", HFILL }},
3710     { &hf_snmp_parameters,
3711       { "parameters", "snmp.parameters",
3712         FT_BYTES, BASE_NONE, NULL, 0,
3713         "OCTET_STRING", HFILL }},
3714     { &hf_snmp_datav2u,
3715       { "datav2u", "snmp.datav2u",
3716         FT_UINT32, BASE_DEC, VALS(snmp_T_datav2u_vals), 0,
3717         NULL, HFILL }},
3718     { &hf_snmp_v2u_plaintext,
3719       { "plaintext", "snmp.plaintext",
3720         FT_UINT32, BASE_DEC, VALS(snmp_PDUs_vals), 0,
3721         "PDUs", HFILL }},
3722     { &hf_snmp_encrypted,
3723       { "encrypted", "snmp.encrypted",
3724         FT_BYTES, BASE_NONE, NULL, 0,
3725         "OCTET_STRING", HFILL }},
3726     { &hf_snmp_msgAuthoritativeEngineID,
3727       { "msgAuthoritativeEngineID", "snmp.msgAuthoritativeEngineID",
3728         FT_BYTES, BASE_NONE, NULL, 0,
3729         NULL, HFILL }},
3730     { &hf_snmp_msgAuthoritativeEngineBoots,
3731       { "msgAuthoritativeEngineBoots", "snmp.msgAuthoritativeEngineBoots",
3732         FT_UINT32, BASE_DEC, NULL, 0,
3733         NULL, HFILL }},
3734     { &hf_snmp_msgAuthoritativeEngineTime,
3735       { "msgAuthoritativeEngineTime", "snmp.msgAuthoritativeEngineTime",
3736         FT_UINT32, BASE_DEC, NULL, 0,
3737         NULL, HFILL }},
3738     { &hf_snmp_msgUserName,
3739       { "msgUserName", "snmp.msgUserName",
3740         FT_STRING, BASE_NONE, NULL, 0,
3741         NULL, HFILL }},
3742     { &hf_snmp_msgAuthenticationParameters,
3743       { "msgAuthenticationParameters", "snmp.msgAuthenticationParameters",
3744         FT_BYTES, BASE_NONE, NULL, 0,
3745         NULL, HFILL }},
3746     { &hf_snmp_msgPrivacyParameters,
3747       { "msgPrivacyParameters", "snmp.msgPrivacyParameters",
3748         FT_BYTES, BASE_NONE, NULL, 0,
3749         NULL, HFILL }},
3750     { &hf_snmp_msgVersion,
3751       { "msgVersion", "snmp.msgVersion",
3752         FT_INT32, BASE_DEC, VALS(snmp_Version_vals), 0,
3753         "Version", HFILL }},
3754     { &hf_snmp_msgGlobalData,
3755       { "msgGlobalData", "snmp.msgGlobalData_element",
3756         FT_NONE, BASE_NONE, NULL, 0,
3757         "HeaderData", HFILL }},
3758     { &hf_snmp_msgSecurityParameters,
3759       { "msgSecurityParameters", "snmp.msgSecurityParameters",
3760         FT_BYTES, BASE_NONE, NULL, 0,
3761         NULL, HFILL }},
3762     { &hf_snmp_msgData,
3763       { "msgData", "snmp.msgData",
3764         FT_UINT32, BASE_DEC, VALS(snmp_ScopedPduData_vals), 0,
3765         "ScopedPduData", HFILL }},
3766     { &hf_snmp_msgID,
3767       { "msgID", "snmp.msgID",
3768         FT_UINT32, BASE_DEC, NULL, 0,
3769         "INTEGER_0_2147483647", HFILL }},
3770     { &hf_snmp_msgMaxSize,
3771       { "msgMaxSize", "snmp.msgMaxSize",
3772         FT_UINT32, BASE_DEC, NULL, 0,
3773         "INTEGER_484_2147483647", HFILL }},
3774     { &hf_snmp_msgFlags,
3775       { "msgFlags", "snmp.msgFlags",
3776         FT_BYTES, BASE_NONE, NULL, 0,
3777         NULL, HFILL }},
3778     { &hf_snmp_msgSecurityModel,
3779       { "msgSecurityModel", "snmp.msgSecurityModel",
3780         FT_UINT32, BASE_DEC, VALS(sec_models), 0,
3781         NULL, HFILL }},
3782     { &hf_snmp_plaintext,
3783       { "plaintext", "snmp.plaintext_element",
3784         FT_NONE, BASE_NONE, NULL, 0,
3785         "ScopedPDU", HFILL }},
3786     { &hf_snmp_encryptedPDU,
3787       { "encryptedPDU", "snmp.encryptedPDU",
3788         FT_BYTES, BASE_NONE, NULL, 0,
3789         NULL, HFILL }},
3790     { &hf_snmp_contextEngineID,
3791       { "contextEngineID", "snmp.contextEngineID",
3792         FT_BYTES, BASE_NONE, NULL, 0,
3793         "SnmpEngineID", HFILL }},
3794     { &hf_snmp_contextName,
3795       { "contextName", "snmp.contextName",
3796         FT_STRING, BASE_NONE, NULL, 0,
3797         "OCTET_STRING", HFILL }},
3798     { &hf_snmp_get_request,
3799       { "get-request", "snmp.get_request_element",
3800         FT_NONE, BASE_NONE, NULL, 0,
3801         "GetRequest_PDU", HFILL }},
3802     { &hf_snmp_get_next_request,
3803       { "get-next-request", "snmp.get_next_request_element",
3804         FT_NONE, BASE_NONE, NULL, 0,
3805         "GetNextRequest_PDU", HFILL }},
3806     { &hf_snmp_get_response,
3807       { "get-response", "snmp.get_response_element",
3808         FT_NONE, BASE_NONE, NULL, 0,
3809         "GetResponse_PDU", HFILL }},
3810     { &hf_snmp_set_request,
3811       { "set-request", "snmp.set_request_element",
3812         FT_NONE, BASE_NONE, NULL, 0,
3813         "SetRequest_PDU", HFILL }},
3814     { &hf_snmp_trap,
3815       { "trap", "snmp.trap_element",
3816         FT_NONE, BASE_NONE, NULL, 0,
3817         "Trap_PDU", HFILL }},
3818     { &hf_snmp_getBulkRequest,
3819       { "getBulkRequest", "snmp.getBulkRequest_element",
3820         FT_NONE, BASE_NONE, NULL, 0,
3821         "GetBulkRequest_PDU", HFILL }},
3822     { &hf_snmp_informRequest,
3823       { "informRequest", "snmp.informRequest_element",
3824         FT_NONE, BASE_NONE, NULL, 0,
3825         "InformRequest_PDU", HFILL }},
3826     { &hf_snmp_snmpV2_trap,
3827       { "snmpV2-trap", "snmp.snmpV2_trap_element",
3828         FT_NONE, BASE_NONE, NULL, 0,
3829         "SNMPv2_Trap_PDU", HFILL }},
3830     { &hf_snmp_report,
3831       { "report", "snmp.report_element",
3832         FT_NONE, BASE_NONE, NULL, 0,
3833         "Report_PDU", HFILL }},
3834     { &hf_snmp_request_id,
3835       { "request-id", "snmp.request_id",
3836         FT_INT32, BASE_DEC, NULL, 0,
3837         "T_request_id", HFILL }},
3838     { &hf_snmp_error_status,
3839       { "error-status", "snmp.error_status",
3840         FT_INT32, BASE_DEC, VALS(snmp_T_error_status_vals), 0,
3841         NULL, HFILL }},
3842     { &hf_snmp_error_index,
3843       { "error-index", "snmp.error_index",
3844         FT_INT32, BASE_DEC, NULL, 0,
3845         "INTEGER", HFILL }},
3846     { &hf_snmp_variable_bindings,
3847       { "variable-bindings", "snmp.variable_bindings",
3848         FT_UINT32, BASE_DEC, NULL, 0,
3849         "VarBindList", HFILL }},
3850     { &hf_snmp_bulkPDU_request_id,
3851       { "request-id", "snmp.request_id",
3852         FT_INT32, BASE_DEC, NULL, 0,
3853         "Integer32", HFILL }},
3854     { &hf_snmp_non_repeaters,
3855       { "non-repeaters", "snmp.non_repeaters",
3856         FT_UINT32, BASE_DEC, NULL, 0,
3857         "INTEGER_0_2147483647", HFILL }},
3858     { &hf_snmp_max_repetitions,
3859       { "max-repetitions", "snmp.max_repetitions",
3860         FT_UINT32, BASE_DEC, NULL, 0,
3861         "INTEGER_0_2147483647", HFILL }},
3862     { &hf_snmp_enterprise,
3863       { "enterprise", "snmp.enterprise",
3864         FT_OID, BASE_NONE, NULL, 0,
3865         "EnterpriseOID", HFILL }},
3866     { &hf_snmp_agent_addr,
3867       { "agent-addr", "snmp.agent_addr",
3868         FT_IPv4, BASE_NONE, NULL, 0,
3869         "NetworkAddress", HFILL }},
3870     { &hf_snmp_generic_trap,
3871       { "generic-trap", "snmp.generic_trap",
3872         FT_INT32, BASE_DEC, VALS(snmp_GenericTrap_vals), 0,
3873         "GenericTrap", HFILL }},
3874     { &hf_snmp_specific_trap,
3875       { "specific-trap", "snmp.specific_trap",
3876         FT_INT32, BASE_DEC, NULL, 0,
3877         "SpecificTrap", HFILL }},
3878     { &hf_snmp_time_stamp,
3879       { "time-stamp", "snmp.time_stamp",
3880         FT_UINT32, BASE_DEC, NULL, 0,
3881         "TimeTicks", HFILL }},
3882     { &hf_snmp_name,
3883       { "name", "snmp.name",
3884         FT_OID, BASE_NONE, NULL, 0,
3885         "ObjectName", HFILL }},
3886     { &hf_snmp_valueType,
3887       { "valueType", "snmp.valueType_element",
3888         FT_NONE, BASE_NONE, NULL, 0,
3889         NULL, HFILL }},
3890     { &hf_snmp_VarBindList_item,
3891       { "VarBind", "snmp.VarBind_element",
3892         FT_NONE, BASE_NONE, NULL, 0,
3893         NULL, HFILL }},
3894     { &hf_snmp_open,
3895       { "open", "snmp.open",
3896         FT_UINT32, BASE_DEC, VALS(snmp_OpenPDU_vals), 0,
3897         "OpenPDU", HFILL }},
3898     { &hf_snmp_close,
3899       { "close", "snmp.close",
3900         FT_INT32, BASE_DEC, VALS(snmp_ClosePDU_U_vals), 0,
3901         "ClosePDU", HFILL }},
3902     { &hf_snmp_registerRequest,
3903       { "registerRequest", "snmp.registerRequest_element",
3904         FT_NONE, BASE_NONE, NULL, 0,
3905         "RReqPDU", HFILL }},
3906     { &hf_snmp_registerResponse,
3907       { "registerResponse", "snmp.registerResponse",
3908         FT_UINT32, BASE_DEC, VALS(snmp_RegisterResponse_vals), 0,
3909         NULL, HFILL }},
3910     { &hf_snmp_commitOrRollback,
3911       { "commitOrRollback", "snmp.commitOrRollback",
3912         FT_INT32, BASE_DEC, VALS(snmp_SOutPDU_U_vals), 0,
3913         "SOutPDU", HFILL }},
3914     { &hf_snmp_rRspPDU,
3915       { "rRspPDU", "snmp.rRspPDU",
3916         FT_INT32, BASE_DEC, VALS(snmp_RRspPDU_U_vals), 0,
3917         NULL, HFILL }},
3918     { &hf_snmp_pDUs,
3919       { "pDUs", "snmp.pDUs",
3920         FT_UINT32, BASE_DEC, VALS(snmp_PDUs_vals), 0,
3921         NULL, HFILL }},
3922     { &hf_snmp_smux_simple,
3923       { "smux-simple", "snmp.smux_simple_element",
3924         FT_NONE, BASE_NONE, NULL, 0,
3925         "SimpleOpen", HFILL }},
3926     { &hf_snmp_smux_version,
3927       { "smux-version", "snmp.smux_version",
3928         FT_INT32, BASE_DEC, VALS(snmp_T_smux_version_vals), 0,
3929         NULL, HFILL }},
3930     { &hf_snmp_identity,
3931       { "identity", "snmp.identity",
3932         FT_OID, BASE_NONE, NULL, 0,
3933         "OBJECT_IDENTIFIER", HFILL }},
3934     { &hf_snmp_description,
3935       { "description", "snmp.description",
3936         FT_BYTES, BASE_NONE, NULL, 0,
3937         "DisplayString", HFILL }},
3938     { &hf_snmp_password,
3939       { "password", "snmp.password",
3940         FT_BYTES, BASE_NONE, NULL, 0,
3941         "OCTET_STRING", HFILL }},
3942     { &hf_snmp_subtree,
3943       { "subtree", "snmp.subtree",
3944         FT_OID, BASE_NONE, NULL, 0,
3945         "ObjectName", HFILL }},
3946     { &hf_snmp_priority,
3947       { "priority", "snmp.priority",
3948         FT_INT32, BASE_DEC, NULL, 0,
3949         "INTEGER_M1_2147483647", HFILL }},
3950     { &hf_snmp_operation,
3951       { "operation", "snmp.operation",
3952         FT_INT32, BASE_DEC, VALS(snmp_T_operation_vals), 0,
3953         NULL, HFILL }},
3954 
3955 /*--- End of included file: packet-snmp-hfarr.c ---*/
3956 #line 2452 "./asn1/snmp/packet-snmp-template.c"
3957 	};
3958 
3959 	/* List of subtrees */
3960 	static gint *ett[] = {
3961 		&ett_snmp,
3962 		&ett_engineid,
3963 		&ett_msgFlags,
3964 		&ett_encryptedPDU,
3965 		&ett_decrypted,
3966 		&ett_authParameters,
3967 		&ett_internet,
3968 		&ett_varbind,
3969 		&ett_name,
3970 		&ett_value,
3971 		&ett_decoding_error,
3972 
3973 /*--- Included file: packet-snmp-ettarr.c ---*/
3974 #line 1 "./asn1/snmp/packet-snmp-ettarr.c"
3975     &ett_snmp_Message,
3976     &ett_snmp_Messagev2u,
3977     &ett_snmp_T_datav2u,
3978     &ett_snmp_UsmSecurityParameters,
3979     &ett_snmp_SNMPv3Message,
3980     &ett_snmp_HeaderData,
3981     &ett_snmp_ScopedPduData,
3982     &ett_snmp_ScopedPDU,
3983     &ett_snmp_PDUs,
3984     &ett_snmp_PDU,
3985     &ett_snmp_BulkPDU,
3986     &ett_snmp_Trap_PDU_U,
3987     &ett_snmp_VarBind,
3988     &ett_snmp_VarBindList,
3989     &ett_snmp_SMUX_PDUs,
3990     &ett_snmp_RegisterResponse,
3991     &ett_snmp_OpenPDU,
3992     &ett_snmp_SimpleOpen_U,
3993     &ett_snmp_RReqPDU_U,
3994 
3995 /*--- End of included file: packet-snmp-ettarr.c ---*/
3996 #line 2468 "./asn1/snmp/packet-snmp-template.c"
3997 	};
3998 	static ei_register_info ei[] = {
3999 		{ &ei_snmp_failed_decrypted_data_pdu, { "snmp.failed_decrypted_data_pdu", PI_MALFORMED, PI_WARN, "Failed to decrypt encryptedPDU", EXPFILL }},
4000 		{ &ei_snmp_decrypted_data_bad_formatted, { "snmp.decrypted_data_bad_formatted", PI_MALFORMED, PI_WARN, "Decrypted data not formatted as expected, wrong key?", EXPFILL }},
4001 		{ &ei_snmp_verify_authentication_error, { "snmp.verify_authentication_error", PI_MALFORMED, PI_ERROR, "Error while verifying Message authenticity", EXPFILL }},
4002 		{ &ei_snmp_authentication_ok, { "snmp.authentication_ok", PI_CHECKSUM, PI_CHAT, "SNMP Authentication OK", EXPFILL }},
4003 		{ &ei_snmp_authentication_error, { "snmp.authentication_error", PI_CHECKSUM, PI_WARN, "SNMP Authentication Error", EXPFILL }},
4004 		{ &ei_snmp_varbind_not_uni_class_seq, { "snmp.varbind.not_uni_class_seq", PI_MALFORMED, PI_WARN, "VarBind is not an universal class sequence", EXPFILL }},
4005 		{ &ei_snmp_varbind_has_indicator, { "snmp.varbind.has_indicator", PI_MALFORMED, PI_WARN, "VarBind has indicator set", EXPFILL }},
4006 		{ &ei_snmp_objectname_not_oid, { "snmp.objectname_not_oid", PI_MALFORMED, PI_WARN, "ObjectName not an OID", EXPFILL }},
4007 		{ &ei_snmp_objectname_has_indicator, { "snmp.objectname_has_indicator", PI_MALFORMED, PI_WARN, "ObjectName has indicator set", EXPFILL }},
4008 		{ &ei_snmp_value_not_primitive_encoding, { "snmp.value_not_primitive_encoding", PI_MALFORMED, PI_WARN, "value not in primitive encoding", EXPFILL }},
4009 		{ &ei_snmp_invalid_oid, { "snmp.invalid_oid", PI_MALFORMED, PI_WARN, "invalid oid", EXPFILL }},
4010 		{ &ei_snmp_varbind_wrong_tag, { "snmp.varbind.wrong_tag", PI_MALFORMED, PI_WARN, "Wrong tag for SNMP VarBind error value", EXPFILL }},
4011 		{ &ei_snmp_varbind_response, { "snmp.varbind.response", PI_RESPONSE_CODE, PI_NOTE, "Response", EXPFILL }},
4012 		{ &ei_snmp_no_instance_subid, { "snmp.no_instance_subid", PI_MALFORMED, PI_WARN, "No instance sub-id in scalar value", EXPFILL }},
4013 		{ &ei_snmp_wrong_num_of_subids, { "snmp.wrong_num_of_subids", PI_MALFORMED, PI_WARN, "Wrong number of instance sub-ids in scalar value", EXPFILL }},
4014 		{ &ei_snmp_index_suboid_too_short, { "snmp.index_suboid_too_short", PI_MALFORMED, PI_WARN, "index sub-oid shorter than expected", EXPFILL }},
4015 		{ &ei_snmp_unimplemented_instance_index, { "snmp.unimplemented_instance_index", PI_UNDECODED, PI_WARN, "OID instaces not handled, if you want this implemented please contact the wireshark developers", EXPFILL }},
4016 		{ &ei_snmp_index_suboid_len0, { "snmp.ndex_suboid_len0", PI_MALFORMED, PI_WARN, "an index sub-oid OID cannot be 0 bytes long!", EXPFILL }},
4017 		{ &ei_snmp_index_suboid_too_long, { "snmp.index_suboid_too_long", PI_MALFORMED, PI_WARN, "index sub-oid should not be longer than remaining oid size", EXPFILL }},
4018 		{ &ei_snmp_index_string_too_long, { "snmp.index_string_too_long", PI_MALFORMED, PI_WARN, "index string should not be longer than remaining oid size", EXPFILL }},
4019 		{ &ei_snmp_column_parent_not_row, { "snmp.column_parent_not_row", PI_MALFORMED, PI_ERROR, "COLUMNS's parent is not a ROW", EXPFILL }},
4020 		{ &ei_snmp_uint_too_large, { "snmp.uint_too_large", PI_UNDECODED, PI_NOTE, "Unsigned integer value > 2^64 - 1", EXPFILL }},
4021 		{ &ei_snmp_int_too_large, { "snmp.int_too_large", PI_UNDECODED, PI_NOTE, "Signed integer value > 2^63 - 1 or <= -2^63", EXPFILL }},
4022 		{ &ei_snmp_integral_value0, { "snmp.integral_value0", PI_UNDECODED, PI_NOTE, "Integral value is zero-length", EXPFILL }},
4023 		{ &ei_snmp_missing_mib, { "snmp.missing_mib", PI_UNDECODED, PI_NOTE, "Unresolved value, Missing MIB", EXPFILL }},
4024 		{ &ei_snmp_varbind_wrong_length_value, { "snmp.varbind.wrong_length_value", PI_MALFORMED, PI_WARN, "Wrong length for SNMP VarBind/value", EXPFILL }},
4025 		{ &ei_snmp_varbind_wrong_class_tag, { "snmp.varbind.wrong_class_tag", PI_MALFORMED, PI_WARN, "Wrong class/tag for SNMP VarBind/value", EXPFILL }},
4026 		{ &ei_snmp_rfc1910_non_conformant, { "snmp.rfc1910_non_conformant", PI_PROTOCOL, PI_WARN, "Data not conforming to RFC1910", EXPFILL }},
4027 		{ &ei_snmp_rfc3411_non_conformant, { "snmp.rfc3411_non_conformant", PI_PROTOCOL, PI_WARN, "Data not conforming to RFC3411", EXPFILL }},
4028 		{ &ei_snmp_version_unknown, { "snmp.version.unknown", PI_PROTOCOL, PI_WARN, "Unknown version", EXPFILL }},
4029 		{ &ei_snmp_trap_pdu_obsolete, { "snmp.trap_pdu_obsolete", PI_PROTOCOL, PI_WARN, "Trap-PDU is obsolete in this SNMP version", EXPFILL }},
4030 
4031 	};
4032 
4033 	expert_module_t* expert_snmp;
4034 	module_t *snmp_module;
4035 
4036 	static uat_field_t users_fields[] = {
4037 		UAT_FLD_BUFFER(snmp_users,engine_id,"Engine ID","Engine-id for this entry (empty = any)"),
4038 		UAT_FLD_LSTRING(snmp_users,userName,"Username","The username"),
4039 		UAT_FLD_VS(snmp_users,auth_model,"Authentication model",auth_types,"Algorithm to be used for authentication."),
4040 		UAT_FLD_LSTRING(snmp_users,authPassword,"Password","The password used for authenticating packets for this entry"),
4041 		UAT_FLD_VS(snmp_users,priv_proto,"Privacy protocol",priv_types,"Algorithm to be used for privacy."),
4042 		UAT_FLD_LSTRING(snmp_users,privPassword,"Privacy password","The password used for encrypting packets for this entry"),
4043 		UAT_END_FIELDS
4044 	};
4045 
4046 	uat_t *assocs_uat = uat_new("SNMP Users",
4047 				    sizeof(snmp_ue_assoc_t),
4048 				    "snmp_users",
4049 				    TRUE,
4050 				    &ueas,
4051 				    &num_ueas,
4052 				    UAT_AFFECTS_DISSECTION,	/* affects dissection of packets, but not set of named fields */
4053 				    "ChSNMPUsersSection",
4054 				    snmp_users_copy_cb,
4055 				    snmp_users_update_cb,
4056 				    snmp_users_free_cb,
4057 				    renew_ue_cache,
4058 				    NULL,
4059 				    users_fields);
4060 
4061 	static uat_field_t specific_traps_flds[] = {
4062 		UAT_FLD_CSTRING(specific_traps,enterprise,"Enterprise OID","Enterprise Object Identifier"),
4063 		UAT_FLD_DEC(specific_traps,trap,"Trap Id","The specific-trap value"),
4064 		UAT_FLD_CSTRING(specific_traps,desc,"Description","Trap type description"),
4065 		UAT_END_FIELDS
4066 	};
4067 
4068 	uat_t* specific_traps_uat = uat_new("SNMP Enterprise Specific Trap Types",
4069 					    sizeof(snmp_st_assoc_t),
4070 					    "snmp_specific_traps",
4071 					    TRUE,
4072 					    &specific_traps,
4073 					    &num_specific_traps,
4074 					    UAT_AFFECTS_DISSECTION, /* affects dissection of packets, but not set of named fields */
4075 					    "ChSNMPEnterpriseSpecificTrapTypes",
4076 					    snmp_specific_trap_copy_cb,
4077 					    NULL,
4078 					    snmp_specific_trap_free_cb,
4079 					    NULL,
4080 					    NULL,
4081 					    specific_traps_flds);
4082 
4083 	/* Register protocol */
4084 	proto_snmp = proto_register_protocol(PNAME, PSNAME, PFNAME);
4085 	snmp_handle = register_dissector("snmp", dissect_snmp, proto_snmp);
4086 
4087 	/* Register fields and subtrees */
4088 	proto_register_field_array(proto_snmp, hf, array_length(hf));
4089 	proto_register_subtree_array(ett, array_length(ett));
4090 	expert_snmp = expert_register_protocol(proto_snmp);
4091 	expert_register_field_array(expert_snmp, ei, array_length(ei));
4092 
4093 
4094 	/* Register configuration preferences */
4095 	snmp_module = prefs_register_protocol(proto_snmp, process_prefs);
4096 	prefs_register_bool_preference(snmp_module, "display_oid",
4097 			"Show SNMP OID in info column",
4098 			"Whether the SNMP OID should be shown in the info column",
4099 			&display_oid);
4100 
4101 	prefs_register_obsolete_preference(snmp_module, "mib_modules");
4102 	prefs_register_obsolete_preference(snmp_module, "users_file");
4103 
4104 	prefs_register_bool_preference(snmp_module, "desegment",
4105 			"Reassemble SNMP-over-TCP messages spanning multiple TCP segments",
4106 			"Whether the SNMP dissector should reassemble messages spanning multiple TCP segments."
4107 			" To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
4108 			&snmp_desegment);
4109 
4110 	prefs_register_bool_preference(snmp_module, "var_in_tree",
4111 			"Display dissected variables inside SNMP tree",
4112 			"ON - display dissected variables inside SNMP tree, OFF - display dissected variables in root tree after SNMP",
4113 			&snmp_var_in_tree);
4114 
4115 	prefs_register_uat_preference(snmp_module, "users_table",
4116 				"Users Table",
4117 				"Table of engine-user associations used for authentication and decryption",
4118 				assocs_uat);
4119 
4120 	prefs_register_uat_preference(snmp_module, "specific_traps_table",
4121 				"Enterprise Specific Trap Types",
4122 				"Table of enterprise specific-trap type descriptions",
4123 				specific_traps_uat);
4124 
4125 #ifdef HAVE_LIBSMI
4126 	prefs_register_static_text_preference(snmp_module, "info_mibs",
4127 				"MIB settings can be changed in the Name Resolution preferences",
4128 				"MIB settings can be changed in the Name Resolution preferences");
4129 #endif
4130 
4131 	value_sub_dissectors_table = register_dissector_table("snmp.variable_oid","SNMP Variable OID", proto_snmp, FT_STRING, BASE_NONE);
4132 
4133 	register_init_routine(init_ue_cache);
4134 	register_cleanup_routine(cleanup_ue_cache);
4135 
4136 	register_ber_syntax_dissector("SNMP", proto_snmp, dissect_snmp_tcp);
4137 
4138 	snmp_tap=register_tap("snmp");
4139 
4140 	register_srt_table(proto_snmp, NULL, 1, snmpstat_packet, snmpstat_init, NULL);
4141 }
4142 
4143 
4144 /*--- proto_reg_handoff_snmp ---------------------------------------*/
proto_reg_handoff_snmp(void)4145 void proto_reg_handoff_snmp(void) {
4146 	dissector_handle_t snmp_tcp_handle;
4147 
4148 	dissector_add_uint_with_preference("udp.port", UDP_PORT_SNMP, snmp_handle);
4149 	dissector_add_uint("ethertype", ETHERTYPE_SNMP, snmp_handle);
4150 	dissector_add_uint("ipx.socket", IPX_SOCKET_SNMP_AGENT, snmp_handle);
4151 	dissector_add_uint("ipx.socket", IPX_SOCKET_SNMP_SINK, snmp_handle);
4152 	dissector_add_uint("hpext.dxsap", HPEXT_SNMP, snmp_handle);
4153 
4154 	snmp_tcp_handle = create_dissector_handle(dissect_snmp_tcp, proto_snmp);
4155 	dissector_add_uint_with_preference("tcp.port", TCP_PORT_SNMP, snmp_tcp_handle);
4156 	/* Since "regular" SNMP port and "trap" SNMP port use the same handler,
4157 	   the "trap" port doesn't really need a separate preference.  Just register
4158 	   normally */
4159 	dissector_add_uint("tcp.port", TCP_PORT_SNMP_TRAP, snmp_tcp_handle);
4160 	dissector_add_uint("udp.port", UDP_PORT_SNMP_TRAP, snmp_handle);
4161 	dissector_add_uint("udp.port", UDP_PORT_SNMP_PATROL, snmp_handle);
4162 
4163 	data_handle = find_dissector("data");
4164 
4165 	/* SNMPv2-MIB sysDescr "1.3.6.1.2.1.1.1.0" */
4166 	dissector_add_string("snmp.variable_oid", "1.3.6.1.2.1.1.1.0",
4167 		create_dissector_handle(dissect_snmp_variable_string, proto_snmp));
4168 	/* SNMPv2-MIB::sysName.0 (1.3.6.1.2.1.1.5.0) */
4169 	dissector_add_string("snmp.variable_oid", "1.3.6.1.2.1.1.5.0",
4170 		create_dissector_handle(dissect_snmp_variable_string, proto_snmp));
4171 
4172 	/*
4173 	 * Process preference settings.
4174 	 *
4175 	 * We can't do this in the register routine, as preferences aren't
4176 	 * read until all dissector register routines have been called (so
4177 	 * that all dissector preferences have been registered).
4178 	 */
4179 	process_prefs();
4180 
4181 }
4182 
4183 void
proto_register_smux(void)4184 proto_register_smux(void)
4185 {
4186 	static gint *ett[] = {
4187 		&ett_smux,
4188 	};
4189 
4190 	proto_smux = proto_register_protocol("SNMP Multiplex Protocol",
4191 	    "SMUX", "smux");
4192 
4193 	proto_register_subtree_array(ett, array_length(ett));
4194 
4195 }
4196 
4197 void
proto_reg_handoff_smux(void)4198 proto_reg_handoff_smux(void)
4199 {
4200 	dissector_handle_t smux_handle;
4201 
4202 	smux_handle = create_dissector_handle(dissect_smux, proto_smux);
4203 	dissector_add_uint_with_preference("tcp.port", TCP_PORT_SMUX, smux_handle);
4204 }
4205 
4206 /*
4207  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
4208  *
4209  * Local variables:
4210  * c-basic-offset: 8
4211  * tab-width: 8
4212  * indent-tabs-mode: t
4213  * End:
4214  *
4215  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
4216  * :indentSize=8:tabSize=8:noTabs=false:
4217  */
4218