Tvbuffify the BOOTP/DHCP dissector.
[obnox/wireshark/wip.git] / packet-tpkt.c
1 /* packet-tpkt.c
2  *
3  * Routines for TPKT dissection
4  * Copyright 2000, Philips Electronics N.V.
5  * Andreas Sikkema <andreas.sikkema@philips.com>
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@zing.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * 
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 /*
28  * This dissector tries to dissect the TPKT protocol according to
29  * RFC 1006
30  *
31  * IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT 
32  *
33  * Please examine the dissector. It is NOT defined in the normal way!
34  * Some variables are references and the dissector also returns a 
35  * value! And no, this is not a heuristic dissector!
36  * 
37  * IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT 
38  */
39
40
41 #ifdef HAVE_CONFIG_H
42 # include "config.h"
43 #endif
44
45 #include <glib.h>
46 #include "packet.h"
47
48 #ifdef HAVE_SYS_TYPES_H
49 #  include <sys/types.h>
50 #endif
51
52 #ifdef HAVE_NETINET_IN_H
53 #  include <netinet/in.h>
54 #endif
55
56 #include <stdio.h>
57 #include <string.h>
58
59 #include "packet-tpkt.h"
60
61 /* TPKT header fields             */
62 static int proto_tpkt          = -1;
63 static int hf_tpkt_version     = -1;
64 static int hf_tpkt_reserved    = -1;
65 static int hf_tpkt_length      = -1;
66
67 /* TPKT fields defining a sub tree */
68 static gint ett_tpkt           = -1;
69
70 int 
71 is_tpkt( tvbuff_t *tvb, unsigned int* offset )
72 {
73         if ( (*offset) + 4 > tvb_length( tvb ) ) return FALSE;
74         if ( ! ( ( tvb_get_guint8( tvb, ( *offset ) ) == 3 ) && 
75                        ( tvb_get_guint8( tvb, ( *offset ) + 1 ) == 0 ) ) ) return FALSE;
76
77   return TRUE;
78 }
79
80 int
81 dissect_tpkt( tvbuff_t *tvb, unsigned int* offset, packet_info *pinfo, proto_tree *tree )
82 {
83         proto_item *ti            = NULL;
84         proto_tree *tpkt_tree     = NULL;
85         unsigned int data_len = 0;
86
87
88         pinfo->current_proto = "TPKT";
89
90         /* There should at least be 4 bytes left in the frame */
91         if ( (*offset) + 4 > tvb_length( tvb ) ) return -1;
92         /* 
93          * The first octet should be 3 and the second one should be 0 
94          * The H.323 implementers guide suggests that this migh not 
95          * always be the case....
96          */
97         if ( ! ( ( tvb_get_guint8( tvb, ( *offset ) ) == 3 ) && 
98                        ( tvb_get_guint8( tvb, ( *offset ) + 1 ) == 0 ) ) ) return -1;
99
100         if ( check_col( pinfo->fd, COL_PROTOCOL ) ) {
101                 col_set_str( pinfo->fd, COL_PROTOCOL, "TPKT" );
102         }
103         
104         if ( check_col( pinfo->fd, COL_INFO) ) {
105                 /*data_len = pntohs( &pd[ (*offset) + 2 ] );*/
106                 data_len = tvb_get_ntohs( tvb, (*offset) + 2 );
107
108                 col_add_fstr( pinfo->fd, COL_INFO, "TPKT Data length = %d", data_len );
109         }
110
111         if ( tree ) {
112                 ti = proto_tree_add_item( tree, proto_tpkt, tvb, (*offset), 4, FALSE );
113                 tpkt_tree = proto_item_add_subtree( ti, ett_tpkt );
114                 /* Version 1st octet */
115                 proto_tree_add_item( tpkt_tree, hf_tpkt_version, tvb, (*offset), 1, FALSE );
116                 (*offset)++;
117                 /* Reserved octet*/
118                 proto_tree_add_item( tpkt_tree, hf_tpkt_reserved, tvb, (*offset), 1, FALSE );
119                 (*offset)++;
120         }
121         else {
122                 (*offset) += 2;
123         }
124         /* Length, two octets */
125         /*data_len = pntohs( &pd[ (*offset) ] );*/
126         data_len = tvb_get_ntohs( tvb, (*offset) );
127
128         if ( tree )
129                 proto_tree_add_uint_format( tpkt_tree, hf_tpkt_length, tvb, (*offset), 2, data_len, "Length: %d", data_len );
130
131         (*offset) += 2;
132         return data_len;
133 }
134
135 void
136 proto_register_tpkt(void)
137 {
138         static hf_register_info hf[] = 
139         {
140                 { 
141                         &hf_tpkt_version,
142                         { 
143                                 "Version", 
144                                 "tpkt.version", 
145                                 FT_UINT8, 
146                                 BASE_DEC, 
147                                 NULL, 
148                                 0x0,
149                                 "" 
150                         }
151                 },
152                 { 
153                         &hf_tpkt_reserved,
154                         { 
155                                 "Reserved", 
156                                 "tpkt.reserved", 
157                                 FT_UINT8, 
158                                 BASE_DEC, 
159                                 NULL, 
160                                 0x0,
161                                 "" 
162                         }
163                 },
164                 { 
165                         &hf_tpkt_length,
166                         { 
167                                 "Length", 
168                                 "tpkt.length", 
169                                 FT_UINT16, 
170                                 BASE_DEC, 
171                                 NULL, 
172                                 0x0,
173                                 "" 
174                         }
175                 },
176 };
177         
178         static gint *ett[] = 
179         {
180                 &ett_tpkt,
181         };
182
183
184         proto_tpkt = proto_register_protocol("TPKT", "TPKT", "tpkt");
185         proto_register_field_array(proto_tpkt, hf, array_length(hf));
186         proto_register_subtree_array(ett, array_length(ett));
187 }