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);
      }
    }
  }
}
Exemple #2
0
  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;