Decode the hardware and protocol types.

Define the hardware type, protocol type, and opcode values fields as
enums.

Dissect the addresses the same way the ARP dissector does, so that we
don't completely give up if the hardware addresses aren't 6-byte
Ethernet/Token Ring addresses or the protocol addresses aren't 4-byte
Appletalk IDs.

svn path=/trunk/; revision=972
This commit is contained in:
Guy Harris 1999-11-04 08:21:04 +00:00
parent edeb0e9426
commit 1f77aab33f
1 changed files with 126 additions and 84 deletions

View File

@ -1,7 +1,7 @@
/* packet-aarp.c
* Routines for Appletalk ARP packet disassembly
*
* $Id: packet-aarp.c,v 1.12 1999/10/16 08:27:25 deniel Exp $
* $Id: packet-aarp.c,v 1.13 1999/11/04 08:21:04 guy Exp $
*
* Simon Wilkinson <sxw@dcs.ed.ac.uk>
*
@ -44,16 +44,6 @@ static int hf_aarp_src_id = -1;
static int hf_aarp_dst_ether = -1;
static int hf_aarp_dst_id = -1;
typedef struct _e_ether_aarp {
guint16 htype, ptype;
guint8 halen, palen;
guint16 op;
guint8 hsaddr[6];
guint8 psaddr[4];
guint8 hdaddr[6];
guint8 pdaddr[4];
} e_ether_aarp;
#ifndef AARP_REQUEST
#define AARP_REQUEST 0x0001
#endif
@ -64,8 +54,23 @@ typedef struct _e_ether_aarp {
#define AARP_PROBE 0x0003
#endif
gchar *
atalkid_to_str(guint8 *ad) {
static const value_string op_vals[] = {
{AARP_REQUEST, "AARP request" },
{AARP_REPLY, "AARP reply" },
{AARP_PROBE, "AARP probe" },
{0, NULL } };
/* AARP protocol HARDWARE identifiers. */
#define AARPHRD_ETHER 1 /* Ethernet 10Mbps */
#define AARPHRD_TR 2 /* Token Ring */
static const value_string hrd_vals[] = {
{AARPHRD_ETHER, "Ethernet" },
{AARPHRD_TR, "Token Ring" },
{0, NULL } };
static gchar *
atalkid_to_str(const guint8 *ad) {
gint node;
static gchar str[3][16];
static gchar *cur;
@ -82,91 +87,128 @@ atalkid_to_str(guint8 *ad) {
sprintf(cur, "%d.%d",node,ad[3]);
return cur;
}
static gchar *
aarphrdaddr_to_str(guint8 *ad, int ad_len, guint16 type) {
if ((type == AARPHRD_ETHER || type == AARPHRD_TR) && ad_len == 6) {
/* Ethernet address (or Token Ring address, which is the same type
of address). */
return ether_to_str(ad);
}
return bytes_to_str(ad, ad_len);
}
static gchar *
aarpproaddr_to_str(guint8 *ad, int ad_len, guint16 type) {
if (type == ETHERTYPE_ATALK && ad_len == 4) {
/* IP address. */
return atalkid_to_str(ad);
}
return bytes_to_str(ad, ad_len);
}
/* Offsets of fields within an AARP packet. */
#define AR_HRD 0
#define AR_PRO 2
#define AR_HLN 4
#define AR_PLN 5
#define AR_OP 6
#define MIN_AARP_HEADER_SIZE 8
void
dissect_aarp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
e_ether_aarp ea;
proto_tree *aarp_tree;
proto_item *ti;
gchar *op_str;
value_string op_vals[] = { {AARP_REQUEST, "AARP request" },
{AARP_REPLY, "AARP reply" },
{AARP_PROBE, "AARP probe" },
{0, NULL } };
guint16 ar_hrd;
guint16 ar_pro;
guint8 ar_hln;
guint8 ar_pln;
guint16 ar_op;
proto_tree *aarp_tree;
proto_item *ti;
gchar *op_str;
int sha_offset, spa_offset, tha_offset, tpa_offset;
gchar *sha_str, *spa_str, *tha_str, *tpa_str;
if (!BYTES_ARE_IN_FRAME(offset, sizeof(e_ether_aarp))) {
if (!BYTES_ARE_IN_FRAME(offset, MIN_AARP_HEADER_SIZE)) {
dissect_data(pd, offset, fd, tree);
return;
}
ea.htype = pntohs(&pd[offset]);
ea.ptype = pntohs(&pd[offset + 2]);
ea.halen = (guint8) pd[offset + 4];
ea.palen = (guint8) pd[offset + 5];
ea.op = pntohs(&pd[offset + 6]);
memcpy(&ea.hsaddr, &pd[offset + 8], 6);
memcpy(&ea.psaddr, &pd[offset + 14], 4);
memcpy(&ea.hdaddr, &pd[offset + 18], 6);
memcpy(&ea.pdaddr, &pd[offset + 24], 4);
ar_hrd = pntohs(&pd[offset + AR_HRD]);
ar_pro = pntohs(&pd[offset + AR_PRO]);
ar_hln = (guint8) pd[offset + AR_HLN];
ar_pln = (guint8) pd[offset + AR_PLN];
ar_op = pntohs(&pd[offset + AR_OP]);
if (!BYTES_ARE_IN_FRAME(offset,
MIN_AARP_HEADER_SIZE + ar_hln*2 + ar_pln*2)) {
dissect_data(pd, offset, fd, tree);
return;
}
/* Extract the addresses. */
sha_offset = offset + MIN_AARP_HEADER_SIZE;
sha_str = aarphrdaddr_to_str((guint8 *) &pd[sha_offset], ar_hln, ar_hrd);
spa_offset = sha_offset + ar_hln;
spa_str = aarpproaddr_to_str((guint8 *) &pd[spa_offset], ar_pln, ar_pro);
tha_offset = spa_offset + ar_pln;
tha_str = aarphrdaddr_to_str((guint8 *) &pd[tha_offset], ar_hln, ar_hrd);
tpa_offset = tha_offset + ar_hln;
tpa_str = aarpproaddr_to_str((guint8 *) &pd[tpa_offset], ar_pln, ar_pro);
if(check_col(fd, COL_PROTOCOL))
col_add_str(fd, COL_PROTOCOL, "AARP");
if (tree) {
if ((op_str = match_strval(ea.op, op_vals)))
ti = proto_tree_add_item_format(tree, proto_aarp, offset, 28, NULL, op_str);
else
ti = proto_tree_add_item_format(tree, proto_aarp, offset, 28, NULL,
"Unknown AARP (opcode 0x%04x)", ea.op);
aarp_tree = proto_item_add_subtree(ti, ETT_AARP);
proto_tree_add_item(aarp_tree, hf_aarp_hard_type, offset, 2, ea.htype);
proto_tree_add_item(aarp_tree, hf_aarp_proto_type, offset + 2, 2,
ea.ptype);
proto_tree_add_item(aarp_tree, hf_aarp_hard_size, offset + 4, 1,
ea.halen);
proto_tree_add_item(aarp_tree, hf_aarp_proto_size, offset + 5, 1,
ea.palen);
proto_tree_add_item_format(aarp_tree, hf_aarp_opcode, offset + 6, 2,
ea.op,
"Opcode: 0x%04x (%s)",
ea.op, op_str ? op_str : "Unknown");
proto_tree_add_item(aarp_tree, hf_aarp_src_ether, offset + 8, 6,
ea.hsaddr);
proto_tree_add_item_format(aarp_tree, hf_aarp_src_id, offset + 14, 4,
ea.psaddr,
"Sender ID: %s",
atalkid_to_str((guint8 *) ea.psaddr));
proto_tree_add_item(aarp_tree, hf_aarp_dst_ether, offset + 18, 6,
ea.hdaddr);
proto_tree_add_item_format(aarp_tree, hf_aarp_dst_id, offset + 24, 4,
ea.pdaddr,
"Target ID: %s",
atalkid_to_str((guint8 *) ea.pdaddr));
}
if (ea.ptype != ETHERTYPE_AARP && ea.ptype != ETHERTYPE_ATALK &&
check_col(fd, COL_INFO)) {
col_add_fstr(fd, COL_INFO, "h/w %d (%d) prot %d (%d) op 0x%04x",
ea.htype, ea.halen, ea.ptype, ea.palen, ea.op);
return;
}
if (check_col(fd, COL_INFO)) {
switch (ea.op) {
switch (ar_op) {
case AARP_REQUEST:
col_add_fstr(fd, COL_INFO, "Who has %s? Tell %s",
atalkid_to_str((guint8 *) ea.pdaddr), atalkid_to_str((guint8 *) ea.psaddr));
col_add_fstr(fd, COL_INFO, "Who has %s? Tell %s", tpa_str, spa_str);
break;
case AARP_REPLY:
col_add_fstr(fd, COL_INFO, "%s is at %s",
atalkid_to_str((guint8 *) ea.psaddr),
ether_to_str((guint8 *) ea.hsaddr));
col_add_fstr(fd, COL_INFO, "%s is at %s", spa_str, sha_str);
break;
case AARP_PROBE:
col_add_fstr(fd, COL_INFO, "Is there a %s",
atalkid_to_str((guint8 *) ea.pdaddr));
col_add_fstr(fd, COL_INFO, "Is there a %s", tpa_str);
break;
default:
col_add_fstr(fd, COL_INFO, "Unknown AARP opcode 0x%04x", ar_op);
break;
}
}
if (tree) {
if ((op_str = match_strval(ar_op, op_vals)))
ti = proto_tree_add_item_format(tree, proto_aarp, offset,
MIN_AARP_HEADER_SIZE + 2*ar_hln +
2*ar_pln, NULL, op_str);
else
ti = proto_tree_add_item_format(tree, proto_aarp, offset,
MIN_AARP_HEADER_SIZE + 2*ar_hln +
2*ar_pln, NULL,
"Unknown AARP (opcode 0x%04x)", ar_op);
aarp_tree = proto_item_add_subtree(ti, ETT_AARP);
proto_tree_add_item(aarp_tree, hf_aarp_hard_type, offset + AR_HRD, 2,
ar_hrd);
proto_tree_add_item(aarp_tree, hf_aarp_proto_type, offset + AR_PRO, 2,
ar_pro);
proto_tree_add_item(aarp_tree, hf_aarp_hard_size, offset + AR_HLN, 1,
ar_hln);
proto_tree_add_item(aarp_tree, hf_aarp_proto_size, offset + AR_PLN, 1,
ar_pln);
proto_tree_add_item(aarp_tree, hf_aarp_opcode, offset + AR_OP, 2,
ar_op);
proto_tree_add_item_format(aarp_tree, hf_aarp_src_ether, sha_offset, ar_hln,
&pd[sha_offset],
"Sender hardware address: %s", sha_str);
proto_tree_add_item_format(aarp_tree, hf_aarp_src_id, spa_offset, ar_pln,
&pd[spa_offset],
"Sender ID: %s", spa_str);
proto_tree_add_item_format(aarp_tree, hf_aarp_dst_ether, tha_offset, ar_hln,
&pd[tha_offset],
"Target hardware address: %s", tha_str);
proto_tree_add_item_format(aarp_tree, hf_aarp_dst_id, tpa_offset, ar_pln,
&pd[tpa_offset],
"Target ID: %s", tpa_str);
}
}
void
@ -175,12 +217,12 @@ proto_register_aarp(void)
static hf_register_info hf[] = {
{ &hf_aarp_hard_type,
{ "Hardware type", "aarp.hard.type",
FT_UINT16, BASE_HEX, NULL, 0x0,
FT_UINT16, BASE_HEX, VALS(hrd_vals), 0x0,
"" }},
{ &hf_aarp_proto_type,
{ "Protocol type", "aarp.proto.type",
FT_UINT16, BASE_HEX, NULL, 0x0,
FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
"" }},
{ &hf_aarp_hard_size,
@ -195,27 +237,27 @@ proto_register_aarp(void)
{ &hf_aarp_opcode,
{ "Opcode", "aarp.opcode",
FT_UINT16, BASE_DEC, NULL, 0x0,
FT_UINT16, BASE_DEC, VALS(op_vals), 0x0,
"" }},
{ &hf_aarp_src_ether,
{ "Sender ether", "aarp.src.ether",
FT_ETHER, BASE_NONE, NULL, 0x0,
FT_BYTES, BASE_NONE, NULL, 0x0,
"" }},
{ &hf_aarp_src_id,
{ "Sender ID", "aarp.src.id",
FT_UINT32, BASE_HEX, NULL, 0x0,
FT_BYTES, BASE_HEX, NULL, 0x0,
"" }},
{ &hf_aarp_dst_ether,
{ "Target ether", "aarp.dst.ether",
FT_ETHER, BASE_NONE, NULL, 0x0,
FT_BYTES, BASE_NONE, NULL, 0x0,
"" }},
{ &hf_aarp_dst_id,
{ "Target ID", "aarp.dst.id",
FT_UINT32, BASE_HEX, NULL, 0x0,
FT_BYTES, BASE_HEX, NULL, 0x0,
"" }},
};