Update Free Software Foundation address.
[metze/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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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                         break;
82                 }
83         }
84 }
85
86
87 /*--- proto_register_mms -------------------------------------------*/
88 void proto_register_mms(void) {
89
90         /* List of fields */
91   static hf_register_info hf[] =
92   {
93 #include "packet-mms-hfarr.c"
94   };
95
96   /* List of subtrees */
97   static gint *ett[] = {
98     &ett_mms,
99 #include "packet-mms-ettarr.c"
100   };
101
102   /* Register protocol */
103   proto_mms = proto_register_protocol(PNAME, PSNAME, PFNAME);
104   register_dissector("mms", dissect_mms, proto_mms);
105   /* Register fields and subtrees */
106   proto_register_field_array(proto_mms, hf, array_length(hf));
107   proto_register_subtree_array(ett, array_length(ett));
108
109
110 }
111
112
113 static gboolean
114 dissect_mms_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
115 {
116         /* must check that this really is an mms packet */
117         int offset = 0;
118         guint32 length = 0 ;
119         guint32 oct;
120         gint idx = 0 ;
121
122         gint8 tmp_class;
123         gboolean tmp_pc;
124         gint32 tmp_tag;
125
126                 /* first, check do we have at least 2 bytes (pdu) */
127         if (!tvb_bytes_exist(tvb, 0, 2))
128                 return FALSE;   /* no */
129
130         /* can we recognize MMS PDU ? Return FALSE if  not */
131         /*   get MMS PDU type */
132         offset = get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
133
134         /* check MMS type */
135
136         /* Class should be constructed */
137         if (tmp_class!=BER_CLASS_CON)
138                 return FALSE;
139
140         /* see if the tag is a valid MMS PDU */
141         match_strval_idx(tmp_tag, mms_MMSpdu_vals, &idx);
142         if  (idx == -1) {
143                 return FALSE;  /* no, it isn't an MMS PDU */
144         }
145
146         /* check MMS length  */
147         oct = tvb_get_guint8(tvb, offset)& 0x7F;
148         if (oct==0)
149                 /* MMS requires length after tag so not MMS if indefinite length*/
150                 return FALSE;
151
152         offset = get_ber_length(tvb, offset, &length, NULL);
153         /* do we have enough bytes? */
154         if (!tvb_bytes_exist(tvb, offset, length))
155                 return FALSE;
156
157         dissect_mms(tvb, pinfo, parent_tree);
158         return TRUE;
159 }
160
161 /*--- proto_reg_handoff_mms --- */
162 void proto_reg_handoff_mms(void) {
163         register_ber_oid_dissector("1.0.9506.2.3", dissect_mms, proto_mms,"MMS");
164         register_ber_oid_dissector("1.0.9506.2.1", dissect_mms, proto_mms,"mms-abstract-syntax-version1(1)");
165         heur_dissector_add("cotp", dissect_mms_heur, proto_mms);
166         heur_dissector_add("cotp_is", dissect_mms_heur, proto_mms);
167 }
168