9f9078833b0298de6492c126e8147721db97e263
[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., 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/packet.h>
32 #include <epan/asn1.h>
33
34 #include <stdio.h>
35 #include <string.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 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, FALSE);
71                 tree = proto_item_add_subtree(item, ett_mms);
72         }
73         if (check_col(pinfo->cinfo, COL_PROTOCOL))
74                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MMS");
75         if (check_col(pinfo->cinfo, COL_INFO))
76                 col_clear(pinfo->cinfo, COL_INFO);
77
78         while (tvb_reported_length_remaining(tvb, offset) > 0){
79                 old_offset=offset;
80                 offset=dissect_mms_MMSpdu(FALSE, tvb, offset, &asn1_ctx , tree, -1);
81                 if(offset == old_offset){
82                         proto_tree_add_text(tree, tvb, offset, -1,"Internal error, zero-byte MMS PDU");
83                         offset = tvb_length(tvb);
84                         break;
85                 }
86         }
87 }
88
89
90 /*--- proto_register_mms -------------------------------------------*/
91 void proto_register_mms(void) {
92
93   /* List of fields */
94   static hf_register_info hf[] =
95   {
96 #include "packet-mms-hfarr.c"
97   };
98
99   /* List of subtrees */
100   static gint *ett[] = {
101     &ett_mms,
102 #include "packet-mms-ettarr.c"
103   };
104
105   /* Register protocol */
106   proto_mms = proto_register_protocol(PNAME, PSNAME, PFNAME);
107   register_dissector("mms", dissect_mms, proto_mms);
108   /* Register fields and subtrees */
109   proto_register_field_array(proto_mms, hf, array_length(hf));
110   proto_register_subtree_array(ett, array_length(ett));
111
112 }
113
114
115 static gboolean
116 dissect_mms_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
117 {       
118         /* must check that this really is an mms packet */
119         int offset = 0;
120         guint32 length = 0 ;
121         guint32 oct;
122         gint idx = 0 ;
123
124         gint8 tmp_class;
125         gboolean tmp_pc;
126         gint32 tmp_tag;
127         
128                 /* first, check do we have at least 2 bytes (pdu) */
129         if (!tvb_bytes_exist(tvb, 0, 2))
130                 return FALSE;   /* no */
131         
132         /* can we recognize MMS PDU ? Return FALSE if  not */
133         /*   get MMS PDU type */
134         offset = get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag);
135         
136         /* check MMS type */
137         
138         /* Class should be constructed */ 
139         if (tmp_class!=BER_CLASS_CON)
140                 return FALSE;
141         
142         /* see if the tag is a valid MMS PDU */
143         match_strval_idx(tmp_tag, mms_MMSpdu_vals, &idx);
144         if  (idx == -1) { 
145                 return FALSE;  /* no, it isn't an MMS PDU */
146         }
147         
148         /* check MMS length  */
149         oct = tvb_get_guint8(tvb, offset)& 0x7F;
150         if (oct==0)
151                 /* MMS requires length after tag so not MMS if indefinite length*/
152                 return FALSE;
153                                                 
154         offset = get_ber_length(tvb, offset, &length, NULL);
155         /* do we have enough bytes? */
156         if (!tvb_bytes_exist(tvb, offset, length))
157                 return FALSE; 
158                 
159         dissect_mms(tvb, pinfo, parent_tree);
160         return TRUE;    
161 }
162
163 /*--- proto_reg_handoff_mms --- */
164 void proto_reg_handoff_mms(void) {
165         register_ber_oid_dissector("1.0.9506.2.3", dissect_mms, proto_mms,"MMS");
166         register_ber_oid_dissector("1.0.9506.2.1", dissect_mms, proto_mms,"mms-abstract-syntax-version1(1)");
167         heur_dissector_add("cotp", dissect_mms_heur, proto_mms);
168         heur_dissector_add("cotp_is", dissect_mms_heur, proto_mms);
169 }
170