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, ¶m_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 ¶meter_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