Rename the routines that handle dissector tables with unsigned integer
[obnox/wireshark/wip.git] / epan / dissectors / packet-pingpongprotocol.c
1 /* packet-pingpongprotocol.c
2  * Routines for the Ping Pong Protocol, a test application of the
3  * rsplib RSerPool implementation
4  * http://tdrwww.exp-math.uni-essen.de/dreibholz/rserpool/
5  *
6  * Copyright 2006 by Thomas Dreibholz <dreibh [AT] exp-math.uni-essen.de>
7  *
8  * $Id$
9  *
10  * Wireshark - Network traffic analyzer
11  * By Gerald Combs <gerald@wireshark.org>
12  * Copyright 1998 Gerald Combs
13  *
14  * Copied from README.developer
15  *
16  * This program is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU General Public License
18  * as published by the Free Software Foundation; either version 2
19  * of the License, or (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29  */
30
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
34
35 #include <epan/packet.h>
36
37
38 #define PINGPONGPROTOCOL_PAYLOAD_PROTOCOL_ID 0x29097602
39
40
41 /* Initialize the protocol and registered fields */
42 static int proto_pingpongprotocol         = -1;
43 static int hf_message_type                = -1;
44 static int hf_message_flags               = -1;
45 static int hf_message_length              = -1;
46 static int hf_ping_messageno              = -1;
47 static int hf_ping_data                   = -1;
48 static int hf_pong_messageno              = -1;
49 static int hf_pong_replyno                = -1;
50 static int hf_pong_data                   = -1;
51
52
53 /* Initialize the subtree pointers */
54 static gint ett_pingpongprotocol = -1;
55
56 static void
57 dissect_pingpongprotocol_message(tvbuff_t *, packet_info *, proto_tree *);
58
59
60 /* Dissectors for messages. This is specific to PingPongProtocol */
61 #define MESSAGE_TYPE_LENGTH    1
62 #define MESSAGE_FLAGS_LENGTH   1
63 #define MESSAGE_LENGTH_LENGTH  2
64
65 #define MESSAGE_TYPE_OFFSET    0
66 #define MESSAGE_FLAGS_OFFSET   (MESSAGE_TYPE_OFFSET    + MESSAGE_TYPE_LENGTH)
67 #define MESSAGE_LENGTH_OFFSET  (MESSAGE_FLAGS_OFFSET   + MESSAGE_FLAGS_LENGTH)
68 #define MESSAGE_VALUE_OFFSET   (MESSAGE_LENGTH_OFFSET  + MESSAGE_LENGTH_LENGTH)
69
70
71 #define PING_MESSAGENO_LENGTH 8
72
73 #define PING_MESSAGENO_OFFSET MESSAGE_VALUE_OFFSET
74 #define PING_DATA_OFFSET      (PING_MESSAGENO_OFFSET + PING_MESSAGENO_LENGTH)
75
76 #define PONG_MESSAGENO_LENGTH 8
77 #define PONG_REPLYNO_LENGTH   8
78
79 #define PONG_MESSAGENO_OFFSET  MESSAGE_VALUE_OFFSET
80 #define PONG_REPLYNO_OFFSET    (PONG_MESSAGENO_OFFSET + PONG_MESSAGENO_LENGTH)
81 #define PONG_DATA_OFFSET       (PONG_REPLYNO_OFFSET + PONG_REPLYNO_LENGTH)
82
83
84 #define PINGPONG_PING_MESSAGE_TYPE 0x01
85 #define PINGPONG_PONG_MESSAGE_TYPE 0x02
86
87
88
89 static const value_string message_type_values[] = {
90   { PINGPONG_PONG_MESSAGE_TYPE, "PingPongProtocol Pong" },
91   { PINGPONG_PING_MESSAGE_TYPE, "PingPongProtocol Ping" },
92   { 0, NULL }
93 };
94
95
96 static void
97 dissect_pingpongprotocol_ping_message(tvbuff_t *message_tvb, proto_tree *message_tree)
98 {
99   guint16 ping_data_length;
100
101   proto_tree_add_item(message_tree, hf_ping_messageno, message_tvb, PING_MESSAGENO_OFFSET, PING_MESSAGENO_LENGTH, FALSE);
102
103   ping_data_length = tvb_get_ntohs(message_tvb, MESSAGE_LENGTH_OFFSET) - PING_DATA_OFFSET;
104   if (ping_data_length > 0)
105     proto_tree_add_item(message_tree, hf_ping_data, message_tvb, PING_DATA_OFFSET, ping_data_length, FALSE);
106 }
107
108 static void
109 dissect_pingpongprotocol_pong_message(tvbuff_t *message_tvb, proto_tree *message_tree)
110 {
111   guint16 pong_data_length;
112
113   proto_tree_add_item(message_tree, hf_pong_messageno, message_tvb, PONG_MESSAGENO_OFFSET, PONG_MESSAGENO_LENGTH, FALSE);
114   proto_tree_add_item(message_tree, hf_pong_replyno,   message_tvb, PONG_REPLYNO_OFFSET,   PONG_REPLYNO_LENGTH,   FALSE);
115
116   pong_data_length = tvb_get_ntohs(message_tvb, MESSAGE_LENGTH_OFFSET) - PONG_DATA_OFFSET;
117   if (pong_data_length > 0) {
118     proto_tree_add_item(message_tree, hf_pong_data, message_tvb, PONG_DATA_OFFSET, pong_data_length, FALSE);
119   }
120 }
121
122
123 static void
124 dissect_pingpongprotocol_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *pingpongprotocol_tree)
125 {
126   guint8 type;
127
128   type = tvb_get_guint8(message_tvb, MESSAGE_TYPE_OFFSET);
129   if (pinfo && (check_col(pinfo->cinfo, COL_INFO))) {
130     col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(type, message_type_values, "Unknown PingPongProtocol type"));
131   }
132   proto_tree_add_item(pingpongprotocol_tree, hf_message_type,   message_tvb, MESSAGE_TYPE_OFFSET,   MESSAGE_TYPE_LENGTH,   FALSE);
133   proto_tree_add_item(pingpongprotocol_tree, hf_message_flags,  message_tvb, MESSAGE_FLAGS_OFFSET,  MESSAGE_FLAGS_LENGTH,  FALSE);
134   proto_tree_add_item(pingpongprotocol_tree, hf_message_length, message_tvb, MESSAGE_LENGTH_OFFSET, MESSAGE_LENGTH_LENGTH, FALSE);
135   switch (type) {
136     case PINGPONG_PING_MESSAGE_TYPE:
137       dissect_pingpongprotocol_ping_message(message_tvb, pingpongprotocol_tree);
138      break;
139     case PINGPONG_PONG_MESSAGE_TYPE:
140       dissect_pingpongprotocol_pong_message(message_tvb, pingpongprotocol_tree);
141      break;
142   }
143 }
144
145 static int
146 dissect_pingpongprotocol(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *tree)
147 {
148   proto_item *pingpongprotocol_item;
149   proto_tree *pingpongprotocol_tree;
150
151   /* pinfo is NULL only if dissect_pingpongprotocol_message is called from dissect_error cause */
152   if (pinfo)
153     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PingPongProtocol");
154
155   /* In the interest of speed, if "tree" is NULL, don't do any work not
156      necessary to generate protocol tree items. */
157   if (tree) {
158     /* create the pingpongprotocol protocol tree */
159     pingpongprotocol_item = proto_tree_add_item(tree, proto_pingpongprotocol, message_tvb, 0, -1, FALSE);
160     pingpongprotocol_tree = proto_item_add_subtree(pingpongprotocol_item, ett_pingpongprotocol);
161   } else {
162     pingpongprotocol_tree = NULL;
163   };
164   /* dissect the message */
165   dissect_pingpongprotocol_message(message_tvb, pinfo, pingpongprotocol_tree);
166   return(TRUE);
167 }
168
169 /* Register the protocol with Wireshark */
170 void
171 proto_register_pingpongprotocol(void)
172 {
173
174   /* Setup list of header fields */
175   static hf_register_info hf[] = {
176     { &hf_message_type,     { "Type",      "pingpongprotocol.message_type",   FT_UINT8,  BASE_DEC, VALS(message_type_values), 0x0, NULL, HFILL } },
177     { &hf_message_flags,    { "Flags",     "pingpongprotocol.message_flags",  FT_UINT8,  BASE_DEC, NULL,                      0x0, NULL, HFILL } },
178     { &hf_message_length,   { "Length",    "pingpongprotocol.message_length", FT_UINT16, BASE_DEC, NULL,                      0x0, NULL, HFILL } },
179     { &hf_ping_messageno,   { "MessageNo", "pingpongprotocol.ping_messageno", FT_UINT64, BASE_DEC, NULL,                      0x0, NULL, HFILL } },
180     { &hf_ping_data,        { "Ping_Data", "pingpongprotocol.ping_data",      FT_BYTES,  BASE_NONE, NULL,                      0x0, NULL, HFILL } },
181     { &hf_pong_messageno,   { "MessageNo", "pingpongprotocol.pong_messageno", FT_UINT64, BASE_DEC, NULL,                      0x0, NULL, HFILL } },
182     { &hf_pong_replyno,     { "ReplyNo",   "pingpongprotocol.pong_replyno",   FT_UINT64, BASE_DEC, NULL,                      0x0, NULL, HFILL } },
183     { &hf_pong_data,        { "Pong_Data", "pingpongprotocol.pong_data",      FT_BYTES,  BASE_NONE, NULL,                      0x0, NULL, HFILL } },
184   };
185
186   /* Setup protocol subtree array */
187   static gint *ett[] = {
188     &ett_pingpongprotocol
189   };
190
191   /* Register the protocol name and description */
192   proto_pingpongprotocol = proto_register_protocol("Ping Pong Protocol", "PingPongProtocol",  "pingpongprotocol");
193
194   /* Required function calls to register the header fields and subtrees used */
195   proto_register_field_array(proto_pingpongprotocol, hf, array_length(hf));
196   proto_register_subtree_array(ett, array_length(ett));
197 }
198
199 void
200 proto_reg_handoff_pingpongprotocol(void)
201 {
202   dissector_handle_t pingpongprotocol_handle;
203
204   pingpongprotocol_handle = new_create_dissector_handle(dissect_pingpongprotocol, proto_pingpongprotocol);
205   dissector_add_uint("sctp.ppi", PINGPONGPROTOCOL_PAYLOAD_PROTOCOL_ID, pingpongprotocol_handle);
206 }