Пример #1
0
static void
dissect_rpl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint16 rpl_len, rpl_type;
	proto_item *ti, *hidden_item;
	proto_tree *rpl_tree;
	tvbuff_t *next_tvb;

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

	rpl_len  = tvb_get_ntohs(tvb, 0);
	rpl_type = tvb_get_ntohs(tvb, 2);

	if (check_col(pinfo->cinfo, COL_INFO)) {
		col_set_str(pinfo->cinfo, COL_INFO,
		    val_to_str_const(rpl_type, rpl_type_vals, "Unknown Type"));
	}
	if (tree) {
		ti = proto_tree_add_item(tree, proto_rpl, tvb, 0,
			rpl_len, ENC_NA);
		rpl_tree = proto_item_add_subtree(ti, ett_rpl);
		hidden_item = proto_tree_add_uint(rpl_tree, hf_rpl_type, tvb, 2, 2,
			rpl_type);
		PROTO_ITEM_SET_HIDDEN(hidden_item);
		next_tvb = tvb_new_subset_remaining(tvb, 0);
		set_actual_length(next_tvb, rpl_len);
		dissect_rpl_container(next_tvb, pinfo, rpl_tree);

		if (tvb_reported_length(tvb) > rpl_len)
			call_dissector(data_handle,
				tvb_new_subset_remaining(tvb, rpl_len), pinfo,
				    tree);
	}
}
Пример #2
0
static void
dissect_snaeth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*snaeth_tree;
	proto_item	*snaeth_ti;
	guint16		len;
	tvbuff_t	*next_tvb;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "SNAETH");
	col_set_str(pinfo->cinfo, COL_INFO, "SNA over Ethernet");

	/* length */
	len = tvb_get_ntohs(tvb, 0);

	if (tree) {
		snaeth_ti = proto_tree_add_item(tree, proto_snaeth, tvb, 0, 3,
		    ENC_NA);
		snaeth_tree = proto_item_add_subtree(snaeth_ti, ett_snaeth);
		proto_tree_add_uint(snaeth_tree, hf_snaeth_len, tvb, 0, 2, len);
		proto_tree_add_text(snaeth_tree, tvb, 2, 1, "Padding");
	}

	/*
	 * Adjust the length of this tvbuff to include only the SNA-over-
	 * Ethernet header and data.
	 */
	set_actual_length(tvb, 3 + len);

	/*
	 * Rest of packet starts with an 802.2 LLC header.
	 */
	next_tvb = tvb_new_subset_remaining(tvb, 3);
	call_dissector(llc_handle, next_tvb, pinfo, tree);
}
Пример #3
0
static void
dissect_idp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*idp_tree = NULL;
	proto_item	*ti = NULL;
	guint16		length;
	guint8		type;
	tvbuff_t	*next_tvb;
	
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "IDP");
	col_clear(pinfo->cinfo, COL_INFO);

	col_clear(pinfo->cinfo, COL_INFO);

	if (tree) {
		ti = proto_tree_add_item(tree, proto_idp, tvb, 0, IDP_HEADER_LEN, FALSE);
		idp_tree = proto_item_add_subtree(ti, ett_idp);
	}

	proto_tree_add_item(idp_tree, hf_idp_checksum, tvb, 0, 2, FALSE);
	length = tvb_get_ntohs(tvb, 2);
	proto_tree_add_uint_format(idp_tree, hf_idp_len, tvb, 2, 2, length,
		"Length: %u bytes", length);
	/* Adjust the tvbuff length to include only the IDP datagram. */
	set_actual_length(tvb, length);
	proto_tree_add_item(idp_tree, hf_idp_hops, tvb, 4, 1, FALSE);
	type = tvb_get_guint8(tvb, 5);
	proto_tree_add_uint(idp_tree, hf_idp_packet_type, tvb, 5, 1, type);

	pinfo->ptype = PT_IDP;

	/* Destination */
	proto_tree_add_item(idp_tree, hf_idp_dnet, tvb, 6, 4, FALSE);
	proto_tree_add_item(idp_tree, hf_idp_dnode, tvb, 10, 6, FALSE);
	pinfo->destport = tvb_get_ntohs(tvb, 16);
	proto_tree_add_uint(idp_tree, hf_idp_dsocket, tvb, 16, 2,
	    pinfo->destport);

	/* Source */
	proto_tree_add_item(idp_tree, hf_idp_snet, tvb, 18, 4, FALSE);
	proto_tree_add_item(idp_tree, hf_idp_snode, tvb, 22, 6, FALSE);
	pinfo->srcport = tvb_get_ntohs(tvb, 28);
	proto_tree_add_uint(idp_tree, hf_idp_ssocket, tvb, 28, 2,
	    pinfo->srcport);

	/* Make the next tvbuff */
	next_tvb = tvb_new_subset_remaining(tvb, IDP_HEADER_LEN);

	/*
	 * Hand off to the dissector for the packet type.
	 */
	if (dissector_try_port(idp_type_dissector_table, type, next_tvb,
	    pinfo, tree))
		return;

	call_dissector(data_handle, next_tvb, pinfo, tree);
}
Пример #4
0
static void
dissect_ipx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	tvbuff_t	*next_tvb;

	proto_tree	*ipx_tree = NULL;
	proto_item	*ti = NULL, *hidden_item;

	const guint8	*src_net_node, *dst_net_node;

	guint8		ipx_hops;
	char 		*str;
	guint16		first_socket, second_socket;
	guint32		ipx_snet, ipx_dnet;
	static ipxhdr_t ipxh_arr[4];
	static int ipx_current=0;
	ipxhdr_t *ipxh;

	ipx_current++;
	if(ipx_current==4){
		ipx_current=0;
	}
	ipxh=&ipxh_arr[ipx_current];


	col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPX");
	col_clear(pinfo->cinfo, COL_INFO);

	/* Calculate here for use in pinfo and in tree */
	ipxh->ipx_dsocket = tvb_get_ntohs(tvb, 16);
	ipxh->ipx_ssocket = tvb_get_ntohs(tvb, 28);
	ipxh->ipx_type    = tvb_get_guint8(tvb, 5);
	ipxh->ipx_length  = tvb_get_ntohs(tvb, 2);

	pinfo->ptype = PT_IPX;
	pinfo->srcport = ipxh->ipx_ssocket;
	pinfo->destport = ipxh->ipx_dsocket;

	/* Adjust the tvbuff length to include only the IPX datagram. */
	set_actual_length(tvb, ipxh->ipx_length);

	src_net_node = tvb_get_ptr(tvb, 18, 10);
	dst_net_node = tvb_get_ptr(tvb, 6,  10);

	SET_ADDRESS(&pinfo->net_src,	AT_IPX, 10, src_net_node);
	SET_ADDRESS(&pinfo->src,	AT_IPX, 10, src_net_node);
	SET_ADDRESS(&ipxh->ipx_src,	AT_IPX, 10, src_net_node);
	SET_ADDRESS(&pinfo->net_dst,	AT_IPX, 10, dst_net_node);
	SET_ADDRESS(&pinfo->dst,	AT_IPX, 10, dst_net_node);
	SET_ADDRESS(&ipxh->ipx_dst,	AT_IPX, 10, dst_net_node);

	if (check_col(pinfo->cinfo, COL_INFO))
		col_add_fstr(pinfo->cinfo, COL_INFO, "%s (0x%04x)",
				socket_text(ipxh->ipx_dsocket), ipxh->ipx_dsocket);

	if (tree) {

		ti = proto_tree_add_item(tree, proto_ipx, tvb, 0, IPX_HEADER_LEN, ENC_NA);
		ipx_tree = proto_item_add_subtree(ti, ett_ipx);
	}

	str=ep_address_to_str(&pinfo->net_src);
	hidden_item = proto_tree_add_string(ipx_tree, hf_ipx_src, tvb, 0, 0, str);
	PROTO_ITEM_SET_HIDDEN(hidden_item);
	hidden_item = proto_tree_add_string(ipx_tree, hf_ipx_addr, tvb, 0, 0, str);
	PROTO_ITEM_SET_HIDDEN(hidden_item);
	str=ep_address_to_str(&pinfo->net_dst);
	hidden_item = proto_tree_add_string(ipx_tree, hf_ipx_dst, tvb, 0, 0, str);
	PROTO_ITEM_SET_HIDDEN(hidden_item);
	hidden_item = proto_tree_add_string(ipx_tree, hf_ipx_addr, tvb, 0, 0, str);
	PROTO_ITEM_SET_HIDDEN(hidden_item);

	proto_tree_add_item(ipx_tree, hf_ipx_checksum, tvb, 0, 2, ENC_BIG_ENDIAN);
	proto_tree_add_uint_format(ipx_tree, hf_ipx_len, tvb, 2, 2, ipxh->ipx_length,
		"Length: %d bytes", ipxh->ipx_length);
	ipx_hops = tvb_get_guint8(tvb, 4);
	proto_tree_add_uint_format(ipx_tree, hf_ipx_hops, tvb, 4, 1, ipx_hops,
		"Transport Control: %d hops", ipx_hops);
	proto_tree_add_uint(ipx_tree, hf_ipx_packet_type, tvb, 5, 1, ipxh->ipx_type);

	/* Destination */
	ipx_dnet = tvb_get_ntohl(tvb, 6);
	proto_tree_add_ipxnet(ipx_tree, hf_ipx_dnet, tvb, 6, 4,
		ipx_dnet);
	hidden_item = proto_tree_add_ipxnet(ipx_tree, hf_ipx_net, tvb, 6, 4,
		ipx_dnet);
	PROTO_ITEM_SET_HIDDEN(hidden_item);
	proto_tree_add_item(ipx_tree, hf_ipx_dnode, tvb, 10, 6, ENC_NA);
	hidden_item = proto_tree_add_item(ipx_tree, hf_ipx_node, tvb, 10, 6, ENC_NA);
	PROTO_ITEM_SET_HIDDEN(hidden_item);
	proto_tree_add_uint(ipx_tree, hf_ipx_dsocket, tvb, 16, 2,
		ipxh->ipx_dsocket);
	hidden_item = proto_tree_add_uint(ipx_tree, hf_ipx_socket, tvb, 16, 2,
		ipxh->ipx_dsocket);
	PROTO_ITEM_SET_HIDDEN(hidden_item);

	/* Source */
	ipx_snet = tvb_get_ntohl(tvb, 18);
	proto_tree_add_ipxnet(ipx_tree, hf_ipx_snet, tvb, 18, 4,
		ipx_snet);
	hidden_item = proto_tree_add_ipxnet(ipx_tree, hf_ipx_net, tvb, 18, 4,
		ipx_snet);
	PROTO_ITEM_SET_HIDDEN(hidden_item);
	proto_tree_add_item(ipx_tree, hf_ipx_snode, tvb, 22, 6, ENC_NA);
	hidden_item = proto_tree_add_item(ipx_tree, hf_ipx_node, tvb, 22, 6, ENC_NA);
	PROTO_ITEM_SET_HIDDEN(hidden_item);
	proto_tree_add_uint(ipx_tree, hf_ipx_ssocket, tvb, 28, 2,
		ipxh->ipx_ssocket);
	hidden_item = proto_tree_add_uint(ipx_tree, hf_ipx_socket, tvb, 28, 2,
		ipxh->ipx_ssocket);
	PROTO_ITEM_SET_HIDDEN(hidden_item);

	/* Make the next tvbuff */
	next_tvb = tvb_new_subset_remaining(tvb, IPX_HEADER_LEN);

	/*
	 * Let the subdissector know what type of IPX packet this is.
	 */
	pinfo->ipxptype = ipxh->ipx_type;

	/*
	 * Check the socket numbers before we check the packet type;
	 * we've seen non-NCP packets with a type of NCP and a
	 * destination socket of IPX_SOCKET_IPX_MESSAGE, and SAP
	 * packets with a type of NCP and a destination socket of
	 * IPX_SOCKET_SAP.
	 *
	 * We've seen NCP packets with a type of NCP, a source socket of
	 * IPX_SOCKET_NCP, and a destination socket of IPX_SOCKET_IPX_MESSAGE,
	 * and we've seen NCP packets with a type of NCP, a source socket of
	 * IPX_SOCKET_IPX_MESSAGE, and a destination socket of
	 * IPX_SOCKET_NCP, so testing the destination socket first doesn't
	 * always give the right answer.  We've also seen SAP packets with
	 * a source socket of IPX_SOCKET_SAP and a destination socket of
	 * IPX_SOCKET_IPX_MESSAGE.
	 *
	 * Unfortunately, we've also seen packets with a source socket
	 * of IPX_SOCKET_NWLINK_SMB_SERVER and a destination socket
	 * of IPX_SOCKET_NWLINK_SMB_NAMEQUERY that were NMPI packets,
	 * not SMB packets, so testing the lower-valued socket first
	 * also doesn't always give the right answer.
	 *
	 * So we start out assuming we should test the lower-numbered
	 * socket number first, but, if the higher-numbered socket is
	 * IPX_SOCKET_NWLINK_SMB_NAMEQUERY, we assume that it's a
	 * NMPI query, and test only that socket.
	 */
	if (ipxh->ipx_ssocket > ipxh->ipx_dsocket) {
		first_socket = ipxh->ipx_dsocket;
		second_socket = ipxh->ipx_ssocket;
	} else {
		first_socket = ipxh->ipx_ssocket;
		second_socket = ipxh->ipx_dsocket;
	}

	tap_queue_packet(ipx_tap, pinfo, ipxh);

	if (second_socket != IPX_SOCKET_NWLINK_SMB_NAMEQUERY) {
		if (dissector_try_uint(ipx_socket_dissector_table, first_socket,
		    next_tvb, pinfo, tree))
			return;
	}
	if (dissector_try_uint(ipx_socket_dissector_table, second_socket,
	    next_tvb, pinfo, tree))
		return;

	/*
	 * Neither of them are known; try the packet type, which will
	 * at least let us, for example, dissect SPX packets as SPX.
	 */
	if (dissector_try_uint(ipx_type_dissector_table, ipxh->ipx_type, next_tvb,
	    pinfo, tree))
		return;

	call_dissector(data_handle,next_tvb, pinfo, tree);
}
Пример #5
0
static void
dissect_dec_bpdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
      guint8  protocol_version;
      guint8  bpdu_type;
      guint8  flags;
      proto_tree *bpdu_tree;
      proto_tree *flags_tree;
      proto_item *ti;
      const char *sep;

      col_set_str(pinfo->cinfo, COL_PROTOCOL, "DEC_STP");
      col_clear(pinfo->cinfo, COL_INFO);

      bpdu_type = tvb_get_guint8(tvb, BPDU_TYPE);

      if (check_col(pinfo->cinfo, COL_INFO)) {
	    col_add_str(pinfo->cinfo, COL_INFO,
			val_to_str(bpdu_type, bpdu_type_vals,
				   "Unknown BPDU type (%u)"));
      }

      set_actual_length(tvb, DEC_BPDU_SIZE);

      if (tree) {
	    ti = proto_tree_add_item(tree, proto_dec_bpdu, tvb, 0, DEC_BPDU_SIZE,
			    	FALSE);
	    bpdu_tree = proto_item_add_subtree(ti, ett_dec_bpdu);

	    protocol_version = tvb_get_guint8(tvb, BPDU_VERSION);

	    proto_tree_add_item(bpdu_tree, hf_dec_bpdu_proto_id, tvb,
				BPDU_DEC_CODE, 1, FALSE);

	    proto_tree_add_uint(bpdu_tree, hf_dec_bpdu_type, tvb,
				BPDU_TYPE, 1, bpdu_type);

	    proto_tree_add_item(bpdu_tree, hf_dec_bpdu_version_id, tvb,
				BPDU_VERSION, 1, FALSE);

	    flags = tvb_get_guint8(tvb, BPDU_FLAGS);
	    ti = proto_tree_add_uint(bpdu_tree, hf_dec_bpdu_flags, tvb,
				     BPDU_FLAGS, 1, flags);
	    flags_tree = proto_item_add_subtree(ti, ett_dec_bpdu_flags);
	    sep = initial_sep;
	    APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_SHORT_TIMERS, ti,
				"%sUse short timers");
	    proto_tree_add_boolean(flags_tree, hf_dec_bpdu_flags_short_timers, tvb,
				   BPDU_FLAGS, 1, flags);
	    APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_TCACK, ti,
				"%sTopology Change Acknowledgment");
	    proto_tree_add_boolean(flags_tree, hf_dec_bpdu_flags_tcack, tvb,
				   BPDU_FLAGS, 1, flags);
	    APPEND_BOOLEAN_FLAG(flags & BPDU_FLAGS_TC, ti,
				"%sTopology Change");
	    proto_tree_add_boolean(flags_tree, hf_dec_bpdu_flags_tc, tvb,
				   BPDU_FLAGS, 1, flags);
	    if (sep != initial_sep) {
	      /* We put something in; put in the terminating ")" */
	      proto_item_append_text(ti, ")");
	    }

	    proto_tree_add_item(bpdu_tree, hf_dec_bpdu_root_pri, tvb,
				BPDU_ROOT_PRI, 2, FALSE);
	    proto_tree_add_item(bpdu_tree, hf_dec_bpdu_root_mac, tvb,
				BPDU_ROOT_MAC, 6, FALSE);
	    proto_tree_add_item(bpdu_tree, hf_dec_bpdu_root_cost, tvb,
				BPDU_ROOT_PATH_COST, 2, FALSE);
	    proto_tree_add_item(bpdu_tree, hf_dec_bpdu_bridge_pri, tvb,
				BPDU_BRIDGE_PRI, 2, FALSE);
	    proto_tree_add_item(bpdu_tree, hf_dec_bpdu_bridge_mac, tvb,
				BPDU_BRIDGE_MAC, 6, FALSE);
	    proto_tree_add_item(bpdu_tree, hf_dec_bpdu_port_id, tvb,
				BPDU_PORT_IDENTIFIER, 1, FALSE);
	    proto_tree_add_item(bpdu_tree, hf_dec_bpdu_msg_age, tvb,
				BPDU_MESSAGE_AGE, 1, FALSE);
	    proto_tree_add_item(bpdu_tree, hf_dec_bpdu_hello_time, tvb,
				BPDU_HELLO_TIME, 1, FALSE);
	    proto_tree_add_item(bpdu_tree, hf_dec_bpdu_max_age, tvb,
				BPDU_MAX_AGE, 1, FALSE);
	    proto_tree_add_item(bpdu_tree, hf_dec_bpdu_forward_delay, tvb,
				BPDU_FORWARD_DELAY, 1, FALSE);

      }
}
Пример #6
0
static void
dissect_eapol(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  int         offset = 0;
  guint8      eapol_type;
  guint8      keydesc_type;
  guint16     eapol_len;
  guint       len;
  guint16     eapol_key_len, eapol_data_len;
  guint8      key_index;
  guint16     keyinfo;
  proto_tree *ti = NULL;
  proto_tree *eapol_tree = NULL;
  proto_tree *keyinfo_item = NULL;
  proto_tree *keyinfo_tree = NULL;
  proto_tree *key_index_tree, *keydes_tree;
  tvbuff_t   *next_tvb;

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "EAPOL");
  col_clear(pinfo->cinfo, COL_INFO);

  if (tree) {
    ti = proto_tree_add_item(tree, proto_eapol, tvb, 0, -1, FALSE);
    eapol_tree = proto_item_add_subtree(ti, ett_eapol);

    proto_tree_add_item(eapol_tree, hf_eapol_version, tvb, offset, 1, FALSE);
  }
  offset++;

  eapol_type = tvb_get_guint8(tvb, offset);
  if (tree)
    proto_tree_add_uint(eapol_tree, hf_eapol_type, tvb, offset, 1, eapol_type);
  if (check_col(pinfo->cinfo, COL_INFO))
    col_add_str(pinfo->cinfo, COL_INFO,
		val_to_str(eapol_type, eapol_type_vals, "Unknown type (0x%02X)"));
  offset++;

  eapol_len = tvb_get_ntohs(tvb, offset);
  len = EAPOL_HDR_LEN + eapol_len;
  set_actual_length(tvb, len);
  if (tree) {
    proto_item_set_len(ti, len);
    proto_tree_add_uint(eapol_tree, hf_eapol_len, tvb, offset, 2, eapol_len);
  }
  offset += 2;

  switch (eapol_type) {

  case EAP_PACKET:
    next_tvb = tvb_new_subset_remaining(tvb, offset);
    call_dissector(eap_handle, next_tvb, pinfo, eapol_tree);
    break;

  case EAPOL_KEY:
    if (tree) {
      keydesc_type = tvb_get_guint8(tvb, offset);
      proto_tree_add_item(eapol_tree, hf_eapol_keydes_type, tvb, offset, 1, FALSE);
      offset += 1;
      if (keydesc_type == EAPOL_WPA_KEY || keydesc_type == EAPOL_RSN_KEY) {
	keyinfo = tvb_get_ntohs(tvb, offset);
	keyinfo_item =
	  proto_tree_add_uint(eapol_tree, hf_eapol_wpa_keydes_keyinfo, tvb,
			      offset, 2, keyinfo);

	keyinfo_tree = proto_item_add_subtree(keyinfo_item, ett_keyinfo);
	proto_tree_add_uint(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_keydes_ver, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_key_type, tvb, offset, 2, keyinfo);
	proto_tree_add_uint(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_key_index, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_install, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_key_ack, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_key_mic, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_secure, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_error, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_request, tvb, offset, 2, keyinfo);
	proto_tree_add_boolean(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_encr_key_data, tvb, offset, 2, keyinfo);

        offset += 2;
        proto_tree_add_uint(eapol_tree, hf_eapol_keydes_keylen, tvb, offset,
        		    2, tvb_get_ntohs(tvb, offset));
        offset += 2;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_replay_counter, tvb,
        		    offset, 8, FALSE);
        offset += 8;
        proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_nonce, tvb, offset,
        		    32, FALSE);
        offset += 32;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_key_iv, tvb,
        		    offset, 16, FALSE);
        offset += 16;
        proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_rsc, tvb, offset,
        		    8, FALSE);
        offset += 8;
        proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_id, tvb, offset, 8,
        		    FALSE);
        offset += 8;
        proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_mic, tvb, offset,
        		    16, FALSE);
        offset += 16;
        eapol_data_len = tvb_get_ntohs(tvb, offset);
        proto_tree_add_uint(eapol_tree, hf_eapol_wpa_keydes_datalen, tvb,
        		    offset, 2, eapol_data_len);
        offset += 2;
        if (eapol_data_len != 0) {
          ti = proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_data,
          	tvb, offset, eapol_data_len, FALSE);
	  if ((keyinfo & KEY_INFO_ENCR_KEY_DATA_MASK) ||
	      !(keyinfo & KEY_INFO_KEY_TYPE_MASK)) {
	    /* RSN: EAPOL-Key Key Data is encrypted.
	     * WPA: Group Keys use encrypted Key Data.
	     * Cannot parse this without knowing the key.
	     * IEEE 802.11i-2004 8.5.2.
	     */
	  } else {
	    keydes_tree = proto_item_add_subtree(ti, ett_eapol_keydes_data);
	    ieee_80211_add_tagged_parameters(tvb, offset, pinfo, keydes_tree,
					     eapol_data_len);
	  }
        }
      } else {
        eapol_key_len = tvb_get_ntohs(tvb, offset);
        proto_tree_add_uint(eapol_tree, hf_eapol_keydes_keylen, tvb, offset, 2, eapol_key_len);
        offset += 2;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_replay_counter, tvb,
  			  offset, 8, FALSE);
        offset += 8;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_key_iv, tvb,
  			  offset, 16, FALSE);
        offset += 16;
        key_index = tvb_get_guint8(tvb, offset);
        ti = proto_tree_add_text(eapol_tree, tvb, offset, 1,
  			       "Key Index: %s, index %u",
  			       (key_index & 0x80) ? "unicast" : "broadcast",
  			       key_index & 0x7F);
        key_index_tree = proto_item_add_subtree(ti, ett_eapol_key_index);
        proto_tree_add_boolean(eapol_tree, hf_eapol_keydes_key_index_keytype,
  			     tvb, offset, 1, key_index);
        proto_tree_add_uint(eapol_tree, hf_eapol_keydes_key_index_indexnum,
  			     tvb, offset, 1, key_index);
        offset += 1;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_key_signature, tvb,
  			  offset, 16, FALSE);
        offset += 16;
        if (eapol_key_len != 0) {
          if (eapol_len > 44) { /* Size of rc4 key with no key content */
            proto_tree_add_item(eapol_tree, hf_eapol_keydes_key, tvb, offset,
  			    eapol_key_len, FALSE);
          } else {
		/* IEEE 802.1X-2004 7.6.3.6: If no bytes remain, then  */
		proto_tree_add_text(eapol_tree, tvb, offset, 0, "Key: Use key locally generated by peer");
          }
        }
      }
    }
    break;

  case EAPOL_ENCAP_ASF_ALERT:	/* XXX - is this an SNMP trap? */
  default:
    next_tvb = tvb_new_subset_remaining(tvb, offset);
    call_dissector(data_handle, next_tvb, pinfo, eapol_tree);
    break;
  }
}
Пример #7
0
static void
dissect_eapol(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  int         offset = 0;
  guint8      eapol_type;
  guint8      keydesc_type;
  guint16     eapol_len;
  guint       len;
  guint16     eapol_key_len, eapol_data_len;
  guint16     keyinfo;
  gboolean    generated_locally;
  proto_tree *ti = NULL;
  proto_tree *eapol_tree = NULL;
  proto_tree *keyinfo_item = NULL;
  proto_tree *keyinfo_tree = NULL;
  proto_tree *key_index_tree, *keydes_tree;
  tvbuff_t   *next_tvb;
  guint8     counter;

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "EAPOL");
  col_clear(pinfo->cinfo, COL_INFO);

  if (tree) {
    ti = proto_tree_add_item(tree, proto_eapol, tvb, 0, -1, ENC_NA);
    eapol_tree = proto_item_add_subtree(ti, ett_eapol);

    proto_tree_add_item(eapol_tree, hf_eapol_version, tvb, offset, 1, ENC_BIG_ENDIAN);
  }
  offset++;

  eapol_type = tvb_get_guint8(tvb, offset);
  if (tree)
    proto_tree_add_item(eapol_tree, hf_eapol_type, tvb, offset, 1, ENC_BIG_ENDIAN);
  col_add_str(pinfo->cinfo, COL_INFO,
                val_to_str(eapol_type, eapol_type_vals, "Unknown Type (0x%02X)"));
  offset++;

  eapol_len = tvb_get_ntohs(tvb, offset);
  len = EAPOL_HDR_LEN + eapol_len;
  set_actual_length(tvb, len);
  if (tree) {
    proto_item_set_len(ti, len);
    proto_tree_add_item(eapol_tree, hf_eapol_len, tvb, offset, 2, ENC_BIG_ENDIAN);
  }
  offset += 2;

  switch (eapol_type) {

  case EAP_PACKET:
    next_tvb = tvb_new_subset_remaining(tvb, offset);
    call_dissector(eap_handle, next_tvb, pinfo, eapol_tree);
    break;

  case EAPOL_KEY:
    if (tree) {
      keydesc_type = tvb_get_guint8(tvb, offset);
      proto_tree_add_item(eapol_tree, hf_eapol_keydes_type, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset += 1;
      if (keydesc_type == EAPOL_WPA_KEY || keydesc_type == EAPOL_RSN_KEY) {
        keyinfo = tvb_get_ntohs(tvb, offset);
        if (keyinfo & KEY_INFO_REQUEST_MASK) {
          col_set_str(pinfo->cinfo, COL_INFO, "Key (Request)");
          if (keyinfo & KEY_INFO_ERROR_MASK)
            col_set_str(pinfo->cinfo, COL_INFO, "Key (Request, Error)");
        } else if (keyinfo & KEY_INFO_KEY_TYPE_MASK) {
          guint16 masked;
          masked = keyinfo &
            (KEY_INFO_INSTALL_MASK | KEY_INFO_KEY_ACK_MASK |
             KEY_INFO_KEY_MIC_MASK | KEY_INFO_SECURE_MASK);

         if (keydesc_type == EAPOL_WPA_KEY) {
             switch (masked) {
                     case KEY_INFO_KEY_ACK_MASK:
                     col_set_str(pinfo->cinfo, COL_INFO, "Key (Message 1 of 4)");
                     break;
                     case KEY_INFO_KEY_MIC_MASK:
                     counter = tvb_get_guint8(tvb, offset+11);
                     if (!counter)
                             col_set_str(pinfo->cinfo, COL_INFO, "Key (Message 2 of 4)");
                     else
                             col_set_str(pinfo->cinfo, COL_INFO, "Key (Message 4 of 4)");
                     break;
                     case (KEY_INFO_INSTALL_MASK | KEY_INFO_KEY_ACK_MASK |
                     KEY_INFO_KEY_MIC_MASK):
                     col_set_str(pinfo->cinfo, COL_INFO, "Key (Message 3 of 4)");
                     break;
             }
         }

         if (keydesc_type == EAPOL_RSN_KEY) {
             switch (masked) {
                     case KEY_INFO_KEY_ACK_MASK:
                     col_set_str(pinfo->cinfo, COL_INFO, "Key (Message 1 of 4)");
                     break;
                     case KEY_INFO_KEY_MIC_MASK:
                     col_set_str(pinfo->cinfo, COL_INFO, "Key (Message 2 of 4)");
                     break;
                     case (KEY_INFO_INSTALL_MASK | KEY_INFO_KEY_ACK_MASK |
                     KEY_INFO_KEY_MIC_MASK | KEY_INFO_SECURE_MASK):
                     col_set_str(pinfo->cinfo, COL_INFO, "Key (Message 3 of 4)");
                     break;
                     case (KEY_INFO_KEY_MIC_MASK | KEY_INFO_SECURE_MASK):
                     col_set_str(pinfo->cinfo, COL_INFO, "Key (Message 4 of 4)");
                     break;
              }
         }

        } else {
          if (keyinfo & KEY_INFO_KEY_ACK_MASK)
            col_set_str(pinfo->cinfo, COL_INFO, "Key (Group Message 1 of 2)");
          else
            col_set_str(pinfo->cinfo, COL_INFO, "Key (Group Message 2 of 2)");
        }
        keyinfo_item =
          proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_keyinfo, tvb,
                              offset, 2, ENC_BIG_ENDIAN);

        keyinfo_tree = proto_item_add_subtree(keyinfo_item, ett_keyinfo);
        proto_tree_add_item(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_keydes_version, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_key_type, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_key_index, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_install, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_key_ack, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_key_mic, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_secure, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_error, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_request, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(keyinfo_tree, hf_eapol_wpa_keydes_keyinfo_encrypted_key_data, tvb, offset, 2, ENC_BIG_ENDIAN);

        offset += 2;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_key_len, tvb, offset,
                            2, ENC_BIG_ENDIAN);
        offset += 2;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_replay_counter, tvb,
                            offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
        proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_nonce, tvb, offset,
                            32, ENC_NA);
        offset += 32;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_key_iv, tvb,
                            offset, 16, ENC_NA);
        offset += 16;
        proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_rsc, tvb, offset,
                            8, ENC_NA);
        offset += 8;
        proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_id, tvb, offset, 8,
                            ENC_NA);
        offset += 8;
        proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_mic, tvb, offset,
                            16, ENC_NA);
        offset += 16;
        eapol_data_len = tvb_get_ntohs(tvb, offset);
        proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_data_len, tvb,
                            offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
        if (eapol_data_len != 0) {
          ti = proto_tree_add_item(eapol_tree, hf_eapol_wpa_keydes_data,
                tvb, offset, eapol_data_len, ENC_NA);
          if ((keyinfo & KEY_INFO_ENCRYPTED_KEY_DATA_MASK) ||
              !(keyinfo & KEY_INFO_KEY_TYPE_MASK)) {
            /* RSN: EAPOL-Key Key Data is encrypted.
             * WPA: Group Keys use encrypted Key Data.
             * Cannot parse this without knowing the key.
             * IEEE 802.11i-2004 8.5.2.
             */
          } else {
            keydes_tree = proto_item_add_subtree(ti, ett_eapol_keydes_data);
            ieee_80211_add_tagged_parameters(tvb, offset, pinfo, keydes_tree,
                                             eapol_data_len, -1);
          }
        }
      } else {
        eapol_key_len = tvb_get_ntohs(tvb, offset);
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_key_len, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_replay_counter, tvb,
                            offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_key_iv, tvb,
                            offset, 16, ENC_NA);
        offset += 16;
        ti = proto_tree_add_item(eapol_tree, hf_eapol_keydes_key_index, tvb, offset, 1, ENC_BIG_ENDIAN);
        key_index_tree = proto_item_add_subtree(ti, ett_eapol_key_index);
        proto_tree_add_item(key_index_tree, hf_eapol_keydes_key_index_type,
                            tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(key_index_tree, hf_eapol_keydes_key_index_number,
                            tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;
        proto_tree_add_item(eapol_tree, hf_eapol_keydes_key_signature, tvb,
                            offset, 16, ENC_NA);
        offset += 16;
        if (eapol_key_len != 0) {
          /* IEEE 802.1X-2004 7.6.3.6: If no bytes remain, then */
          generated_locally = eapol_len <= 44; /* Size of rc4 key with no key content */
          if (!generated_locally) {
              proto_tree_add_item(eapol_tree, hf_eapol_keydes_key, tvb, offset,
                                  eapol_key_len, ENC_NA);
          }

          proto_tree_add_boolean(eapol_tree, hf_eapol_keydes_key_generated_locally, tvb, offset,
                                 0, generated_locally);
        }
      }
    }
    break;

  case EAPOL_ENCAP_ASF_ALERT:   /* XXX - is this an SNMP trap? */
  default:
    next_tvb = tvb_new_subset_remaining(tvb, offset);
    call_dissector(data_handle, next_tvb, pinfo, eapol_tree);
    break;
  }
}