diff -rN ethereal-0.10.14/epan/dissectors/Makefile.common ethereal-0.10.14-2/epan/dissectors/Makefile.common
279a280
> 	packet-ewsd.c	\
diff -rN ethereal-0.10.14/epan/dissectors/Makefile.in ethereal-0.10.14-2/epan/dissectors/Makefile.in
190c190
< 	packet-ethertype.lo packet-extreme.lo packet-fc.lo \
---
> 	packet-ethertype.lo packet-ewsd.lo packet-extreme.lo packet-fc.lo \
799a800
> 	packet-ewsd.c	\
1777a1779
> @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet-ewsd.Plo@am__quote@
diff -rN ethereal-0.10.14/epan/dissectors/packet-ewsd.c ethereal-0.10.14-2/epan/dissectors/packet-ewsd.c
0a1,306
> /* packet-ewsd.c
>  *
>  * Radek Podgorny <radek@podgorny.cz>
>  *
>  * 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
> 
> #include <stdio.h>
> #include <string.h>
> #include <glib.h>
> #include <epan/packet.h>
> 
> 
> #define FAMILY_COMMAND 0xf1
> #define FAMILY_ANSWER 0xf2
> 
> 
> static int proto_ewsd = -1;
> 
> static guint8 hf_ewsd_family = -1;
> static guint8 hf_ewsd_dir = -1;
> static guint8 hf_ewsd_pltype = -1;
> static guint16 hf_ewsd_connid = -1;
> static guint8 hf_ewsd_subseq = -1;
> //static gint hf_ewsd_shit = -1;
> 
> static gint ett_ewsd = -1;
> static gint ett_ewsd_preamble = -1;
> static gint ett_ewsd_ewsd = -1;
> 
> 
> guint8 idmatch(guint8 *info, guint8 *mask) {
> 	int info_len = strlen(info);
> 	int mask_len = strlen(mask);
> 
> 	if (info_len != mask_len) return 0;
> 
> 	int i = 0;
> 	for (i = 0; i < mask_len; i++) {
> 		if (mask[i] == 'x') continue;
> 		if (mask[i] != info[i]) return 0;
> 	}
> 
> 	return 1;
> }
> 
> /* idinfo is used as we recurse deeper (we need to keep track of upper level ids) */
> guint16 dis_ewsd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 *levelinfo) {
> 	guint8 id;
> 	guint16 len;
> 
> 	tvbuff_t *subtvb;
> 
> 	guint16 pos;
> 
> 	id = tvb_get_guint8(tvb, 0);
> 	len = tvb_get_ntohs(tvb, 1);
> 
> 	// Broken when enabled?
> 	//tvb_set_reported_length(tvb, len+3);
> 
> 	guint8 mylevel[100];
> 	strcpy(mylevel, levelinfo);
> 	int i = strlen(mylevel);
> 	mylevel[i] = id + '0';
> 	mylevel[i+1] = 0;
> 
> 	if (idmatch(mylevel, "x")
> 	|| (idmatch(mylevel, "x3") && hf_ewsd_dir == 0x0c && hf_ewsd_pltype == 1)
> 	|| idmatch(mylevel, "x4")
> 	|| (idmatch(mylevel, "x43") && hf_ewsd_dir == 4 && hf_ewsd_pltype == 0)
> 	|| (idmatch(mylevel, "x432") && hf_ewsd_dir == 4 && hf_ewsd_pltype == 0)
> 	|| (idmatch(mylevel, "x5") && hf_ewsd_dir == 2 && hf_ewsd_pltype == 0)
> 	|| (idmatch(mylevel, "x5") && hf_ewsd_dir == 0x0e && hf_ewsd_pltype == 0)
> 	|| idmatch(mylevel, "x6")
> 	|| idmatch(mylevel, "x8")) {
> 		proto_item *ti = proto_tree_add_text(tree, tvb, 0, len+3, "ewsd %d (len: %d) (mylevel: %s)", id, len, mylevel);
> 		proto_tree *subtree = proto_item_add_subtree(ti, ett_ewsd_preamble);
> 
> 		pos = 3;
> 		while (pos < len+3) {
> 			subtvb = tvb_new_subset(tvb, pos, -1, -1);
> 			guint16 len = dis_ewsd(subtvb, pinfo, subtree, mylevel);
> 			pos += len;
> 		}
> 	} else if (idmatch(mylevel, "x2")) {
> 		guint8 *unk1 = tvb_bytes_to_str_punct(tvb, 3, 2, '.');
> 		guint16 jobnr = tvb_get_ntohs(tvb, 5);
> 		guint8 *unk2 = tvb_bytes_to_str_punct(tvb, 7, len-4, '.');
> 		proto_tree_add_text(tree, tvb, 3, 2, "!!!unknown!!! (mylevel: %s) - %s", mylevel, unk1);
> 		proto_tree_add_text(tree, tvb, 5, 2, "Job number: %d", jobnr);
> 		proto_tree_add_text(tree, tvb, 7, len-4, "!!!unknown!!! (mylevel: %s) - %s", mylevel, unk2);
> /* */		if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, " (x2-unk2: %s)", unk2);
> 	} else if (idmatch(mylevel, "x31")) {
> 		guint8 *exname = tvb_get_ephemeral_string(tvb, 3, len);
> 		proto_tree_add_text(tree, tvb, 3, len, "Exchange name: %s", exname);
> 	} else if (idmatch(mylevel, "x32")) {
> 		guint8 *apsver = tvb_get_ephemeral_string(tvb, 3, len);
> 		proto_tree_add_text(tree, tvb, 3, len, "APS version: %s", apsver);
> 	} else if (idmatch(mylevel, "x33")) {
> 		guint8 *patchver = tvb_get_ephemeral_string(tvb, 3, len);
> 		proto_tree_add_text(tree, tvb, 3, len, "Patch version: %s", patchver);
> 	} else if (idmatch(mylevel, "x35")) {
> 		guint8 *username = tvb_get_ephemeral_string(tvb, 3, len);
> 		proto_tree_add_text(tree, tvb, 3, len, "Username: %s", username);
> 	} else if (idmatch(mylevel, "x41") && hf_ewsd_dir == 4 && hf_ewsd_pltype == 0) {
> 		guint8 *termname = tvb_get_ephemeral_string(tvb, 3, len);
> 		proto_tree_add_text(tree, tvb, 3, len, "Terminal name: %s", termname);
> 	} else if (idmatch(mylevel, "x41")) {
> 		guint8 *exname = tvb_get_ephemeral_string(tvb, 3, len);
> 		proto_tree_add_text(tree, tvb, 3, len, "Exchange name: %s", exname);
> 	} else if (idmatch(mylevel, "x42")) {
> 		guint8 *apsver = tvb_get_ephemeral_string(tvb, 3, len);
> 		proto_tree_add_text(tree, tvb, 3, len, "APS version: %s", apsver);
> 	} else if (idmatch(mylevel, "x43")) {
> 		guint8 *patchver = tvb_get_ephemeral_string(tvb, 3, len);
> 		proto_tree_add_text(tree, tvb, 3, len, "Patch version: %s", patchver);
> 	} else if (idmatch(mylevel, "x4322")) {
> 		guint8 *username = tvb_get_ephemeral_string(tvb, 3, len);
> 		proto_tree_add_text(tree, tvb, 3, len, "Username: %s", username);
> 	} else if (idmatch(mylevel, "x4323")) {
> 		guint8 *date = tvb_get_ephemeral_string(tvb, 3, 6);
> 		guint8 *time = tvb_get_ephemeral_string(tvb, 9, 6);
> 		guint8 *unk = tvb_bytes_to_str_punct(tvb, 15, len-12, '.');
> 		proto_tree_add_text(tree, tvb, 3, 6, "Date: %s", date);
> 		proto_tree_add_text(tree, tvb, 9, 6, "Time: %s", time);
> 		proto_tree_add_text(tree, tvb, 15, len-12, "!!!unknown!!! (mylevel: %s) - %s", mylevel, unk);
> 	} else if (idmatch(mylevel, "x44")) {
> 		guint8 *termname = tvb_get_ephemeral_string(tvb, 3, len);
> 		proto_tree_add_text(tree, tvb, 3, len, "Terminal name: %s", termname);
> 	} else if (idmatch(mylevel, "x45")) {
> 		guint8 *username = tvb_get_ephemeral_string(tvb, 3, len);
> 		proto_tree_add_text(tree, tvb, 3, len, "Username: %s", username);
> 	} else if (idmatch(mylevel, "x46")) {
> 		guint8 year = tvb_get_guint8(tvb, 3);
> 		guint8 month = tvb_get_guint8(tvb, 4);
> 		guint8 day = tvb_get_guint8(tvb, 5);
> 		proto_tree_add_text(tree, tvb, 3, len, "Date: %.2d-%.2d-%.2d", year, month, day);
> 	} else if (idmatch(mylevel, "x47")) {
> 		guint8 hour = tvb_get_guint8(tvb, 3);
> 		guint8 minute = tvb_get_guint8(tvb, 4);
> 		guint8 second = tvb_get_guint8(tvb, 5);
> 		proto_tree_add_text(tree, tvb, 3, len, "Time: %.2d:%.2d:%.2d", hour, minute, second);
> 	} else if (idmatch(mylevel, "x52") && hf_ewsd_family == FAMILY_COMMAND && hf_ewsd_dir == 2 && hf_ewsd_pltype == 0) {
> 		guint8 *err = tvb_get_ephemeral_string(tvb, 3, len);
> 		proto_tree_add_text(tree, tvb, 3, len, "Command error: %s", err);
> 	} else if (idmatch(mylevel, "x61") && hf_ewsd_family == FAMILY_COMMAND) {
> 		guint8 *command = tvb_get_ephemeral_string(tvb, 3, len);
> 		proto_tree_add_text(tree, tvb, 3, len, "Command: %s", command);
> 	} else if (idmatch(mylevel, "x7") && hf_ewsd_family == FAMILY_ANSWER) {
> 		// tvb_get_ephemeral_string seems to be unhappy with large lengths
> 		guint16 tmp = len; if (tmp > 1024) tmp = 1024;
> 		guint8 *ans = tvb_get_ephemeral_string(tvb, 3, tmp);
> 		proto_tree_add_text(tree, tvb, 3, len, "Answer: %s", ans);
> 	} else {
> 		guint8 *data = tvb_bytes_to_str_punct(tvb, 3, len, '.');
> 		proto_tree_add_text(tree, tvb, 3, len, "!!!unknown!!! (mylevel: %s) - %s", mylevel, data);
> 	}
> 
> 	return len+3;
> }
> 
> void dis_preamble(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
> 	proto_item *ti;
> 	proto_tree *subtree;
> 	tvbuff_t *subtvb;
> 
> 	hf_ewsd_family = tvb_get_guint8(tvb, 0);
> 
> 	if (hf_ewsd_family != FAMILY_COMMAND
> 	&& hf_ewsd_family != FAMILY_ANSWER) {
> 		if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, "Something weird!!!");
> 		return;
> 	}
> 
> 	guint8 unk1 = tvb_get_guint8(tvb, 1);
> 	hf_ewsd_dir = tvb_get_guint8(tvb, 2);
> 	hf_ewsd_pltype = tvb_get_guint8(tvb, 3);
> 	hf_ewsd_connid = tvb_get_ntohs(tvb, 4);
> 	hf_ewsd_subseq = tvb_get_guint8(tvb, 6);
> 	guint8 unk2 = tvb_get_guint8(tvb, 7);
> 	guint16 unk3 = tvb_get_ntohs(tvb, 8);
> 	guint8 tail = tvb_get_guint8(tvb, 10);
> 
> 	ti = proto_tree_add_text(tree, tvb, 0, 11,
> 		"preamble (family?: %#.2x) (dir?: %#.2x) (pltype?: %#.2x) (connid?: %#.4x) (subseq?: %d) (unk3?: %#.4x) (tail?: %#.2x)",
> 		hf_ewsd_family, hf_ewsd_dir, hf_ewsd_pltype, hf_ewsd_connid, hf_ewsd_subseq, unk3, tail);
> 
> 	subtree = proto_item_add_subtree(ti, ett_ewsd_preamble);
> 	proto_tree_add_text(subtree, tvb, 0, 1, "family: %#.2x", hf_ewsd_family);
> 	proto_tree_add_text(subtree, tvb, 1, 1, "unk1: %#.2x", unk1);
> 	proto_tree_add_text(subtree, tvb, 2, 1, "dir: %#.2x", hf_ewsd_dir);
> 	proto_tree_add_text(subtree, tvb, 3, 1, "payload type: %#.2x", hf_ewsd_pltype);
> 	proto_tree_add_text(subtree, tvb, 4, 2, "cennection id: %#.4x", hf_ewsd_connid);
> 	proto_tree_add_text(subtree, tvb, 6, 1, "subseq: %d", hf_ewsd_subseq);
> 	proto_tree_add_text(subtree, tvb, 7, 1, "unk2: %#.2x", unk2);
> 	proto_tree_add_text(subtree, tvb, 8, 2, "unk3: %#.4x", unk3);
> 	proto_tree_add_text(subtree, tvb, 10, 1, "tail: %#.2x", tail);
> 
> 
> 	if (hf_ewsd_dir == 1 && hf_ewsd_pltype == 2) {
> 		if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, "Something!!!");
> 		subtvb = tvb_new_subset(tvb, 11, -1, -1);
> 		dis_ewsd(subtvb, pinfo, tree, "");
> 	} else if (hf_ewsd_dir == 2 && hf_ewsd_subseq > 1) {
> 		if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, "Continued answer");
> 		// tvb_get_ephemeral_string seems to be unhappy with large lengths
> 		guint16 tmp = tvb_length_remaining(tvb, 11);// if (tmp > 1024) tmp = 1024;
> 		guint8 *ans = tvb_get_ephemeral_string(tvb, 11, tmp);
> 		proto_tree_add_text(tree, tvb, 11, -1, "Continued answer: %s", ans);
> 	} else if (hf_ewsd_dir == 2 && hf_ewsd_pltype == 0) {
> 		if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, "Command");
> 		subtvb = tvb_new_subset(tvb, 11, -1, -1);
> 		dis_ewsd(subtvb, pinfo, tree, "");
> 	} else if (hf_ewsd_dir == 2 && hf_ewsd_pltype == 1 && hf_ewsd_subseq <= 1) {
> 		if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, "Long answer");
> 		subtvb = tvb_new_subset(tvb, 11, -1, -1);
> 		dis_ewsd(subtvb, pinfo, tree, "");
> 	} else if (hf_ewsd_dir == 2 && hf_ewsd_pltype == 2) {
> 		if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, "Short answer");
> 		subtvb = tvb_new_subset(tvb, 11, -1, -1);
> 		dis_ewsd(subtvb, pinfo, tree, "");
> 	} else if (hf_ewsd_dir == 3 && hf_ewsd_pltype == 1) {
> 		if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, "Command confirmation");
> 		subtvb = tvb_new_subset(tvb, 11, -1, -1);
> 		dis_ewsd(subtvb, pinfo, tree, "");
> 	} else if (hf_ewsd_dir == 4 && hf_ewsd_pltype == 0) {
> 		if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, "Login attempt ?");
> 		subtvb = tvb_new_subset(tvb, 11, -1, -1);
> 		dis_ewsd(subtvb, pinfo, tree, "");
> 	} else if (hf_ewsd_dir == 0x0c && hf_ewsd_pltype == 1) {
> 		if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, "Login accept ?");
> 		subtvb = tvb_new_subset(tvb, 11, -1, -1);
> 		dis_ewsd(subtvb, pinfo, tree, "");
> 	} else if (hf_ewsd_dir == 0x0e && hf_ewsd_pltype == 0) {
> 		if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, "Something!!!");
> 		subtvb = tvb_new_subset(tvb, 11, -1, -1);
> 		dis_ewsd(subtvb, pinfo, tree, "");
> 	} else if (hf_ewsd_dir == 3 && hf_ewsd_pltype == 6) {
> 		if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, "Answer confirmation, send more data");
> 	} else {
> 		if (check_col(pinfo->cinfo, COL_INFO)) col_add_str(pinfo->cinfo, COL_INFO, "!!!unknown!!!");
> 	}
> }
> 
> static void dissect_ewsd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
> 	proto_item *ti;
> 	proto_tree *subtree;
> 	tvbuff_t *subtvb;
> 
> 	if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_add_str(pinfo->cinfo, COL_PROTOCOL, "EWSD");
> 
> 	if (tree) {
> 		ti = proto_tree_add_item(tree, proto_ewsd, tvb, 0, -1, FALSE);
> 		subtree = proto_item_add_subtree(ti, ett_ewsd);
> 
> 		subtvb = tvb_new_subset(tvb, 0, -1, -1);
> 		dis_preamble(subtvb, pinfo, subtree);
> 	}
> }
> 
> void proto_register_ewsd(void) {
> //	static hf_register_info hf[] = {
> //		{&hf_ewsd_direction, {"Direction", "ewsd.direction", FT_INT8, BASE_HEX, NULL, 0x0, "Direction", HFILL}},
> //		{&hf_ewsd_data, {"Test data", "ewsd.data", FT_BYTES, BASE_HEX, NULL, 0x0, "Test data", HFILL}},
> //		{&hf_ewsd_realdata, {"realdata", "ewsd.realdata", FT_BYTES, BASE_HEX, NULL, 0, "realdata", HFILL}},
> //	};
> 
> 	static gint *ett[] = {
> 		&ett_ewsd,
> 		&ett_ewsd_preamble,
> 		&ett_ewsd_ewsd
> 	};
> 
> 	proto_ewsd = proto_register_protocol("Siemens EWSD", "EWSD", "ewsd");
> //	proto_register_field_array(proto_ewsd, hf, array_length(hf));
> 	proto_register_subtree_array(ett, array_length(ett));
> 
> 	register_dissector("ewsd", dissect_ewsd, proto_ewsd);
> 	register_dissector_table("ewsd.ewsd", "ewsd ewsd", FT_UINT8, BASE_DEC);
> }
> 
> void proto_reg_handoff_ewsd(void) {
> 	dissector_handle_t ewsd_handle = NULL;
> 
> 	ewsd_handle = create_dissector_handle(dissect_ewsd, proto_ewsd);
> 
> 	dissector_add("ewsd.ewsd", 0, proto_ewsd);
> }
diff -rN ethereal-0.10.14/epan/dissectors/packet-x25.c ethereal-0.10.14-2/epan/dissectors/packet-x25.c
2367a2368,2373
> 	// added by Radek Podgorny
> 	dissector_handle_t *t = find_dissector("ewsd");
> 	call_dissector(t, next_tvb, pinfo, tree);
> 	pinfo->private_data = saved_private_data;
> 	return;
> 
diff -rN ethereal-0.10.14/epan/dissectors/register.c ethereal-0.10.14-2/epan/dissectors/register.c
197a198
>   {extern void proto_register_ewsd (void); proto_register_ewsd ();}
815a817
>   {extern void proto_reg_handoff_ewsd (void); proto_reg_handoff_ewsd ();}
