Ethereal-dev: Re: [Ethereal-dev] LAT Protocol specs
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Guy Harris <gharris@xxxxxxxxxxxx>
Date: Thu, 12 Oct 2000 00:46:59 -0700
On Wed, Oct 11, 2000 at 11:49:21PM +0900, Richard Sharpe wrote: > I am there fore motivated to start a LAT dissector for Ethereal. Can anyone > point me to the protocol specs? They're probably locked up in some building in Massachusetts or New Hampshire in the northeastern US. I.e., LAT is a DEC-proprietary protocol; DEC have never published a spec. However, at http://linux-decnet.sourceforge.net/ is the Linux DECNET project page; if you go to http://sourceforge.net/projects/linux-decnet/ there's a link for latd 1.0, a LAT daemon. I downloaded an older version of latd and started working on a LAT dissector; I've attached what I have so far. It compiles (or it did last time I tried it, which wasn't too long ago, I think), and it dissects some LAT stuff, but not all of it. It probably should be changed to use the new string stuff Gilbert stuck in - as I remember, there are some counted strings in the protocol.
/* packet-lat.c * Routines for the disassembly of DEC's LAT protocol * * $Id$ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@xxxxxxxx> * 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. */ #include "config.h" #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif #include <stdlib.h> #include <string.h> #include <glib.h> #include "packet.h" #include "etypes.h" /* * Information on LAT taken from the Linux "latd". */ static int proto_lat = -1; static int hf_lat_cmd = -1; static int hf_lat_num_slots = -1; static int hf_lat_remote_connid = -1; static int hf_lat_local_connid = -1; static int hf_lat_seq_number = -1; static int hf_lat_ack_number = -1; static int hf_lat_slotcmd_local_session = -1; static int hf_lat_slotcmd_remote_session = -1; static int hf_lat_slotcmd_length = -1; static int hf_lat_slotcmd_command = -1; static int hf_lat_circuit_timer = -1; static int hf_lat_hiver = -1; static int hf_lat_lover = -1; static int hf_lat_latver = -1; static int hf_lat_latver_minor = -1; static int hf_lat_incarnation = -1; static int hf_lat_change_flags = -1; static int hf_lat_mtu = -1; static int hf_lat_multicast_timer = -1; static int hf_lat_node_status = -1; static int hf_lat_group_length = -1; static int hf_lat_nodename = -1; static int hf_lat_greeting = -1; static int hf_lat_num_services = -1; static int hf_lat_service_rating = -1; static int hf_lat_service_name = -1; static int hf_lat_service_ident = -1; static gint ett_lat = -1; /* LAT commands. */ #define LAT_CCMD_SREPLY 0x00 /* From Host */ #define LAT_CCMD_SDATA 0x01 /* From Host: Response required */ #define LAT_CCMD_SESSION 0x02 /* To Host */ #define LAT_CCMD_CONNECT 0x06 #define LAT_CCMD_CONREF 0x08 /* Connection Refused (I think) */ #define LAT_CCMD_CONACK 0x04 #define LAT_CCMD_DISCON 0x0A #define LAT_CCMD_SERVICE 0x28 #define LAT_CCMD_ENQUIRE 0x38 #define LAT_CCMD_ENQREPLY 0x3C static const value_string command_vals[] = { { LAT_CCMD_SREPLY, "Session reply" }, { LAT_CCMD_SDATA, "Session data" }, { LAT_CCMD_SESSION, "Session" }, { LAT_CCMD_CONNECT, "Connect" }, { LAT_CCMD_CONREF, "Connection refused" }, { LAT_CCMD_CONACK, "Connection ACK" }, { LAT_CCMD_DISCON, "Disconnect" }, { LAT_CCMD_SERVICE, "Service" }, { LAT_CCMD_ENQUIRE, "Enquire" }, { LAT_CCMD_ENQREPLY, "Enquire reply" }, { 0, NULL }, }; static void dissect_lat_sreply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree); static void dissect_lat_service(const u_char *pd, int offset, frame_data *fd, proto_tree *tree); static int dissect_lat_string(const u_char *pd, int offset, int hf, proto_tree *tree); static guint dissect_lat_header(const u_char *pd, int offset, frame_data *fd, proto_tree *tree); static void dissect_lat_slots(const u_char *pd, int offset, guint num_slots, proto_tree *tree); static void dissect_lat(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { proto_item *ti; proto_tree *lat_tree = NULL; guint8 command; command = pd[offset]; if (check_col(fd, COL_PROTOCOL)) col_add_str(fd, COL_PROTOCOL, "LAT"); if (check_col(fd, COL_INFO)) { col_add_fstr(fd, COL_INFO, "%s", val_to_str(command, command_vals, "Unknown command (%02x)")); } if (tree) { ti = proto_tree_add_item(tree, proto_lat, NullTVB, offset, END_OF_FRAME, NULL); lat_tree = proto_item_add_subtree(ti, ett_lat); /* LAT header */ proto_tree_add_uint(lat_tree, hf_lat_cmd, NullTVB, offset, 1, command); offset += 1; switch (command) { case LAT_CCMD_SREPLY: dissect_lat_sreply(pd, offset, fd, lat_tree); break; #if 0 case LAT_CCMD_SDATA: dissect_lat_header(pd, offset, fd, lat_tree); break; case LAT_CCMD_SESSION: dissect_lat_header(pd, offset, fd, lat_tree); break; case LAT_CCMD_CONNECT: dissect_lat_connect(pd, offset, fd, lat_tree); break; case LAT_CCMD_CONREF: dissect_lat_conref(pd, offset, fd, lat_tree); break; case LAT_CCMD_CONACK: dissect_lat_conack(pd, offset, fd, lat_tree); break; case LAT_CCMD_DISCON: dissect_lat_discon(pd, offset, fd, lat_tree); break; #endif case LAT_CCMD_SERVICE: dissect_lat_service(pd, offset, fd, lat_tree); break; #if 0 case LAT_CCMD_ENQUIRE: dissect_lat_enquire(pd, offset, fd, lat_tree); break; case LAT_CCMD_ENQREPLY: dissect_lat_enqreply(pd, offset, fd, lat_tree); break; #endif default: old_dissect_data(pd, offset, fd, lat_tree); break; } } } static void dissect_lat_sreply(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { guint8 num_slots; num_slots = dissect_lat_header(pd, offset, fd, tree); offset += 1 + 2 + 2 + 1 + 1; dissect_lat_slots(pd, offset, num_slots, tree); } static const value_string node_status_vals[] = { { 2, "Accepting connections" }, { 3, "Not accepting connections" }, { 0, NULL }, }; static void dissect_lat_service(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { guint8 group_length; guint8 num_services; int i; proto_tree_add_uint_format(tree, hf_lat_circuit_timer, NullTVB, offset, 1, pd[offset], "Circuit timer: %u milliseconds", pd[offset]*10); offset += 1; proto_tree_add_uint(tree, hf_lat_hiver, NullTVB, offset, 1, pd[offset]); offset += 1; proto_tree_add_uint(tree, hf_lat_lover, NullTVB, offset, 1, pd[offset]); offset += 1; proto_tree_add_uint(tree, hf_lat_latver, NullTVB, offset, 1, pd[offset]); offset += 1; proto_tree_add_uint(tree, hf_lat_latver_minor, NullTVB, offset, 1, pd[offset]); offset += 1; proto_tree_add_uint(tree, hf_lat_incarnation, NullTVB, offset, 1, pd[offset]); offset += 1; proto_tree_add_uint(tree, hf_lat_change_flags, NullTVB, offset, 1, pd[offset]); offset += 1; proto_tree_add_uint(tree, hf_lat_mtu, NullTVB, offset, 2, pletohs(&pd[offset])); offset += 2; proto_tree_add_uint_format(tree, hf_lat_multicast_timer, NullTVB, offset, 1, pd[offset], "Multicast timer: %u seconds", pd[offset]); offset += 1; proto_tree_add_uint(tree, hf_lat_node_status, NullTVB, offset, 1, pd[offset]); offset += 1; group_length = pd[offset]; proto_tree_add_uint(tree, hf_lat_group_length, NullTVB, offset, 1, group_length); offset += 1; /* XXX - what are these? */ proto_tree_add_text(tree, NullTVB, offset, group_length, "Groups"); offset += group_length; offset = dissect_lat_string(pd, offset, hf_lat_nodename, tree); offset = dissect_lat_string(pd, offset, hf_lat_greeting, tree); num_services = pd[offset]; proto_tree_add_uint(tree, hf_lat_num_services, NullTVB, offset, 1, num_services); offset += 1; for (i = 0; i < num_services; i++) { proto_tree_add_uint(tree, hf_lat_service_rating, NullTVB, offset, 1, pd[offset]); offset += 1; offset = dissect_lat_string(pd, offset, hf_lat_service_name, tree); offset = dissect_lat_string(pd, offset, hf_lat_service_ident, tree); } } static int dissect_lat_string(const u_char *pd, int offset, int hf, proto_tree *tree) { guint8 string_len; char *stringptr; /* XXX - alas, FT_STRING is null-terminated, not counted, so we have to copy the string to a buffer and null-terminate it. */ string_len = pd[offset]; stringptr = g_malloc(string_len + 1); memcpy(stringptr, &pd[offset + 1], string_len); stringptr[string_len] = '\0'; proto_tree_add_string(tree, hf, NullTVB, offset, 1 + string_len, stringptr); g_free(stringptr); return offset + 1 + string_len; } static guint dissect_lat_header(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { guint8 num_slots; num_slots = pd[offset]; proto_tree_add_uint(tree, hf_lat_num_slots, NullTVB, offset, 1, num_slots); offset += 1; proto_tree_add_uint(tree, hf_lat_remote_connid, NullTVB, offset, 2, pletohs(&pd[offset])); offset += 2; proto_tree_add_uint(tree, hf_lat_local_connid, NullTVB, offset, 2, pletohs(&pd[offset])); offset += 2; proto_tree_add_uint(tree, hf_lat_seq_number, NullTVB, offset, 1, pd[offset]); offset += 1; proto_tree_add_uint(tree, hf_lat_ack_number, NullTVB, offset, 1, pd[offset]); offset += 1; return num_slots; } static void dissect_lat_slots(const u_char *pd, int offset, guint num_slots, proto_tree *tree) { int i; for (i = 0; i < num_slots; i++) { proto_tree_add_uint(tree, hf_lat_slotcmd_local_session, NullTVB, offset, 1, pd[offset]); offset += 1; proto_tree_add_uint(tree, hf_lat_slotcmd_remote_session, NullTVB, offset, 1, pd[offset]); offset += 1; proto_tree_add_uint(tree, hf_lat_slotcmd_length, NullTVB, offset, 1, pd[offset]); offset += 1; proto_tree_add_uint(tree, hf_lat_slotcmd_command, NullTVB, offset, 1, pd[offset]); offset += 1; } } void proto_register_lat(void) { static hf_register_info hf[] = { { &hf_lat_cmd, { "Command", "lat.command", FT_UINT8, BASE_HEX, VALS(command_vals), 0x0, "" }}, { &hf_lat_num_slots, { "Number of slots", "lat.num_slots", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_remote_connid, { "Remote connection ID", "lat.remote_connid", FT_UINT16, BASE_HEX, NULL, 0x0, "" }}, { &hf_lat_local_connid, { "Local connection ID", "lat.local_connid", FT_UINT16, BASE_HEX, NULL, 0x0, "" }}, { &hf_lat_seq_number, { "Sequence number", "lat.seq_number", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_ack_number, { "Ack number", "lat.ack_number", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_slotcmd_local_session, { "Local session", "lat.slotcmd.local_session", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_slotcmd_remote_session, { "Remote session", "lat.slotcmd.remote_session", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_slotcmd_length, { "Length", "lat.slotcmd.length", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_slotcmd_command, { "Command", "lat.slotcmd.command", FT_UINT8, BASE_HEX, NULL, 0x0, "" }}, { &hf_lat_circuit_timer, { "Circuit timer", "lat.circuit_timer", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_hiver, { "Highest protocol version acceptable", "lat.hiver", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_lover, { "Lowest protocol version acceptable", "lat.lover", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_latver, { "LAT version number", "lat.latver", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_latver_minor, { "LAT minor version number (?)", "lat.latver_minor", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_incarnation, { "Message incarnation (?)", "lat.incarnation", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_change_flags, { "Change flags (?)", "lat.change_flags", FT_UINT8, BASE_HEX, NULL, 0x0, "" }}, { &hf_lat_mtu, { "MTU", "lat.mtu", FT_UINT16, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_multicast_timer, { "Multicast timer", "lat.multicast_timer", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_node_status, { "Node status", "lat.node_status", FT_UINT8, BASE_DEC, VALS(node_status_vals), 0x0, "" }}, { &hf_lat_group_length, { "Group length", "lat.group_length", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_nodename, { "Node name", "lat.nodename", FT_STRING, 0, NULL, 0x0, "" }}, { &hf_lat_greeting, { "Greeting", "lat.greeting", FT_STRING, 0, NULL, 0x0, "" }}, { &hf_lat_num_services, { "Number of services", "lat.num_services", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_service_rating, { "Rating", "lat.service_rating", FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, { &hf_lat_service_name, { "Service name", "lat.service.name", FT_STRING, 0, NULL, 0x0, "" }}, { &hf_lat_service_ident, { "Service identification", "lat.service.ident", FT_STRING, 0, NULL, 0x0, "" }}, }; static gint *ett[] = { &ett_lat, }; proto_lat = proto_register_protocol("Local Area Transport", "lat"); proto_register_field_array(proto_lat, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); } void proto_reg_handoff_lat(void) { old_dissector_add("ethertype", ETHERTYPE_LAT, dissect_lat); }
- Follow-Ups:
- Re: [Ethereal-dev] LAT Protocol specs
- From: Richard Sharpe
- Re: [Ethereal-dev] LAT Protocol specs
- From: Gerald Combs
- Re: [Ethereal-dev] LAT Protocol specs
- References:
- [Ethereal-dev] LAT Protocol specs
- From: Richard Sharpe
- [Ethereal-dev] LAT Protocol specs
- Prev by Date: [Ethereal-dev] LAT Protocol specs
- Next by Date: Re: [Ethereal-dev] add "/Capture/Stop" menu item
- Previous by thread: [Ethereal-dev] LAT Protocol specs
- Next by thread: Re: [Ethereal-dev] LAT Protocol specs
- Index(es):