/**
 * dissect_content_length is a utility function which
 * calculates how long is the payload section of the message
 * in bytes. Used only by the UDP dissector.
 *
 * @see dissect_packetid()
 * @see dissect_reliable_message_index_base()
 * @see dissect_reliable_message_number()
 * @see dissect_messageid()
 * @see dissect_payload()
 * @param buffer the buffer to the data
 * @param offset the offset where to start reading the data
 * @param tree the parent tree where the dissected data is going to be inserted
 * @return int returns the content length of the packet
 *
 */
static int
dissect_content_length(tvbuff_t *buffer, int offset, proto_tree *tree)
{
    proto_item *msgflags_ti;
    proto_tree *msgflags_tree;
    guint32     length;

    length  = tvb_get_bits8(buffer, offset * 8 + 12, 4) << 8;
    length += tvb_get_bits8(buffer, offset * 8, 8);

    if(tree != NULL)
    {
        msgflags_ti   = proto_tree_add_item(tree, hf_knet_msg_flags, buffer, offset + 1, 1, ENC_NA);
        msgflags_tree = proto_item_add_subtree(msgflags_ti, ett_knet_message_flags);

        proto_tree_add_item(msgflags_tree, hf_knet_msg_fs, buffer, offset+1, 1, ENC_NA); /* Fragment start flag */
        proto_tree_add_item(msgflags_tree, hf_knet_msg_ff, buffer, offset+1, 1, ENC_NA);  /* Fragment flag */
        proto_tree_add_item(msgflags_tree, hf_knet_msg_inorder, buffer, offset+1, 1, ENC_NA); /* Inorder flag */
        proto_tree_add_item(msgflags_tree, hf_knet_msg_reliable, buffer, offset+1, 1, ENC_NA); /* Reliable flag */

        proto_tree_add_uint(tree, hf_knet_content_length, buffer, offset, 2, length);
    }

    return length;
}
/**
 * dissect_content_length_vle is a utility function which
 * calculates how long is the payload section of the message
 * in bytes which is VLE encoded.
 *
 * @see dissect_packetid()
 * @see dissect_reliable_message_index_base()
 * @see dissect_reliable_message_number()
 * @see dissect_messageid()
 * @see dissect_payload()
 * @param buffer the buffer to the data
 * @param offset the offset where to start reading the data
 * @param tree the parent tree where the dissected data is going to be inserted
 * @return int returns the content length of the packet
 *
 */
static int
dissect_content_length_vle(tvbuff_t *buffer, int *offset, proto_tree *tree)
{
    int     byte_count;
    guint32 length;

    length     = 0;
    byte_count = count_vle_bytes(buffer, *offset);

    switch(byte_count) /*We must calculate length by hand because we use the length later */
    {
        case 4:
            length = tvb_get_bits8(buffer,   ((*offset) + 3) * 8, 8) <<23;
            length += tvb_get_bits8(buffer,  ((*offset) + 2) * 8, 8) <<15;
            /* FALLTHRU */
        case 2:
            length +=(tvb_get_bits8(buffer,  ((*offset) + 1) * 8, 8) & 127) <<7;
            /* FALLTHRU */
        case 1:
            length +=(tvb_get_bits8(buffer,  (*offset) * 8, 8) & 127);
        break;
        default:
            REPORT_DISSECTOR_BUG("Error in Content Length calculation");
        break;
    }

    if(tree != NULL)
    {
        proto_tree_add_uint(tree, hf_knet_content_length, buffer, (*offset), byte_count, length);
        (*offset) += byte_count;
    }

    return length;
}
/**
 * dissect_packetid is a utility function which calculates
 * the packets Packet ID from the data. Packet ID is a field
 * located in the datagram header.
 *
 * @see dissect_reliable_message_index_base()
 * @see dissect_reliable_message_number()
 * @see dissect_content_length()
 * @see dissect_messageid()
 * @see dissect_payload()
 * @param buffer the buffer to the data
 * @param offset the offset where to start reading the data
 * @param tree the parent tree where the dissected data is going to be inserted
 * @return int returns the new offset
 *
 */
static int
dissect_packetid(tvbuff_t *buffer, int offset, proto_tree *tree)
{
    guint32 packetid;

    packetid  = tvb_get_bits8(buffer, offset * 8 + 16, 8) << 14;
    packetid += tvb_get_bits8(buffer, offset * 8 + 8, 8) << 6;
    packetid += tvb_get_bits8(buffer, offset * 8, 8) & 63;
    if(offset == 0 && tree != NULL)
        proto_tree_add_uint(tree, hf_knet_packetid, buffer, 0, 3, packetid);

    return packetid;
}
/**
 * counts length of the variable length encoded field
 *
 * @param  tvb the buffer to the data
 * @param  offset the offset of data in the buffer
 * @return int returns number of bytes used
 *
 */
static int
count_vle_bytes(tvbuff_t *tvb, int offset)
{
    int byte_count;

    byte_count = 1;

    if((tvb_get_bits8(tvb, (offset) * 8, 8) & 128) > 0)     /* If the first bit of the first byte is 1 */
        byte_count = 2;                                     /* There's at least 2 bytes of content length */
    if((tvb_get_bits8(tvb, (offset) * 8 + 8, 8) & 128) > 0) /* If the next one is also 1 */
        byte_count = 4;

    return byte_count;
}
static void
dissect_ayiya(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree *ayiya_tree;
	int offset = 0;
	int idlen, siglen, ayiya_len;
	guint8 next_header, opcode;
	tvbuff_t *payload;

	idlen = 1 << tvb_get_bits8(tvb, 0, 4);
	siglen = tvb_get_bits8(tvb, 8, 4) * 4;
	opcode = tvb_get_bits8(tvb, 20, 4);
	next_header = tvb_get_guint8(tvb, 3);

	ayiya_len = 8+idlen+siglen;

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

	if (tree) {
		proto_item *ti;
		nstime_t tv;
		ti = proto_tree_add_protocol_format( tree, proto_ayiya, tvb,
											 offset, ayiya_len, "AYIYA" );
		ayiya_tree = proto_item_add_subtree(ti, ett_ayiya);

		proto_tree_add_bits_item(ayiya_tree, hf_id_len, tvb, 0, 4, ENC_BIG_ENDIAN);
		proto_tree_add_bits_item(ayiya_tree, hf_id_type, tvb, 4, 4, ENC_BIG_ENDIAN);
		proto_tree_add_bits_item(ayiya_tree, hf_sig_len, tvb, 8, 4, ENC_BIG_ENDIAN);
		proto_tree_add_bits_item(ayiya_tree, hf_hash_method, tvb, 12, 4, ENC_BIG_ENDIAN);
		proto_tree_add_bits_item(ayiya_tree, hf_auth_method, tvb, 16, 4, ENC_BIG_ENDIAN);
		proto_tree_add_bits_item(ayiya_tree, hf_opcode, tvb, 20, 4, ENC_BIG_ENDIAN);
		proto_tree_add_uint_format(ayiya_tree, hf_next_header, tvb,
								   3, 1, next_header,
								   "Next header: %s (0x%02x)",
								   ipprotostr(next_header), next_header);
		tv.secs = tvb_get_ntohl(tvb, 4);
		tv.nsecs = 0;
		proto_tree_add_time(ayiya_tree, hf_epoch, tvb, 4, 4, &tv);
		proto_tree_add_item(ayiya_tree, hf_identity, tvb, 8, idlen, ENC_NA);
		proto_tree_add_item(ayiya_tree, hf_signature, tvb, 8+idlen, siglen, ENC_NA);
	}
	offset = ayiya_len;
	switch (opcode) {
	case OPCODE_FORWARD:
		payload = tvb_new_subset_remaining(tvb, offset);
		dissector_try_uint(ip_dissector_table, next_header, payload, pinfo, tree);
		break;
	}
}
/**
 * dissect_messageid is a utility function which
 * calculates the ID of the message.
 *
 * @see dissect_packetid()
 * @see dissect_reliable_message_index_base()
 * @see dissect_content_length()
 * @see dissect_reliable_message_number()
 * @see dissect_payload()
 * @param buffer the buffer to the data
 * @param offset the offset where to start reading the data
 * @param tree the parent tree where the dissected data is going to be inserted
 * @return int returns the messageid
 *
 */
static int
dissect_messageid(tvbuff_t *buffer, int *offset, proto_tree *tree, packet_info *pinfo, emem_strbuf_t* info_field)
{
    gint   messageid_length;
    guint8 messageid;

    messageid = tvb_get_bits8(buffer, (*offset) * 8, 8);

    switch(messageid)
    {
        case DISCONNECT:
        case DISCONNECTACK:
        case CONNECTSYN:
        case CONNECTSYNACK:
        case CONNECTACK:
            messageid_length = 4;
        break;
        default:
            messageid_length = 1;
        break;
    }

    proto_tree_add_bytes_format(tree, hf_knet_messageid, buffer, *offset, messageid_length, NULL,
    "Message ID: %s (%d)", val_to_str_const(messageid, packettypenames, "AppData or Malformed Message ID"), messageid);

    col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str_const(messageid, packettypenames, "AppData "));

    *offset += messageid_length;

    ep_strbuf_append_printf(info_field, "Msg ID (%d) ", messageid);

    return messageid;
}
Exemple #7
0
static void
dissect_nsh_md_type_2(tvbuff_t *tvb, proto_tree *nsh_tree, int offset, int nsh_bytes_len)
{

	int type2_metadata_len = 0;

	while (offset < nsh_bytes_len) {

		proto_tree_add_item(nsh_tree, hf_nsh_metadata_class, tvb, offset, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(nsh_tree, hf_nsh_metadata_type, tvb, offset + 2, 1, ENC_BIG_ENDIAN);

		/* Bits 24 - 26 are reserved */
		proto_tree_add_item(nsh_tree, hf_nsh_metadata_reservedbits, tvb, offset + 3, 1, ENC_BIG_ENDIAN);

		/*Bits 27-31 represent length in 4 bytes words*/
		proto_tree_add_item(nsh_tree, hf_nsh_metadata_length, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
		type2_metadata_len = 4 * tvb_get_bits8(tvb, ((offset + 3) * 8) + 3, 5);

		if (type2_metadata_len >= 4)
			proto_tree_add_item(nsh_tree, hf_nsh_metadata, tvb, offset + 4, type2_metadata_len, ENC_NA);

		offset = offset + 4 + type2_metadata_len;

	}


}
/**
 * dissect_reliable_message_number is a utility function which
 * calculates the RMN if and only if the reliable flag in the
 * message block is set to 1.
 *
 * @see dissect_packetid()
 * @see dissect_reliable_message_index_base()
 * @see dissect_content_length()
 * @see dissect_messageid()
 * @see dissect_payload()
 * @param buffer the buffer to the data
 * @param offset the offset where to start reading the data
 * @param tree the parent tree where the dissected data is going to be inserted
 * @return int returns the new offset
 *
 */
static int
dissect_reliable_message_number(tvbuff_t *buffer, int offset, proto_tree *tree)
{
    int byte_count;

    byte_count = 1;

    if((tvb_get_bits8(buffer, offset * 8, 8) & 128) > 0)
        byte_count = 2;

    if(tree != NULL)
        proto_tree_add_item(tree, hf_knet_msg_reliable_message_number, buffer, offset, byte_count, ENC_LITTLE_ENDIAN);

    return byte_count;
}
static gboolean dissect_mysensors_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
  guint8 version;

  /* 0) Test minimum packet length */
  if (tvb_length(tvb) < MYSENSORS_MSG_HEADER_LENGTH)
    return FALSE;

  /* 1) Test protocol verion -- only version 2 (1.4) currently supported */
  version = tvb_get_bits8(tvb, 3*8+5, 3);
  if (version != V2_14)
    return FALSE;

  dissect_mysensors(tvb, pinfo, tree);
    
  return TRUE;
}
Exemple #10
0
WSLUA_METHOD TvbRange_bitfield(lua_State* L) {
	/* Get a bitfield from a TvbRange. */
#define WSLUA_OPTARG_TvbRange_bitfield_POSITION 2 /* The bit offset from the beginning of the TvbRange. Defaults to 0. */
#define WSLUA_OPTARG_TvbRange_bitfield_LENGTH 3 /* The length (in bits) of the field. Defaults to 1. */

    TvbRange tvbr = checkTvbRange(L,1);
    int pos = luaL_optint(L,WSLUA_OPTARG_TvbRange_bitfield_POSITION,0);
    int len = luaL_optint(L,WSLUA_OPTARG_TvbRange_bitfield_LENGTH,1);

    if (!(tvbr && tvbr->tvb)) return 0;
    if (tvbr->tvb->expired) {
        luaL_error(L,"expired tvb");
        return 0;
    }

    if ((pos+len) > (tvbr->len<<3)) {
        luaL_error(L, "Requested bitfield out of range");
        return 0;
    }

    if (len <= 8) {
        lua_pushnumber(L,(lua_Number)tvb_get_bits8(tvbr->tvb->ws_tvb,tvbr->offset*8 + pos, len));
        return 1;
    } else if (len <= 16) {
        lua_pushnumber(L,tvb_get_bits16(tvbr->tvb->ws_tvb,tvbr->offset*8 + pos, len, FALSE));
        return 1;
    } else if (len <= 32) {
        lua_pushnumber(L,tvb_get_bits32(tvbr->tvb->ws_tvb,tvbr->offset*8 + pos, len, FALSE));
        return 1;
    } else if (len <= 64) {
        UInt64 num = (UInt64)g_malloc(sizeof(guint64));
        *num = tvb_get_bits64(tvbr->tvb->ws_tvb,tvbr->offset*8 + pos, len, FALSE);
        pushUInt64(L,num);
        WSLUA_RETURN(1); /* The bitfield value */
    } else {
        luaL_error(L,"TvbRange:bitfield() does not handle %d bits",len);
        return 0;
    }
}
/* Dissect a P-GSL ACess Burst Message */
static void
dissect_pgsl_access_burst(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree,
			  RlcMacPrivateData_t *rlcmac_data)
{
	proto_item *ti;
	proto_tree *pacch_tree;
	tvbuff_t *data_tvb;
	guint rxlev, abtype, abi;
	guint16 acc_delay;

	ti = proto_tree_add_item(tree, hf_pgsl_pacch, tvb, offset, 5, ENC_NA);
	pacch_tree = proto_item_add_subtree(ti, ett_pacch);

	proto_tree_add_item_ret_uint(pacch_tree, hf_pgsl_ab_rxlev, tvb, offset++, 1, ENC_NA, &rxlev);
	/* Access Delay is encoded as 10-bit field with the lowest 8
	 * bits in the first octet, with the two highest bits in the
	 * lowest bits of the second octet */
	acc_delay = tvb_get_guint8(tvb, offset);
	acc_delay |= tvb_get_bits8(tvb, (offset+1)*8+6, 2) << 8;
	proto_tree_add_uint(pacch_tree, hf_pgsl_ab_acc_delay, tvb, offset, 2, acc_delay);
	/* ABI and AB Type are in the same octet as the acc_dely msb's */
	offset++;
	proto_tree_add_item_ret_uint(pacch_tree, hf_pgsl_ab_abi, tvb, offset, 1, ENC_NA, &abi);
	proto_tree_add_item_ret_uint(pacch_tree, hf_pgsl_ab_ab_type, tvb, offset, 1, ENC_NA, &abtype);
	offset++;
	/* Update the 'master' item */
	if (abi) {
		proto_item_append_text(ti, " Valid, RxLev %u, Delay %u bits, Type %s", rxlev, acc_delay,
					val_to_str(abtype, pgsl_ab_type_vals, "0x%x"));
		/* decode actual access burst */
		data_tvb = tvb_new_subset_length(tvb, offset, 2);
		call_dissector_with_data(sub_handles[SUB_RLCMAC_UL], data_tvb, pinfo, pacch_tree,
					 (void *) rlcmac_data);
	} else
		proto_item_append_text(ti, " Invalid, RxLev %u", rxlev);
}
Exemple #12
0
void
dissect_802_3(volatile int length, gboolean is_802_2, tvbuff_t *tvb,
	      int offset_after_length, packet_info *pinfo, proto_tree *tree,
	      proto_tree *fh_tree, int length_id, int trailer_id, expert_field* ei_len,
	      int fcs_len)
{
  proto_item		*length_it;
  tvbuff_t		*volatile next_tvb = NULL;
  tvbuff_t		*trailer_tvb = NULL;
  const char		*saved_proto;
  gint			captured_length, reported_length;
  void			*pd_save;

  length_it = proto_tree_add_uint(fh_tree, length_id, tvb,
                                  offset_after_length - 2, 2, length);

  /* Get the length of the payload.
     If the FCS length is positive, remove the FCS.
     (If it's zero, there's no FCS; if it's negative, we don't know whether
     there's an FCS, so we'll guess based on the length of the trailer.) */
  reported_length = tvb_reported_length_remaining(tvb, offset_after_length);
  if (fcs_len > 0) {
    if (reported_length >= fcs_len)
      reported_length -= fcs_len;
  }

  /* Make sure the length in the 802.3 header doesn't go past the end of
     the payload. */
  if (length > reported_length) {
    length = reported_length;
    expert_add_info(pinfo, length_it, ei_len);
  }

  /* Give the next dissector only 'length' number of bytes. */
  captured_length = tvb_captured_length_remaining(tvb, offset_after_length);
  if (captured_length > length)
    captured_length = length;
  next_tvb = tvb_new_subset(tvb, offset_after_length, captured_length, length);

  /* Dissect the payload either as IPX or as an LLC frame.
     Catch non-fatal exceptions, so that if the reported length
     of "next_tvb" was reduced by some dissector before an
     exception was thrown, we can still put in an item for
     the trailer. */
  saved_proto = pinfo->current_proto;
  pd_save = pinfo->private_data;
  TRY {
    if (is_802_2)
      call_dissector(llc_handle, next_tvb, pinfo, tree);
    else {
      /* Check if first three bits of payload are 0x7.
         If so, then payload is IPX.  If not, then it's CCSDS.
         Refer to packet-eth.c for setting of is_802_2 variable. */
      if (tvb_get_bits8(next_tvb, 0, 3) == 7)
        call_dissector(ipx_handle, next_tvb, pinfo, tree);
      else
        call_dissector(ccsds_handle, next_tvb, pinfo, tree);
    }
  }
  CATCH_NONFATAL_ERRORS {
    /* Somebody threw an exception that means that there was a problem
       dissecting the payload; that means that a dissector was found,
       so we don't need to dissect the payload as data or update the
       protocol or info columns.

       Just show the exception and then drive on to show the trailer,
       after noting that a dissector was found and restoring the
       protocol value that was in effect before we called the subdissector. */
    pinfo->private_data = pd_save;

    show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
  }
  ENDTRY;

  /* Restore the protocol value, so that any exception thrown by
     tvb_new_subset_remaining() refers to the protocol for which
     this is a trailer, and restore the private_data structure in
     case one of the called dissectors modified it. */
  pinfo->private_data = pd_save;
  pinfo->current_proto = saved_proto;

  /* Construct a tvbuff for the trailer; if the trailer is past the
     end of the captured data, this will throw a BoundsError, which
     is what we want, as it'll report that the packet was cut short. */
  trailer_tvb = tvb_new_subset_remaining(tvb, offset_after_length + length);

  add_ethernet_trailer(pinfo, tree, fh_tree, trailer_id, tvb, trailer_tvb, fcs_len);
}
Exemple #13
0
static int
dissect_ndef_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_item *ti;
	proto_tree *ndef_record_tree;
	guint8 sr;
	guint8 il;
	guint8 type_length;
	guint payload_length;
	guint id_length;
	guint offset;

	if (tvb_length(tvb) < NDEF_STANDARD_RECORD_MIN_LEN)
		return 0;  // XXX Error.
	
	sr = tvb_get_bits8(tvb, SR_BIT_OFFSET, 1);
	il = tvb_get_bits8(tvb, IL_BIT_OFFSET, 1);

	if (tree) {
		ti = proto_tree_add_item(tree, hf_ndef_record, tvb, 0, -1,
			ENC_BIG_ENDIAN);

		ndef_record_tree = proto_item_add_subtree(ti, ett_ndef_record);

		offset = 0;

		proto_tree_add_item(ndef_record_tree,
		    hf_ndef_record_mb, tvb, offset, 1, ENC_BIG_ENDIAN);
		proto_tree_add_item(ndef_record_tree,
		    hf_ndef_record_me, tvb, offset, 1, ENC_BIG_ENDIAN);
		proto_tree_add_item(ndef_record_tree,
		    hf_ndef_record_cf, tvb, offset, 1, ENC_BIG_ENDIAN);
		proto_tree_add_item(ndef_record_tree,
		    hf_ndef_record_sr, tvb, offset, 1, ENC_BIG_ENDIAN);
		proto_tree_add_item(ndef_record_tree,
		    hf_ndef_record_il, tvb, offset, 1, ENC_BIG_ENDIAN);
		proto_tree_add_item(ndef_record_tree,
		    hf_ndef_record_tnf, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		type_length = tvb_get_guint8(tvb, offset);
		proto_tree_add_item(ndef_record_tree,
		    hf_ndef_record_type_length, tvb, offset, 1,
		    ENC_BIG_ENDIAN);
		offset += 1;

		if (sr == 1) {
			payload_length = tvb_get_guint8(tvb, offset);
			// MUST be 1, can check here.
			proto_tree_add_item(ndef_record_tree,
			    hf_ndef_record_payload_length_sr, tvb, offset, 1,
			    ENC_BIG_ENDIAN);
			offset += 1;
		} else {
			payload_length = tvb_get_ntohl(tvb, offset);
			proto_tree_add_item(ndef_record_tree,
			    hf_ndef_record_payload_length, tvb, offset, 4,
			    ENC_BIG_ENDIAN);
			offset += 4;
		}
		if (il != 0) {
			id_length = tvb_get_guint8(tvb, offset);
			proto_tree_add_item(ndef_record_tree,
			    hf_ndef_record_id_length, tvb, offset, 1,
			    ENC_BIG_ENDIAN);
			offset += 1;
		} else {
			id_length = 0; // default.
		}

		if (type_length > 0) {
			// TODO(stevec): Decode common types.
			proto_tree_add_item(ndef_record_tree,
			    hf_ndef_record_type, tvb, offset, type_length,
			    ENC_BIG_ENDIAN);
			offset += 1;
		}
		
		if (id_length > 0) {
			proto_tree_add_item(ndef_record_tree,
			    hf_ndef_record_id, tvb, offset, id_length,
			    ENC_BIG_ENDIAN);
			offset += 1;
		}

		if (payload_length > 0) {
			proto_tree_add_item(ndef_record_tree,
			    hf_ndef_record_payload, tvb, offset,
			    payload_length,
			    ENC_NA);
		}
	}

	return tvb_length(tvb);
}
Exemple #14
0
static void
dissect_edsa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint8 edsa_tag;
	guint8 edsa_tagged;
	guint8 edsa_dev;
	guint8 edsa_port;
	guint8 edsa_trunk;
	guint8 edsa_cfi;
	guint8 edsa_prio;
	guint8 edsa_vid;
	guint8 edsa_code;
	guint16 edsa_ethtype;
	gboolean is_802_2;

	proto_tree  *edsa_tree = NULL;
	proto_item  *ti;

	edsa_tag 	= tvb_get_bits8(tvb, (8 * 2) + 0 , 2);
	edsa_tagged 	= tvb_get_bits8(tvb, (8 * 2) + 2, 1);
	edsa_dev 	= tvb_get_bits8(tvb, (8 * 2) + 3, 5);
	edsa_port 	= tvb_get_bits8(tvb, (8 * 3) + 0, 5);
	edsa_trunk 	= tvb_get_bits8(tvb, (8 * 3) + 5, 1);
	edsa_cfi 	= tvb_get_bits8(tvb, (8 * 3) + 7, 0);
	edsa_prio	= tvb_get_bits8(tvb, (8 * 4) + 0, 3);
	edsa_vid 	= tvb_get_bits16(tvb, (8 * 4) + 4, 12, TRUE);

	edsa_code	= (tvb_get_bits8(tvb, (8 * 3) + 5, 2) << 2 |
			   tvb_get_bits8(tvb, (8 * 4) + 3, 1));
	edsa_ethtype	= tvb_get_ntohs(tvb, 6);

	if (tree) {
		ti = proto_tree_add_protocol_format(
			tree, proto_edsa, tvb, 0, EDSA_HEADER_SIZE,
			"EtherType Distributed Switch Architecture, %s Dev: %d Port: %d VID: %d",
			val_to_str(edsa_tag, tag_vals, "tag %d"),
			edsa_dev, edsa_port, edsa_vid);
		edsa_tree = proto_item_add_subtree(ti, ett_edsa);
		proto_tree_add_uint(edsa_tree, hf_edsa_tag,
				    tvb, 2, 1, edsa_tag);
		switch (edsa_tag) {
		case TAG_TO_CPU:
			proto_tree_add_boolean(
				edsa_tree, hf_edsa_tagged, tvb, 2, 1,
				edsa_tagged);
			proto_tree_add_uint(
				edsa_tree, hf_edsa_dev, tvb, 2, 1, edsa_dev);
			proto_tree_add_uint(
				edsa_tree, hf_edsa_port, tvb, 3, 1, edsa_port);
			proto_tree_add_uint(
				edsa_tree, hf_edsa_vid, tvb, 4, 2, edsa_vid);
			proto_tree_add_uint(
				edsa_tree, hf_edsa_code, tvb, 3, 2, edsa_code);
			proto_tree_add_uint(
				edsa_tree, hf_edsa_prio, tvb, 4, 1, edsa_prio);
			proto_tree_add_boolean(
				edsa_tree, hf_edsa_cfi, tvb, 3, 1, edsa_cfi);
			break;
		case TAG_FROM_CPU:
			proto_tree_add_boolean(
				edsa_tree, hf_edsa_tagged, tvb, 2, 1,
				edsa_tagged);
			proto_tree_add_uint(
				edsa_tree, hf_edsa_dev, tvb, 2, 1, edsa_dev);
			proto_tree_add_uint(
				edsa_tree, hf_edsa_port, tvb, 3, 1, edsa_port);
			proto_tree_add_uint(
				edsa_tree, hf_edsa_vid, tvb, 4, 2, edsa_vid);
			proto_tree_add_uint(
				edsa_tree, hf_edsa_prio, tvb, 4, 1, edsa_prio);
			proto_tree_add_boolean(
				edsa_tree, hf_edsa_cfi, tvb, 3, 1, edsa_cfi);
			break;
		case TAG_FORWARD:
			proto_tree_add_boolean(
				edsa_tree, hf_edsa_tagged, tvb, 2, 1,
				edsa_tagged);
			proto_tree_add_uint(
				edsa_tree, hf_edsa_dev, tvb, 2, 1, edsa_dev);
			proto_tree_add_uint(
				edsa_tree, hf_edsa_port, tvb, 3, 1, edsa_port);
			proto_tree_add_boolean(
				edsa_tree, hf_edsa_trunk, tvb, 3, 1,
				edsa_trunk);
			proto_tree_add_uint(
				edsa_tree, hf_edsa_vid, tvb, 4, 2, edsa_vid);
			proto_tree_add_uint(
				edsa_tree, hf_edsa_prio, tvb, 4, 1, edsa_prio);
			proto_tree_add_boolean(
				edsa_tree, hf_edsa_cfi, tvb, 3, 1, edsa_cfi);
			break;
		}
	}
	if (edsa_ethtype <= IEEE_802_3_MAX_LEN) {
		/* Is there an 802.2 layer? I can tell by looking at
		   the first 2 bytes after the VLAN header. If they
		   are 0xffff, then what follows the VLAN header is an
		   IPX payload, meaning no 802.2.  (IPX/SPX is they
		   only thing that can be contained inside a straight
		   802.3 packet, so presumably the same applies for
		   Ethernet VLAN packets). A non-0xffff value means
		   that there's an 802.2 layer inside the VLAN
		   layer */
		is_802_2 = TRUE;

		/* Don't throw an exception for this check (even a
		 * BoundsError) */
		if (tvb_captured_length_remaining(tvb, 8) >= 2) {
			if (tvb_get_ntohs(tvb, 8) == 0xffff) {
				is_802_2 = FALSE;
			}
			dissect_802_3(edsa_ethtype, is_802_2, tvb, 8, pinfo,
				      tree, edsa_tree, hf_edsa_len,
				      hf_edsa_trailer, &ei_edsa_len, 0);
		}
	} else {
		ethertype_data_t ethertype_data;

		ethertype_data.etype = edsa_ethtype;
		ethertype_data.offset_after_ethertype = 8;
		ethertype_data.fh_tree = edsa_tree;
		ethertype_data.etype_id = hf_edsa_ethtype;
		ethertype_data.trailer_id = hf_edsa_trailer;
		ethertype_data.fcs_len = 0;

		call_dissector_with_data(ethertype_handle, tvb, pinfo, tree,
					 &ethertype_data);
  }
}
void
dissect_802_3(volatile int length, gboolean is_802_2, tvbuff_t *tvb,
	      int offset_after_length, packet_info *pinfo, proto_tree *tree,
	      proto_tree *fh_tree, int length_id, int trailer_id,
	      int fcs_len)
{
  proto_item		*length_it;
  tvbuff_t		*volatile next_tvb = NULL;
  tvbuff_t		*volatile trailer_tvb = NULL;
  const char		*saved_proto;
  gint			captured_length, reported_length;

  length_it = proto_tree_add_uint(fh_tree, length_id, tvb,
                                  offset_after_length - 2, 2, length);

  /* Get the length of the payload.
     If the FCS length is positive, remove the FCS.
     (If it's zero, there's no FCS; if it's negative, we don't know whether
     there's an FCS, so we'll guess based on the length of the trailer.) */
  reported_length = tvb_reported_length_remaining(tvb, offset_after_length);
  if (fcs_len > 0) {
    if (reported_length >= fcs_len)
      reported_length -= fcs_len;
  }

  /* Make sure the length in the 802.3 header doesn't go past the end of
     the payload. */
  if (length > reported_length) {
    length = reported_length;
    expert_add_info_format(pinfo, length_it, PI_MALFORMED, PI_ERROR,
        "Length field value goes past the end of the payload");
  }

  /* Give the next dissector only 'length' number of bytes. */
  captured_length = tvb_length_remaining(tvb, offset_after_length);
  if (captured_length > length)
    captured_length = length;
  next_tvb = tvb_new_subset(tvb, offset_after_length, captured_length, length);
  TRY {
    trailer_tvb = tvb_new_subset_remaining(tvb, offset_after_length + length);
  }
  CATCH2(BoundsError, ReportedBoundsError) {
    /* The packet has exactly "length" bytes worth of captured data
       left in it, so the "tvb_new_subset()" creating "trailer_tvb"
       threw an exception.

       This means that all the data in the frame is within the length
       value (assuming our offset isn't past the end of the tvb), so
       we give all the data to the next protocol and have no trailer. */
    trailer_tvb = NULL;
  }
  ENDTRY;

  /* Dissect the payload either as IPX or as an LLC frame.
     Catch BoundsError and ReportedBoundsError, so that if the
     reported length of "next_tvb" was reduced by some dissector
     before an exception was thrown, we can still put in an item
     for the trailer. */
  saved_proto = pinfo->current_proto;
  TRY {
    if (is_802_2)
      call_dissector(llc_handle, next_tvb, pinfo, tree);
    else {
      /* Check if first three bits of payload are 0x7.
         If so, then payload is IPX.  If not, then it's CCSDS.
         Refer to packet-eth.c for setting of is_802_2 variable. */
      if (tvb_get_bits8(next_tvb, 0, 3) == 7)
        call_dissector(ipx_handle, next_tvb, pinfo, tree);
      else
        call_dissector(ccsds_handle, next_tvb, pinfo, tree);
    }
  }
  CATCH(BoundsError) {
   /* Somebody threw BoundsError, which means that dissecting the payload
      found that the packet was cut off by a snapshot length before the
      end of the payload.  The trailer comes after the payload, so *all*
      of the trailer is cut off - don't bother adding the trailer, just
      rethrow the exception so it gets reported. */
   RETHROW;
  }
  CATCH_ALL {
    /* Well, somebody threw an exception other than BoundsError.
       Show the exception, and then drive on to show the trailer,
       restoring the protocol value that was in effect before we
       called the subdissector. */
    show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
    pinfo->current_proto = saved_proto;
  }
  ENDTRY;

  add_ethernet_trailer(pinfo, fh_tree, trailer_id, tvb, trailer_tvb, fcs_len);
}
Exemple #16
0
static int
dissect_openvpn_msg_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *openvpn_tree, proto_tree *parent_tree, gint offset)
{
  gboolean       tls_auth;
  guint          openvpn_keyid;
  guint          openvpn_opcode;
  guint32        msg_mpid      = -1;
  guint32        msg_sessionid = -1;
  guint8         openvpn_predict_tlsauth_arraylength;
  proto_item    *ti2;
  proto_tree    *packetarray_tree, *type_tree;
  guint32        msg_length_remaining;
  gboolean       msg_lastframe;
  fragment_head *frag_msg;
  tvbuff_t      *new_tvb;
  gboolean       save_fragmented;

  /* Clear out stuff in the info column */
  col_set_str(pinfo->cinfo, COL_PROTOCOL, PSNAME);
  col_clear(pinfo->cinfo,COL_INFO);

  /* read opcode and write to info column */
  openvpn_opcode = tvb_get_bits8(tvb, offset*8, 5);
  col_append_fstr(pinfo->cinfo, COL_INFO, "MessageType: %s",
                  val_to_str_const(openvpn_opcode, openvpn_message_types, "Unknown Messagetype"));


  openvpn_keyid = tvb_get_bits8(tvb, offset*8 + 5, 3);
  proto_item_append_text(parent_tree, ", Opcode: %s, Key ID: %d",
                         val_to_str(openvpn_opcode, openvpn_message_types, "Unknown (0x%02x)"),
                         openvpn_keyid);

  ti2 = proto_tree_add_item(openvpn_tree, hf_openvpn_pdu_type, tvb, offset, 1, ENC_BIG_ENDIAN);
  proto_item_append_text(ti2, " [opcode/key_id]");

  type_tree = proto_item_add_subtree(ti2, ett_openvpn_type);
  proto_tree_add_item(type_tree, hf_openvpn_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
  proto_tree_add_item(type_tree, hf_openvpn_keyid, tvb, offset, 1, ENC_BIG_ENDIAN);
  offset += 1;

  /* if we have a P_CONTROL or P_ACK packet */
  if (openvpn_opcode != P_DATA_V1) {
    /* read sessionid */
    msg_sessionid = tvb_get_bits32(tvb, offset*8+32, 32, ENC_BIG_ENDIAN);
    proto_tree_add_item(openvpn_tree, hf_openvpn_sessionid, tvb, offset, 8, ENC_BIG_ENDIAN);
    offset += 8;

    /* tls-auth detection (this can be overridden by preferences */
    openvpn_predict_tlsauth_arraylength = tvb_get_guint8(tvb, offset);
    /* if the first 4 bytes that would, if tls-auth is used, contain part of the hmac,
       lack entropy, we asume no tls-auth is used */
    if (pref_tls_auth_override == FALSE) {
      if ((openvpn_opcode != P_DATA_V1)
          && (openvpn_predict_tlsauth_arraylength > 0)
          && check_for_valid_hmac(tvb_get_ntohl(tvb, offset))) {
        tls_auth = TRUE;
      } else {
        tls_auth = FALSE;
      }
    } else {
      tls_auth = pref_tls_auth;
    }

    if (tls_auth == TRUE) {
      proto_tree_add_item(openvpn_tree, hf_openvpn_hmac, tvb, offset, tls_auth_hmac_size, ENC_NA);
      offset += tls_auth_hmac_size;

      if (tvb_length_remaining(tvb, offset) >= 8) {
        proto_tree_add_item(openvpn_tree, hf_openvpn_pid, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;

        if (pref_long_format) {
          proto_tree_add_item(openvpn_tree, hf_openvpn_net_time, tvb, offset, 4, ENC_BIG_ENDIAN);
          offset += 4;
        }
      }
    }

    if (tvb_length_remaining(tvb, offset) >= 1) {
      /* read P_ACK packet-id array length */
      gint pid_arraylength = tvb_get_guint8(tvb, offset);
      gint i;
      proto_tree_add_item(openvpn_tree, hf_openvpn_mpid_arraylength, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset += 1;

      if (pid_arraylength > 0) {

        packetarray_tree = proto_tree_add_subtree(openvpn_tree, tvb, offset, 0, ett_openvpn_packetarray, NULL, "Packet-ID Array");
        for (i = 0; i < pid_arraylength; i++) {
          proto_tree_add_item(packetarray_tree, hf_openvpn_mpid_arrayelement, tvb, offset, 4, ENC_BIG_ENDIAN);
          offset += 4;
        }

        if (tvb_length_remaining(tvb, offset) >= 8) {
          proto_tree_add_item(openvpn_tree, hf_openvpn_rsessionid, tvb, offset, 8, ENC_BIG_ENDIAN);
          offset += 8;
        }
      }
    }

    /* if we have a P_CONTROL packet */
    if (openvpn_opcode != P_ACK_V1) {
      /* read Message Packet-ID */
      if (tvb_length_remaining(tvb, offset) >= 4) {
        msg_mpid = tvb_get_bits32(tvb, offset*8, 32, ENC_BIG_ENDIAN);
        proto_tree_add_item(openvpn_tree, hf_openvpn_mpid, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
      }
    }
  }

  /* if we have more data left, determine what to do */
  msg_length_remaining = tvb_length_remaining(tvb, offset);

  if (msg_length_remaining == 0) {
    return tvb_length(tvb);
  }

  if (openvpn_opcode != P_CONTROL_V1) {
    proto_tree *data_tree;
    data_tree = proto_tree_add_subtree_format(openvpn_tree, tvb, offset, -1,
                              ett_openvpn_data, NULL, "Data (%d bytes)",
                              tvb_length_remaining(tvb, offset));

    proto_tree_add_item(data_tree, hf_openvpn_data, tvb, offset, -1, ENC_NA);
    return tvb_length(tvb);
  }

  /* Try to reassemble */

  /* an ordinary openvpn control packet contains 100 bytes only if it is part of a
     fragmented message and is not the last fragment of the current transmission.
     Note that the tvb contains exactly one openvpn PDU:
     UDP: by definition;
     TCP: because of the use of tcp_dissect_pdus().
  */
  if (msg_length_remaining == 100) {
    msg_lastframe = FALSE;
  } else {
    msg_lastframe = TRUE;
  }

  save_fragmented = pinfo->fragmented;
  pinfo->fragmented = TRUE;

  frag_msg = fragment_add_seq_next(
    &msg_reassembly_table,
    tvb,
    offset,
    pinfo,
    msg_sessionid,         /* ID for fragments belonging together */
    NULL,
    msg_length_remaining,  /* fragment length - to the end        */
    !(msg_lastframe));     /* More fragments ?                    */

  /* show "data" fragment on tree unless "reassembled" message has just one part.       */
  /* i.e., show if ("not reassembled") or ("reassembled" and "has multiple fragments")  */
  if ((frag_msg == NULL) || (frag_msg->next != NULL)) {
    proto_tree *data_tree;
    data_tree = proto_tree_add_subtree_format(openvpn_tree, tvb, offset, -1,
                              ett_openvpn_data, NULL, "Message fragment (%d bytes)",
                              tvb_length_remaining(tvb, offset));

    proto_tree_add_item(data_tree, hf_openvpn_fragment_bytes, tvb, offset, -1, ENC_NA);
    }

  new_tvb = NULL;
  if (frag_msg) {
    if (msg_lastframe) { /* Reassembled */
      new_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled Message",
                                         frag_msg, &openvpn_frag_items, NULL, openvpn_tree);
      if (frag_msg->next != NULL) { /* multiple frags ? */
        col_append_str(pinfo->cinfo, COL_INFO, " (Message Reassembled "); /* overwritten by next dissector */
      }

    } else { /* Not last packet of reassembled Short Message */
      col_append_fstr(pinfo->cinfo, COL_INFO, " (Message fragment %d) ", msg_mpid);
      if (pinfo->fd->num != frag_msg->reassembled_in) {
        /* Add a "Reassembled in" link if not reassembled in this frame */
        proto_tree_add_uint(openvpn_tree, hf_openvpn_reassembled_in,
                            tvb, 0, 0, frag_msg->reassembled_in);
      }
    }
  } /* if (frag_msg) */

  pinfo->fragmented = save_fragmented;

  /* Now see if we need to call subdissector.
     new_tvb is non-null if we "reassembled* a message (even just one fragment) */

  if (new_tvb) {
    /* call SSL/TLS dissector if we just processed the last fragment */
    call_dissector(ssl_handle, new_tvb, pinfo, parent_tree);
  }

  return tvb_length(tvb);
}
Exemple #17
0
static void
gcsna_message_GCSNA1xCircuitService(proto_item *item, tvbuff_t *tvb, packet_info *pinfo, proto_tree *mainTree, proto_tree *tree, guint *offset)
{
    guint16 alt_gcsna_incl = 0, num_alt_gcsna_opt = -1, iws_incl = 0;
    guint8 num_res;
    guint bit_offset = *offset * 8;
    proto_tree *subtree = NULL;
    tvbuff_t *new_tvb;

    /* GCSNAOption 8 bits */
    item = proto_tree_add_item(tree, hf_gcsna_gcsna_option, tvb, *offset, 1, ENC_BIG_ENDIAN);
    subtree = proto_item_add_subtree(item, ett_gcsna_option);
    proto_tree_add_bits_item(subtree, hf_gcsna_gcsnaClass, tvb, bit_offset, 5, ENC_BIG_ENDIAN);
    bit_offset += 5;
    proto_tree_add_bits_item(subtree, hf_gcsna_gcsnaClassRev, tvb, bit_offset, 3, ENC_BIG_ENDIAN);
    bit_offset += 3;

    alt_gcsna_incl = tvb_get_bits8(tvb, bit_offset, 1);
    proto_tree_add_bits_item(subtree, hf_gcsna_altGCSNAOptionIncluded, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
    bit_offset += 1;
    if (alt_gcsna_incl)
    {
        num_alt_gcsna_opt = tvb_get_bits8(tvb, bit_offset, 8);
        proto_tree_add_bits_item(subtree, hf_gcsna_NumaltGCSNAOption, tvb, bit_offset, 8, ENC_BIG_ENDIAN);
        bit_offset += 8;

        while (num_alt_gcsna_opt != 0)
        {
            proto_tree_add_bits_item(subtree, hf_gcsna_altGCSNAOption, tvb, bit_offset, 8, ENC_BIG_ENDIAN);
            bit_offset += 8;
            num_alt_gcsna_opt--;
        }
    }

    iws_incl = tvb_get_bits8(tvb, bit_offset, 1);
    proto_tree_add_bits_item(subtree, hf_gcsna_iwsidIncluded, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
    bit_offset++;

    if (iws_incl)
    {
        proto_tree_add_bits_item(subtree, hf_gcsna_iwsidValue, tvb, bit_offset, 16, ENC_BIG_ENDIAN);
        bit_offset += 16;
    }

    proto_tree_add_bits_item(subtree, hf_gcsna_ackRequired, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
    bit_offset++;
    proto_tree_add_bits_item(subtree, hf_gcsna_stopDupDetect, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
    bit_offset++;
    proto_tree_add_bits_item(subtree, hf_gcsna_msgSequence, tvb, bit_offset, 6, ENC_BIG_ENDIAN);
    bit_offset += 6;

    proto_tree_add_bits_item(subtree, hf_gcsna_NumTLACEncapsulated1xL3PDU, tvb, bit_offset, 2, ENC_BIG_ENDIAN);
    bit_offset += 2;

    /* The sender shall include reserved bits to make this message integral number of octets up to TLACEncapsulated1xL3PDU field.
     * The sender 5 shall set all bits in this field to '0'. The receiver shall ignore this field.
     */

     /* calculate number of reserved bits */
    num_res = 8 - (bit_offset & 0x3);
    proto_tree_add_bits_item(subtree, hf_gcsna_tlacReserved, tvb, bit_offset, num_res, ENC_BIG_ENDIAN);
    bit_offset = bit_offset + num_res;
    *offset = bit_offset >> 3;

    proto_tree_add_item(subtree, hf_gcsna_tlacEncapsulated, tvb, *offset, -1, ENC_NA);

    if (cdma2k_handle) {
        new_tvb = tvb_new_subset_length_caplen(tvb, *offset, -1, -1);
        call_dissector(cdma2k_handle, new_tvb, pinfo, mainTree);
    }
    /* set the offset to the end of the message */
    *offset += tvb_reported_length_remaining(tvb, *offset);

}
Exemple #18
0
/* -------------- */
static gboolean check_is_802_2(tvbuff_t *tvb, int fcs_len)
{
  volatile gboolean is_802_2;
  volatile int length;
  gint captured_length, reported_length;

  is_802_2 = TRUE;

    /* Is there an 802.2 layer? I can tell by looking at the first 2
       bytes after the 802.3 header. If they are 0xffff, then what
       follows the 802.3 header is an IPX payload, meaning no 802.2.
       A non-0xffff value means that there's an 802.2 layer or CCSDS
       layer inside the 802.3 layer */

  TRY {
    if (tvb_get_ntohs(tvb, 14) == 0xffff) {
        is_802_2 = FALSE;
    }
    /* Is this a CCSDS payload instead of an 802.2 (LLC)?
       Check the conditions enabled by the user for CCSDS presence */
    else if (ccsds_heuristic_length || ccsds_heuristic_version ||
             ccsds_heuristic_header || ccsds_heuristic_bit) {
      gboolean CCSDS_len = TRUE;
      gboolean CCSDS_ver = TRUE;
      gboolean CCSDS_head = TRUE;
      gboolean CCSDS_bit = TRUE;
      /* See if the reported payload size matches the
         size contained in the CCSDS header. */
      if (ccsds_heuristic_length) {
        /* The following technique to account for FCS
           is copied from packet-ieee8023.c dissect_802_3() */
        length = tvb_get_ntohs(tvb, 12);
        reported_length = tvb_reported_length_remaining(tvb, ETH_HEADER_SIZE);
        if (fcs_len > 0) {
          if (reported_length >= fcs_len)
            reported_length -= fcs_len;
        }
        /* Make sure the length in the 802.3 header doesn't go past the end of
           the payload. */
        if (length > reported_length) {
          length = reported_length;
        }
        /* Only allow inspection of 'length' number of bytes. */
        captured_length = tvb_length_remaining(tvb, ETH_HEADER_SIZE);
        if (captured_length > length)
          captured_length = length;

        /* Check if payload is large enough to contain a CCSDS header */
        if (captured_length >= 6) {
          /* Compare length to packet length contained in CCSDS header. */
          if (length != 7 + tvb_get_ntohs(tvb, ETH_HEADER_SIZE + 4))
            CCSDS_len = FALSE;
        }
      }
      /* Check if CCSDS Version number (first 3 bits of payload) is zero */
      if ((ccsds_heuristic_version) && (tvb_get_bits8(tvb, 8*ETH_HEADER_SIZE, 3)!=0))
        CCSDS_ver = FALSE;
      /* Check if Secondary Header Flag (4th bit of payload) is set to one. */
      if ((ccsds_heuristic_header) && (tvb_get_bits8(tvb, 8*ETH_HEADER_SIZE + 4, 1)!=1))
        CCSDS_head = FALSE;
      /* Check if spare bit (1st bit of 7th word of payload) is zero. */
      if ((ccsds_heuristic_bit) && (tvb_get_bits8(tvb, 8*ETH_HEADER_SIZE + 16*6, 1)!=0))
        CCSDS_bit = FALSE;
      /* If all the conditions are true, don't interpret payload as an 802.2 (LLC).
       * Additional check in packet-802.3.c will distinguish between
       * IPX and CCSDS packets*/
      if (CCSDS_len && CCSDS_ver && CCSDS_head && CCSDS_bit)
        is_802_2 = FALSE;
    }
  }
  CATCH_BOUNDS_ERRORS {
        ; /* do nothing */

  }
  ENDTRY;
  return is_802_2;
}
// content format
static void dissect_mysensors(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  // your variable definitions go here
  int bitoffset = 0;

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "mysensors");
  
  // Clear out stuff in the info column
  col_clear(pinfo->cinfo,COL_INFO);
  if (tree)
  {
    // in case that someone wants to know some details of our protocol
    // spawn a subtree and cut the sequence in readable parts
    proto_item *pi = NULL;
    proto_item *ti = NULL;
    proto_tree *mysensors_tree = NULL;
    tvbuff_t* tvb_next;
    guint8 payloadLen, dataType, type, sensor, sender, last, dest, reqack, isack;
    MySensors_Command commandType;
    gchar* info;
    
    ti = proto_tree_add_item(tree, proto_mysensors, tvb, 0 /*start*/, -1 /*to end*/, ENC_NA);
    mysensors_tree = proto_item_add_subtree(ti, ett_mysensors);
    
    proto_tree_add_item(mysensors_tree, hf_mysensors_last, tvb, bitoffset>>3, 1, encoding);
    last = tvb_get_guint8(tvb, bitoffset>>3);
    bitoffset += 8;
    proto_tree_add_item(mysensors_tree, hf_mysensors_sender, tvb, bitoffset>>3, 1, encoding);
    sender = tvb_get_guint8(tvb, bitoffset>>3);
    bitoffset += 8;
    proto_tree_add_item(mysensors_tree, hf_mysensors_dest, tvb, bitoffset>>3, 1, encoding);
    dest = tvb_get_guint8(tvb, bitoffset>>3);
    bitoffset += 8;

    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_length, tvb, bitoffset, 5, encoding);
    payloadLen = tvb_get_bits8(tvb, bitoffset, 5);
    bitoffset += 5;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_version, tvb, bitoffset, 3, encoding);
    bitoffset += 3;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_datatype, tvb, bitoffset, 3, encoding);
    dataType = tvb_get_bits8(tvb, bitoffset, 3);  // Type of payload
    bitoffset += 3;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_isack, tvb, bitoffset, 1, encoding);
    isack = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 1);
    bitoffset += 1;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_reqack, tvb, bitoffset, 1, encoding);
    reqack = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 1);
    bitoffset += 1;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_commandtype, tvb, bitoffset, 3, encoding);
    commandType = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 3);
    bitoffset += 3;

    type = tvb_get_guint8(tvb, bitoffset>>3);
    proto_tree_add_uint_format_value(mysensors_tree, hf_mysensors_type, tvb, bitoffset>>3, 1, type, "%s (%d)", typeToStr(commandType, type), (guint8)type);
    bitoffset += 8;
    proto_tree_add_item(mysensors_tree, hf_mysensors_sensor, tvb, bitoffset>>3, 1, encoding);
    sensor = tvb_get_guint8(tvb, bitoffset>>3);
    bitoffset += 8;

    // Create tvb for the payload.
    tvb_next = tvb_new_subset(tvb, bitoffset>>3, payloadLen, payloadLen);

    info = buildColInfo( pinfo, payloadLen, dataType, commandType, reqack, isack, type, sensor, tvb_next );
    col_add_str(pinfo->cinfo, COL_INFO, info);
    proto_item_append_text(ti, " - %s", info);
    col_add_fstr(pinfo->cinfo, COL_DEF_SRC, "%d", sender);
    col_add_fstr(pinfo->cinfo, COL_DEF_DST, "%d", dest);

    // Pass payload to generic data dissector
    call_dissector(data_handle, tvb_next, pinfo, mysensors_tree);
  }
}
Exemple #20
0
/* common dissector function for dissecting TFP payloads */
static void
dissect_tfp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {

    gint   byte_offset = 0;
    gint   bit_offset  = 48;

    guint8 hv_tfp_len;
    guint8 hv_tfp_fid;
    guint8 hv_tfp_seq;

    gchar  tfp_uid_string[BASE58_MAX_STR_SIZE];

    base58_encode(tvb_get_letohl(tvb, 0), &tfp_uid_string[0]);

    hv_tfp_len = tvb_get_guint8(tvb, byte_offset_len);
    hv_tfp_fid = tvb_get_guint8(tvb, byte_offset_fid);
    hv_tfp_seq = tvb_get_bits8(tvb, bit_offset, bit_count_tfp_seq);

    col_add_fstr(pinfo->cinfo, COL_INFO,
                 "UID: %s, Len: %d, FID: %d, Seq: %d",
                 &tfp_uid_string[0], hv_tfp_len, hv_tfp_fid, hv_tfp_seq);

    /* call for details */
    if (tree) {
        proto_tree *tfp_tree;
        proto_item *ti;

        ti = proto_tree_add_protocol_format(tree, proto_tfp, tvb, 0, -1,
                                            "Tinkerforge Protocol, UID: %s, Len: %d, FID: %d, Seq: %d",
                                            &tfp_uid_string[0], hv_tfp_len, hv_tfp_fid, hv_tfp_seq);
        tfp_tree = proto_item_add_subtree(ti, ett_tfp);

        /* Use ...string_format_value() so we can show the complete generated string but specify */
        /*  the field length as being just the 4 bytes from which the string is generated.	 */
        ti = proto_tree_add_string_format_value(tfp_tree,
                                                hf_tfp_uid,
                                                tvb, byte_offset, byte_count_tfp_uid,
                                                &tfp_uid_string[0], "%s", &tfp_uid_string[0]);
        PROTO_ITEM_SET_GENERATED(ti);

        proto_tree_add_item(tfp_tree,
                            hf_tfp_uid_numeric,
                            tvb,
                            byte_offset,
                            byte_count_tfp_uid,
                            ENC_LITTLE_ENDIAN);

        byte_offset += byte_count_tfp_uid;

        proto_tree_add_item(tfp_tree,
                            hf_tfp_len,
                            tvb,
                            byte_offset,
                            byte_count_tfp_len,
                            ENC_LITTLE_ENDIAN);

        byte_offset += byte_count_tfp_len;

        proto_tree_add_item(tfp_tree,
                            hf_tfp_fid,
                            tvb,
                            byte_offset,
                            byte_count_tfp_fid,
                            ENC_LITTLE_ENDIAN);

        byte_offset += byte_count_tfp_fid;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_seq,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_seq,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_seq;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_r,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_r,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_r;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_a,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_a,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_a;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_oo,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_oo,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_oo;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_e,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_e,
                                 ENC_LITTLE_ENDIAN);

        bit_offset += bit_count_tfp_e;

        proto_tree_add_bits_item(tfp_tree,
                                 hf_tfp_future_use,
                                 tvb,
                                 bit_offset,
                                 bit_count_tfp_future_use,
                                 ENC_LITTLE_ENDIAN);

        /*bit_offset += bit_count_tfp_future_use;*/

        if ((tvb_reported_length(tvb)) > 8) {

            byte_offset += byte_count_tfp_flags;

            proto_tree_add_item(tfp_tree, hf_tfp_payload, tvb, byte_offset, -1, ENC_NA);
        }
    }
}
    case TCTF_CCCH_FACH_FDD:
    case TCTF_MCCH_FACH_FDD:
    case TCTF_MSCH_FACH_FDD:
    case TCTF_CTCH_FACH_FDD:
        return tctf;
    default:
        return tctf; /* TODO */
    }
}

static guint16 tree_add_common_dcch_dtch_fields(tvbuff_t *tvb, packet_info *pinfo _U_,
        proto_tree *tree, guint16 bitoffs, fp_info *fpinf, umts_mac_info *macinf)
{
    guint8 ueid_type;

    ueid_type = tvb_get_bits8(tvb, bitoffs, 2);
    proto_tree_add_bits_item(tree, hf_mac_ueid_type, tvb, bitoffs, 2, ENC_BIG_ENDIAN);
    bitoffs += 2;
    if (ueid_type == MAC_UEID_TYPE_URNTI) {
        proto_tree_add_bits_item(tree, hf_mac_urnti, tvb, bitoffs, 32, ENC_BIG_ENDIAN);
        bitoffs += 32;
    } else if (ueid_type == MAC_UEID_TYPE_CRNTI) {
        proto_tree_add_bits_item(tree, hf_mac_crnti, tvb, 4, 16, ENC_BIG_ENDIAN);
        bitoffs += 16;
    }

    if (macinf->ctmux[fpinf->cur_tb]) {
        proto_tree_add_bits_item(tree, hf_mac_ct, tvb, bitoffs, 4, ENC_BIG_ENDIAN);
        bitoffs += 4;
    }
    return bitoffs;
Exemple #22
0
/* Code to actually dissect the packets */
static int
dissect_lisp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    gint offset = 0;
    guint8 flags;
    guint8 ip_ver;
    tvbuff_t *next_tvb;
    proto_item *ti;
    proto_item *tif;
    proto_tree *lisp_data_tree;
    proto_tree *lisp_data_flags_tree;

    /* Check that there's enough data */
    if (tvb_length(tvb) < LISP_DATA_HEADER_LEN)
        return 0;

    /* Make entries in Protocol column and Info column on summary display */
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "LISP");

    col_set_str(pinfo->cinfo, COL_INFO, "LISP Encapsulation Header");

    if (tree) {

        /* create display subtree for the protocol */
        ti = proto_tree_add_item(tree, proto_lisp_data, tvb, 0,
                LISP_DATA_HEADER_LEN, FALSE);

        lisp_data_tree = proto_item_add_subtree(ti, ett_lisp_data);

        tif = proto_tree_add_item(lisp_data_tree,
                hf_lisp_data_flags, tvb, offset, 1, FALSE);

        lisp_data_flags_tree = proto_item_add_subtree(tif, ett_lisp_data_flags);

        proto_tree_add_item(lisp_data_flags_tree,
                hf_lisp_data_flags_nonce, tvb, offset, 1, FALSE);
        proto_tree_add_item(lisp_data_flags_tree,
                hf_lisp_data_flags_lsb, tvb, offset, 1, FALSE);
        proto_tree_add_item(lisp_data_flags_tree,
                hf_lisp_data_flags_enr, tvb, offset, 1, FALSE);
        proto_tree_add_item(lisp_data_flags_tree,
                hf_lisp_data_flags_mv, tvb, offset, 1, FALSE);
        proto_tree_add_item(lisp_data_flags_tree,
                hf_lisp_data_flags_iid, tvb, offset, 1, FALSE);
        proto_tree_add_item(lisp_data_flags_tree,
                hf_lisp_data_flags_res, tvb, offset, 1, FALSE);

        flags = tvb_get_guint8(tvb, offset);
        offset += 1;

        if (flags&LISP_DATA_FLAG_E && !(flags&LISP_DATA_FLAG_N)) {
            proto_tree_add_text(lisp_data_tree, tvb, offset, 0,
                    "Invalid flag combination: if E is set, N MUST be set");
        }

        if (flags&LISP_DATA_FLAG_N) {
            if (flags&LISP_DATA_FLAG_V) {
                proto_tree_add_text(lisp_data_tree, tvb, offset, 0,
                        "Invalid flag combination: N and V can't be set both");
            }
            proto_tree_add_item(lisp_data_tree,
                    hf_lisp_data_nonce, tvb, offset, 3, FALSE);
        } else {
            if (flags&LISP_DATA_FLAG_V) {
                proto_item *tiv;
                proto_tree *lisp_data_mapver_tree;

                tiv = proto_tree_add_item(lisp_data_tree,
                        hf_lisp_data_mapver, tvb, offset, 3, FALSE);

                lisp_data_mapver_tree = proto_item_add_subtree(tiv, ett_lisp_data_mapver);

                proto_tree_add_item(lisp_data_mapver_tree,
                        hf_lisp_data_srcmapver, tvb, offset, 3, FALSE);
                proto_tree_add_item(lisp_data_mapver_tree,
                        hf_lisp_data_dstmapver, tvb, offset, 3, FALSE);
            }
        }
        offset += 3;

        if (flags&LISP_DATA_FLAG_I) {
            proto_tree_add_item(lisp_data_tree,
                    hf_lisp_data_iid, tvb, offset, 3, FALSE);
            offset += 3;
            if (flags&LISP_DATA_FLAG_L) {
                proto_tree_add_item(lisp_data_tree,
                        hf_lisp_data_lsb8, tvb, offset, 1, FALSE);
            }
            offset +=1;
        } else {
            if (flags&LISP_DATA_FLAG_L) {
                proto_tree_add_item(lisp_data_tree,
                        hf_lisp_data_lsb, tvb, offset, 4, FALSE);
                offset += 4;
            }
        }
    }

    /* Check if there is stuff left in the buffer, and return if not */

    /* Determine if encapsulated packet is IPv4 or IPv6, and call dissector */
    next_tvb = tvb_new_subset(tvb, LISP_DATA_HEADER_LEN, -1, -1);
    ip_ver = tvb_get_bits8(next_tvb, 0, 4);
    switch (ip_ver) {
        case 4:
            call_dissector(ipv4_handle, next_tvb, pinfo, tree);
            break;
        case 6:
            call_dissector(ipv6_handle, next_tvb, pinfo, tree);
            break;
        default:
            call_dissector(data_handle, next_tvb, pinfo, tree);
            break;
    }

    /* Return the amount of data this dissector was able to dissect */
    return tvb_length(tvb);
}
Exemple #23
0
/* AU Header dissection */
static offset_struct* dissect_auheader( tvbuff_t *tvb, offset_struct *poffset, packet_info *pinfo, proto_tree *ismacryp_tree, guint set_version )
{
	proto_item *ismacryp_item;
	proto_tree *ismacryp_header_tree;
	proto_tree *ismacryp_header_byte_tree;

	guint16 header_len_bytes = 0; /* total length of non-first AU header in bytes (rounded up) */
	gint header_len = 0; /* length of AU headers in bits */
	gint cts_flag =0;
	gint dts_flag =0;
	gboolean first_au_flag=FALSE;
	gint bit_offset = 0;

	/*first determine total AU header length */
	/* calculate each AU header length in bits first */
	switch (set_version) {
		case V11:
			if (selective_encryption)
				header_len+=8; /* add one byte to header length */
			break;
		case V20:
			if (selective_encryption || slice_indication || padding_indication)
				header_len+=8; /* add one byte to header length */
			break;
		default:
			DISSECTOR_ASSERT_NOT_REACHED();
			break;
	}	/* end switch */
	header_len+=au_size_length; /* add au size length */

	if (poffset->offset_bytes==AU_HEADERS_LENGTH_SIZE){	/*first AU */
		header_len+=8*(iv_length);                      /* add IV length */
		header_len+=8*key_indicator_length;             /* add key indicator length */
		header_len+=au_index_length;                    /* add AU index length */
		first_au_flag = TRUE;
	}
	else { /* not the first AU */
		if (key_indicator_per_au_flag == TRUE)
			header_len+=8*key_indicator_length; /* add key indicator length */
		header_len+=8*(delta_iv_length);                /* add delta IV length */
		header_len+=au_index_delta_length;              /* add AU delta index length */
	}
	/* CTS flag is present? */
	if (cts_delta_length != 0){    /* need to test whether cts_delta_flag is TRUE or FALSE */
		cts_flag=tvb_get_bits8(tvb, AU_HEADERS_LENGTH_SIZE*8+header_len, 1); /*fetch 1 bit CTS flag  */
		header_len+=1;         /* add CTS flag bit */
		if (cts_flag==1)
			header_len+=cts_delta_length; /* add CTS delta length bits if CTS flag SET */
	}
	/* DTS flag is present? */
	if (dts_delta_length != 0){ /* need to test whether dts_delta_flag is TRUE or FALSE */
		dts_flag=tvb_get_bits8(tvb, AU_HEADERS_LENGTH_SIZE*8+header_len, 1); /*fetch 1 bit DTS flag */
		header_len+=1;      /* add DTS flag bit */
		if (dts_flag==1)
			header_len+=dts_delta_length; /* add DTS delta length bits if DTS flag SET */
	}
	/* RAP flag present? */
	if (random_access_indication != FALSE)
		header_len+=1;      /* add 1 bit RAP flag */

	/* stream state indication present */
	if (stream_state_indication !=0)
		header_len+=stream_state_indication; /* add stream state indication bits */

	/* convert header_len to bytes (rounded up) */
	if (header_len% 8!=0)
	{
		header_len_bytes=((header_len)/8)+1; /*add 1 */
	}
	else
		header_len_bytes=((header_len)/8);

	/* add AU header tree  */
	ismacryp_item = proto_tree_add_item(ismacryp_tree, hf_ismacryp_header, tvb, poffset->offset_bytes, header_len_bytes, ENC_NA );
	proto_item_append_text(ismacryp_item, ": Length=%d bits", header_len); /* add text to Header tree indicating length */
	/* sanity check if actual AU header length is zero bits, which indicates an error */
	if ( header_len == 0) /* something wrong */
	{
		proto_item_append_text(ismacryp_item, " Error - zero bit AU header size - check parameters!");
	}
	ismacryp_header_tree = proto_item_add_subtree(ismacryp_item, ett_ismacryp_header);

	/* ismacryp header analysis */
	/* we are being asked for details  */

	/* Extra 1 Byte Header? */

	if ((set_version==V20 && (selective_encryption || slice_indication || padding_indication))
		|| (set_version==V11 && selective_encryption)){

		/* add  header byte tree	*/
		ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_header_byte,
						    tvb, poffset->offset_bytes, 1, ENC_NA );
		proto_item_append_text(ismacryp_item, ": Length=8 bits"); /* add text to Header byte tree indicating length */
		ismacryp_header_byte_tree = proto_item_add_subtree(ismacryp_item, ett_ismacryp_header_byte);

		/*ismacryp_header_byte_tree */
		/* we are being asked for details */
		/* tvb is network order, so get MSB bits first, so shift 8 bits and work "backwards" */
		add_bits(poffset,7);   /*shift 7 bits to get correct bit */
		/* AU_is_encrypted bit */
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		if (selective_encryption){ /* bit used */
			proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_au_is_encrypted,
						 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit AU_is_encrypted */
		}
		else { /* bit unused */
			proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits,
						 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit unused */
		}
		switch (set_version){ /* ISMACryp version? */
			case V11:
				/* Reserved bits */
				add_bits(poffset, -7); /* move back 7 bits for reserved bits */
				bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
				proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_reserved_bits,
							 tvb, bit_offset, 7, ENC_BIG_ENDIAN); /*fetch 7 bits reserved */
				add_bits(poffset,8);   /* offset to next byte */
				break;
			case V20:
				/* Slice_start bit */
				add_bits(poffset, -1); /* move back 1 bit for slice_start */
				bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
				if (slice_indication){
					proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_slice_start,
								 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit slice_start */
				}
				else { /* bit unused */
					proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits,
								 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit unused */
				}
				add_bits(poffset, -1); /* move back 1 bit for slice_end */

				/* Slice_end bit */
				bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
				if (slice_indication){
					proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_slice_end,
								 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit Slice_end */
				}
				else { /* bit unused */
					proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits,
								 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /*fetch 1 bit unused */
				}
				add_bits(poffset, -3); /* move back 3 bits for padding_bitcount */

				/* Padding_bitcount bits */
				bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
				if (padding_indication){
					proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_padding_bitcount,
								 tvb, bit_offset, 3, ENC_BIG_ENDIAN); /*fetch 3 bits padding_bitcount */
				}
				else { /* bits unused */
					proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_unused_bits,
								 tvb, bit_offset, 3, ENC_BIG_ENDIAN); /*fetch 3 bits unused */
				}
				add_bits(poffset, -2); /* move back 2 bits for reserved bits */

				/* Reserved bits */
				bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
				proto_tree_add_bits_item(ismacryp_header_byte_tree, hf_ismacryp_reserved_bits,
							 tvb, bit_offset, 2, ENC_BIG_ENDIAN); /*fetch 2 bits reserved */
				add_bits(poffset,8); /* offset to next byte */
				break;
			default:
				DISSECTOR_ASSERT_NOT_REACHED();
				break;
		} /* end switch set_version */
	} /* end selective encryption */
	/* IV */
	if (first_au_flag == TRUE && iv_length != 0)
	{
		ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_iv, tvb, poffset->offset_bytes, iv_length, ENC_NA);
		proto_item_append_text(ismacryp_item, ": Length=%d bytes",iv_length); /* add IV info */
		col_append_fstr( pinfo->cinfo, COL_INFO,
			", IV=0x%s", tvb_bytes_to_str_punct(tvb, poffset->offset_bytes, iv_length,' '));

		poffset->offset_bytes+=iv_length; /* add IV length to offset_bytes */
	}
	/*Delta  IV */
	if (first_au_flag == FALSE && delta_iv_length != 0)
	{
		ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_delta_iv,
						    tvb, poffset->offset_bytes, delta_iv_length, ENC_NA);
		proto_item_append_text(ismacryp_item, ": Length=%d bytes",delta_iv_length); /* add delta IV info */
		col_append_fstr( pinfo->cinfo, COL_INFO,
			", Delta IV=0x%s", tvb_bytes_to_str_punct(tvb, poffset->offset_bytes, delta_iv_length,' '));
		poffset->offset_bytes+=iv_length; /* add IV length to offset_bytes */
	}
	/* Key Indicator */
	if ( key_indicator_length != 0 && ( first_au_flag == TRUE || key_indicator_per_au_flag == TRUE) )
	{
		/* (first AU or KI for each AU) and non-zero KeyIndicator size */
		ismacryp_item = proto_tree_add_item(ismacryp_header_tree, hf_ismacryp_key_indicator,
						    tvb, poffset->offset_bytes, key_indicator_length, ENC_NA);
		proto_item_append_text(ismacryp_item,": Length=%d bytes",key_indicator_length); /* add KI info */
		col_append_fstr( pinfo->cinfo, COL_INFO,
					 ", KI=0x%s", tvb_bytes_to_str_punct(tvb, poffset->offset_bytes, key_indicator_length,' '));
		poffset->offset_bytes+=key_indicator_length; /* add KI length to offset_bytes */
	}
	/* AU size */
	if (au_size_length != 0) /* in bits */
	{
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree,hf_ismacryp_au_size,
							 tvb, bit_offset, au_size_length, ENC_BIG_ENDIAN);
		proto_item_append_text(ismacryp_item, " bytes: Length=%d bits",au_size_length); /* add AU size info */
		/*bit_offset+=au_size_length;*/
		add_bits(poffset, au_size_length);
	}
	/* AU Index */
	if (first_au_flag == TRUE && au_index_length != 0) /* first AU and non-zero AU size */
	{
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree,hf_ismacryp_au_index,
							 tvb, bit_offset, au_index_length, ENC_BIG_ENDIAN);
		proto_item_append_text(ismacryp_item, " bits: Length=%d bits",au_index_length); /* add AU index info */
		/*bit_offset+=au_index_length;*/
		add_bits(poffset, au_index_length);
	}
	/* AU index delta */
	if (first_au_flag == FALSE && au_index_delta_length != 0) /* not first AU and non-zero AU delta size */
	{
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree,hf_ismacryp_au_index_delta,
							 tvb, bit_offset, au_index_delta_length, ENC_BIG_ENDIAN);
		proto_item_append_text(ismacryp_item, ": Length=%d bits", au_index_delta_length); /* add AU index info */
		/*bit_offset+=au_index_delta_length;*/
		add_bits(poffset, au_index_delta_length);
	}
	/* CTS delta value */
	if (cts_delta_length != 0)
	{
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_cts_flag,
					 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /* read CTS flag */
		add_bits(poffset, 1);
		if (cts_flag==1)
		{
			/* now fetch CTS delta value (remember offset 1 bit due to CTS flag) */
			bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
			ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_cts_delta,
								 tvb, bit_offset, cts_delta_length, ENC_BIG_ENDIAN); /* read CTS delta value */
			proto_item_append_text(ismacryp_item, ": Length=%d bits",cts_delta_length); /* add CTS delta info */
			add_bits(poffset, cts_delta_length);
		}
	}
	/* DTS delta value */
	if (dts_delta_length != 0)
	{
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_dts_flag,
					 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /* read DTS flag */
		add_bits(poffset, 1);

		/* now fetch DTS delta value (remember offset x bits due to DTS flag) */
		if (dts_flag ==1)
		{
			bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
			ismacryp_item = proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_dts_delta,
								 tvb, bit_offset, dts_delta_length, ENC_BIG_ENDIAN); /* read DTS delta value */
			proto_item_append_text(ismacryp_item, ": Length=%d bits",dts_delta_length); /* add DTS delta info */
			add_bits(poffset, dts_delta_length);
		}
	}
	/* RAP */
	if (random_access_indication != FALSE)
	{
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_rap_flag,
					 tvb, bit_offset, 1, ENC_BIG_ENDIAN); /* read RAP flag */
		add_bits(poffset, 1);
	}
	/*STREAM STATE */
	if (stream_state_indication != 0)
	{
		bit_offset = (poffset->offset_bytes)*8+poffset->offset_bits; /* offset in bits */
		proto_tree_add_bits_item(ismacryp_header_tree, hf_ismacryp_stream_state,
					 tvb, bit_offset, stream_state_indication, ENC_BIG_ENDIAN); /* read stream state */
		add_bits(poffset, stream_state_indication);
	}
	/* end header details */
return poffset;
}
Exemple #24
0
static void gcsna_message_GCSNAServiceReject(proto_item *item, tvbuff_t *tvb, proto_tree *tree, guint *offset)
{
    guint16 cause_val = -1, num_fields = -1, l_offset = -1;
    proto_tree *subtree = NULL;

    item = proto_tree_add_item(tree, hf_gcsna_servicereject, tvb, *offset, 1, ENC_NA);
    subtree = proto_item_add_subtree(item, ett_gcsna_subtree);

    l_offset = *offset * 8;
    proto_tree_add_bits_item(subtree, hf_gcsna_rejSequence, tvb, l_offset, 6, ENC_BIG_ENDIAN);
    l_offset += 6;
    proto_tree_add_bits_item(subtree, hf_gcsna_cause, tvb, l_offset, 8, ENC_BIG_ENDIAN);
    cause_val = tvb_get_bits8(tvb, *offset * 8 + 6, 8);
    l_offset += 8;

    switch (cause_val)
    {
    case 0:
    case 2:
    {
        num_fields = tvb_get_bits8(tvb, l_offset, 8);
        l_offset += 8;

        while (num_fields > 0)
        {
            proto_tree_add_bits_item(subtree, hf_gcsna_gcsnaClass, tvb, l_offset, 5, ENC_BIG_ENDIAN);
            l_offset += 5;
            proto_tree_add_bits_item(subtree, hf_gcsna_gcsnaClassRev, tvb, l_offset, 3, ENC_BIG_ENDIAN);
            l_offset += 3;
            num_fields--;
        }

        if (cause_val == 2)
        {
            proto_tree_add_bits_item(subtree, hf_gcsna_1xProtocolRevision, tvb, l_offset, 8, ENC_BIG_ENDIAN);
            l_offset += 8;
        }

        break;
    }

    case 1:
    {
        proto_tree_add_bits_item(subtree, hf_gcsna_1xProtocolRevision, tvb, l_offset, 8, ENC_BIG_ENDIAN);
        l_offset += 8;
        break;
    }

    case 3:
    {
        proto_tree_add_bits_item(subtree, hf_gcsna_invalidMessageId, tvb, l_offset, 8, ENC_BIG_ENDIAN);
        l_offset += 8;
        break;
    }

    /*This Cause Value is not supported in IWS Stack*/
    case 5:
    {
        num_fields = tvb_get_bits8(tvb, l_offset, 8);
        l_offset += 8;

        while (num_fields > 0)
        {
            proto_tree_add_bits_item(subtree, hf_gcsna_recordType, tvb, l_offset, 8, ENC_BIG_ENDIAN);
            l_offset += 8;
            num_fields--;
        }
        break;
    }

    default:
    {
        proto_tree_add_item(subtree, hf_gcsna_unsupported_reject_seq, tvb, l_offset, -1, ENC_NA);
        break;
    }
    }

    if (l_offset % 8 == 0)
    {
        *offset = (l_offset / 8);
    } else
    {
        *offset = (l_offset / 8) + 1;
    }

}
Exemple #25
0
/* G.7041 6.1.2 GFP payload area */
static void
dissect_gfp_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *gfp_tree, guint *offset, guint payload_len)
{
    tvbuff_t *payload_tvb;
    proto_item *type_ti = NULL;
    proto_item *fcs_ti;
    proto_tree *fcs_tree = NULL;
    guint pti, pfi, exi, upi;
    guint fcs, fcs_calc;
    guint fcs_len = 0;

    /* G.7041 6.1.2.3 Payload area scrambling
     * Note that payload when sent on the wire is scrambled as per ATM
     * with a 1 + x^43 multiplicative scrambler. Likely already removed by
     * the time we get a capture file (as with ATM). Could have a pref,
     * but if it's present we have to save state over subsequent frames,
     * always would fail to decode the first 43 payload bytes of a capture. */

    /* G.7041 6.1.2.1 Payload Header - at least 4 bytes */
    tvb_ensure_bytes_exist(tvb, *offset, 4);
    payload_len -= 4;

    /* G.7041 6.1.2.1.1 GFP type field - mandatory 2 bytes */
    pti = tvb_get_bits8(tvb, 8*(*offset), 3);
    pfi = tvb_get_bits8(tvb, 8*(*offset)+3, 1);
    exi = tvb_get_bits8(tvb, 8*(*offset)+4, 4);
    upi = tvb_get_guint8(tvb, *offset+1);
    p_add_proto_data(pinfo->pool, pinfo, proto_gfp, 0, GUINT_TO_POINTER(upi));

    col_add_str(pinfo->cinfo, COL_INFO, val_to_str(pti, gfp_pti_vals, "Reserved PTI (%d)"));
    if (pti == GFP_USER_DATA ||
            pti == GFP_MANAGEMENT_COMMUNICATIONS) {
        /* G.7041 Table 6-3 - GFP_MANAGEMENT_COMMUNICATIONS
         * uses the same UPI table as USER_DATA, though
         * "not all of these UPI types are applicable" in that case. */
        type_ti = proto_tree_add_bitmask_with_flags(gfp_tree, tvb, *offset, hf_gfp_type,
                  ett_gfp_type, gfp_type_data_fields, ENC_BIG_ENDIAN, BMT_NO_FLAGS);
        col_append_sep_str(pinfo->cinfo, COL_INFO, ": ", rval_to_str(upi, gfp_upi_data_rvals, "Unknown 0x%02x"));
    } else if (pti == GFP_CLIENT_MANAGEMENT) {
        /* G.7041 Table 6-4 */
        type_ti = proto_tree_add_bitmask_with_flags(gfp_tree, tvb, *offset, hf_gfp_type,
                  ett_gfp_type, gfp_type_management_fields, ENC_BIG_ENDIAN, BMT_NO_FLAGS);
        col_append_sep_str(pinfo->cinfo, COL_INFO, ": ", rval_to_str(upi, gfp_upi_management_rvals, "Unknown 0x%02x"));
    }

    /* G.7041 6.1.2.1.2 Type HEC (tHEC) - mandatory 2 bytes */
    gfp_add_hec_tree(tvb, pinfo, gfp_tree, offset, 2, hf_gfp_thec, hf_gfp_thec_status, &ei_gfp_thec_bad);

    switch (exi) {
    case GFP_EXT_NULL:
        /* G.7041 6.1.2.1.3.1 Null extension header */
        break;

    case GFP_EXT_LINEAR:
        /* G.7041 6.1.2.1.3.2 Extension header for a linear frame */
        if (payload_len < 4) {
            expert_add_info(pinfo, type_ti, &ei_gfp_exi_short);
            payload_len = 0;
        }
        else {
            payload_len -= 4;
        }
        proto_tree_add_item(gfp_tree, hf_gfp_cid, tvb, *offset, 1, ENC_BIG_ENDIAN);
        /* Next byte spare field, reserved */

        /* 6.1.2.1.4 Extension HEC field */
        gfp_add_hec_tree(tvb, pinfo, gfp_tree, offset, 2, hf_gfp_ehec, hf_gfp_ehec_status, &ei_gfp_ehec_bad);
        break;
    case GFP_EXT_RING:
    /* 6.1.2.1.3.3 Extension header for a ring frame */
    /* "For further study." Undefined so fall through */
    default:
        /* Reserved */
        /* TODO: Mark as error / unhandled? */
        break;
    }

    proto_item_set_end(gfp_tree, tvb, *offset);

    if (pfi == 1) { /* 6.1.2.2.1 Payload FCS field present */
        if (payload_len < 4) {
            expert_add_info(pinfo, type_ti, &ei_gfp_pfi_short);
            fcs_len = payload_len;
            payload_len = 0;
        } else {
            fcs_len = 4;
            payload_len -= 4;
        }

        proto_tree_set_appendix(gfp_tree, tvb, *offset + payload_len, fcs_len);
        fcs = tvb_get_ntohl(tvb, *offset + payload_len);
        /* Same CRC32 as ATM */
        /* As with ATM, we can either compute the CRC as it would be
         * calculated and compare (last step involves taking the complement),
         * or we can include the passed CRC in the input and check to see
         * if the remainder is a known value. I like the first method
         * only because it lets us display what we should have received. */
        /* Method 1: */
        fcs_calc = crc32_mpeg2_tvb_offset(tvb, *offset, payload_len);
        if (fcs == ~fcs_calc) {
            fcs_ti = proto_tree_add_uint_format_value(gfp_tree, hf_gfp_fcs, tvb, *offset+payload_len, 4, fcs, "0x%08x [correct]", fcs);
            fcs_tree = proto_item_add_subtree(fcs_ti, ett_gfp_fcs);
            fcs_ti = proto_tree_add_boolean(fcs_tree, hf_gfp_fcs_good, tvb, *offset+payload_len, 4, TRUE);
            PROTO_ITEM_SET_GENERATED(fcs_ti);
            fcs_ti = proto_tree_add_boolean(fcs_tree, hf_gfp_fcs_bad, tvb, *offset+payload_len, 4, FALSE);
            PROTO_ITEM_SET_GENERATED(fcs_ti);
        } else {
            fcs_ti = proto_tree_add_uint_format_value(gfp_tree, hf_gfp_fcs, tvb, *offset+payload_len, 4, fcs, "0x%08x [incorrect, should be 0x%08x]", fcs, fcs_calc);
            fcs_tree = proto_item_add_subtree(fcs_ti, ett_gfp_fcs);
            fcs_ti = proto_tree_add_boolean(fcs_tree, hf_gfp_fcs_good, tvb, *offset+payload_len, 4, FALSE);
            PROTO_ITEM_SET_GENERATED(fcs_ti);
            fcs_ti = proto_tree_add_boolean(fcs_tree, hf_gfp_fcs_bad, tvb, *offset+payload_len, 4, TRUE);
            PROTO_ITEM_SET_GENERATED(fcs_ti);
            expert_add_info(pinfo, fcs_ti, &ei_gfp_fcs_bad);
        }
        /* Method 2: */
        /* fcs_calc = crc32_mpeg2_tvb_offset(tvb, *offset, payload_len+4);
        fcs_ti = proto_tree_add_uint(gfp_tree, hf_gfp_fcs, tvb, *offset+payload_len, 4, fcs);
        proto_item_append_text(fcs_ti, (fcs_calc == 0xC704DD7B) ? " [correct]" : " [incorrect]"); */
    }

    /* Some client frames we can do. Others are not implemented yet.
     * Transparent mode types are much trickier than frame-mapped,
     * since they requires reassembling streams across multiple GFP packets. */
    payload_tvb = tvb_new_subset_length(tvb, *offset, payload_len);
    switch (pti) {
    case GFP_USER_DATA:
    case GFP_MANAGEMENT_COMMUNICATIONS:
        if (!dissector_try_uint(gfp_dissector_table, upi, payload_tvb, pinfo, tree)) {
            expert_add_info_format(pinfo, type_ti, &ei_gfp_payload_undecoded, "Payload type 0x%02x (%s) unsupported", upi, rval_to_str_const(upi, gfp_upi_data_rvals, "UNKNOWN"));
            call_data_dissector(payload_tvb, pinfo, tree);
        }
        break;

    case GFP_CLIENT_MANAGEMENT:
        call_data_dissector(payload_tvb, pinfo, tree);
        break;

    default:
        break;
    }
    *offset += payload_len;
    *offset += fcs_len;
}