For proto_tree_add_item(..., proto_xxx, ...)use ENC_NA as the encoding arg.
[obnox/wireshark/wip.git] / asn1 / mms / packet-mms-template.c
1 /* packet-mms_asn1.c
2  *
3  * Ronnie Sahlberg 2005
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <glib.h>
31 #include <epan/prefs.h>
32 #include <epan/packet.h>
33 #include <epan/asn1.h>
34 #include <epan/expert.h>
35 #include <epan/nstime.h>
36
37 #include "packet-ber.h"
38 #include "packet-acse.h"
39 #include "packet-mms.h"
40
41 #define PNAME  "MMS"
42 #define PSNAME "MMS"
43 #define PFNAME "mms"
44
45 /* Initialize the protocol and registered fields */
46 static int proto_mms = -1;
47
48 #include "packet-mms-hf.c"
49
50 /* Initialize the subtree pointers */
51 static gint ett_mms = -1;
52 #include "packet-mms-ett.c"
53
54 #include "packet-mms-fn.c"
55
56 /*
57 * Dissect MMS PDUs inside a PPDU.
58 */
59 static void
60 dissect_mms(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
61 {
62         int offset = 0;
63         int old_offset;
64         proto_item *item=NULL;
65         proto_tree *tree=NULL;
66         asn1_ctx_t asn1_ctx;
67         asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
68
69         if(parent_tree){
70                 item = proto_tree_add_item(parent_tree, proto_mms, tvb, 0, -1, ENC_NA);
71                 tree = proto_item_add_subtree(item, ett_mms);
72         }
73         col_set_str(pinfo->cinfo, COL_PROTOCOL, "MMS");
74         col_clear(pinfo->cinfo, COL_INFO);
75
76         while (tvb_reported_length_remaining(tvb, offset) > 0){
77                 old_offset=offset;
78                 offset=dissect_mms_MMSpdu(FALSE, tvb, offset, &asn1_ctx , tree, -1);
79                 if(offset == old_offset){
80                         proto_tree_add_text(tree, tvb, offset, -1,"Internal error, zero-byte MMS PDU");
81                         offset = tvb_length(tvb);
82                         break;
83                 }
84         }
85 }
86
87
88 /*--- proto_register_mms -------------------------------------------*/
89 void proto_register_mms(void) {
90
91         /* List of fields */
92   static hf_register_info hf[] =
93   {
94 #include "packet-mms-hfarr.c"
95   };
96
97   /* List of subtrees */
98   static gint *ett[] = {
99     &ett_mms,
100 #include "packet-mms-ettarr.c"
101   };
102
103   /* Register protocol */
104   proto_mms = proto_register_protocol(PNAME, PSNAME, PFNAME);
105   register_dissector("mms", dissect_mms, proto_mms);
106   /* Register fields and subtrees */
107   proto_register_field_array(proto_mms, hf, array_length(hf));
108   proto_register_subtree_array(ett, array_length(ett));
109
110
111 }
112
113
114 static gboolean
115 dissect_mms_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
116 {
117         /* must check that this really is an mms packet */
118         int offset = 0;
119         guint32 length = 0 ;
120         guint32 oct;
121         gint idx = 0 ;
122
123         gint8 tmp_class;
124         gboolean tmp_pc;
125         gint32 tmp_tag;
126
127                 /* first, check do we have at least 2 bytes (pdu) */
128         if (!tvb_bytes_exist(tvb, 0, 2))
129                 return FALSE;   /* no */
130
131         /* can we recognize MMS PDU ? Return FALSE if  not */
132         /*   get MMS PDU type */
133         offset = get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
134
135         /* check MMS type */
136
137         /* Class should be constructed */
138         if (tmp_class!=BER_CLASS_CON)
139                 return FALSE;
140
141         /* see if the tag is a valid MMS PDU */
142         match_strval_idx(tmp_tag, mms_MMSpdu_vals, &idx);
143         if  (idx == -1) {
144                 return FALSE;  /* no, it isn't an MMS PDU */
145         }
146
147         /* check MMS length  */
148         oct = tvb_get_guint8(tvb, offset)& 0x7F;
149         if (oct==0)
150                 /* MMS requires length after tag so not MMS if indefinite length*/
151                 return FALSE;
152
153         offset = get_ber_length(tvb, offset, &length, NULL);
154         /* do we have enough bytes? */
155         if (!tvb_bytes_exist(tvb, offset, length))
156                 return FALSE;
157
158         dissect_mms(tvb, pinfo, parent_tree);
159         return TRUE;
160 }
161
162 /*--- proto_reg_handoff_mms --- */
163 void proto_reg_handoff_mms(void) {
164         register_ber_oid_dissector("1.0.9506.2.3", dissect_mms, proto_mms,"MMS");
165         register_ber_oid_dissector("1.0.9506.2.1", dissect_mms, proto_mms,"mms-abstract-syntax-version1(1)");
166         heur_dissector_add("cotp", dissect_mms_heur, proto_mms);
167         heur_dissector_add("cotp_is", dissect_mms_heur, proto_mms);
168 }
169