static gchar * aarphrdaddr_to_str(const guint8 *ad, int ad_len, guint16 type) { if (AARP_HW_IS_ETHER(type, ad_len)) { /* 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 const gchar * tvb_aarphrdaddr_to_str(tvbuff_t *tvb, gint offset, int ad_len, guint16 type) { if (AARP_HW_IS_ETHER(type, ad_len)) { /* Ethernet address (or Token Ring address, which is the same type of address). */ return tvb_ether_to_str(tvb, offset); } return tvb_bytes_to_str(tvb, offset, ad_len); }
static void dissect_aarp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint16 ar_hrd; guint16 ar_pro; guint8 ar_hln; guint8 ar_pln; guint16 ar_op; proto_tree *aarp_tree; proto_item *ti; const gchar *op_str; int sha_offset, spa_offset, tha_offset, tpa_offset; const gchar *sha_str, *spa_str, /* *tha_str, */ *tpa_str; col_set_str(pinfo->cinfo, COL_PROTOCOL, "AARP"); col_clear(pinfo->cinfo, COL_INFO); ar_hrd = tvb_get_ntohs(tvb, AR_HRD); ar_pro = tvb_get_ntohs(tvb, AR_PRO); ar_hln = tvb_get_guint8(tvb, AR_HLN); ar_pln = tvb_get_guint8(tvb, AR_PLN); ar_op = tvb_get_ntohs(tvb, AR_OP); /* Get the offsets of the addresses. */ sha_offset = MIN_AARP_HEADER_SIZE; spa_offset = sha_offset + ar_hln; tha_offset = spa_offset + ar_pln; tpa_offset = tha_offset + ar_hln; /* Extract the addresses. */ sha_str = tvb_aarphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd); spa_str = tvb_aarpproaddr_to_str(tvb, spa_offset, ar_pln, ar_pro); #if 0 /* TODO: tha_str is currently not shown nor parsed */ tha_str = tvb_aarphrdaddr_to_str(tvb, tha_offset, ar_hln, ar_hrd); #endif tpa_str = tvb_aarpproaddr_to_str(tvb, tpa_offset, ar_pln, ar_pro); switch (ar_op) { case AARP_REQUEST: case AARP_REQUEST_SWAPPED: col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s? Tell %s", tpa_str, spa_str); break; case AARP_REPLY: case AARP_REPLY_SWAPPED: col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s", spa_str, sha_str); break; case AARP_PROBE: case AARP_PROBE_SWAPPED: col_add_fstr(pinfo->cinfo, COL_INFO, "Is there a %s", tpa_str); break; default: col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown AARP opcode 0x%04x", ar_op); break; } if (tree) { if ((op_str = try_val_to_str(ar_op, op_vals))) ti = proto_tree_add_protocol_format(tree, proto_aarp, tvb, 0, MIN_AARP_HEADER_SIZE + 2*ar_hln + 2*ar_pln, "AppleTalk Address Resolution Protocol (%s)", op_str); else ti = proto_tree_add_protocol_format(tree, proto_aarp, tvb, 0, MIN_AARP_HEADER_SIZE + 2*ar_hln + 2*ar_pln, "AppleTalk Address Resolution Protocol (opcode 0x%04x)", ar_op); aarp_tree = proto_item_add_subtree(ti, ett_aarp); proto_tree_add_uint(aarp_tree, hf_aarp_hard_type, tvb, AR_HRD, 2, ar_hrd); proto_tree_add_uint(aarp_tree, hf_aarp_proto_type, tvb, AR_PRO, 2, ar_pro); proto_tree_add_uint(aarp_tree, hf_aarp_hard_size, tvb, AR_HLN, 1, ar_hln); proto_tree_add_uint(aarp_tree, hf_aarp_proto_size, tvb, AR_PLN, 1, ar_pln); proto_tree_add_uint(aarp_tree, hf_aarp_opcode, tvb, AR_OP, 2, ar_op); if (ar_hln != 0) { proto_tree_add_item(aarp_tree, AARP_HW_IS_ETHER(ar_hrd, ar_hln) ? hf_aarp_src_hw_mac : hf_aarp_src_hw, tvb, sha_offset, ar_hln, ENC_NA); } if (ar_pln != 0) { if (AARP_PRO_IS_ATALK(ar_pro, ar_pln)) { proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_src_proto_id, tvb, spa_offset, ar_pln, NULL, "%s", spa_str); } else { proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_src_proto, tvb, spa_offset, ar_pln, NULL, "%s", spa_str); } } if (ar_hln != 0) { proto_tree_add_item(aarp_tree, AARP_HW_IS_ETHER(ar_hrd, ar_hln) ? hf_aarp_dst_hw_mac : hf_aarp_dst_hw, tvb, tha_offset, ar_hln, ENC_NA); } if (ar_pln != 0) { if (AARP_PRO_IS_ATALK(ar_pro, ar_pln)) { proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_dst_proto_id, tvb, tpa_offset, ar_pln, NULL, "%s", tpa_str); } else { proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_dst_proto, tvb, tpa_offset, ar_pln, NULL, "%s", tpa_str); } } } }