dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
packet-op-uavtalk.c
Go to the documentation of this file.
1 /* packet-op-uavtalk.c
2  * Routines for OpenPilot UAVTalk packet dissection
3  * Copyright 2012 Stacey Sheldon <stac@solidgoldbomb.org>
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, see <http://www.gnu.org/licenses/>
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24  */
25 
26 
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30 
31 #include <epan/packet.h>
32 #include <epan/prefs.h>
33 #include <epan/ptvcursor.h> /* ptvcursor_* */
34 
35 #include <glib.h>
36 #include <string.h>
37 
38 static guint global_op_uavtalk_port = 9000;
39 
40 static int proto_op_uavtalk = -1;
41 
42 static gint ett_op_uavtalk = -1;
43 
44 static dissector_handle_t data_handle;
45 static dissector_table_t uavtalk_subdissector_table;
46 
47 static int hf_op_uavtalk_sync = -1;
48 static int hf_op_uavtalk_version = -1;
49 static int hf_op_uavtalk_type = -1;
50 static int hf_op_uavtalk_len = -1;
51 static int hf_op_uavtalk_objid = -1;
52 static int hf_op_uavtalk_crc8 = -1;
53 
54 #define UAVTALK_SYNC_VAL 0x3C
55 
56 static const value_string uavtalk_packet_types[]={
57  { 0, "TxObj" },
58  { 1, "GetObj" },
59  { 2, "SetObjAckd" },
60  { 3, "Ack" },
61  { 4, "Nack" },
62  { 0, NULL }
63 };
64 
66 
67 #define UAVTALK_HEADER_SIZE 8
68 #define UAVTALK_TRAILER_SIZE 1
69 static int dissect_op_uavtalk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
70 {
71  gint offset = 0;
72 
73  guint8 packet_type = tvb_get_guint8(tvb, 1) & 0x7;
74  guint32 objid = tvb_get_letohl(tvb, 4);
75  guint32 payload_length = tvb_get_letohs(tvb, 2) - UAVTALK_HEADER_SIZE - UAVTALK_TRAILER_SIZE;
76  guint32 reported_length = tvb_reported_length(tvb);
77 
78  col_set_str(pinfo->cinfo, COL_PROTOCOL, "UAVTALK");
79  /* Clear out stuff in the info column */
80  col_clear(pinfo->cinfo, COL_INFO);
81 
82  col_append_fstr(pinfo->cinfo, COL_INFO, "%s: 0x%08x", val_to_str_const(packet_type, uavtalk_packet_types, ""), objid);
83  if (objid & 0x1) {
84  col_append_str(pinfo->cinfo, COL_INFO, "(META)");
85  }
86 
87 
88  if (tree) { /* we are being asked for details */
89  proto_tree *op_uavtalk_tree = NULL;
90  ptvcursor_t * cursor;
91  proto_item *ti = NULL;
92 
93  /* Add a top-level entry to the dissector tree for this protocol */
94  ti = proto_tree_add_item(tree, proto_op_uavtalk, tvb, 0, -1, ENC_NA);
95 
96  /* Create a subtree to contain the dissection of this protocol */
97  op_uavtalk_tree = proto_item_add_subtree(ti, ett_op_uavtalk);
98 
99  /* Dissect the packet and populate the subtree */
100  cursor = ptvcursor_new(op_uavtalk_tree, tvb, 0);
101 
102  /* Populate the fields in this protocol */
103  ptvcursor_add(cursor, hf_op_uavtalk_sync, 1, ENC_LITTLE_ENDIAN);
104  ptvcursor_add_no_advance(cursor, hf_op_uavtalk_version, 1, ENC_LITTLE_ENDIAN);
105  ptvcursor_add(cursor, hf_op_uavtalk_type, 1, ENC_LITTLE_ENDIAN);
106  ptvcursor_add(cursor, hf_op_uavtalk_len, 2, ENC_LITTLE_ENDIAN);
107  ptvcursor_add(cursor, hf_op_uavtalk_objid, 4, ENC_LITTLE_ENDIAN);
108 
109  offset = ptvcursor_current_offset(cursor);
110 
111  ptvcursor_free(cursor);
112 
113  proto_tree_add_item(op_uavtalk_tree, hf_op_uavtalk_crc8, tvb, reported_length - UAVTALK_TRAILER_SIZE, UAVTALK_TRAILER_SIZE, ENC_LITTLE_ENDIAN);
114  } else {
115  offset = UAVTALK_HEADER_SIZE;
116  }
117 
118  {
119  tvbuff_t * next_tvb = tvb_new_subset(tvb, offset,
120  reported_length - UAVTALK_HEADER_SIZE - UAVTALK_TRAILER_SIZE,
121  payload_length);
122 
123  /* Check if we have an embedded objid to decode */
124  if ((packet_type == 0) || (packet_type == 2)) {
125  /* Call any registered subdissector for this objid */
126  if (!dissector_try_uint(uavtalk_subdissector_table, objid, next_tvb, pinfo, tree)) {
127  /* No subdissector registered, use the default data dissector */
128  call_dissector(data_handle, next_tvb, pinfo, tree);
129  }
130  } else {
131  /* Render any remaining data as raw bytes */
132  call_dissector(data_handle, next_tvb, pinfo, tree);
133  }
134  }
135 
136  return UAVTALK_HEADER_SIZE + UAVTALK_TRAILER_SIZE;
137 }
138 
140 {
141  module_t * op_uavtalk_module;
142 
143  static hf_register_info hf[] = {
144  { &hf_op_uavtalk_sync,
145  { "Sync Byte", "uavtalk.sync", FT_UINT8,
146  BASE_HEX, NULL, 0x0, NULL, HFILL }
147  },
148  { &hf_op_uavtalk_version,
149  { "Version", "uavtalk.ver", FT_UINT8,
150  BASE_DEC, NULL, 0xf8, NULL, HFILL }
151  },
152  { &hf_op_uavtalk_type,
153  { "Type", "uavtalk.type", FT_UINT8,
154  BASE_HEX, VALS(uavtalk_packet_types), 0x07, NULL, HFILL }
155  },
156  { &hf_op_uavtalk_len,
157  { "Length", "uavtalk.len", FT_UINT16,
158  BASE_DEC, NULL, 0x0, NULL, HFILL }
159  },
160  { &hf_op_uavtalk_objid,
161  { "ObjID", "uavtalk.objid", FT_UINT32,
162  BASE_HEX, NULL, 0x0, NULL, HFILL }
163  },
164  { &hf_op_uavtalk_crc8,
165  { "Crc8", "uavtalk.crc8", FT_UINT8,
166  BASE_HEX, NULL, 0x0, NULL, HFILL }
167  },
168  };
169 
170 /* Setup protocol subtree array */
171 
172  static gint *ett[] = {
173  &ett_op_uavtalk
174  };
175 
176  proto_op_uavtalk = proto_register_protocol("OpenPilot UAVTalk Protocol",
177  "UAVTALK",
178  "uavtalk");
179 
180  /* Allow subdissectors for each objid to bind for decoding */
181  uavtalk_subdissector_table = register_dissector_table("uavtalk.objid", "UAVObject ID", FT_UINT32, BASE_HEX);
182 
183  proto_register_subtree_array(ett, array_length(ett));
184  proto_register_field_array(proto_op_uavtalk, hf, array_length(hf));
185 
186  op_uavtalk_module = prefs_register_protocol(proto_op_uavtalk, proto_reg_handoff_op_uavtalk);
187 
188  prefs_register_uint_preference(op_uavtalk_module, "udp.port", "UAVTALK UDP port",
189  "UAVTALK port (default 9000)", 10, &global_op_uavtalk_port);
190 }
191 
193 {
194  dissector_handle_t op_uavtalk_handle;
195 
196  op_uavtalk_handle = new_create_dissector_handle(dissect_op_uavtalk, proto_op_uavtalk);
197  dissector_add_handle("udp.port", op_uavtalk_handle); /* for "decode as" */
198 
199  if (global_op_uavtalk_port != 0) {
200  dissector_add_uint("udp.port", global_op_uavtalk_port, op_uavtalk_handle);
201  }
202 
203  /* Lookup the default dissector for raw data */
204  data_handle = find_dissector("data");
205 }
void proto_register_op_uavtalk(void)
DataFields data
void proto_reg_handoff_op_uavtalk(void)