aboutsummaryrefslogtreecommitdiffstats
path: root/packet-aarp.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>1999-11-04 08:21:04 +0000
committerGuy Harris <guy@alum.mit.edu>1999-11-04 08:21:04 +0000
commit1f77aab33f841d81d9d7ab81ff67c2e8cea5cc28 (patch)
tree616ffb79380f3fccbfbb5c5c92a3316fc93e95b2 /packet-aarp.c
parentedeb0e9426117396a6c630476ac942821c3d5f56 (diff)
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
Diffstat (limited to 'packet-aarp.c')
-rw-r--r--packet-aarp.c212
1 files changed, 127 insertions, 85 deletions
diff --git a/packet-aarp.c b/packet-aarp.c
index 1c9db7e016..757a79cc51 100644
--- a/packet-aarp.c
+++ b/packet-aarp.c
@@ -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 } };
-
- if (!BYTES_ARE_IN_FRAME(offset, sizeof(e_ether_aarp))) {
+ 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, 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,
"" }},
};