aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-adwin.c
diff options
context:
space:
mode:
authorJeff Morriss <jeff.morriss@ulticom.com>2010-10-25 01:43:54 +0000
committerJeff Morriss <jeff.morriss@ulticom.com>2010-10-25 01:43:54 +0000
commit0f93035b154a8da9ff1cd62c030c5259e6fb8238 (patch)
treea2ccce11069dbbfe64aead7bbbbcb227e693fa8a /epan/dissectors/packet-adwin.c
parent8c7c46d0fcef076fd59c01178be6d45f00acf9e9 (diff)
From Thomas Boehne via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5324 :
The company I work for uses two proprietary protocols, for which I initially developed wireshark plugins. Now we would like to integrate them into the public wireshark repository. I followed the READMEs and converted the plugins into a static dissectors. I cleaned up the code until checkAPI.pl was silent, translated all terms to english and ran randpkt and fuzz-testing for a long time. All that I found was a bug in a different dissector. From me: - Fold the header files into the dissectors - Clean up some memory leaks - Strengthen the heuristics of adwin-config (the TCP heuristics are still pretty weak) - Make packet-adwin.c a "new style" dissector - Use find_or_create_conversation() - Remove most of the check_col()'s svn path=/trunk/; revision=34640
Diffstat (limited to 'epan/dissectors/packet-adwin.c')
-rw-r--r--epan/dissectors/packet-adwin.c1449
1 files changed, 1449 insertions, 0 deletions
diff --git a/epan/dissectors/packet-adwin.c b/epan/dissectors/packet-adwin.c
new file mode 100644
index 0000000000..761c28519c
--- /dev/null
+++ b/epan/dissectors/packet-adwin.c
@@ -0,0 +1,1449 @@
+/* packet-adwin.c
+ * Routines for ADwin protocol dissection
+ * Copyright 2010, Thomas Boehne <TBoehne[AT]ADwin.de>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+/* includes needed for wireshark */
+#include <glib.h>
+#include <epan/prefs.h>
+#include <epan/packet.h>
+#include <epan/proto.h>
+#include <epan/conversation.h>
+#include <epan/emem.h>
+
+/* This is registered to a different protocol */
+#define ADWIN_COMM_PORT 6543
+
+/* lengths of valid packet structures */
+#define UDPH1_OLD_LENGTH 52
+#define UDPH1_NEW_LENGTH 56
+#define UDPR1_LENGTH 32
+#define UDPH2_LENGTH 412 /* AFAIK: unused */
+#define UDPR2_LENGTH 1008
+#define UDPR3_LENGTH 1408
+#define UDPR4_LENGTH 1416
+#define GetDataSHPacket_LENGTH 1356
+#define GetDataSHRequest_LENGTH 64
+
+/* operating systems */
+#define OS_WINDOWS 0x00
+#define OS_LINUX 0x10
+#define OS_JAVA 0x20
+#define OS_DOT_NET 0x40
+#define OS_GENERIC 0x80
+static const value_string osys_mapping[] = {
+ { OS_WINDOWS, "Windows"},
+ { OS_LINUX, "Linux"},
+ { OS_JAVA, "Java"},
+ { OS_DOT_NET, ".Net"},
+ { OS_GENERIC, "Generic TCP/IP Driver"},
+ { 0, NULL },
+};
+
+/* error codes */
+#define EC_OK 0
+#define EC_TIMEOUT_TO_LINK 1
+#define EC_TIMEOUT_FROM_LINK 2
+#define EC_TIMEOUT_FAST_TO_LINK 3
+#define EC_TIMEOUT_FAST_FROM_LINK 4
+#define EC_TIMEOUT 5
+#define EC_UDP_TIMEOUT -1
+#define EC_WRONG_PASSWORD -5
+#define EC_TRY_LATER -10
+#define EC_FILE_ERROR -15
+#define EC_PACKET_ERROR -20
+#define EC_PACKET_TOO_LARGE -25
+#define EC_WRONG_SIZE -26
+#define EC_WRONG_VERSION -30
+#define EC_DATA_TOO_SMALL -31
+#define EC_FIFO_NOT_ENOUGH_DATA -32
+#define EC_INVALID_PACKET_ORDER -33
+#define EC_WRONG_BINARY_FILE -35
+#define EC_ALREADY_PROCESSED -40
+#define EC_RETRY_UNKNOWN -41
+#define EC_MEMORY_ERROR -100
+static const value_string error_code_mapping[] = {
+ { EC_OK, "OK"},
+ { EC_TIMEOUT_TO_LINK, "Timeout to link"},
+ { EC_TIMEOUT_FROM_LINK, "Timeout from link"},
+ { EC_TIMEOUT_FAST_TO_LINK, "Timeout fast to link"},
+ { EC_TIMEOUT_FAST_FROM_LINK, "Timeout fast from link"},
+ { EC_TIMEOUT, "Timeout"},
+ { EC_UDP_TIMEOUT, "UDP timeout"},
+ { EC_WRONG_PASSWORD, "Wrong password"},
+ { EC_TRY_LATER, "Try later"},
+ { EC_FILE_ERROR, "File error"},
+ { EC_PACKET_ERROR, "Packet error"},
+ { EC_WRONG_SIZE, "Wrong size"},
+ { EC_WRONG_VERSION, "Wrong version"},
+ { EC_DATA_TOO_SMALL, "Data too small"},
+ { EC_FIFO_NOT_ENOUGH_DATA, "Fifo has not enough data"},
+ { EC_INVALID_PACKET_ORDER, "Invalid Packet order"},
+ { EC_WRONG_BINARY_FILE, "Binary/Processor mismatch"},
+ { EC_ALREADY_PROCESSED, "Already processed"},
+ { EC_RETRY_UNKNOWN, "Retry unknown"},
+ { EC_MEMORY_ERROR, "Memory error"},
+ { 0, NULL },
+};
+
+static const value_string data_type_mapping[] = {
+ { 2, "short / int"},
+ { 3, "int"},
+ { 4, "long"},
+ { 5, "float"},
+ { 6, "double"},
+ { 20, "variant"},
+ { 0, NULL },
+};
+
+#define I_3PLUS1 0
+#define I_LOAD_BIN_FILE 4
+#define I_GET_DATA_TYPE 100
+#define I_GET_DATA 7
+#define I_GET_DATA_SHIFTED_HANDSHAKE 107
+#define I_GET_DATA_SMALL 207
+#define I_SET_DATA 8
+#define I_SET_DATA_LAST_STATUS 108
+#define I_CREATE_DATA 10
+#define I_GET_PAR_ALL 13
+#define I_GET_WORKLOAD 20
+#define I_GET_FIFO 24
+#define I_GET_FIFO_RETRY 124
+#define I_SET_FIFO 25
+#define I_SET_FIFO_RETRY 125
+#define I_BOOT 50
+#define I_GET_ARM_VERSION 1000
+#define I_TEST_VERSION 255
+#define I_GET_MEMORY 1000000
+
+static const value_string instruction_mapping[] = {
+ { I_3PLUS1, "3+1 instruction" },
+ { I_GET_DATA_TYPE, "Get data type" },
+ { I_LOAD_BIN_FILE, "Load binary file" },
+ { I_GET_DATA, "Get data" },
+ { I_GET_DATA_SHIFTED_HANDSHAKE, "Get data (shifted handshake)" },
+ { I_GET_DATA_SMALL, "Get data (small/fast)" },
+ { I_SET_DATA, "Set data" },
+ { I_SET_DATA_LAST_STATUS, "Get status of last set data" },
+ { I_CREATE_DATA, "Create data" },
+ { I_GET_PAR_ALL, "Get all parameters" },
+ { I_GET_FIFO, "Get fifo" },
+ { I_GET_FIFO_RETRY, "Get fifo - retry" },
+ { I_SET_FIFO, "Set fifo" },
+ { I_SET_FIFO_RETRY, "Set fifo - retry" },
+ { I_BOOT, "Boot" },
+ { I_GET_ARM_VERSION, "Get ARM-Version" },
+ { I_TEST_VERSION, "Get/test version information" },
+ { I_GET_WORKLOAD, "Get workload"},
+ { I_GET_MEMORY, "Get memory DSP" },
+ { 0, NULL },
+};
+
+/* 3+1 instructions */
+#define I_3P1_GET_PAR 1
+#define I_3P1_START 2
+#define I_3P1_STOP 3
+#define I_3P1_GET_MEMORY_INFO 5
+#define I_3P1_SET_PAR 6
+#define I_3P1_CLEAR_DATA 9
+#define I_3P1_GET_DATA_LENGTH 11
+#define I_3P1_GET_DETAILED_MEM_INFO 12
+#define I_3P1_CLEAR_PROCESS 14
+#define I_3P1_ADC 15
+#define I_3P1_DAC 16
+#define I_3P1_GET_DIGIN 17
+#define I_3P1_SET_DIGOUT 18
+#define I_3P1_GET_DIGOUT 19
+#define I_3P1_CLEAR_FIFO 21
+#define I_3P1_GET_FIFO_EMPTY 22
+#define I_3P1_GET_FIFO_COUNT 23
+static const value_string instruction_3plus1_mapping[] = {
+ { I_3P1_GET_PAR, "Get parameter"},
+ { I_3P1_START, "Start process"},
+ { I_3P1_STOP, "Stop process"},
+ { I_3P1_SET_PAR, "Set parameter"},
+ { I_3P1_CLEAR_DATA, "Clear data"},
+ { I_3P1_GET_DATA_LENGTH, "Get data length"},
+ { I_3P1_GET_DETAILED_MEM_INFO, "Get detailed memory info"},
+ { I_3P1_CLEAR_PROCESS, "Clear process"},
+ { I_3P1_CLEAR_FIFO, "Clear fifo"},
+ { I_3P1_GET_FIFO_EMPTY, "Get fifo empty"},
+ { I_3P1_GET_FIFO_COUNT, "Get fifo full/count"},
+ { I_3P1_GET_MEMORY_INFO, "Get memory info"},
+ { I_3P1_ADC, "Get ADC value"},
+ { I_3P1_DAC, "Set DAC value"},
+ { I_3P1_GET_DIGIN, "Get digital in"},
+ { I_3P1_SET_DIGOUT, "Set digital out"},
+ { I_3P1_GET_DIGOUT, "Get digital out"},
+ { 0, NULL },
+};
+
+static const value_string parameter_mapping[] = {
+ { 901 , "Status of Process No. 01"},
+ { 902 , "Status of Process No. 02"},
+ { 903 , "Status of Process No. 03"},
+ { 904 , "Status of Process No. 04"},
+ { 905 , "Status of Process No. 05"},
+ { 906 , "Status of Process No. 06"},
+ { 907 , "Status of Process No. 07"},
+ { 908 , "Status of Process No. 08"},
+ { 909 , "Status of Process No. 09"},
+ { 910 , "Status of Process No. 10"},
+ { 911 , "GlobalDelay for Process No. 01"},
+ { 912 , "GlobalDelay for Process No. 02"},
+ { 913 , "GlobalDelay for Process No. 03"},
+ { 914 , "GlobalDelay for Process No. 04"},
+ { 915 , "GlobalDelay for Process No. 05"},
+ { 916 , "GlobalDelay for Process No. 06"},
+ { 917 , "GlobalDelay for Process No. 07"},
+ { 918 , "GlobalDelay for Process No. 08"},
+ { 919 , "GlobalDelay for Process No. 09"},
+ { 920 , "GlobalDelay for Process No. 10"},
+ { 921 , "GlobalDelay for Process No. 11"},
+ { 922 , "GlobalDelay for Process No. 12"},
+ { 923 , "GlobalDelay for Process No. 13"},
+ { 924 , "GlobalDelay for Process No. 14"},
+ { 925 , "GlobalDelay for Process No. 15"},
+ { 926 , "GlobalDelay for Process No. 16"},
+ { 951 , "Debug Information of Process No. 01"},
+ { 952 , "Debug Information of Process No. 02"},
+ { 953 , "Debug Information of Process No. 03"},
+ { 954 , "Debug Information of Process No. 04"},
+ { 955 , "Debug Information of Process No. 05"},
+ { 956 , "Debug Information of Process No. 06"},
+ { 957 , "Debug Information of Process No. 07"},
+ { 958 , "Debug Information of Process No. 08"},
+ { 959 , "Debug Information of Process No. 09"},
+ { 960 , "Debug Information of Process No. 10"},
+ { 961 , "Debug Information of Process No. 11"},
+ { 962 , "Debug Information of Process No. 12"},
+ { 963 , "Debug Information of Process No. 13"},
+ { 964 , "Debug Information of Process No. 14"},
+ { 965 , "Debug Information of Process No. 15"},
+ { 966 , "Debug Information of Process No. 16"},
+ { 1001 , "Parameter No. 01"},
+ { 1002 , "Parameter No. 02"},
+ { 1003 , "Parameter No. 03"},
+ { 1004 , "Parameter No. 04"},
+ { 1005 , "Parameter No. 05"},
+ { 1006 , "Parameter No. 06"},
+ { 1007 , "Parameter No. 07"},
+ { 1008 , "Parameter No. 08"},
+ { 1009 , "Parameter No. 09"},
+ { 1010 , "Parameter No. 10"},
+ { 1011 , "Parameter No. 11"},
+ { 1012 , "Parameter No. 12"},
+ { 1013 , "Parameter No. 13"},
+ { 1014 , "Parameter No. 14"},
+ { 1015 , "Parameter No. 15"},
+ { 1016 , "Parameter No. 16"},
+ { 1017 , "Parameter No. 17"},
+ { 1018 , "Parameter No. 18"},
+ { 1019 , "Parameter No. 19"},
+ { 1020 , "Parameter No. 20"},
+ { 1021 , "Parameter No. 21"},
+ { 1022 , "Parameter No. 22"},
+ { 1023 , "Parameter No. 23"},
+ { 1024 , "Parameter No. 24"},
+ { 1025 , "Parameter No. 25"},
+ { 1026 , "Parameter No. 26"},
+ { 1027 , "Parameter No. 27"},
+ { 1028 , "Parameter No. 28"},
+ { 1029 , "Parameter No. 29"},
+ { 1030 , "Parameter No. 30"},
+ { 1031 , "Parameter No. 31"},
+ { 1032 , "Parameter No. 32"},
+ { 1033 , "Parameter No. 33"},
+ { 1034 , "Parameter No. 34"},
+ { 1035 , "Parameter No. 35"},
+ { 1036 , "Parameter No. 36"},
+ { 1037 , "Parameter No. 37"},
+ { 1038 , "Parameter No. 38"},
+ { 1039 , "Parameter No. 39"},
+ { 1040 , "Parameter No. 40"},
+ { 1041 , "Parameter No. 41"},
+ { 1042 , "Parameter No. 42"},
+ { 1043 , "Parameter No. 43"},
+ { 1044 , "Parameter No. 44"},
+ { 1045 , "Parameter No. 45"},
+ { 1046 , "Parameter No. 46"},
+ { 1047 , "Parameter No. 47"},
+ { 1048 , "Parameter No. 48"},
+ { 1049 , "Parameter No. 49"},
+ { 1050 , "Parameter No. 50"},
+ { 1051 , "Parameter No. 51"},
+ { 1052 , "Parameter No. 52"},
+ { 1053 , "Parameter No. 53"},
+ { 1054 , "Parameter No. 54"},
+ { 1055 , "Parameter No. 55"},
+ { 1056 , "Parameter No. 56"},
+ { 1057 , "Parameter No. 57"},
+ { 1058 , "Parameter No. 58"},
+ { 1059 , "Parameter No. 59"},
+ { 1060 , "Parameter No. 60"},
+ { 1061 , "Parameter No. 61"},
+ { 1062 , "Parameter No. 62"},
+ { 1063 , "Parameter No. 63"},
+ { 1064 , "Parameter No. 64"},
+ { 1065 , "Parameter No. 65"},
+ { 1066 , "Parameter No. 66"},
+ { 1067 , "Parameter No. 67"},
+ { 1068 , "Parameter No. 68"},
+ { 1069 , "Parameter No. 69"},
+ { 1070 , "Parameter No. 70"},
+ { 1071 , "Parameter No. 71"},
+ { 1072 , "Parameter No. 72"},
+ { 1073 , "Parameter No. 73"},
+ { 1074 , "Parameter No. 74"},
+ { 1075 , "Parameter No. 75"},
+ { 1076 , "Parameter No. 76"},
+ { 1077 , "Parameter No. 77"},
+ { 1078 , "Parameter No. 78"},
+ { 1079 , "Parameter No. 79"},
+ { 1080 , "Parameter No. 80"},
+ { 1101 , "Float-Parameter No. 01"},
+ { 1102 , "Float-Parameter No. 02"},
+ { 1103 , "Float-Parameter No. 03"},
+ { 1104 , "Float-Parameter No. 04"},
+ { 1105 , "Float-Parameter No. 05"},
+ { 1106 , "Float-Parameter No. 06"},
+ { 1107 , "Float-Parameter No. 07"},
+ { 1108 , "Float-Parameter No. 08"},
+ { 1109 , "Float-Parameter No. 09"},
+ { 1110 , "Float-Parameter No. 10"},
+ { 1111 , "Float-Parameter No. 11"},
+ { 1112 , "Float-Parameter No. 12"},
+ { 1113 , "Float-Parameter No. 13"},
+ { 1114 , "Float-Parameter No. 14"},
+ { 1115 , "Float-Parameter No. 15"},
+ { 1116 , "Float-Parameter No. 16"},
+ { 1117 , "Float-Parameter No. 17"},
+ { 1118 , "Float-Parameter No. 18"},
+ { 1119 , "Float-Parameter No. 19"},
+ { 1120 , "Float-Parameter No. 20"},
+ { 1121 , "Float-Parameter No. 21"},
+ { 1122 , "Float-Parameter No. 22"},
+ { 1123 , "Float-Parameter No. 23"},
+ { 1124 , "Float-Parameter No. 24"},
+ { 1125 , "Float-Parameter No. 25"},
+ { 1126 , "Float-Parameter No. 26"},
+ { 1127 , "Float-Parameter No. 27"},
+ { 1128 , "Float-Parameter No. 28"},
+ { 1129 , "Float-Parameter No. 29"},
+ { 1130 , "Float-Parameter No. 30"},
+ { 1131 , "Float-Parameter No. 31"},
+ { 1132 , "Float-Parameter No. 32"},
+ { 1133 , "Float-Parameter No. 33"},
+ { 1134 , "Float-Parameter No. 34"},
+ { 1135 , "Float-Parameter No. 35"},
+ { 1136 , "Float-Parameter No. 36"},
+ { 1137 , "Float-Parameter No. 37"},
+ { 1138 , "Float-Parameter No. 38"},
+ { 1139 , "Float-Parameter No. 39"},
+ { 1140 , "Float-Parameter No. 40"},
+ { 1141 , "Float-Parameter No. 41"},
+ { 1142 , "Float-Parameter No. 42"},
+ { 1143 , "Float-Parameter No. 43"},
+ { 1144 , "Float-Parameter No. 44"},
+ { 1145 , "Float-Parameter No. 45"},
+ { 1146 , "Float-Parameter No. 46"},
+ { 1147 , "Float-Parameter No. 47"},
+ { 1148 , "Float-Parameter No. 48"},
+ { 1149 , "Float-Parameter No. 49"},
+ { 1150 , "Float-Parameter No. 50"},
+ { 1151 , "Float-Parameter No. 51"},
+ { 1152 , "Float-Parameter No. 52"},
+ { 1153 , "Float-Parameter No. 53"},
+ { 1154 , "Float-Parameter No. 54"},
+ { 1155 , "Float-Parameter No. 55"},
+ { 1156 , "Float-Parameter No. 56"},
+ { 1157 , "Float-Parameter No. 57"},
+ { 1158 , "Float-Parameter No. 58"},
+ { 1159 , "Float-Parameter No. 59"},
+ { 1160 , "Float-Parameter No. 60"},
+ { 1161 , "Float-Parameter No. 61"},
+ { 1162 , "Float-Parameter No. 62"},
+ { 1163 , "Float-Parameter No. 63"},
+ { 1164 , "Float-Parameter No. 64"},
+ { 1165 , "Float-Parameter No. 65"},
+ { 1166 , "Float-Parameter No. 66"},
+ { 1167 , "Float-Parameter No. 67"},
+ { 1168 , "Float-Parameter No. 68"},
+ { 1169 , "Float-Parameter No. 69"},
+ { 1170 , "Float-Parameter No. 70"},
+ { 1171 , "Float-Parameter No. 71"},
+ { 1172 , "Float-Parameter No. 72"},
+ { 1173 , "Float-Parameter No. 73"},
+ { 1174 , "Float-Parameter No. 74"},
+ { 1175 , "Float-Parameter No. 75"},
+ { 1176 , "Float-Parameter No. 76"},
+ { 1177 , "Float-Parameter No. 77"},
+ { 1178 , "Float-Parameter No. 78"},
+ { 1179 , "Float-Parameter No. 79"},
+ { 1180 , "Float-Parameter No. 80"},
+ { 4891 , "Status of Process No. 11"},
+ { 4892 , "Status of Process No. 12"},
+ { 4893 , "Status of Process No. 13"},
+ { 4894 , "Status of Process No. 14"},
+ { 4895 , "Status of Process No. 15"},
+ { 4896 , "Status of Process No. 16"},
+ {10000 , "Start Timing Analyzer"},
+ {10001 , "Stop Timing Analyzer"},
+ { 0, NULL },
+};
+
+typedef enum {
+ APT_UDPH1_old, APT_UDPH1_new, APT_UDPR1, APT_UDPR2, APT_UDPR3,
+ APT_UDPR4, APT_GDSHP, APT_GDSHR
+} adwin_packet_types_t;
+
+static const value_string packet_type_mapping[] = {
+ { APT_UDPH1_old, "UDPH1 old"},
+ { APT_UDPH1_new, "UDPH1 new"},
+ { APT_UDPR1, "UDPR1"},
+ { APT_UDPR2, "UDPR2"},
+ { APT_UDPR3, "UDPR3"},
+ { APT_UDPR4, "UDPR4"},
+ { APT_GDSHP, "GDSHP"},
+ { APT_GDSHR, "GDSHR"},
+ { 0, NULL },
+};
+
+/* add little endian number (incorrect network byte-order) value to a tree */
+#define ADWIN_ADD_LE(tree, field, offset, length) \
+ proto_tree_add_item(tree, hf_adwin_##field, tvb, offset, \
+ length, TRUE);
+
+/* add big endian number (correct network byte-order) value to a tree */
+#define ADWIN_ADD_BE(tree, field, offset, length) \
+ proto_tree_add_item(tree, hf_adwin_##field, tvb, offset, \
+ length, FALSE);
+
+#define SET_PACKET_TYPE(tree, type) \
+ proto_tree_add_int(tree, hf_adwin_packet_type, tvb, 0, tvb_length(tvb), type);
+
+
+/* Initialize the protocol and registered fields */
+static int proto_adwin = -1;
+
+static unsigned int global_adwin_udp_port = ADWIN_COMM_PORT;
+static unsigned int udp_port = 0;
+static int global_adwin_dissect_data = 1;
+
+static int hf_adwin_address = -1;
+static int hf_adwin_armVersion = -1;
+static int hf_adwin_binfilesize = -1;
+static int hf_adwin_blocksize = -1;
+static int hf_adwin_count = -1;
+static int hf_adwin_complete_packets = -1;
+static int hf_adwin_data_int = -1;
+static int hf_adwin_data_float = -1;
+static int hf_adwin_data_hex = -1;
+static int hf_adwin_data_no16 = -1;
+static int hf_adwin_data_no32 = -1;
+static int hf_adwin_data_packet_index = -1;
+static int hf_adwin_data_type = -1;
+static int hf_adwin_dll_version = -1;
+static int hf_adwin_fifo_no16 = -1;
+static int hf_adwin_fifo_no32 = -1;
+static int hf_adwin_instruction = -1;
+static int hf_adwin_is_range = -1;
+static int hf_adwin_i3plus1 = -1;
+static int hf_adwin_link_addr = -1;
+static int hf_adwin_mem_type = -1;
+static int hf_adwin_memsize = -1;
+static int hf_adwin_osys = -1;
+static int hf_adwin_packet_index = -1;
+static int hf_adwin_packet_no = -1;
+static int hf_adwin_packet_start = -1;
+static int hf_adwin_packet_end = -1;
+static int hf_adwin_packet_type = -1;
+static int hf_adwin_parameter = -1;
+static int hf_adwin_password = -1;
+static int hf_adwin_process_no = -1;
+static int hf_adwin_processor = -1;
+static int hf_adwin_response_in = -1;
+static int hf_adwin_response_to = -1;
+static int hf_adwin_response_time = -1;
+static int hf_adwin_retry_packet_index= -1;
+static int hf_adwin_request_no = -1;
+static int hf_adwin_start_index = -1;
+static int hf_adwin_status = -1;
+static int hf_adwin_timeout = -1;
+static int hf_adwin_unused = -1;
+static int hf_adwin_val1 = -1;
+static int hf_adwin_val1f = -1;
+static int hf_adwin_val2 = -1;
+static int hf_adwin_val3 = -1;
+static int hf_adwin_val4 = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_adwin = -1;
+static gint ett_adwin_debug = -1;
+
+/* response/request tracking */
+typedef struct _adwin_transaction_t {
+ guint32 req_frame;
+ guint32 rep_frame;
+ nstime_t req_time;
+} adwin_transaction_t;
+
+/* response/request tracking */
+typedef struct _adwin_conv_info_t {
+ emem_tree_t *pdus;
+} adwin_conv_info_t;
+
+typedef enum { ADWIN_REQUEST,
+ ADWIN_RESPONSE
+} adwin_direction_t;
+
+static void
+adwin_request_response_handling(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *adwin_tree, guint32 seq_num, adwin_direction_t direction)
+{
+ conversation_t *conversation;
+ adwin_conv_info_t *adwin_info;
+ adwin_transaction_t *adwin_trans;
+
+ /*
+ * Find or create a conversation for this connection.
+ */
+ conversation = find_or_create_conversation(pinfo);
+
+ /*
+ * Do we already have a state structure for this conv
+ */
+ adwin_info = conversation_get_proto_data(conversation, proto_adwin);
+ if (!adwin_info) {
+ /*
+ * No. Attach that information to the conversation, and add
+ * it to the list of information structures.
+ */
+ adwin_info = se_alloc(sizeof(adwin_conv_info_t));
+ adwin_info->pdus = se_tree_create_non_persistent(
+ EMEM_TREE_TYPE_RED_BLACK, "adwin_pdus");
+
+ conversation_add_proto_data(conversation, proto_adwin, adwin_info);
+ }
+ if (!pinfo->fd->flags.visited) {
+ if (direction == ADWIN_REQUEST) {
+ /* This is a request */
+ adwin_trans = se_alloc(sizeof(adwin_transaction_t));
+ adwin_trans->req_frame = pinfo->fd->num;
+ adwin_trans->rep_frame = 0;
+ adwin_trans->req_time = pinfo->fd->abs_ts;
+ se_tree_insert32(adwin_info->pdus, seq_num, (void *)adwin_trans);
+ } else {
+ adwin_trans = se_tree_lookup32(adwin_info->pdus, seq_num);
+ if (adwin_trans) {
+ adwin_trans->rep_frame = pinfo->fd->num;
+ }
+ }
+ } else {
+ adwin_trans = se_tree_lookup32(adwin_info->pdus, seq_num);
+ }
+ if (!adwin_trans) {
+ /* create a "fake" adwin_trans structure */
+ adwin_trans = ep_alloc(sizeof(adwin_transaction_t));
+ adwin_trans->req_frame = 0;
+ adwin_trans->rep_frame = 0;
+ adwin_trans->req_time = pinfo->fd->abs_ts;
+ }
+
+ /* print state tracking in the tree */
+ if (direction == ADWIN_REQUEST) {
+ /* This is a request */
+ if (adwin_trans->rep_frame) {
+ proto_item *it;
+
+ it = proto_tree_add_uint(adwin_tree, hf_adwin_response_in,
+ tvb, 0, 0, adwin_trans->rep_frame);
+ PROTO_ITEM_SET_GENERATED(it);
+ }
+ } else {
+ /* This is a reply */
+ if (adwin_trans->req_frame) {
+ proto_item *it;
+ nstime_t ns;
+
+ it = proto_tree_add_uint(adwin_tree, hf_adwin_response_to,
+ tvb, 0, 0, adwin_trans->req_frame);
+ PROTO_ITEM_SET_GENERATED(it);
+
+ nstime_delta(&ns, &pinfo->fd->abs_ts, &adwin_trans->req_time);
+ it = proto_tree_add_time(adwin_tree, hf_adwin_response_time, tvb, 0, 0, &ns);
+ PROTO_ITEM_SET_GENERATED(it);
+ }
+ }
+}
+
+static void
+dissect_UDPH1_generic(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *adwin_tree, proto_tree *adwin_debug_tree, gchar** info_string, gchar* packet_name)
+{
+ guint32 i3plus1code = 0, instructionID, seq_num;
+
+ instructionID = tvb_get_letohl(tvb, 0);
+ *info_string = ep_strdup_printf("%s: %s", packet_name,
+ val_to_str(instructionID, instruction_mapping, "unknown instruction: %d"));
+
+ if (instructionID == I_3PLUS1) {
+ gchar *tmp = *info_string;
+
+ i3plus1code = tvb_get_letohl(tvb, 20);
+ *info_string = ep_strdup_printf("%s: %s", tmp, val_to_str(i3plus1code, instruction_3plus1_mapping, "unknown 3+1 code: %d"));
+ }
+
+ /* Get the transaction identifier */
+ seq_num = tvb_get_letohl(tvb, 4);
+ adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_REQUEST);
+
+ if (! adwin_tree)
+ return;
+
+ SET_PACKET_TYPE(adwin_tree, APT_UDPH1_old);
+
+ ADWIN_ADD_LE(adwin_tree, instruction, 0, 4);
+ ADWIN_ADD_LE(adwin_tree, packet_index, 4, 4);
+ ADWIN_ADD_BE(adwin_tree, password, 8, 10);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 18, 2);
+
+ switch(instructionID) {
+ case I_3PLUS1:
+ ADWIN_ADD_LE(adwin_tree, i3plus1, 20, 4);
+ switch (i3plus1code) {
+ case I_3P1_SET_PAR:
+ ADWIN_ADD_LE(adwin_tree, parameter, 24, 4);
+ ADWIN_ADD_LE(adwin_tree, val1, 28, 4);
+ ADWIN_ADD_LE(adwin_tree, val1f, 28, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 32, 4);
+ break;
+ case I_3P1_GET_PAR:
+ ADWIN_ADD_LE(adwin_tree, parameter, 24, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 28, 8);
+ break;
+ case I_3P1_GET_MEMORY_INFO:
+ case I_3P1_GET_DETAILED_MEM_INFO:
+ ADWIN_ADD_LE(adwin_tree, mem_type, 24, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 28, 8);
+ break;
+ case I_3P1_START:
+ case I_3P1_STOP:
+ case I_3P1_CLEAR_PROCESS:
+ ADWIN_ADD_LE(adwin_tree, process_no, 24, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 28, 8);
+ break;
+ case I_3P1_GET_DATA_LENGTH:
+ ADWIN_ADD_LE(adwin_tree, data_no32, 24, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 28, 8);
+ break;
+ case I_3P1_CLEAR_FIFO:
+ case I_3P1_GET_FIFO_EMPTY:
+ case I_3P1_GET_FIFO_COUNT:
+ ADWIN_ADD_LE(adwin_tree, fifo_no32, 24, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 28, 8);
+ break;
+ default: ; /* should not happen */
+ /* illegal values should be displayed properly
+ by 3plus1_mapping */
+ }
+ break;
+ case I_BOOT:
+ ADWIN_ADD_LE(adwin_tree, memsize, 20, 4);
+ ADWIN_ADD_LE(adwin_tree, blocksize, 24, 2);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 26, 2);
+ ADWIN_ADD_LE(adwin_tree, processor, 28, 4);
+ ADWIN_ADD_LE(adwin_tree, binfilesize, 32, 4);
+ break;
+ case I_LOAD_BIN_FILE:
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 20, 6);
+ ADWIN_ADD_LE(adwin_tree, blocksize, 26, 2);
+ ADWIN_ADD_LE(adwin_tree, processor, 28, 4);
+ ADWIN_ADD_LE(adwin_tree, binfilesize, 32, 4);
+ break;
+ case I_GET_WORKLOAD:
+ ADWIN_ADD_LE(adwin_tree, instruction, 20, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 24, 12);
+ break;
+ case I_GET_DATA_TYPE:
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 20, 4);
+ ADWIN_ADD_LE(adwin_tree, data_no32, 24, 4);
+ ADWIN_ADD_LE(adwin_tree, start_index, 28, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 32, 4);
+ break;
+ case I_GET_DATA:
+ case I_SET_DATA:
+ ADWIN_ADD_LE(adwin_tree, data_type, 20, 4);
+ ADWIN_ADD_LE(adwin_tree, data_no16, 24, 2);
+ ADWIN_ADD_LE(adwin_tree, blocksize, 26, 2);
+ ADWIN_ADD_LE(adwin_tree, start_index, 28, 4);
+ ADWIN_ADD_LE(adwin_tree, count, 32, 4);
+ break;
+ case I_GET_DATA_SHIFTED_HANDSHAKE:
+ ADWIN_ADD_BE(adwin_tree, data_no16, 20, 2);
+ ADWIN_ADD_BE(adwin_tree, blocksize, 22, 2);
+ ADWIN_ADD_BE(adwin_tree, start_index, 24, 4);
+ ADWIN_ADD_BE(adwin_tree, count, 28, 4);
+ ADWIN_ADD_BE(adwin_debug_tree, unused, 32, 4);
+ break;
+ case I_GET_DATA_SMALL:
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 20, 4);
+ ADWIN_ADD_LE(adwin_tree, data_no16, 24, 2);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 26, 2);
+ ADWIN_ADD_LE(adwin_tree, start_index, 28, 4);
+ ADWIN_ADD_LE(adwin_tree, count, 32, 4);
+ break;
+ case I_GET_PAR_ALL:
+ ADWIN_ADD_LE(adwin_tree, start_index, 20, 4);
+ ADWIN_ADD_LE(adwin_tree, count, 24, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 28, 8);
+ break;
+ case I_SET_DATA_LAST_STATUS:
+ ADWIN_ADD_LE(adwin_tree, data_packet_index, 20, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 24, 12);
+ break;
+ case I_GET_ARM_VERSION:
+ ADWIN_ADD_LE(adwin_tree, armVersion, 20, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, unused,24, 12);
+ break;
+ case I_GET_FIFO:
+ case I_SET_FIFO:
+ ADWIN_ADD_LE(adwin_tree, data_type, 20, 4);
+ ADWIN_ADD_LE(adwin_tree, fifo_no16, 24, 2);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 26, 6);
+ ADWIN_ADD_LE(adwin_tree, count, 32, 4);
+ break;
+ case I_GET_FIFO_RETRY:
+ case I_SET_FIFO_RETRY:
+ ADWIN_ADD_LE(adwin_tree, data_type, 20, 4);
+ ADWIN_ADD_LE(adwin_tree, fifo_no16, 24, 2);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 26, 2);
+ ADWIN_ADD_LE(adwin_tree, retry_packet_index, 28, 4);
+ ADWIN_ADD_LE(adwin_tree, count, 32, 4);
+ break;
+ case I_TEST_VERSION:
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 20, 16);
+ break;
+ case I_GET_MEMORY:
+ ADWIN_ADD_LE(adwin_tree, address, 20, 4);
+ ADWIN_ADD_LE(adwin_tree, count, 24, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 28, 8);
+ break;
+ default: ; /* should not happen */
+ /* illegal values should be displayed properly by
+ instruction_mapping */
+ }
+
+ ADWIN_ADD_LE(adwin_debug_tree, link_addr,36, 4);
+ ADWIN_ADD_LE(adwin_tree, timeout, 40, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, osys, 44, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 48, 4);
+
+}
+
+
+static void
+dissect_UDPH1_old(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *adwin_tree, proto_tree *adwin_debug_tree, gchar** info_string)
+{
+ dissect_UDPH1_generic(tvb, pinfo, adwin_tree, adwin_debug_tree, info_string, "UDPH1 (old)");
+}
+
+static void
+dissect_UDPH1_new(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *adwin_tree, proto_tree *adwin_debug_tree,
+ gchar** info_string)
+{
+ gchar* dll_version_s;
+ gint32 dll_i;
+
+ dissect_UDPH1_generic(tvb, pinfo, adwin_tree, adwin_debug_tree, info_string, "UDPH1 (new)");
+
+ if (! adwin_tree)
+ return;
+
+ SET_PACKET_TYPE(adwin_tree, APT_UDPH1_new);
+ dll_i = tvb_get_letohl(tvb, 52);
+ dll_version_s = ep_strdup_printf("%d.%d.%d",
+ dll_i / 1000000,
+ (dll_i - dll_i / 1000000 * 1000000) / 1000,
+ dll_i % 1000);
+
+ proto_tree_add_string(adwin_debug_tree, hf_adwin_dll_version,
+ tvb, 52, 4, dll_version_s);
+}
+
+static void
+dissect_UDPR1(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *adwin_tree, proto_tree *adwin_debug_tree,
+ gchar** info_string)
+{
+ const gchar *status_string;
+ guint32 seq_num, status;
+
+ status = tvb_get_letohl(tvb, 0);
+ status_string = match_strval(status, error_code_mapping);
+ if (status_string) {
+ *info_string = ep_strdup_printf("UDPR1 Status: %s", status_string);
+ } else {
+ *info_string = ep_strdup_printf("UDPR1 Undefined error code %d", status);
+ }
+
+ /* Get the transaction identifier */
+ seq_num = tvb_get_letohl(tvb, 4);
+ adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE);
+
+ if (! adwin_tree)
+ return;
+
+ SET_PACKET_TYPE(adwin_tree, APT_UDPR1);
+ ADWIN_ADD_LE(adwin_tree, status, 0, 4);
+ ADWIN_ADD_LE(adwin_tree, packet_index, 4, 4);
+ ADWIN_ADD_LE(adwin_tree, val1, 8, 4);
+ ADWIN_ADD_LE(adwin_tree, val1f, 8, 4);
+ ADWIN_ADD_LE(adwin_tree, val2, 12, 4);
+ ADWIN_ADD_LE(adwin_tree, val3, 16, 4);
+ ADWIN_ADD_LE(adwin_tree, val4, 20, 4);
+ ADWIN_ADD_LE(adwin_debug_tree, unused, 24, 8);
+}
+
+static void
+dissect_UDPR2(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *adwin_tree, proto_tree *adwin_debug_tree,
+ gchar** info_string)
+{
+ const gchar *status_string;
+ guint32 i, status, seq_num;
+
+ status = tvb_get_letohl(tvb, 0);
+ status_string = match_strval(status, error_code_mapping);
+ if (status_string) {
+ *info_string = ep_strdup_printf("UDPR2 Status: %s", status_string);
+ } else {
+ *info_string = ep_strdup_printf("UDPR2 Undefined error code %d", status);
+ }
+
+ /* Get the transaction identifier */
+ seq_num = tvb_get_letohl(tvb, 4);
+ adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE);
+
+ if (! adwin_tree)
+ return;
+
+ SET_PACKET_TYPE(adwin_tree, APT_UDPR2);
+ ADWIN_ADD_LE(adwin_tree, status, 0, 4);
+ ADWIN_ADD_LE(adwin_tree, packet_index, 4, 4);
+
+ if (! global_adwin_dissect_data) {
+ proto_tree_add_text(adwin_debug_tree, tvb, 8, 250 * 4, "Data");
+ return;
+ }
+
+ for (i = 0; i < 250; i++) {
+ proto_item *item;
+ guint32 offset = 8 + i * sizeof(guint32);
+ gint32 value = tvb_get_letohl(tvb, offset);
+ void * fvalue = &value;
+ proto_tree_add_text(adwin_debug_tree, tvb, offset, 4,
+ "Data[%3d]: %10d - %10f - 0x%08x",
+ i, value, *(float*)fvalue, value);
+ item = ADWIN_ADD_LE(adwin_debug_tree, data_int, offset, 4);
+ PROTO_ITEM_SET_HIDDEN(item);
+ item = ADWIN_ADD_LE(adwin_debug_tree, data_float, offset, 4);
+ PROTO_ITEM_SET_HIDDEN(item);
+ item = ADWIN_ADD_LE(adwin_debug_tree, data_hex, offset, 4);
+ PROTO_ITEM_SET_HIDDEN(item);
+ }
+}
+
+static void
+dissect_UDPR3(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *adwin_tree, proto_tree *adwin_debug_tree)
+{
+ guint32 i, seq_num;
+
+ /* Get the transaction identifier */
+ seq_num = tvb_get_letohl(tvb, 0);
+ adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE);
+
+ if (! adwin_tree)
+ return;
+
+ SET_PACKET_TYPE(adwin_tree, APT_UDPR3);
+ ADWIN_ADD_LE(adwin_tree, packet_index, 0, 4);
+ ADWIN_ADD_LE(adwin_tree, packet_no, 4, 4);
+
+ if (! global_adwin_dissect_data) {
+ proto_tree_add_text(adwin_debug_tree, tvb, 8, 350 * 4, "Data");
+ return;
+ }
+
+ for (i = 0; i < 350; i++) {
+ proto_item *item;
+ guint32 offset = 8 + i * sizeof(guint32);
+ gint32 value = tvb_get_letohl(tvb, offset);
+ void * fvalue = &value;
+ proto_tree_add_text(adwin_debug_tree, tvb, offset, 4,
+ "Data[%3d]: %10d - %10f - 0x%08x",
+ i, value, *(float*)fvalue, value);
+ item = ADWIN_ADD_LE(adwin_debug_tree, data_int, offset, 4);
+ PROTO_ITEM_SET_HIDDEN(item);
+ item = ADWIN_ADD_LE(adwin_debug_tree, data_float, offset, 4);
+ PROTO_ITEM_SET_HIDDEN(item);
+ item = ADWIN_ADD_LE(adwin_debug_tree, data_hex, offset, 4);
+ PROTO_ITEM_SET_HIDDEN(item);
+ }
+}
+
+static void
+dissect_UDPR4(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *adwin_tree, proto_tree *adwin_debug_tree, gchar** info_string)
+{
+ const gchar *status_string;
+ guint32 data_type, i, status, seq_num;
+
+ status = tvb_get_letohl(tvb, 0);
+ status_string = match_strval(status, error_code_mapping);
+ if (status_string) {
+ *info_string = ep_strdup_printf("UDPR4 Status: %s", status_string);
+ } else {
+ *info_string = ep_strdup_printf("UDPR4 Undefined error code %d", status);
+ }
+
+ /* Get the transaction identifier */
+ seq_num = tvb_get_letohl(tvb, 4);
+ adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE);
+
+ if (! adwin_tree)
+ return;
+
+ SET_PACKET_TYPE(adwin_tree, APT_UDPR4);
+ ADWIN_ADD_LE(adwin_tree, status, 0, 4);
+ ADWIN_ADD_LE(adwin_tree, packet_index, 4, 4);
+ ADWIN_ADD_LE(adwin_tree, packet_no, 1408, 4);
+ ADWIN_ADD_LE(adwin_tree, data_type, 1412, 4);
+
+ data_type = tvb_get_letohl(tvb, 1412);
+
+ if (! global_adwin_dissect_data) {
+ proto_tree_add_text(adwin_debug_tree, tvb, 8, 350 * 4, "Data");
+ return;
+ }
+
+ for (i = 0; i < 350; i++) {
+ proto_item *item;
+ guint32 offset = 8 + i * sizeof(guint32);
+ gint32 value = tvb_get_letohl(tvb, offset);
+ void * fvalue = &value;
+ switch (data_type) {
+ case 2:
+ case 3:
+ case 4: /* some kind of int, usually int/long */
+ proto_tree_add_text(adwin_debug_tree, tvb, offset, 4,
+ "Data[%3d]: %10d - 0x%08x",
+ i, value, value);
+ item = ADWIN_ADD_LE(adwin_debug_tree, data_int, offset, 4);
+ PROTO_ITEM_SET_HIDDEN(item);
+ item = ADWIN_ADD_LE(adwin_debug_tree, data_hex, offset, 4);
+ PROTO_ITEM_SET_HIDDEN(item);
+ break;
+ case 5: /* float */
+ proto_tree_add_text(adwin_debug_tree, tvb, offset, 4,
+ "Data[%3d]: %10f - 0x%08x",
+ i, *(float*)fvalue, value);
+ item = ADWIN_ADD_LE(adwin_debug_tree, data_float, offset, 4);
+ PROTO_ITEM_SET_HIDDEN(item);
+ item = ADWIN_ADD_LE(adwin_debug_tree, data_hex, offset, 4);
+ PROTO_ITEM_SET_HIDDEN(item);
+ break;
+ default: /* string, double, variant, something funny... */
+ proto_tree_add_text(adwin_debug_tree, tvb, offset, 4,
+ "Data[%3d]: 0x%08x",
+ i, value);
+ item = ADWIN_ADD_LE(adwin_debug_tree, data_hex, offset, 4);
+ PROTO_ITEM_SET_HIDDEN(item);
+ }
+ }
+}
+
+static void
+dissect_GDSHP(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *adwin_tree, proto_tree *adwin_debug_tree)
+{
+ guint32 i, seq_num;
+
+ /* Get the transaction identifier */
+ seq_num = tvb_get_ntohl(tvb, 0);
+ adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE);
+
+ if (! adwin_tree)
+ return;
+
+ SET_PACKET_TYPE(adwin_tree, APT_GDSHP);
+ ADWIN_ADD_BE(adwin_tree, packet_index, 0, 4);
+ ADWIN_ADD_BE(adwin_tree, packet_no, 4, 4);
+ ADWIN_ADD_BE(adwin_tree, unused, 8, 4);
+
+ if (! global_adwin_dissect_data) {
+ proto_tree_add_text(adwin_debug_tree, tvb, 12, 336 * 4, "Data");
+ return;
+ }
+
+ for (i = 0; i < 336; i++) {
+ proto_item *item;
+ guint32 offset = 12 + i * sizeof(guint32);
+ gint32 value = tvb_get_letohl(tvb, offset);
+ void * fvalue = &value;
+ proto_tree_add_text(adwin_debug_tree, tvb, offset, 4,
+ "Data[%3d]: %10d - %10f - 0x%08x",
+ i, value, *(float*)fvalue, value);
+ item = ADWIN_ADD_LE(adwin_debug_tree, data_int, offset, 4);
+ PROTO_ITEM_SET_HIDDEN(item);
+ item = ADWIN_ADD_LE(adwin_debug_tree, data_float, offset, 4);
+ PROTO_ITEM_SET_HIDDEN(item);
+ item = ADWIN_ADD_LE(adwin_debug_tree, data_hex, offset, 4);
+ PROTO_ITEM_SET_HIDDEN(item);
+ }
+}
+
+static void
+dissect_GDSHR(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *adwin_tree, proto_tree *adwin_debug_tree)
+{
+ guint32 is_range, packet_start, packet_end, seq_num;
+
+ /* Get the transaction identifier */
+ seq_num = tvb_get_ntohl(tvb, 0);
+ adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE);
+
+ if (! adwin_tree)
+ return;
+
+ SET_PACKET_TYPE(adwin_tree, APT_GDSHR);
+ ADWIN_ADD_BE(adwin_tree, packet_index, 0, 4);
+ ADWIN_ADD_BE(adwin_tree, request_no, 4, 4);
+ ADWIN_ADD_BE(adwin_tree, complete_packets, 8, 4);
+ ADWIN_ADD_BE(adwin_debug_tree, is_range, 12, 4);
+ ADWIN_ADD_BE(adwin_debug_tree, packet_start, 16, 4);
+ ADWIN_ADD_BE(adwin_debug_tree, packet_end, 20, 4);
+
+ is_range = tvb_get_ntohl(tvb, 12);
+ packet_start = tvb_get_ntohl(tvb, 16);
+
+ switch(is_range) {
+ case 0: proto_tree_add_text(adwin_tree, tvb, 12, 12,
+ "GDSH status: get single packet no %d",
+ packet_start);
+ break;
+ case 1: packet_end = tvb_get_ntohl(tvb, 20);
+ proto_tree_add_text(adwin_tree, tvb, 12, 12,
+ "GDSH status: get packets %d - %d",
+ packet_start, packet_end);
+ break;
+ case 2: proto_tree_add_text(adwin_tree, tvb, 12, 12,
+ "GDSH status: finished");
+ break;
+ default: /* should not happen */
+ proto_tree_add_text(adwin_tree, tvb, 12, 12,
+ "GDSH status: unknown code %d", is_range);
+ }
+ ADWIN_ADD_BE(adwin_debug_tree, unused, 24, 40);
+}
+
+/* here we determine which type of packet is sent by looking at its
+ size. That is safe since the main server application that processes
+ these packets does it this way, too.
+
+ Depending on the packet type, the appropriate dissector is
+ called. */
+
+static int
+dissect_adwin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_item *ti, *ti2;
+ proto_tree *adwin_tree, *adwin_debug_tree;
+ gchar *info_string;
+ guint32 length;
+
+ length = tvb_reported_length(tvb);
+
+ /* First do some heuristics to see if this packet belongs to us */
+ if(! (length == UDPH1_OLD_LENGTH
+ || length == UDPH1_NEW_LENGTH
+ || length == UDPR1_LENGTH
+ || length == UDPH2_LENGTH
+ || length == UDPR2_LENGTH
+ || length == UDPR3_LENGTH
+ || length == UDPR4_LENGTH
+ || length == GetDataSHPacket_LENGTH
+ || length == GetDataSHRequest_LENGTH))
+ return(0);
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "ADwin");
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ if (tree) {
+ ti = proto_tree_add_item(tree, proto_adwin, tvb, 0, -1, TRUE);
+ adwin_tree = proto_item_add_subtree(ti, ett_adwin);
+
+ ti2 = proto_tree_add_item(adwin_tree, proto_adwin, tvb, 0, -1, TRUE);
+ adwin_debug_tree = proto_item_add_subtree(ti2, ett_adwin_debug);
+ proto_item_set_text(ti2, "ADwin Debug information");
+ } else {
+ adwin_tree = NULL;
+ adwin_debug_tree = NULL;
+ }
+
+ switch (length) {
+ case UDPH1_OLD_LENGTH:
+ dissect_UDPH1_old(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string);
+ break;
+ case UDPH1_NEW_LENGTH:
+ dissect_UDPH1_new(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string);
+ break;
+ case UDPR1_LENGTH:
+ dissect_UDPR1(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string);
+ break;
+ case UDPH2_LENGTH: /* to the best of my knowledge, this struct
+ * has never been used publically! */
+ /* dissect_UDPH2(tvb, pinfo, adwin_tree, adwin_debug_tree); */
+ info_string = ep_strdup("UDPH2 - UNUSED");
+ break;
+ case UDPR2_LENGTH:
+ dissect_UDPR2(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string);
+ break;
+ case UDPR3_LENGTH:
+ dissect_UDPR3(tvb, pinfo, adwin_tree, adwin_debug_tree);
+ info_string = ep_strdup("UDPR3");
+ break;
+ case UDPR4_LENGTH:
+ dissect_UDPR4(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string);
+ break;
+ case GetDataSHPacket_LENGTH:
+ dissect_GDSHP(tvb, pinfo, adwin_tree, adwin_debug_tree);
+ info_string = ep_strdup("GDSHP");
+ break;
+ case GetDataSHRequest_LENGTH:
+ dissect_GDSHR(tvb, pinfo, adwin_tree, adwin_debug_tree);
+ info_string = ep_strdup("GDSHR");
+ break;
+ default:
+ info_string = ep_strdup_printf("Unknown ADwin packet, length: %d", length);
+ break;
+ }
+
+ col_add_str(pinfo->cinfo, COL_INFO, info_string);
+
+ return (tvb_reported_length(tvb));
+}
+
+void proto_reg_handoff_adwin(void);
+
+void
+proto_register_adwin(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_adwin_address,
+ { "memory address", "adwin.address",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ "Memory address to read on DSP", HFILL }
+ },
+ { &hf_adwin_armVersion,
+ { "Get ARM Version", "adwin.armVersion",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_binfilesize,
+ { "File size", "adwin.binfilesize",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "Size of binary file", HFILL }
+ },
+ { &hf_adwin_blocksize,
+ { "Blocksize", "adwin.blocksize",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "Maximum number of unacknowledged packets", HFILL }
+ },
+ { &hf_adwin_complete_packets,
+ { "Complete packets", "adwin.complete_packets",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "Highest sequential package number", HFILL }
+ },
+ { &hf_adwin_count,
+ { "Count", "adwin.count",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "Number of longs", HFILL }
+ },
+ { &hf_adwin_data_int,
+ { "Data element int", "adwin.data_int",
+ FT_INT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_data_float,
+ { "Data element float", "adwin.data_float",
+ FT_FLOAT, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_data_hex,
+ { "Data element hex", "adwin.data_hex",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_data_no16,
+ { "Data No. (16bit)", "adwin.data",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_data_no32,
+ { "Data No. (32bit)", "adwin.data",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_data_type,
+ { "Data type", "adwin.data_type",
+ FT_UINT32, BASE_DEC, data_type_mapping, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_data_packet_index,
+ { "Data packet index", "adwin.data_packet_index",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_dll_version,
+ { "DLL Version", "adwin.dll_version",
+ FT_STRINGZ, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_fifo_no16,
+ { "FiFo No. (16bit)", "adwin.fifo_no",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_fifo_no32,
+ { "FiFo No. (32bit)", "adwin.fifo_no",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_instruction,
+ { "Instruction", "adwin.instruction",
+ FT_UINT32, BASE_DEC, instruction_mapping, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_is_range,
+ { "packets are a range", "adwin.is_range",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_i3plus1,
+ { "3+1 Instruction", "adwin.i3plus1",
+ FT_UINT32, BASE_DEC, instruction_3plus1_mapping, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_link_addr,
+ { "Link address", "adwin.link_addr",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ "Link address (TCP/IP Server only)", HFILL }
+ },
+ { &hf_adwin_mem_type,
+ { "Memory type", "adwin.mem_type",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_memsize,
+ { "Memory size", "adwin.memsize",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_osys,
+ { "Operating system", "adwin.osys",
+ FT_UINT32, BASE_DEC, osys_mapping, 0x0,
+ "Operating system / environment", HFILL }
+ },
+ { &hf_adwin_packet_end,
+ { "End packet", "adwin.packet_end",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "GDSH: End Packet", HFILL }
+ },
+ { &hf_adwin_packet_index,
+ { "Packet index", "adwin.packet_index",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_packet_no,
+ { "Packet No.", "adwin.packet_no",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_packet_start,
+ { "Starting packet", "adwin.packet_start",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "GDSH: Starting Packet", HFILL }
+ },
+ { &hf_adwin_packet_type,
+ { "Packet type", "adwin.packet_type",
+ FT_INT32, BASE_DEC, packet_type_mapping, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_parameter,
+ { "Parameter", "adwin.parameter",
+ FT_UINT32, BASE_DEC, parameter_mapping, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_password,
+ { "Password", "adwin.password",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ "Password for ADwin system", HFILL }
+ },
+ { &hf_adwin_process_no,
+ { "Process No.", "adwin.process_no",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_processor,
+ { "Processor", "adwin.processor",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_response_in,
+ { "Response In", "adwin.response_in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "The response to this ADwin request is in this frame", HFILL }
+ },
+ { &hf_adwin_response_to,
+ { "Request In", "adwin.response_to",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "This is a response to the ADwin request in this frame", HFILL }
+ },
+ { &hf_adwin_response_time,
+ { "Response time", "adwin.response_time",
+ FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
+ "The time between the Request and the Reply", HFILL }
+ },
+ { &hf_adwin_retry_packet_index,
+ { "Retry packet index", "adwin.retry_packet_index",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_request_no,
+ { "Request Number", "adwin.request_no",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "Request number index", HFILL }
+ },
+ { &hf_adwin_start_index,
+ { "Start index", "adwin.start_index",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_status,
+ { "Status", "adwin.status",
+ FT_INT32, BASE_DEC, error_code_mapping, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_timeout,
+ { "Timeout", "adwin.timeout",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "Timeout in ms", HFILL }
+ },
+ { &hf_adwin_unused,
+ { "Unused", "adwin.unused",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_adwin_val1,
+ { "Value 1 (as int)", "adwin.val1",
+ FT_INT32, BASE_DEC, NULL, 0x0,
+ "Generic return value 1 interpreted as integer (correct interpretation depends on request).", HFILL }
+ },
+ { &hf_adwin_val1f,
+ { "Value 1 (as float)", "adwin.val1f",
+ FT_FLOAT, BASE_NONE, NULL, 0x0,
+ "Generic return value 1 interpreted as float (correct interpretation depends on request).", HFILL }
+ },
+ { &hf_adwin_val2,
+ { "Value 2", "adwin.val2",
+ FT_INT32, BASE_DEC, NULL, 0x0,
+ "Generic return value 2 (interpretation depends on request).", HFILL }
+ },
+ { &hf_adwin_val3,
+ { "Value 3", "adwin.val3",
+ FT_INT32, BASE_DEC, NULL, 0x0,
+ "Generic return value 3 (interpretation depends on request).", HFILL }
+ },
+ { &hf_adwin_val4,
+ { "Value 4", "adwin.val4",
+ FT_INT32, BASE_DEC, NULL, 0x0,
+ "Generic return value 4 (interpretation depends on request).", HFILL }
+ },
+ };
+
+ /* Setup protocol subtree array */
+ static gint *ett[] = {
+ &ett_adwin,
+ &ett_adwin_debug,
+ };
+ module_t *adwin_module;
+
+ /* Register the protocol name and description */
+ proto_adwin = proto_register_protocol("ADwin communication protocol",
+ "ADwin", "adwin");
+
+ /* Required function calls to register the header fields and
+ subtrees used */
+ proto_register_field_array(proto_adwin, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ /* Register our configuration options for ADwin, particularly
+ our port */
+ adwin_module = prefs_register_protocol(proto_adwin, proto_reg_handoff_adwin);
+
+ prefs_register_uint_preference(adwin_module, "udp.port", "ADwin UDP Port",
+ "Set the UDP port for ADwin packets (if other"
+ " than the default of 6543)",
+ 10, &global_adwin_udp_port);
+
+ prefs_register_bool_preference(adwin_module, "dissect_data",
+ "Dissect Data sections",
+ "Specify if the Data sections of packets "
+ "should be dissected or not",
+ &global_adwin_dissect_data);
+}
+
+void
+proto_reg_handoff_adwin(void)
+{
+ static int adwin_prefs_initialized = FALSE;
+ static dissector_handle_t adwin_handle;
+
+ if (! adwin_prefs_initialized) {
+ adwin_handle = new_create_dissector_handle(dissect_adwin, proto_adwin);
+ adwin_prefs_initialized = TRUE;
+ } else {
+ dissector_delete("udp.port", udp_port, adwin_handle);
+ }
+
+ udp_port = global_adwin_udp_port;
+ dissector_add("udp.port", global_adwin_udp_port, adwin_handle);
+}