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):





