Esempio n. 1
0
static void
decode_iei_ip_address(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
  guint8 addr_type;
  guint32 ip4_addr;
  struct e_in6_addr ip6_addr;

  addr_type = tvb_get_guint8(bi->tvb, bi->offset);
  proto_tree_add_item(bi->nsip_tree, hf_nsip_ip_address_type,
                          bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN);
  switch (addr_type) {
  case NSIP_IP_ADDRESS_TYPE_IPV4:
    ie->total_length = 2 + ipv4_element.address_length;
    ip4_addr = tvb_get_ipv4(bi->tvb, bi->offset+1);
    proto_tree_add_ipv4(bi->nsip_tree, hf_nsip_ip_address_ipv4,
        bi->tvb, ie_start_offset, ie->total_length,
        ip4_addr);
    break;
  case NSIP_IP_ADDRESS_TYPE_IPV6:
    ie->total_length = 2 + ipv6_element.address_length;
    tvb_get_ipv6(bi->tvb, bi->offset+1, &ip6_addr);
    proto_tree_add_ipv6(bi->nsip_tree, hf_nsip_ip_address_ipv4,
        bi->tvb, ie_start_offset, ie->total_length,
        (guint8 *)&ip6_addr);
    break;
  default:
    return; /* error */
  }
  bi->offset += ie->value_length;
}
Esempio n. 2
0
static int
zebra_route(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 len,
	    guint8 family)
{
	guint32	prefix4;
	guint8 message, prefixlen, buffer6[16];

	proto_tree_add_item(tree, hf_zebra_type, tvb,
			    offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	proto_tree_add_item(tree, hf_zebra_rtflags, tvb,
			    offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	message = tvb_get_guint8(tvb, offset);
	offset = zebra_route_message(tree, tvb, offset, message);

	prefixlen = tvb_get_guint8(tvb, offset);
	proto_tree_add_uint(tree, hf_zebra_prefixlen, tvb,
			    offset, 1, prefixlen);
	offset += 1;

	if (family == ZEBRA_FAMILY_IPV6) {
		memset(buffer6, '\0', sizeof buffer6);
		tvb_memcpy(tvb, buffer6, offset,
			   MIN((unsigned) PSIZE(prefixlen), sizeof buffer6));
		proto_tree_add_ipv6(tree, hf_zebra_prefix6,
				    tvb, offset, PSIZE(prefixlen), buffer6);
	}else {
		prefix4 = 0;
		tvb_memcpy(tvb, (guint8 *)&prefix4, offset,
			   MIN((unsigned) PSIZE(prefixlen), sizeof prefix4));
		proto_tree_add_ipv4(tree, hf_zebra_prefix4,
				    tvb, offset, PSIZE(prefixlen), prefix4);
	}
	offset += PSIZE(prefixlen);

	if (message & ZEBRA_ZAPI_MESSAGE_NEXTHOP) {
		offset = zebra_route_nexthop(tree, tvb, offset, len);
	}
	if (message & ZEBRA_ZAPI_MESSAGE_IFINDEX) {
		offset = zebra_route_ifindex(tree, tvb, offset, len);
	}
	if (message & ZEBRA_ZAPI_MESSAGE_DISTANCE) {
		proto_tree_add_item(tree, hf_zebra_distance,
				    tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;
	}
	if (message & ZEBRA_ZAPI_MESSAGE_METRIC) {
		proto_tree_add_item(tree, hf_zebra_metric,
				    tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
	}
	return offset;
}
/*
 * Name: isis_dissect_ipv6_int_clv()
 *
 * Description:
 *	Take apart the CLV that lists all the IPv6 interfaces.  The
 *	meaning of which is slightly different for the different base packet
 *	types, but the display is not different.  What we have is n ip
 *	addresses, plain and simple.
 *
 * Input:
 *	tvbuff_t * : tvbuffer for packet data
 *	proto_tree * : protocol display tree to fill out.  May be NULL
 *	int : offset into packet data where we are.
 *	int : length of clv we are decoding
 *	int : tree id to use for proto tree.
 *
 * Output:
 *	void, but we will add to proto tree if !NULL.
 */
void
isis_dissect_ipv6_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
	int length, int tree_id)
{
	guint8 addr [16];

	if ( length <= 0 ) {
		return;
	}

	while ( length > 0 ) {
		if ( length < 16 ) {
			isis_dissect_unknown(tvb, tree, offset,
				"Short IPv6 interface address (%d vs 16)",length );
			return;
		}
		tvb_memcpy(tvb, addr, offset, sizeof(addr));
		if ( tree ) {
			proto_tree_add_ipv6(tree, tree_id, tvb, offset, 16, addr);
		}
		offset += 16;
		length -= 16;
	}
}
Esempio n. 4
0
/*
 * Name: isis_dissect_ipv6_int_clv()
 *
 * Description:
 *    Take apart the CLV that lists all the IPv6 interfaces.  The
 *    meaning of which is slightly different for the different base packet
 *    types, but the display is not different.  What we have is n ip
 *    addresses, plain and simple.
 *
 * Input:
 *    tvbuff_t * : tvbuffer for packet data
 *    proto_tree * : protocol display tree to fill out.  May be NULL
 *    int : offset into packet data where we are.
 *    int : length of clv we are decoding
 *    int : tree id to use for proto tree.
 *
 * Output:
 *    void, but we will add to proto tree if !NULL.
 */
void
isis_dissect_ipv6_int_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, expert_field* expert,
    int offset, int length, int tree_id)
{
    guint8 addr [16];

    if ( length <= 0 ) {
        return;
    }

    while ( length > 0 ) {
        if ( length < 16 ) {
            proto_tree_add_expert_format(tree, pinfo, expert, tvb, offset, -1,
                "Short IPv6 interface address (%d vs 16)",length );
            return;
        }
        tvb_memcpy(tvb, addr, offset, sizeof(addr));
        if ( tree ) {
            proto_tree_add_ipv6(tree, tree_id, tvb, offset, 16, addr);
        }
        offset += 16;
        length -= 16;
    }
}
Esempio n. 5
0
static int dissect_pbb_addressblock(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint maxoffset,
    guint8 addressType, guint8 addressSize) {
  guint8 addr[MAX_ADDR_SIZE];

  guint8 numAddr;
  guint8 address_flags;
  guint8 head_length = 0, tail_length = 0;
  guint block_length = 0, midSize = 0;
  guint block_index = 0, head_index = 0, tail_index = 0, mid_index = 0, prefix_index = 0;

  proto_tree *addr_tree = NULL;
  proto_tree *addrFlags_tree = NULL;
  proto_tree *addrValue_tree = NULL;

  proto_item *addr_item = NULL;
  proto_item *addrFlags_item = NULL;
  proto_item *addrValue_item = NULL;

  int i = 0;

  if (maxoffset - offset < 2) {
    proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset,
        "Not enough octets for minimal addressblock header");
    return tvb_reported_length(tvb);
  }

  DISSECTOR_ASSERT(addressSize <= MAX_ADDR_SIZE);

  memset(addr, 0, addressSize);

  block_length = 2;
  block_index = offset;
  midSize = addressSize;

  numAddr = tvb_get_guint8(tvb, offset++);
  address_flags = tvb_get_guint8(tvb, offset++);

  if ((address_flags & ADDR_HASHEAD) != 0) {
    head_index = offset;

    if (maxoffset - offset <= 0) {
      proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset,
         "Not enough octets for addressblock head");
      return tvb_reported_length(tvb);
    }
    head_length = tvb_get_guint8(tvb, offset++);

    if (head_length > addressSize-1) {
      proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset,
          "address head length is too long");
      return tvb_reported_length(tvb);
    }
    if (maxoffset - offset < head_length) {
      proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset,
          "Not enough octets for addressblock head");
      return tvb_reported_length(tvb);
    }
    tvb_memcpy(tvb, addr, offset, head_length);

    midSize -= head_length;
    block_length += (head_length+1);
    offset += head_length;
  }
  if ((address_flags & ADDR_HASZEROTAIL) != 0) {
    tail_index = offset;

    if (maxoffset - offset <= 0) {
      proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset,
          "Not enough octets for addressblock tail");
      return tvb_reported_length(tvb);
    }
    tail_length = tvb_get_guint8(tvb, offset++);
    if (tail_length > addressSize-1-head_length) {
      proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset,
          "address tail length is too long");
      return tvb_reported_length(tvb);
    }
    midSize -= tail_length;
    block_length++;
  }
  else if ((address_flags & ADDR_HASFULLTAIL) != 0) {
    tail_index = offset;

    if (maxoffset - offset <= 0) {
      proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset,
          "Not enough octets for addressblock tail");
      return tvb_reported_length(tvb);
    }
    tail_length = tvb_get_guint8(tvb, offset++);
    if (tail_length > addressSize-1-head_length) {
      proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset,
          "address tail length is too long");
      return tvb_reported_length(tvb);
    }

    if (maxoffset - offset < tail_length) {
      proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset,
          "Not enough octets for addressblock tail");
      return tvb_reported_length(tvb);
    }
    tvb_memcpy(tvb, &addr[addressSize - tail_length], offset, tail_length);

    midSize -= tail_length;
    block_length += (tail_length+1);
    offset += tail_length;
  }

  mid_index = offset;
  block_length += numAddr * midSize;
  offset += numAddr * midSize;

  if ((address_flags & ADDR_HASSINGLEPRELEN) != 0) {
    prefix_index = offset;
    block_length++;
  }
  else if ((address_flags & ADDR_HASMULTIPRELEN) != 0) {
    prefix_index = offset;
    block_length += numAddr;
  }

  if (maxoffset < block_index + block_length) {
    proto_tree_add_expert_format(tree, pinfo, &ei_packetbb_error, tvb, offset, maxoffset - offset,
        "Not enough octets for address block");
    return maxoffset;
  }

  /* add address tree */
  addr_item = proto_tree_add_item(tree, hf_packetbb_addr, tvb, block_index, block_length, ENC_NA);
  addr_tree = proto_item_add_subtree(addr_item, ett_packetbb_addr);
  proto_item_append_text(addr_item, " (%d addresses)", numAddr);

  /* add num-addr */
  proto_tree_add_item(addr_tree, hf_packetbb_addr_num, tvb, block_index, 1, ENC_BIG_ENDIAN);

  /* add flags */
  addrFlags_item = proto_tree_add_item(addr_tree, hf_packetbb_addr_flags, tvb, block_index+1, 1, ENC_BIG_ENDIAN);
  addrFlags_tree = proto_item_add_subtree(addrFlags_item, ett_packetbb_addr_flags);

  proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_hashead, tvb, block_index+1, 1, ENC_BIG_ENDIAN);
  proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_hasfulltail, tvb, block_index+1, 1, ENC_BIG_ENDIAN);
  proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_haszerotail, tvb, block_index+1, 1, ENC_BIG_ENDIAN);
  proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_hassingleprelen, tvb, block_index+1, 1, ENC_BIG_ENDIAN);
  proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_hasmultiprelen, tvb, block_index+1, 1, ENC_BIG_ENDIAN);

  if ((address_flags & ADDR_HASHEAD) != 0) {
    /* add head */
    proto_tree_add_item(addr_tree, hf_packetbb_addr_head, tvb, head_index, head_length+1, ENC_NA);
  }

  if ((address_flags & ADDR_HASFULLTAIL) != 0) {
    /* add full tail */
    proto_tree_add_item(addr_tree, hf_packetbb_addr_tail, tvb, tail_index, tail_length+1, ENC_NA);
  }
  else if ((address_flags & ADDR_HASZEROTAIL) != 0) {
    /* add zero tail */
    proto_tree_add_item(addr_tree, hf_packetbb_addr_tail, tvb, tail_index, 1, ENC_NA);
  }
  for (i=0; i<numAddr; i++) {
    guint32 ipv4 = 0;
    guint8 prefix = addressSize * 8;

    tvb_memcpy(tvb, &addr[head_length], mid_index + midSize*i, midSize);
    ipv4 = (addr[3] << 24) + (addr[2] << 16) + (addr[1] << 8) + addr[0];

    switch (addressType) {
      case 0:
        addrValue_item = proto_tree_add_ipv4(addr_tree, hf_packetbb_addr_value[addressType],
            tvb, mid_index, block_index + block_length - mid_index, ipv4);
        break;
      case 1:
        addrValue_item = proto_tree_add_ipv6(addr_tree, hf_packetbb_addr_value[addressType],
            tvb, mid_index, block_index + block_length - mid_index, (struct e_in6_addr *)addr);
        break;
      case 2:
        addrValue_item = proto_tree_add_ether(addr_tree, hf_packetbb_addr_value[addressType],
            tvb, mid_index, block_index + block_length - mid_index, addr);
        break;
      case 3:
        addrValue_item = proto_tree_add_bytes(addr_tree, hf_packetbb_addr_value[addressType],
            tvb, mid_index, block_index + block_length - mid_index, addr);
        break;
      default:
        break;
    }
    addrValue_tree = proto_item_add_subtree(addrValue_item, ett_packetbb_addr_value);

    proto_tree_add_item(addrValue_tree, hf_packetbb_addr_value_mid, tvb,
        mid_index + midSize*i, midSize, ENC_NA);

    if ((address_flags & ADDR_HASSINGLEPRELEN) != 0) {
      prefix = tvb_get_guint8(tvb, prefix_index);
      proto_tree_add_item(addrValue_tree, hf_packetbb_addr_value_prefix, tvb, prefix_index, 1, ENC_BIG_ENDIAN);
    }
    else if ((address_flags & ADDR_HASMULTIPRELEN) != 0) {
      prefix = tvb_get_guint8(tvb, prefix_index + i);
      proto_tree_add_item(addrValue_tree, hf_packetbb_addr_value_prefix, tvb, prefix_index + i, 1, ENC_BIG_ENDIAN);
    }
    proto_item_append_text(addrValue_item, "/%d", prefix);
  }

  offset = dissect_pbb_tlvblock(tvb, pinfo, addr_tree, block_index + block_length, maxoffset, numAddr);
  return offset;
}
Esempio n. 6
0
static int
dissect_ppcap_destination_address(tvbuff_t *tvb, packet_info * pinfo, proto_tree * ppcap_tree1, int offset)
{
	int key2;
	guint16 msg_len;
	msg_len = tvb_get_ntohs(tvb, offset);
	proto_tree_add_item( ppcap_tree1, hf_ppcap_length, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset  = offset + 2;
	proto_tree_add_item(ppcap_tree1, hf_ppcap_destreserved, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	key2 = tvb_get_ntohs(tvb, offset);
	proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	if (key2 == 1)
	{
		ssn = tvb_get_guint8(tvb, offset);
		proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn1, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		proto_tree_add_item(ppcap_tree1, hf_ppcap_spc1, tvb, offset, 3, ENC_BIG_ENDIAN);

		/*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/
		mtp3_addr_dpc = wmem_new0(wmem_packet_scope(), mtp3_addr_pc_t);
		mtp3_addr_dpc->pc = (guint32)tvb_get_ntoh24(tvb, offset);
		mtp3_addr_dpc->type = ITU_STANDARD;
		mtp3_addr_dpc->ni = 0;
		SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc);

		if (msg_len%4)
			msg_len = msg_len + (4 - (msg_len%4));

		offset += msg_len-1;
		return offset;

	}
	else if (key2 == 2)
	{
		proto_tree_add_item(ppcap_tree1, hf_ppcap_dpc, tvb, offset, 4, ENC_BIG_ENDIAN);

		/*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/
		mtp3_addr_dpc = wmem_new0(wmem_packet_scope(), mtp3_addr_pc_t);
		mtp3_addr_dpc->pc = tvb_get_ntohl(tvb, offset);
		mtp3_addr_dpc->type = ITU_STANDARD;
		mtp3_addr_dpc->ni = 0;
		SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc);
	}
	else if (key2 == 3)
	{
		if (msg_len%16 != 0)
		{
			proto_tree_add_ipv4(ppcap_tree1, hf_ppcap_destination_ip_address1, tvb, offset, msg_len, tvb_get_ipv4(tvb, offset));
			TVB_SET_ADDRESS(&pinfo->net_dst, AT_IPv4, tvb, offset, 4);
			COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst);
		}
		else
		{
			struct e_in6_addr value;

			tvb_get_ipv6(tvb, offset,&value);
			proto_tree_add_ipv6(ppcap_tree1, hf_ppcap_destination_ip_address2, tvb, offset, msg_len, &value);
			TVB_SET_ADDRESS(&pinfo->net_dst, AT_IPv6, tvb, offset, 6);
			COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst);
		}
	}

	else if (key2 == 4)
	{
		char *string;
		string = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, msg_len, ENC_UTF_8|ENC_NA);
		proto_tree_add_string(ppcap_tree1, hf_ppcap_destination_nodeid, tvb, offset, msg_len, string);
		TVB_SET_ADDRESS(&pinfo->net_dst, AT_STRINGZ, tvb, offset, msg_len);
		COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst);
	}

	if (msg_len%4)
		msg_len = msg_len+(4-(msg_len%4));

	offset += msg_len;

	return offset;
}
Esempio n. 7
0
static int
dissect_ppcap_source_address(tvbuff_t *tvb, packet_info *pinfo, proto_tree * ppcap_tree1, int offset)
{
	int key1;
	guint16 msg_len;
	msg_len = tvb_get_ntohs(tvb, offset);
	proto_tree_add_item( ppcap_tree1, hf_ppcap_length, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset  = offset + 2;
	proto_tree_add_item(ppcap_tree1, hf_ppcap_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	key1 = tvb_get_ntohs(tvb, offset);
	proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	if (key1 == 1)
	{
		proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;
		proto_tree_add_item(ppcap_tree1, hf_ppcap_spc, tvb, offset, 3, ENC_BIG_ENDIAN);
		/*src_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/
		mtp3_addr_opc = wmem_new0(wmem_packet_scope(), mtp3_addr_pc_t);
		mtp3_addr_opc->pc = (guint32 )tvb_get_ntoh24(tvb, offset);
		mtp3_addr_opc->type = ITU_STANDARD;
		mtp3_addr_opc->ni = 0;
		/*SET_ADDRESS(&pinfo->net_src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc);*/
		SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc);
		if (msg_len%4)
			msg_len = msg_len + (4 - (msg_len%4));

		offset += msg_len-1;
		return offset;
	}
	else if (key1 == 2)
	{
		proto_tree_add_item(ppcap_tree1, hf_ppcap_opc, tvb, offset, msg_len, ENC_BIG_ENDIAN);

		/*src_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/
		mtp3_addr_opc = wmem_new0(wmem_packet_scope(), mtp3_addr_pc_t);
		mtp3_addr_opc->pc = tvb_get_ntohl(tvb, offset);
		mtp3_addr_opc->type = ITU_STANDARD;
		mtp3_addr_opc->ni = 0;
		SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc);
	}
	else if (key1 == 3)
	{
		if (msg_len%16 != 0)
		{

			proto_tree_add_ipv4(ppcap_tree1, hf_ppcap_source_ip_address1, tvb, offset, msg_len, tvb_get_ipv4(tvb, offset));
			TVB_SET_ADDRESS(&pinfo->net_src, AT_IPv4, tvb, offset, 4);
			COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src);
		}
		else
		{
			struct e_in6_addr value;
			tvb_get_ipv6(tvb, offset, &value);
			proto_tree_add_ipv6(ppcap_tree1, hf_ppcap_source_ip_address2, tvb, offset, msg_len, &value);
			TVB_SET_ADDRESS(&pinfo->net_src, AT_IPv6, tvb, offset, 6);
			COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src);
		}
	}

	else if (key1 == 4)

	{
		proto_tree_add_item(ppcap_tree1, hf_ppcap_source_nodeid, tvb, offset, msg_len, ENC_ASCII|ENC_NA);
		TVB_SET_ADDRESS(&pinfo->net_src, AT_STRINGZ, tvb, offset, msg_len);
		COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src);
	}
	if (msg_len%4)
		msg_len = msg_len + (4 - (msg_len%4));
	offset += msg_len;
	return offset;
}
Esempio n. 8
0
static void
dissect_aodv_draft_01_v6_rrep(tvbuff_t *tvb, packet_info *pinfo,
			      proto_tree *aodv_tree, proto_item *ti)
{
    int offset = 1;
    proto_item *tj;
    proto_tree *aodv_flags_tree;
    guint8 flags;
    guint8 prefix_sz;
    guint8 hop_count;
    guint32 dest_seqno;
    struct e_in6_addr dest_addr_v6;
    struct e_in6_addr orig_addr_v6;
    guint32 lifetime;
    int extlen;

    flags = tvb_get_guint8(tvb, offset);
    if (aodv_tree) {
	tj = proto_tree_add_text(aodv_tree, tvb, offset, 1, "Flags:");
	aodv_flags_tree = proto_item_add_subtree(tj, ett_aodv_flags);
	proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rrep_repair,
			       tvb, offset, 1, flags);
	proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rrep_ack, tvb,
			       offset, 1, flags);
	if (flags & RREP_REP)
	    proto_item_append_text(tj, " R");
	if (flags & RREP_ACK_REQ)
	    proto_item_append_text(tj, " A");
    }
    offset += 1;

    prefix_sz = tvb_get_guint8(tvb, offset) & 0x7F;
    if (aodv_tree)
	proto_tree_add_uint(aodv_tree, hf_aodv_prefix_sz, tvb, offset, 1,
			    prefix_sz);
    offset += 1;

    hop_count = tvb_get_guint8(tvb, offset);
    if (aodv_tree)
	proto_tree_add_uint(aodv_tree, hf_aodv_hopcount, tvb, offset, 1,
			    hop_count);
    offset += 1;

    dest_seqno = tvb_get_ntohl(tvb, offset);
    if (aodv_tree)
	proto_tree_add_uint(aodv_tree, hf_aodv_dest_seqno, tvb, offset, 4,
			    dest_seqno);
    offset += 4;

    tvb_get_ipv6(tvb, offset, &dest_addr_v6);
    if (aodv_tree) {
	proto_tree_add_ipv6(aodv_tree, hf_aodv_dest_ipv6, tvb, offset,
			    INET6_ADDRLEN, (guint8 *)&dest_addr_v6);
	proto_item_append_text(ti, ", Dest IP: %s",
			       ip6_to_str(&dest_addr_v6));
    }

	col_append_fstr(pinfo->cinfo, COL_INFO, ", D: %s",
			ip6_to_str(&dest_addr_v6));
    offset += INET6_ADDRLEN;

    tvb_get_ipv6(tvb, offset, &orig_addr_v6);
    if (aodv_tree) {
	proto_tree_add_ipv6(aodv_tree, hf_aodv_orig_ipv6, tvb, offset,
			    INET6_ADDRLEN, (guint8 *)&orig_addr_v6);
	proto_item_append_text(ti, ", Orig IP: %s",
			       ip6_to_str(&orig_addr_v6));
    }

	col_append_fstr(pinfo->cinfo, COL_INFO, ", O: %s",
			ip6_to_str(&orig_addr_v6));
    offset += INET6_ADDRLEN;

    lifetime = tvb_get_ntohl(tvb, offset);
    if (aodv_tree) {
	proto_tree_add_uint(aodv_tree, hf_aodv_lifetime, tvb, offset, 4,
			    lifetime);
	proto_item_append_text(ti, ", Lifetime=%u", lifetime);
    }

	col_append_fstr(pinfo->cinfo, COL_INFO, " Hcnt=%u DSN=%u Lifetime=%u",
			hop_count,
			dest_seqno,
			lifetime);
    offset += 4;

    if (aodv_tree) {
	extlen = tvb_reported_length_remaining(tvb, offset);
	if (extlen > 0)
	    dissect_aodv_ext(tvb, offset, aodv_tree);
    }
}
Esempio n. 9
0
static void
dissect_aodv_draft_01_v6_rreq(tvbuff_t *tvb, packet_info *pinfo,
			      proto_tree *aodv_tree, proto_item *ti)
{
    int offset = 1;
    proto_item *tj;
    proto_tree *aodv_flags_tree;
    guint8 flags;
    guint8 hop_count;
    guint32 rreq_id;
    guint32 dest_seqno;
    guint32 orig_seqno;
    struct e_in6_addr dest_addr_v6;
    struct e_in6_addr orig_addr_v6;
    int extlen;

    flags = tvb_get_guint8(tvb, offset);
    if (aodv_tree) {
	tj = proto_tree_add_text(aodv_tree, tvb, offset, 1, "Flags:");
	aodv_flags_tree = proto_item_add_subtree(tj, ett_aodv_flags);
	proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_join,
			       tvb, offset, 1, flags);
	proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_repair,
			       tvb, offset, 1, flags);
	proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_gratuitous,
			       tvb, offset, 1, flags);
	proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_destinationonly,
			       tvb, offset, 1, flags);
	proto_tree_add_boolean(aodv_flags_tree, hf_aodv_flags_rreq_unknown,
			       tvb, offset, 1, flags);
	if (flags & RREQ_JOIN)
	    proto_item_append_text(tj, " J");
	if (flags & RREQ_REP)
	    proto_item_append_text(tj, " R");
	if (flags & RREQ_GRATRREP)
	    proto_item_append_text(tj, " G");
	if (flags & RREQ_DESTONLY)
	    proto_item_append_text(tj, " D");
	if (flags & RREQ_UNKNSEQ)
	    proto_item_append_text(tj, " U");
    }
    offset += 2;	/* skip reserved byte */

    hop_count = tvb_get_guint8(tvb, offset);
    if (aodv_tree)
	proto_tree_add_uint(aodv_tree, hf_aodv_hopcount, tvb, offset, 1,
			     hop_count);
    offset += 1;

    rreq_id = tvb_get_ntohl(tvb, offset);
    if (aodv_tree)
	proto_tree_add_uint(aodv_tree, hf_aodv_rreq_id, tvb, offset, 4,
			    rreq_id);
    offset += 4;

    dest_seqno = tvb_get_ntohl(tvb, offset);
    if (aodv_tree)
	proto_tree_add_uint(aodv_tree, hf_aodv_dest_seqno, tvb, offset, 4,
			    dest_seqno);
    offset += 4;

    orig_seqno = tvb_get_ntohl(tvb, offset);
    if (aodv_tree)
	proto_tree_add_uint(aodv_tree, hf_aodv_orig_seqno, tvb, offset, 4,
			    orig_seqno);
    offset += 4;

    tvb_get_ipv6(tvb, offset, &dest_addr_v6);
    if (aodv_tree) {
	proto_tree_add_ipv6(aodv_tree, hf_aodv_dest_ipv6, tvb, offset,
			    INET6_ADDRLEN, (guint8 *)&dest_addr_v6);
	proto_item_append_text(ti, ", Dest IP: %s",
			       ip6_to_str(&dest_addr_v6));
    }

	col_append_fstr(pinfo->cinfo, COL_INFO, ", D: %s",
			ip6_to_str(&dest_addr_v6));
    offset += INET6_ADDRLEN;

    tvb_get_ipv6(tvb, offset, &orig_addr_v6);
    if (aodv_tree) {
	proto_tree_add_ipv6(aodv_tree, hf_aodv_orig_ipv6, tvb, offset,
			    INET6_ADDRLEN, (guint8 *)&orig_addr_v6);
	proto_item_append_text(ti, ", Orig IP: %s",
			       ip6_to_str(&orig_addr_v6));
    }

	col_append_fstr(pinfo->cinfo, COL_INFO,
			", O: %s Id=%u Hcnt=%u DSN=%u OSN=%u",
			ip6_to_str(&orig_addr_v6),
			rreq_id,
			hop_count,
			dest_seqno,
			orig_seqno);
    offset += INET6_ADDRLEN;

    if (aodv_tree) {
	extlen = tvb_reported_length_remaining(tvb, offset);
	if (extlen > 0)
	    dissect_aodv_ext(tvb, offset, aodv_tree);
    }
}
Esempio n. 10
0
static void
dissect_ftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    gboolean        is_request;
    proto_tree     *ftp_tree          = NULL;
    proto_tree     *reqresp_tree      = NULL;
    proto_item     *ti, *hidden_item;
    gint            offset;
    const guchar   *line;
    guint32         code;
    gchar           code_str[4];
    gboolean        is_port_request   = FALSE;
    gboolean        is_eprt_request   = FALSE;
    gboolean        is_pasv_response  = FALSE;
    gboolean        is_epasv_response = FALSE;
    gint            next_offset;
    int             linelen;
    int             tokenlen          = 0;
    const guchar   *next_token;
    guint32         pasv_ip;
    guint32         pasv_offset;
    guint32         ftp_ip;
    guint32         ftp_ip_len;
    guint32         eprt_offset;
    guint32         eprt_af           = 0;
    guint32         eprt_ip;
    guint16         eprt_ipv6[8];
    guint32         eprt_ip_len       = 0;
    guint16         ftp_port;
    guint32         ftp_port_len;
    address         ftp_ip_address;
    gboolean        ftp_nat;
    conversation_t *conversation;

    ftp_ip_address = pinfo->src;

    if (pinfo->match_uint == pinfo->destport)
        is_request = TRUE;
    else
        is_request = FALSE;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "FTP");

    /*
     * Find the end of the first line.
     *
     * Note that "tvb_find_line_end()" will return a value that is
     * not longer than what's in the buffer, so the "tvb_get_ptr()"
     * call won't throw an exception.
     */
    linelen = tvb_find_line_end(tvb, 0, -1, &next_offset, FALSE);
    line    = tvb_get_ptr(tvb, 0, linelen);

    /*
     * Put the first line from the buffer into the summary
     * (but leave out the line terminator).
     */
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %s",
        is_request ? "Request" : "Response",
        format_text(line, linelen));

    ti = proto_tree_add_item(tree, proto_ftp, tvb, 0, -1, ENC_NA);
    ftp_tree = proto_item_add_subtree(ti, ett_ftp);

    if (is_request) {
        hidden_item = proto_tree_add_boolean(ftp_tree,
                hf_ftp_request, tvb, 0, 0, TRUE);
        PROTO_ITEM_SET_HIDDEN(hidden_item);
        hidden_item = proto_tree_add_boolean(ftp_tree,
                hf_ftp_response, tvb, 0, 0, FALSE);
        PROTO_ITEM_SET_HIDDEN(hidden_item);
    } else {
        hidden_item = proto_tree_add_boolean(ftp_tree,
                hf_ftp_request, tvb, 0, 0, FALSE);
        PROTO_ITEM_SET_HIDDEN(hidden_item);
        hidden_item = proto_tree_add_boolean(ftp_tree,
                hf_ftp_response, tvb, 0, 0, TRUE);
        PROTO_ITEM_SET_HIDDEN(hidden_item);
    }

    /* Put the line into the protocol tree. */
    ti = proto_tree_add_text(ftp_tree, tvb, 0, next_offset, "%s",
            tvb_format_text(tvb, 0, next_offset));
    reqresp_tree = proto_item_add_subtree(ti, ett_ftp_reqresp);

    if (is_request) {
        /*
         * Extract the first token, and, if there is a first
         * token, add it as the request.
         */
        tokenlen = get_token_len(line, line + linelen, &next_token);
        if (tokenlen != 0) {
            proto_tree_add_item(reqresp_tree, hf_ftp_request_command,
                    tvb, 0, tokenlen, ENC_ASCII|ENC_NA);
            if (strncmp(line, "PORT", tokenlen) == 0)
                is_port_request = TRUE;
            /*
             * EPRT request command, as per RFC 2428
             */
            else if (strncmp(line, "EPRT", tokenlen) == 0)
                is_eprt_request = TRUE;
        }
    } else {
        /*
         * This is a response; the response code is 3 digits,
         * followed by a space or hyphen, possibly followed by
         * text.
         *
         * If the line doesn't start with 3 digits, it's part of
         * a continuation.
         *
         * XXX - keep track of state in the first pass, and
         * treat non-continuation lines not beginning with digits
         * as errors?
         */
        if (linelen >= 3 && isdigit(line[0]) && isdigit(line[1])
            && isdigit(line[2])) {
            /*
             * One-line reply, or first or last line
             * of a multi-line reply.
             */
            tvb_get_nstringz0(tvb, 0, sizeof(code_str), code_str);
            code = (guint32)strtoul(code_str, NULL, 10);

            proto_tree_add_uint(reqresp_tree,
                    hf_ftp_response_code, tvb, 0, 3, code);

            /*
             * See if it's a passive-mode response.
             *
             * XXX - does anybody do FOOBAR, as per RFC
             * 1639, or has that been supplanted by RFC 2428?
             */
            if (code == 227)
                is_pasv_response = TRUE;

            /*
             * Responses to EPSV command, as per RFC 2428
             */
            if (code == 229)
                is_epasv_response = TRUE;

            /*
             * Skip the 3 digits and, if present, the
             * space or hyphen.
             */
            if (linelen >= 4)
                next_token = line + 4;
            else
                next_token = line + linelen;
        } else {
            /*
             * Line doesn't start with 3 digits; assume it's
             * a line in the middle of a multi-line reply.
             */
            next_token = line;
        }
    }

    offset   = (gint) (next_token - line);
    linelen -= (int) (next_token - line);
    line     = next_token;

    /*
     * Add the rest of the first line as request or
     * reply data.
     */
    if (linelen != 0) {
        if (is_request) {
            proto_tree_add_item(reqresp_tree,
                    hf_ftp_request_arg, tvb, offset,
                    linelen, ENC_ASCII|ENC_NA);
        } else {
            proto_tree_add_item(reqresp_tree,
                    hf_ftp_response_arg, tvb, offset,
                    linelen, ENC_ASCII|ENC_NA);
        }
    }
    offset = next_offset;

    /*
     * If this is a PORT request or a PASV response, handle it.
     */
    if (is_port_request) {
        if (parse_port_pasv(line, linelen, &ftp_ip, &ftp_port, &pasv_offset, &ftp_ip_len, &ftp_port_len)) {
            proto_tree_add_ipv4(reqresp_tree, hf_ftp_active_ip,
                    tvb, pasv_offset + (tokenlen+1) , ftp_ip_len, ftp_ip);
            proto_tree_add_uint(reqresp_tree, hf_ftp_active_port,
                    tvb, pasv_offset + 1 + (tokenlen+1) + ftp_ip_len, ftp_port_len, ftp_port);
            SET_ADDRESS(&ftp_ip_address, AT_IPv4, 4, (const guint8 *)&ftp_ip);
            ftp_nat = !ADDRESSES_EQUAL(&pinfo->src, &ftp_ip_address);
            if (ftp_nat) {
                proto_tree_add_boolean(reqresp_tree, hf_ftp_active_nat,
                        tvb, 0, 0, ftp_nat);
            }
        }
    }

    if (is_pasv_response) {
        if (linelen != 0) {
            /*
             * This frame contains a PASV response; set up a
             * conversation for the data.
             */
            if (parse_port_pasv(line, linelen, &pasv_ip, &ftp_port, &pasv_offset, &ftp_ip_len, &ftp_port_len)) {
                proto_tree_add_ipv4(reqresp_tree, hf_ftp_pasv_ip,
                        tvb, pasv_offset + 4, ftp_ip_len, pasv_ip);
                proto_tree_add_uint(reqresp_tree, hf_ftp_pasv_port,
                        tvb, pasv_offset + 4 + 1 + ftp_ip_len, ftp_port_len, ftp_port);
                SET_ADDRESS(&ftp_ip_address, AT_IPv4, 4,
                    (const guint8 *)&pasv_ip);
                ftp_nat = !ADDRESSES_EQUAL(&pinfo->src, &ftp_ip_address);
                if (ftp_nat) {
                    proto_tree_add_boolean(reqresp_tree, hf_ftp_pasv_nat,
                            tvb, 0, 0, ftp_nat);
                }

                /*
                 * We use "ftp_ip_address", so that if
                 * we're NAT'd we look for the un-NAT'd
                 * connection.
                 *
                 * XXX - should this call to
                 * "find_conversation()" just use
                 * "ftp_ip_address" and "server_port", and
                 * wildcard everything else?
                 */
                conversation = find_conversation(pinfo->fd->num, &ftp_ip_address,
                    &pinfo->dst, PT_TCP, ftp_port, 0,
                    NO_PORT_B);
                if (conversation == NULL) {
                    /*
                     * XXX - should this call to "conversation_new()"
                     * just use "ftp_ip_address" and "server_port",
                     * and wildcard everything else?
                     *
                     * XXX - what if we did find a conversation?  As
                     * we create it only on the first pass through the
                     * packets, if we find one, it's presumably an
                     * unrelated conversation.  Should we remove the
                     * old one from the hash table and put this one in
                     * its place?  Can the conversation code handle
                     * conversations not in the hash table?  Or should
                     * we make conversations support start and end
                     * frames, as circuits do, and treat this as an
                     * indication that one conversation was closed and
                     * a new one was opened?
                     */
                    conversation = conversation_new(
                        pinfo->fd->num, &ftp_ip_address, &pinfo->dst,
                        PT_TCP, ftp_port, 0, NO_PORT2);
                    conversation_set_dissector(conversation, ftpdata_handle);
                }
            }
        }
    }

    if (is_eprt_request) {
        /* 
         * RFC2428 - sect. 2
         * This frame contains a EPRT request; let's dissect it and set up a 
         * conversation for the data connection.
         */
        if (parse_eprt_request(line, linelen,
                    &eprt_af, &eprt_ip, eprt_ipv6, &ftp_port,
                    &eprt_ip_len, &ftp_port_len)) {

            /* since parse_eprt_request() returned TRUE,
               we know that we have a valid address family */
            eprt_offset = tokenlen + 1 + 1;  /* token, space, 1st delimiter */
            proto_tree_add_uint(reqresp_tree, hf_ftp_eprt_af, tvb, 
                    eprt_offset, 1, eprt_af);
            eprt_offset += 1 + 1; /* addr family, 2nd delimiter */

            if (eprt_af == EPRT_AF_IPv4) {
                proto_tree_add_ipv4(reqresp_tree, hf_ftp_eprt_ip,
                        tvb, eprt_offset, eprt_ip_len, eprt_ip);
                SET_ADDRESS(&ftp_ip_address, AT_IPv4, 4,
                        (const guint8 *)&eprt_ip);
            }
            else if (eprt_af == EPRT_AF_IPv6) {
                proto_tree_add_ipv6(reqresp_tree, hf_ftp_eprt_ipv6,
                        tvb, eprt_offset, eprt_ip_len, (const guint8 *)eprt_ipv6);
                SET_ADDRESS(&ftp_ip_address, AT_IPv6, 16,
                        (const guint8 *)&eprt_ipv6);
            }
            eprt_offset += eprt_ip_len + 1; /* addr, 3rd delimiter */

            proto_tree_add_uint(reqresp_tree, hf_ftp_eprt_port,
                    tvb, eprt_offset, ftp_port_len, ftp_port);

            /* Find/create conversation for data */
            conversation = find_conversation(pinfo->fd->num,
                    &pinfo->src, &ftp_ip_address,
                    PT_TCP, ftp_port, 0, NO_PORT_B);
            if (conversation == NULL) {
                conversation = conversation_new(
                        pinfo->fd->num, &pinfo->src, &ftp_ip_address, 
                        PT_TCP, ftp_port, 0, NO_PORT2);
                conversation_set_dissector(conversation,
                        ftpdata_handle);
            }
        }
        else {
            proto_item *item;
            item = proto_tree_add_text(reqresp_tree, 
                    tvb, offset - linelen - 1, linelen, "Invalid EPRT arguments");
            expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN,
                    "EPRT arguments must have the form: |<family>|<addr>|<port>|");
        }
    }

    if (is_epasv_response) {
        if (linelen != 0) {
            proto_item *addr_it;
            /*
             * RFC2428 - sect. 3
             * This frame contains an  EPSV response; set up a
             * conversation for the data.
             */
            if (parse_extended_pasv_response(line, linelen,
                        &ftp_port, &pasv_offset, &ftp_port_len)) {
                /* Add IP address and port number to tree */

                if (ftp_ip_address.type == AT_IPv4) {
                    guint32 addr;
                    memcpy(&addr, ftp_ip_address.data, 4);
                    addr_it = proto_tree_add_ipv4(reqresp_tree,
                            hf_ftp_epsv_ip, tvb, 0, 0, addr);
                    PROTO_ITEM_SET_GENERATED(addr_it);
                }
                else if (ftp_ip_address.type == AT_IPv6) {
                    addr_it = proto_tree_add_ipv6(reqresp_tree,
                            hf_ftp_epsv_ipv6, tvb, 0, 0,
                            (guint8*)ftp_ip_address.data);
                    PROTO_ITEM_SET_GENERATED(addr_it);
                }

                proto_tree_add_uint(reqresp_tree, 
                        hf_ftp_epsv_port, tvb, pasv_offset + 4, 
                        ftp_port_len, ftp_port);

                /* Find/create conversation for data */
                conversation = find_conversation(pinfo->fd->num, &ftp_ip_address,
                                                 &pinfo->dst, PT_TCP, ftp_port, 0,
                                                 NO_PORT_B);
                if (conversation == NULL) {
                    conversation = conversation_new(
                        pinfo->fd->num, &ftp_ip_address, &pinfo->dst,
                        PT_TCP, ftp_port, 0, NO_PORT2);
                    conversation_set_dissector(conversation,
                        ftpdata_handle);
                }
            }
            else {
                proto_item *item;
                item = proto_tree_add_text(reqresp_tree,
                        tvb, offset - linelen - 1, linelen, "Invalid EPSV arguments");
                expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN,
                        "EPSV arguments must have the form (|||<port>|)");
            }
        }
    }

    /*
     * Show the rest of the request or response as text,
     * a line at a time.
     * XXX - only if there's a continuation indicator?
     */
    while (tvb_offset_exists(tvb, offset)) {
        /*
         * Find the end of the line.
         */
        tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);

        /*
         * Put this line.
         */
        proto_tree_add_text(ftp_tree, tvb, offset,
                next_offset - offset, "%s",
                tvb_format_text(tvb, offset, next_offset - offset));
        offset = next_offset;
    }
}
Esempio n. 11
0
static int
dissect_zebra_request(proto_tree *tree, gboolean request, tvbuff_t *tvb,
	int offset, guint16 len, guint8 command)
{
	guint32	prefix4;
	guint16 i;
	guint8  buffer6[16], prefixlen, message;
	proto_item *ti;
	proto_tree *msg_tree;

	proto_tree_add_uint(tree, hf_zebra_len, tvb, offset, 2, len);
	offset += 2;
	proto_tree_add_uint(tree, hf_zebra_command, tvb, offset, 1,
		command);
	offset += 1;
	switch(command) {
		case ZEBRA_INTERFACE_ADD:
		case ZEBRA_INTERFACE_UP:
		case ZEBRA_INTERFACE_DOWN:
			if (request) break;
			/* Request just subscribes to messages */

			proto_tree_add_item(tree, hf_zebra_interface,
				tvb, offset, INTERFACE_NAMSIZ, ENC_ASCII|ENC_NA);
			offset += INTERFACE_NAMSIZ;

			proto_tree_add_item(tree, hf_zebra_index, tvb,
				 offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(tree, hf_zebra_intflags, tvb,
				 offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(tree, hf_zebra_metric, tvb,
				 offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(tree, hf_zebra_mtu, tvb,
				 offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(tree, hf_zebra_bandwidth, tvb,
				 offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			break;
		case ZEBRA_INTERFACE_DELETE:
			proto_tree_add_item(tree, hf_zebra_interface,
				tvb, offset, INTERFACE_NAMSIZ, ENC_ASCII|ENC_NA);
			offset += INTERFACE_NAMSIZ;

			proto_tree_add_item(tree, hf_zebra_index, tvb,
				 offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
			break;
		case ZEBRA_INTERFACE_ADDRESS_ADD:
		case ZEBRA_INTERFACE_ADDRESS_DELETE:
			proto_tree_add_item(tree, hf_zebra_index, tvb,
				 offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(tree, hf_zebra_family, tvb,
				 offset, 1, ENC_BIG_ENDIAN);
			offset += 1;

			/* XXX - switch on the address family here, instead? */
			if (len == 17) { /* IPv4 */
				proto_tree_add_item(tree, hf_zebra_prefix4,
					tvb, offset, 4, ENC_BIG_ENDIAN);
				offset += 4;
			}
			else if (len == 41) { /* IPv6 */
				proto_tree_add_item(tree, hf_zebra_prefix6,
					tvb, offset, 16, ENC_NA);
				offset += 16;
			}
			else break;

			proto_tree_add_item(tree, hf_zebra_prefixlen, tvb,
				 offset, 1, ENC_BIG_ENDIAN);
			offset += 1;

			if (len == 17) { /* IPv4 */
				proto_tree_add_item(tree, hf_zebra_dest4,
					tvb, offset, 4, ENC_BIG_ENDIAN);
				offset += 4;
			}
			else if (len == 41) { /* IPv6 */
				proto_tree_add_item(tree, hf_zebra_dest6,
					tvb, offset, 16, ENC_NA);
				offset += 16;
			}
			break;

		case ZEBRA_IPV4_ROUTE_ADD:
		case ZEBRA_IPV4_ROUTE_DELETE:
			proto_tree_add_item(tree, hf_zebra_type, tvb,
				 offset, 1, ENC_BIG_ENDIAN);
			offset += 1;

			proto_tree_add_item(tree, hf_zebra_rtflags, tvb,
				 offset, 1, ENC_BIG_ENDIAN);
			offset += 1;

			message = tvb_get_guint8(tvb, offset);
			ti = proto_tree_add_uint(tree, hf_zebra_message, tvb,
				 offset, 1, message);
			msg_tree = proto_item_add_subtree(ti, ett_message);
			proto_tree_add_boolean(msg_tree, hf_zebra_msg_nexthop,
				tvb, offset, 1, message);
			proto_tree_add_boolean(msg_tree, hf_zebra_msg_index,
				tvb, offset, 1, message);
			proto_tree_add_boolean(msg_tree, hf_zebra_msg_distance,
				tvb, offset, 1, message);
			proto_tree_add_boolean(msg_tree, hf_zebra_msg_metric,
				tvb, offset, 1, message);
			offset += 1;

			prefixlen = tvb_get_guint8(tvb, offset);
			proto_tree_add_uint(tree, hf_zebra_prefixlen, tvb,
				 offset, 1, prefixlen);
			offset += 1;

			prefix4 = 0;
			tvb_memcpy(tvb, (guint8 *)&prefix4, offset,
			    MIN((unsigned) PSIZE(prefixlen), sizeof prefix4));
			proto_tree_add_ipv4(tree, hf_zebra_prefix4,
				tvb, offset, PSIZE(prefixlen), prefix4);
			offset += PSIZE(prefixlen);

			if (message & ZEBRA_ZAPI_MESSAGE_NEXTHOP) {
				i = tvb_get_guint8(tvb, offset);
				proto_tree_add_uint(tree, hf_zebra_nexthopnum,
					tvb, offset, 1, i);
				offset += 1;

				if (i>len) break; /* Sanity */

				while (i--) {
					proto_tree_add_item(tree,
						hf_zebra_nexthop4, tvb,
						offset, 4, ENC_BIG_ENDIAN);
					offset += 4;
				}
			}
			if (message & ZEBRA_ZAPI_MESSAGE_IFINDEX) {
				i = tvb_get_guint8(tvb, offset);
				proto_tree_add_uint(tree, hf_zebra_indexnum,
					tvb, offset, 1, i);
				offset += 1;

				if (i>len) break; /* Sanity */

				while (i--) {
					proto_tree_add_item(tree,
						hf_zebra_index, tvb,
						offset, 4, ENC_BIG_ENDIAN);
					offset += 4;
				}
			}
			if (message & ZEBRA_ZAPI_MESSAGE_DISTANCE) {
				proto_tree_add_item(tree, hf_zebra_distance,
					tvb, offset, 1, ENC_BIG_ENDIAN);
				offset += 1;
			}
			if (message & ZEBRA_ZAPI_MESSAGE_METRIC) {
				proto_tree_add_item(tree, hf_zebra_metric,
					tvb, offset, 4, ENC_BIG_ENDIAN);
				offset += 4;
			}
			break;
		case ZEBRA_IPV6_ROUTE_ADD:
		case ZEBRA_IPV6_ROUTE_DELETE:
			proto_tree_add_item(tree, hf_zebra_type, tvb,
				 offset, 1, ENC_BIG_ENDIAN);
			offset += 1;

			proto_tree_add_item(tree, hf_zebra_rtflags, tvb,
				 offset, 1, ENC_BIG_ENDIAN);
			offset += 1;

			message = tvb_get_guint8(tvb, offset);
			ti = proto_tree_add_uint(tree, hf_zebra_message, tvb,
				 offset, 1, message);
			msg_tree = proto_item_add_subtree(ti, ett_message);
			proto_tree_add_boolean(msg_tree, hf_zebra_msg_nexthop,
				tvb, offset, 1, message);
			proto_tree_add_boolean(msg_tree, hf_zebra_msg_index,
				tvb, offset, 1, message);
			proto_tree_add_boolean(msg_tree, hf_zebra_msg_distance,
				tvb, offset, 1, message);
			proto_tree_add_boolean(msg_tree, hf_zebra_msg_metric,
				tvb, offset, 1, message);
			offset += 1;

			prefixlen = tvb_get_guint8(tvb, offset);
			proto_tree_add_uint(tree, hf_zebra_prefixlen, tvb,
				 offset, 1, prefixlen);
			offset += 1;

			memset(buffer6, '\0', sizeof buffer6);
			tvb_memcpy(tvb, buffer6, offset,
			    MIN((unsigned) PSIZE(prefixlen), sizeof buffer6));
			proto_tree_add_ipv6(tree, hf_zebra_prefix6,
				tvb, offset, PSIZE(prefixlen), buffer6);
			offset += PSIZE(prefixlen);

			if (message & ZEBRA_ZAPI_MESSAGE_NEXTHOP) {
				i = tvb_get_guint8(tvb, offset);
				proto_tree_add_uint(tree, hf_zebra_nexthopnum,
					tvb, offset, 1, i);
				offset += 1;

				if (i>len) break; /* Sanity */

				while (i--) {
					proto_tree_add_item(tree,
						hf_zebra_nexthop6, tvb,
						offset, 16, ENC_NA);
					offset += 16;
				}
			}
			if (message & ZEBRA_ZAPI_MESSAGE_IFINDEX) {
				i = tvb_get_guint8(tvb, offset);
				proto_tree_add_uint(tree, hf_zebra_indexnum,
					tvb, offset, 1, i);
				offset += 1;

				if (i>len) break; /* Sanity */

				while (i--) {
					proto_tree_add_item(tree,
						hf_zebra_index, tvb,
						offset, 4, ENC_BIG_ENDIAN);
					offset += 4;
				}
			}
			if (message & ZEBRA_ZAPI_MESSAGE_DISTANCE) {
				proto_tree_add_item(tree, hf_zebra_distance,
					tvb, offset, 1, ENC_BIG_ENDIAN);
				offset += 1;
			}
			if (message & ZEBRA_ZAPI_MESSAGE_METRIC) {
				proto_tree_add_item(tree, hf_zebra_metric,
					tvb, offset, 4, ENC_BIG_ENDIAN);
				offset += 4;
			}
			break;
		case ZEBRA_REDISTRIBUTE_ADD:
		case ZEBRA_REDISTRIBUTE_DELETE:
			proto_tree_add_item(tree, hf_zebra_type, tvb,
				 offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			break;
		case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
		case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
			break;
		case ZEBRA_IPV4_NEXTHOP_LOOKUP:
			proto_tree_add_item(tree, hf_zebra_nexthop4,
				tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(tree, hf_zebra_metric,
				tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
			break;
		case ZEBRA_IPV6_NEXTHOP_LOOKUP:
			/* Not yet implemeted in ZEBRA */
			break;
	}
return offset;
}
Esempio n. 12
0
static int
dissect_ppcap_destination_address(tvbuff_t *tvb, packet_info * pinfo, proto_tree * ppcap_tree1, int offset, guint16 msg_len )
{
	int key2;
	const guchar *dst_addr;
	/*guint32 dst_addr1;*/

	proto_tree_add_item(ppcap_tree1, hf_ppcap_destreserved, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	key2 = tvb_get_ntohs(tvb, offset);
	proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	if (key2 == 1)
	{
		ssn = tvb_get_guint8(tvb, offset);
		proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn1, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		proto_tree_add_item(ppcap_tree1, hf_ppcap_spc1, tvb, offset, 3, ENC_BIG_ENDIAN);

		/*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/
		mtp3_addr_dpc = ep_alloc0(sizeof(mtp3_addr_pc_t));
		mtp3_addr_dpc->pc = (guint32)tvb_get_ntoh24(tvb, offset);
		mtp3_addr_dpc->type = 1; /* ITU_STANDARD */
		mtp3_addr_dpc->ni = 0;
                SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc);
		/*dst_addr = tvb_get_ptr(tvb, offset, msg_len-1);
		SET_ADDRESS(&pinfo->net_dst, AT_SS7PC, msg_len-1, dst_addr);
		SET_ADDRESS(&pinfo->dst, AT_SS7PC, msg_len-1, dst_addr);*/

		if (msg_len%4)
			msg_len = msg_len + (4 - (msg_len%4));

        offset += msg_len-1;
        return offset;

	}
	else if (key2 == 2)
	{
		proto_tree_add_item(ppcap_tree1, hf_ppcap_dpc, tvb, offset, 4, ENC_BIG_ENDIAN);

		/*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/
		mtp3_addr_dpc = ep_alloc0(sizeof(mtp3_addr_pc_t));
		mtp3_addr_dpc->pc = tvb_get_ntohl(tvb, offset);
		mtp3_addr_dpc->type = 1; /* ITU_STANDARD */
		mtp3_addr_dpc->ni = 0;
        SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc);
	}
	else if (key2 == 3)
	{
		if (msg_len%4 == 0)
		{
			proto_tree_add_ipv4(ppcap_tree1, hf_ppcap_destination_ip_address1, tvb, offset, msg_len, tvb_get_ipv4(tvb, offset));
			dst_addr = tvb_get_ptr(tvb, offset, 4);
			SET_ADDRESS(&pinfo->net_dst, AT_IPv4, 4, dst_addr);
			SET_ADDRESS(&pinfo->dst, AT_IPv4, 4, dst_addr);
		}
		else
		{
			struct e_in6_addr value;

			tvb_get_ipv6(tvb, offset,&value);
			proto_tree_add_ipv6(ppcap_tree1, hf_ppcap_destination_ip_address2, tvb, offset, msg_len, (guint8*)&value);
			dst_addr = tvb_get_ptr(tvb, offset, 6);
			SET_ADDRESS(&pinfo->net_dst, AT_IPv6, 6, dst_addr);
			SET_ADDRESS(&pinfo->dst, AT_IPv6, 6, dst_addr);
		}
	}

	else if (key2 == 4)
	{
		char *string;
		string = tvb_get_string(tvb, offset, msg_len);
		proto_tree_add_string(ppcap_tree1, hf_ppcap_destination_nodeid, tvb, offset, msg_len, string);
		dst_addr = tvb_get_ptr(tvb, offset, msg_len);
		SET_ADDRESS(&pinfo->net_dst, AT_STRINGZ, msg_len, dst_addr);
		SET_ADDRESS(&pinfo->dst, AT_STRINGZ, msg_len, dst_addr);
		/*g_free(string);*/
	}

	if (msg_len%4)
		msg_len = msg_len+(4-(msg_len%4));
		offset += msg_len;
	return offset;
}
Esempio n. 13
0
static int
dissect_ppcap_source_address(tvbuff_t *tvb, packet_info *pinfo, proto_tree * ppcap_tree1, int offset, guint16 msg_len)
{
	int key1;
	const guchar  *src_addr;
	/*guint32 src_addr1;*/
	proto_tree_add_item(ppcap_tree1, hf_ppcap_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	key1 = tvb_get_ntohs(tvb, offset);
	proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	if (key1 == 1)
	{
		proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;
		proto_tree_add_item(ppcap_tree1, hf_ppcap_spc, tvb, offset, 3, ENC_BIG_ENDIAN);
		/*src_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/
		mtp3_addr_opc = ep_alloc0(sizeof(mtp3_addr_pc_t));
		mtp3_addr_opc->pc = (guint32 )tvb_get_ntoh24(tvb, offset);
		mtp3_addr_opc->type = 1; /* ITU_STANDARD */
		mtp3_addr_opc->ni = 0;
		/*SET_ADDRESS(&pinfo->net_src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc);*/
		SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc);
		if (msg_len%4)
			msg_len = msg_len + (4 - (msg_len%4));

		offset += msg_len-1;
		return offset;
	}
	else if (key1 == 2)
	{
		proto_tree_add_item(ppcap_tree1, hf_ppcap_opc, tvb, offset, msg_len, ENC_BIG_ENDIAN);

		/*src_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/
		mtp3_addr_opc = ep_alloc0(sizeof(mtp3_addr_pc_t));
		mtp3_addr_opc->pc = tvb_get_ntohl(tvb, offset);
		mtp3_addr_opc->type = 1; /* ITU_STANDARD */
		mtp3_addr_opc->ni = 0;
		SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc);
		/*src_addr = tvb_get_ptr(tvb, offset, 4);*/
		/*SET_ADDRESS(&pinfo->net_src, AT_SS7PC, 4, src_addr);*/
		/*SET_ADDRESS(&pinfo->src, AT_SS7PC, 4, src_addr);*/
	}
	else if (key1 == 3)
	{
		if (msg_len%4 == 0)
		{

			proto_tree_add_ipv4(ppcap_tree1, hf_ppcap_source_ip_address1, tvb, offset, msg_len, tvb_get_ipv4(tvb, offset));
			src_addr = tvb_get_ptr(tvb, offset, 4);
			SET_ADDRESS(&pinfo->net_src, AT_IPv4, 4, src_addr);
			SET_ADDRESS(&pinfo->src, AT_IPv4, 4, src_addr);
		}
		else
		{
			struct e_in6_addr value;
			tvb_get_ipv6(tvb, offset, &value);
			proto_tree_add_ipv6(ppcap_tree1, hf_ppcap_source_ip_address2, tvb, offset, msg_len, (guint8*)&value);
			src_addr = tvb_get_ptr(tvb, offset, 6);
			SET_ADDRESS(&pinfo->net_src, AT_IPv6, 6, src_addr);
			SET_ADDRESS(&pinfo->src, AT_IPv6, 6, src_addr);
		}
	}

	else if (key1 == 4)

	{
		proto_tree_add_item(ppcap_tree1, hf_ppcap_source_nodeid, tvb, offset, msg_len, ENC_BIG_ENDIAN|ENC_ASCII);
		src_addr = tvb_get_ptr(tvb, offset, msg_len);
		SET_ADDRESS(&pinfo->net_src, AT_STRINGZ, msg_len, src_addr);
		SET_ADDRESS(&pinfo->src, AT_STRINGZ, msg_len, src_addr);
	}
	if (msg_len%4)
		msg_len = msg_len + (4 - (msg_len%4));
	offset += msg_len;
	return offset;
}