示例#1
0
/* returns TRUE if this TCP segment carries a MPA REQUEST and FLASE otherwise */
static gboolean
is_mpa_req(tvbuff_t *tvb, packet_info *pinfo)
{
	conversation_t *conversation = NULL;
	mpa_state_t *state = NULL;
	guint8 mcrres;

	if (tvb_get_ntoh64(tvb, 0) != MPA_REQ_REP_FRAME
			|| tvb_get_ntoh64(tvb, 8) != MPA_ID_REQ_FRAME)
		return FALSE;

	conversation = find_conversation(pinfo->fd->num, &pinfo->src,
			&pinfo->dst, pinfo->ptype, pinfo->srcport,
			pinfo->destport, 0);

	if (!conversation) {
		conversation = conversation_new(pinfo->fd->num, &pinfo->src,
				&pinfo->dst, pinfo->ptype, pinfo->srcport,
				pinfo->destport, 0);
	}

	if (!get_mpa_state(conversation)) {

		/* associate a MPA connection state to this conversation if
		 * there is no MPA state already associated to this connection
		 */
		state = init_mpa_state();

		/* anaylize MPA connection parameter and record them */
		mcrres = tvb_get_guint8(tvb, 16);
		state->ini_exp_m_res = mcrres & MPA_MARKER_FLAG;
		state->crc = mcrres & MPA_CRC_FLAG;
		state->revision = tvb_get_guint8(tvb, 17);
		state->req_frame_num = pinfo->fd->num;
		state->minfo[MPA_INITIATOR].port = pinfo->srcport;
		state->minfo[MPA_RESPONDER].port = pinfo->destport;

		conversation_add_proto_data(conversation, proto_iwarp_mpa, state);

		/* update expert info */
		if (mcrres & MPA_RESERVED_FLAG)
			expert_add_info_format(pinfo, NULL, PI_REQUEST_CODE, PI_WARN,
					"Res field is NOT set to zero as required by RFC 5044");

		if (state->revision != 1)
			expert_add_info_format(pinfo, NULL, PI_REQUEST_CODE, PI_WARN,
					"Rev field is NOT set to one as required by RFC 5044");
	}
	return TRUE;
}
示例#2
0
/*
 *  get a Blefuscuoan signed 64 bit integer from a tvb
 */
WSLUA_METHOD TvbRange_int64(lua_State* L) {
	/* Get a Big Endian (network order) signed 64 bit integer from a TvbRange. The range must be 1-8 octets long. */
    TvbRange tvbr = checkTvbRange(L,1);
    if (!(tvbr && tvbr->tvb)) return 0;
    if (tvbr->tvb->expired) {
        luaL_error(L,"expired tvb");
        return 0;
    }

    switch (tvbr->len) {
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8: {
            Int64 num = (Int64)g_malloc(sizeof(gint64));
            *num = (gint64)tvb_get_ntoh64(tvbr->tvb->ws_tvb,tvbr->offset);
            pushInt64(L,num);
            WSLUA_RETURN(1);
        }
        default:
            luaL_error(L,"TvbRange:int64() does not handle %d byte integers",tvbr->len);
            return 0;
    }
}
示例#3
0
/*
 *  get a Blefuscuoan signed 64 bit integer from a tvb
 */
WSLUA_METHOD TvbRange_int64(lua_State* L) {
    /* Get a Big Endian (network order) signed 64 bit integer from a `TvbRange`, as an `Int64` object.
       The range must be 1, 2, 4 or 8 octets long. */
    TvbRange tvbr = checkTvbRange(L,1);
    if (!(tvbr && tvbr->tvb)) return 0;
    if (tvbr->tvb->expired) {
        luaL_error(L,"expired tvb");
        return 0;
    }

    switch (tvbr->len) {
        case 1:
            pushInt64(L,(gint8)tvb_get_guint8(tvbr->tvb->ws_tvb,tvbr->offset));
            return 1;
        case 2:
            pushInt64(L,(gint16)tvb_get_ntohs(tvbr->tvb->ws_tvb,tvbr->offset));
            return 1;
        case 4:
            pushInt64(L,(gint32)tvb_get_ntohl(tvbr->tvb->ws_tvb,tvbr->offset));
            return 1;
        case 8:
            pushInt64(L,(gint64)tvb_get_ntoh64(tvbr->tvb->ws_tvb,tvbr->offset));
            WSLUA_RETURN(1); /* The `Int64` object. */
        default:
            luaL_error(L,"TvbRange:int64() does not handle %d byte integers",tvbr->len);
            return 0;
    }
}
static void add_time_details( proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint32 offset)
{
    guint64 time;

    time = tvb_get_ntoh64(tvb, offset + 1 );
    proto_tree_add_item(tree, hf_mc_time, tvb, offset + 1, 8, FALSE);
}
static guint64
corosync_totemsrp_get_guint64(tvbuff_t* tvb, gint offset, const guint encoding)
{
  if (encoding == ENC_LITTLE_ENDIAN)
    return tvb_get_letoh64(tvb, offset);

  return tvb_get_ntoh64(tvb, offset);
}
示例#6
0
/* returns TRUE if this TCP segment carries a MPA REPLY and FALSE otherwise */
static gboolean
is_mpa_rep(tvbuff_t *tvb, packet_info *pinfo)
{
	conversation_t *conversation = NULL;
	mpa_state_t *state = NULL;
	guint8 mcrres;

	if (tvb_get_ntoh64(tvb, 0) != MPA_REQ_REP_FRAME
			|| tvb_get_ntoh64(tvb, 8) != MPA_ID_REP_FRAME) {
		return FALSE;
	}

	conversation = find_conversation(pinfo->fd->num, &pinfo->src,
			&pinfo->dst, pinfo->ptype, pinfo->srcport,
			pinfo->destport, 0);

	if (!conversation) {
		return FALSE;
	}

	state = get_mpa_state(conversation);
	if (!state) {
		return FALSE;
	}

	if (!state->full_operation) {
		/* update state of this conversation */
		mcrres = tvb_get_guint8(tvb, 16);
		state->res_exp_m_ini = mcrres & MPA_MARKER_FLAG;
		state->crc = state->crc | (mcrres & MPA_CRC_FLAG);
		state->rep_frame_num = pinfo->fd->num;

		 /* enter Full Operation Phase only if the Reject bit is not set */
		if (!(mcrres & MPA_REJECT_FLAG))
			state->full_operation = TRUE;
		else
			expert_add_info_format(pinfo, NULL, PI_RESPONSE_CODE, PI_NOTE,
				"Reject bit set by Responder");
	}
	return TRUE;
}
示例#7
0
/* returns TRUE if this TCP segment carries a MPA REQUEST and FLASE otherwise */
static gboolean
is_mpa_req(tvbuff_t *tvb, packet_info *pinfo)
{
	conversation_t *conversation = NULL;
	mpa_state_t *state = NULL;
	guint8 mcrres;

	if (tvb_get_ntoh64(tvb, 0) != MPA_REQ_REP_FRAME
			|| tvb_get_ntoh64(tvb, 8) != MPA_ID_REQ_FRAME)
		return FALSE;

	conversation = find_or_create_conversation(pinfo);

	if (!get_mpa_state(conversation)) {

		/* associate a MPA connection state to this conversation if
		 * there is no MPA state already associated to this connection
		 */
		state = init_mpa_state();

		/* anaylize MPA connection parameter and record them */
		mcrres = tvb_get_guint8(tvb, 16);
		state->ini_exp_m_res = mcrres & MPA_MARKER_FLAG;
		state->crc = mcrres & MPA_CRC_FLAG;
		state->revision = tvb_get_guint8(tvb, 17);
		state->req_frame_num = pinfo->fd->num;
		state->minfo[MPA_INITIATOR].port = pinfo->srcport;
		state->minfo[MPA_RESPONDER].port = pinfo->destport;

		conversation_add_proto_data(conversation, proto_iwarp_mpa, state);

		/* update expert info */
		if (mcrres & MPA_RESERVED_FLAG)
			expert_add_info(pinfo, NULL, &ei_mpa_res_field_not_set0);

		if (state->revision != 1)
			expert_add_info(pinfo, NULL, &ei_mpa_rev_field_not_set1);
	}
	return TRUE;
}
示例#8
0
static int dlm_name_handler(proto_tree *tree, tvbuff_t *tvb, guint offset, int namelen)
{
	guint8 lock_type;
	guint64 blkno;
	proto_item *ti;

	ti = proto_tree_add_item(tree, hf_dlm_name, tvb, offset, namelen, ENC_ASCII|ENC_NA);
	lock_type = tvb_get_guint8(tvb, offset);
	if (lock_type == 'N') {
		blkno = tvb_get_ntoh64(tvb, offset + OCFS2_DENTRY_LOCK_INO_START);
		proto_item_append_text(ti, "%08x", (unsigned int)blkno);
	}

	return offset + namelen;
}
示例#9
0
static int
dissect_kt_replication(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
    gint new_offset;
    guint32 next32, size;
    guint64 ts;
    nstime_t ns_ts;
    proto_item *pi;

    new_offset = offset;

    proto_tree_add_item(tree, hf_kt_magic, tvb, new_offset, 1, ENC_BIG_ENDIAN);
    new_offset++;

    if (tvb_reported_length_remaining(tvb, new_offset) > 0) {
        next32 = tvb_get_ntohl(tvb, new_offset);
        if (next32 <= 1) { /* This means request. the 32 bits are flags */
            proto_tree_add_item(tree, hf_kt_flags, tvb, new_offset, 4, ENC_BIG_ENDIAN);
            new_offset += 4;

            proto_tree_add_item(tree, hf_kt_ts, tvb, new_offset, 8, ENC_BIG_ENDIAN);
            new_offset += 8;

            proto_tree_add_item(tree, hf_kt_sid, tvb, new_offset, 2, ENC_BIG_ENDIAN);
            new_offset += 2;
        } else { /* This is a response. The 32 bits are the first half of the ts */
            ts = tvb_get_ntoh64(tvb, new_offset);
            ns_ts.secs = (time_t)(ts/1000000000);
            ns_ts.nsecs = (int)(ts%1000000000);
            proto_tree_add_time(tree, hf_kt_ts, tvb, new_offset, 8, &ns_ts);
            new_offset += 8;

            size = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(tree, hf_kt_size, tvb, new_offset, 4, size);
            new_offset += 4;

            proto_tree_add_item(tree, hf_kt_log, tvb, new_offset, size, ENC_NA);
            new_offset += size;
        }
    } else {
        /* This is an empty ack to the message with magic 0xB0. */
        pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE);
        PROTO_ITEM_SET_GENERATED(pi);
        col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]");
    }

    return new_offset;
}
static gint32 tvb_get_ntohint(tvbuff_t * tvb, guint offset, guint size)
{
    switch(size) {
        case 1: return (gint32)tvb_get_guint8(tvb, offset); 
        case 2: return (gint32)tvb_get_ntohs(tvb, offset); 
        case 3: return (gint32)tvb_get_ntoh24(tvb, offset); 
        case 4: return (gint32)tvb_get_ntohl(tvb, offset); 
        /*case 5: return (gint32)tvb_get_ntoh40(tvb, offset); */
        /*case 6: return (gint32)tvb_get_ntoh48(tvb, offset); */
        /*case 7: return (gint32)tvb_get_ntoh56(tvb, offset); */
        case 8: return (gint32)tvb_get_ntoh64(tvb, offset); 
        default: break;
    }
    DISSECTOR_ASSERT(FALSE);
    return 0;
}
示例#11
0
static int dlm_cookie_handler(proto_tree *tree, tvbuff_t *tvb, guint offset, int hf_cookie)
{
	proto_item *item;
	guint64 cookie;
	guint64 seq;
	guint8 node_idx;

	item = proto_tree_add_item(tree, hf_cookie, tvb, offset, 8, ENC_BIG_ENDIAN);
	cookie = tvb_get_ntoh64(tvb, offset);

	cookie >>= 56;
	node_idx = (guint8)((cookie >> 56) & G_GINT64_CONSTANT(0xff));
	seq = cookie & G_GINT64_CONSTANT(0x00ffffffffffffff);

	proto_item_append_text(item, " (%u:%" G_GINT64_MODIFIER "u)", node_idx, seq);

	return offset + 8;
}
示例#12
0
/* Dissection routines */
static int
dissect_kt_replication_wait(tvbuff_t *tvb, proto_tree *tree, gint offset)
{
    gint new_offset;
    guint64 ts;
    nstime_t ns_ts;

    new_offset = offset;

    proto_tree_add_item(tree, hf_kt_magic, tvb, new_offset, 1, ENC_BIG_ENDIAN);
    new_offset++;

    ts = tvb_get_ntoh64(tvb, new_offset);
    ns_ts.secs = (time_t)(ts/1000000000);
    ns_ts.nsecs = (int)(ts%1000000000);
    proto_tree_add_time(tree, hf_kt_ts, tvb, new_offset, 8, &ns_ts);
    new_offset += 8;

    return new_offset;
}
示例#13
0
/* Dissection routines */
static int
dissect_kt_replication_wait(tvbuff_t *tvb, proto_tree *tree)
{
    int offset;
    guint64 ts;
    nstime_t ns_ts;

    proto_item *pi;

    pi = proto_tree_add_uint(tree, hf_kt_type, tvb, 0, 1, KT_OPER_REQUEST);
    PROTO_ITEM_SET_GENERATED(pi);

    offset = 1;

    ts = tvb_get_ntoh64(tvb, offset);
    ns_ts.secs = (time_t)(ts/1000000000);
    ns_ts.nsecs = (int)(ts%1000000000);
    proto_tree_add_time(tree, hf_kt_ts, tvb, offset, 8, &ns_ts);
    offset += 8;

    return offset;
}
示例#14
0
static int
dissect_daap_one_tag(proto_tree *tree, tvbuff_t *tvb, int offset, int length)
{
   unsigned int tagname;
   int tagsize;
   int new_offset;
   proto_item *ti = NULL;
   proto_item *ti2 = NULL;
   proto_tree *new_tree = NULL;

   do {
      if (!tvb_offset_exists(tvb, offset)) 
	 break;

      tagname = tvb_get_ntohl(tvb, offset);
      tagsize = tvb_get_ntohl(tvb, offset+4);
      tvb_ensure_bytes_exist(tvb, offset, tagsize+8);
      ti = proto_tree_add_text(tree, tvb, offset, tagsize+8, 
			       "Tag: %c%c%c%c, Size: %d", 
			       tvb_get_guint8(tvb, offset),
			       tvb_get_guint8(tvb, offset+1),
			       tvb_get_guint8(tvb, offset+2),
			       tvb_get_guint8(tvb, offset+3),
			       tagsize);

      ti2 = proto_tree_add_item(tree, hf_daap_name, tvb, offset, 4, FALSE);
      PROTO_ITEM_SET_HIDDEN(ti2);
      ti2 = proto_tree_add_item(tree, hf_daap_size, tvb, offset+4, 4, FALSE);
      PROTO_ITEM_SET_HIDDEN(ti2);
      offset += 8;
      length -= 8;

      switch (tagname) {
      case daap_mcon:
      case daap_msrv:
      case daap_mccr:
      case daap_mdcl:
      case daap_mlog:
      case daap_mupd:
      case daap_avdb:
      case daap_mlcl:
      case daap_mlit:
      case daap_mbcl:
      case daap_adbs:
      case daap_aply:
      case daap_apso:
      case daap_mudl:
      case daap_abro:
      case daap_abal:
      case daap_abcp:
      case daap_abgn:
      case daap_prsv:
      case daap_arif:
	 /* Container tags */
	 new_tree = proto_item_add_subtree(ti, ett_daap_sub);
	 new_offset = dissect_daap_one_tag(new_tree, tvb, offset, 
					   tagsize);
	 break;
      case daap_minm:
      case daap_msts:
      case daap_mcnm:
      case daap_mcna:
      case daap_asal:
      case daap_asar:
      case daap_ascm:
      case daap_asfm:
      case daap_aseq:
      case daap_asgn:
      case daap_asdt:
      case daap_asul:
	 /* Tags contain strings */
	 proto_item_append_text(ti, ", Data: %s",
				tvb_format_text(tvb, offset, tagsize));
	 break;
      case daap_mper:
	 /* Tags conain uint64 */
	 proto_item_append_text(ti, ", Persistent Id: %" G_GINT64_MODIFIER "u", 
				tvb_get_ntoh64(tvb, offset));
	 break;
      case daap_mstt:
	 proto_item_append_text(ti, ", Status: %d", 
				tvb_get_ntohl(tvb, offset));
	 break;
      case daap_musr:
      case daap_msur:
	 proto_item_append_text(ti, ", Revision: %d", 
				tvb_get_ntohl(tvb, offset));
	 break;
      case daap_miid:
      case daap_mcti:
      case daap_mpco:
      case daap_mlid:
	 proto_item_append_text(ti, ", Id: %d", 
				tvb_get_ntohl(tvb, offset));
	 break;
      case daap_mrco:
      case daap_mtco:
      case daap_mimc:
      case daap_msdc:
	 proto_item_append_text(ti, ", Count: %d", 
				tvb_get_ntohl(tvb, offset));
	 break;
      case daap_mstm:
	 proto_item_append_text(ti, ", Timeout: %d seconds", 
				tvb_get_ntohl(tvb, offset));
	 break;
      case daap_asda:
      case daap_asdm:
      case daap_assr:
      case daap_assz:
      case daap_asst:
      case daap_assp:
      case daap_astm:
      case daap_aeNV:
	 /* Tags conain uint32 */
	 proto_item_append_text(ti, ", Data: %d", 
				tvb_get_ntohl(tvb, offset));
	 break;

      case daap_mcty:
      case daap_asbt:
      case daap_asbr:
      case daap_asdc:
      case daap_asdn:
      case daap_astc:
      case daap_astn:
      case daap_asyr:
	 /* Tags conain uint16 */
	 proto_item_append_text(ti, ", Data: %d", 
				tvb_get_ntohs(tvb, offset));
	 break;

      case daap_mikd:
      case daap_msau:
      case daap_msty:
      case daap_asrv:
      case daap_asur:
      case daap_asdk:
	 /* Tags conain uint8 */
	 proto_item_append_text(ti, ", Data: %d", 
				tvb_get_guint8(tvb, offset));

	 break;

      case daap_mslr:
      case daap_msal:
      case daap_msup:
      case daap_mspi:
      case daap_msex:
      case daap_msbr:
      case daap_msqy:
      case daap_msix:
      case daap_msrs:
      case daap_asco:
      case daap_asdb:
      case daap_abpl:
      case daap_aeSP:
	 /* Tags ARE boolean. Data is (uint8), but it seems
	  * the value is always zero. So, if the tag is present
	  * the "bool" is true. 
	  */
	 proto_item_append_text(ti, ", Data: True");
	 break;

      case daap_mpro:
      case daap_apro:
	 /* Tags conain version (uint32) */
	 proto_item_append_text(ti, ", Version: %d.%d.%d.%d",
				tvb_get_guint8(tvb, offset),
				tvb_get_guint8(tvb, offset+1),
				tvb_get_guint8(tvb, offset+2),
				tvb_get_guint8(tvb, offset+3));
	 break;

      default: 
	 break;
      }
      offset += tagsize;
      length -= tagsize;
   } while (length > 0);
   return offset;
}
示例#15
0
/* Decode an EXT_FTI extension and fill FEC array */
void fec_decode_ext_fti(struct _ext *e, tvbuff_t *tvb, proto_tree *tree, gint ett, struct _fec_ptr f)
{
	proto_item* ti = NULL;
	proto_tree *ext_tree;

	if (tree)
		ti = proto_tree_add_none_format(tree, f.hf->fti_header, tvb, e->offset, e->length,
			"EXT_FTI, FEC Object Transmission Information (%u)", e->het);

	if (f.fec->encoding_id_present)
	{
		ext_tree = proto_item_add_subtree(ti, ett);
		rmt_ext_decode_default_header(e, tvb, ext_tree);

		/* Decode 48-bit length field */
		f.fec->transfer_length = tvb_get_ntoh64(tvb, e->offset) & G_GINT64_CONSTANT(0xFFFFFFFFFFFFU);

		if (f.fec->encoding_id >= 128)
		{
			/* Decode FEC Instance ID */
			f.fec->instance_id_present = TRUE;
			f.fec->instance_id = (guint8) tvb_get_ntohs(tvb, e->offset+8);
		}

		if (tree)
			proto_tree_add_uint64(ext_tree, f.hf->fti_transfer_length, tvb, e->offset+2, 6, f.fec->transfer_length);

		switch (f.fec->encoding_id)
		{
		case 0:
		case 2:
		case 128:
		case 130:
			f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10);
			f.fec->max_source_block_length = tvb_get_ntohl(tvb, e->offset+12);

			if (tree)
			{
				proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length);
				proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 4, f.fec->max_source_block_length);
			}
			break;

		case 129:
			f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10);
			f.fec->max_source_block_length = tvb_get_ntohs(tvb, e->offset+12);
			f.fec->max_number_encoding_symbols = tvb_get_ntohs(tvb, e->offset+14);

			if (tree)
			{
				proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length);
				proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 2, f.fec->max_source_block_length);
				proto_tree_add_uint(ext_tree, f.hf->fti_max_number_encoding_symbols, tvb, e->offset+14, 2, f.fec->max_number_encoding_symbols);
			}
			break;

		case 132:
			f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10);
			f.fec->max_source_block_length = tvb_get_ntohl(tvb, e->offset+12);
			f.fec->max_number_encoding_symbols = tvb_get_ntohl(tvb, e->offset+16);

			if (tree)
			{
				proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length);
				proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 4, f.fec->max_source_block_length);
				proto_tree_add_uint(ext_tree, f.hf->fti_max_number_encoding_symbols, tvb, e->offset+16, 4, f.fec->max_number_encoding_symbols);
			}
			break;
		}

	} else
		if (tree)
			rmt_ext_decode_default_subtree(e, tvb, ti, ett);
}
示例#16
0
static void
dissect_nflog(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    const int start_tlv_offset = 4;

    proto_tree *nflog_tree = NULL;
    proto_item *ti;

    int offset = 0;

    tvbuff_t *next_tvb = NULL;
    int aftype;

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

    aftype = tvb_get_guint8(tvb, 0);

    /* Header */
    if (proto_field_is_referenced(tree, hfi_nflog->id)) {
        ti = proto_tree_add_item(tree, hfi_nflog, tvb, 0, -1, ENC_NA);
        nflog_tree = proto_item_add_subtree(ti, ett_nflog);

        proto_tree_add_item(nflog_tree, &hfi_nflog_family, tvb, offset, 1, ENC_NA);
        offset += 1;

        proto_tree_add_item(nflog_tree, &hfi_nflog_version, tvb, offset, 1, ENC_NA);
        offset += 1;

        proto_tree_add_item(nflog_tree, &hfi_nflog_resid, tvb, offset, 2, ENC_BIG_ENDIAN);
        /*offset += 2;*/
    }

    offset = start_tlv_offset;
    /* TLVs */
    while (tvb_reported_length_remaining(tvb, offset) >= 4) {
        guint16 tlv_len = tvb_get_h_guint16(tvb, offset + 0);
        guint16 tlv_type;
        guint16 value_len;

        proto_tree *tlv_tree;

        /* malformed */
        if (tlv_len < 4)
            return;

        value_len = tlv_len - 4;
        tlv_type = (tvb_get_h_guint16(tvb, offset + 2) & 0x7fff);

        if (nflog_tree) {
            gboolean handled = FALSE;

            ti = proto_tree_add_bytes_format(nflog_tree, hfi_nflog_tlv.id,
                             tvb, offset, tlv_len, NULL,
                             "TLV Type: %s (%u), Length: %u",
                             val_to_str_const(tlv_type, nflog_tlv_vals, "Unknown"),
                             tlv_type, tlv_len);
            tlv_tree = proto_item_add_subtree(ti, ett_nflog_tlv);

            proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_length, tvb, offset + 0, 2, ENC_HOST_ENDIAN);
            proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_type, tvb, offset + 2, 2, ENC_HOST_ENDIAN);
            switch (tlv_type) {
                case WS_NFULA_PAYLOAD:
                    handled = TRUE;
                    break;

                case WS_NFULA_PREFIX:
                    if (value_len >= 1) {
                        proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_prefix,
                                    tvb, offset + 4, value_len, ENC_NA);
                        handled = TRUE;
                    }
                    break;

                case WS_NFULA_UID:
                    if (value_len == 4) {
                        proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_uid,
                                    tvb, offset + 4, value_len, ENC_BIG_ENDIAN);
                        handled = TRUE;
                    }
                    break;

                case WS_NFULA_GID:
                    if (value_len == 4) {
                        proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_gid,
                                    tvb, offset + 4, value_len, ENC_BIG_ENDIAN);
                        handled = TRUE;
                    }
                    break;

                case WS_NFULA_TIMESTAMP:
                    if (value_len == 16) {
                        nstime_t ts;

                        ts.secs  = (time_t)tvb_get_ntoh64(tvb, offset + 4);
                        /* XXX - add an "expert info" warning if this is >= 10^9? */
                        ts.nsecs = (int)tvb_get_ntoh64(tvb, offset + 12);
                        proto_tree_add_time(tlv_tree, &hfi_nflog_tlv_timestamp,
                                    tvb, offset + 4, value_len, &ts);
                        handled = TRUE;
                    }
                    break;
            }

            if (!handled)
                    proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_unknown,
                                        tvb, offset + 4, value_len, ENC_NA);
        }

        if (tlv_type == WS_NFULA_PAYLOAD)
            next_tvb = tvb_new_subset_length(tvb, offset + 4, value_len);

        offset += ((tlv_len + 3) & ~3); /* next TLV aligned to 4B */
    }

    if (next_tvb) {
        switch (aftype) {
            case LINUX_AF_INET:
                call_dissector(ip_handle, next_tvb, pinfo, tree);
                break;
            case LINUX_AF_INET6:
                call_dissector(ip6_handle, next_tvb, pinfo, tree);
                break;
            default:
                call_dissector(data_handle, next_tvb, pinfo, tree);
                break;
        }
    }
}
示例#17
0
/* dissect EDID data from the receiver
   return the offset after the dissected data */
static gint
dissect_hdmi_edid(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree)
{
    proto_item *yi;
    proto_tree *edid_tree;
    guint64     edid_hdr;
    guint16     manf_id;
    gchar       manf_id_str[4]; /* 3 letters + 0-termination */
    guint8      week, year;
    int         year_hf;

    edid_tree = proto_tree_add_subtree(tree, tvb,
            offset, -1, ett_hdmi_edid, NULL,
            "Extended Display Identification Data (EDID)");

    edid_hdr = tvb_get_ntoh64(tvb, offset);
    if (edid_hdr != EDID_HDR_VALUE)
        return offset; /* XXX handle fragmented EDID messages */

    col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "EDID");

    proto_tree_add_item(edid_tree, hf_hdmi_edid_hdr,
            tvb, offset, 8, ENC_LITTLE_ENDIAN);
    offset += 8;

    /* read as big endian for easier splitting */
    manf_id = tvb_get_ntohs(tvb, offset);
    /* XXX check that MSB is 0 */
    manf_id_str[0] = CAPITAL_LETTER(manf_id, 10);
    manf_id_str[1] = CAPITAL_LETTER(manf_id,  5);
    manf_id_str[2] = CAPITAL_LETTER(manf_id,  0);
    manf_id_str[3] = 0;
    proto_tree_add_string(edid_tree, hf_hdmi_edid_manf_id,
            tvb, offset, 2, manf_id_str);
    offset += 2;

    proto_tree_add_item(edid_tree, hf_hdmi_edid_manf_prod_code,
            tvb, offset, 2, ENC_LITTLE_ENDIAN);
    offset += 2;

    proto_tree_add_item(edid_tree, hf_hdmi_edid_manf_serial,
            tvb, offset, 4, ENC_LITTLE_ENDIAN);
    offset += 4;

    week = tvb_get_guint8(tvb, offset);
    proto_tree_add_item(edid_tree, hf_hdmi_edid_manf_week,
            tvb, offset, 1, ENC_LITTLE_ENDIAN);
    offset += 1;

    year_hf = week == 255 ? hf_hdmi_edid_mod_year : hf_hdmi_edid_manf_year;
    year = tvb_get_guint8(tvb, offset);
    yi = proto_tree_add_item(edid_tree, year_hf,
            tvb, offset, 1, ENC_LITTLE_ENDIAN);
    proto_item_append_text(yi, " (year %d)", 1990+year);
    offset += 1;

    proto_tree_add_item(edid_tree, hf_hdmi_edid_version, tvb, offset, 2, ENC_BIG_ENDIAN);

    /* XXX dissect the parts following the EDID header */

    return tvb_reported_length(tvb);
}
示例#18
0
static int
dissect_kt_get_bulk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
    guint32 next32, rnum, ksiz, vsiz;
    guint64 xt;
    nstime_t ts;
    gint new_offset, rec_start_offset;
    proto_item *ti;
    proto_item *pi;
    proto_tree *rec_tree;

    new_offset = offset;

    proto_tree_add_item(tree, hf_kt_magic, tvb, new_offset, 1, ENC_BIG_ENDIAN);
    new_offset++;

    next32 = tvb_get_ntohl(tvb, new_offset);

    if (next32 == 0) {
        if (tvb_reported_length_remaining(tvb, (new_offset + 4)) > 0) { /* request */
            pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_REQUEST);
            PROTO_ITEM_SET_GENERATED(pi);

            proto_tree_add_uint(tree, hf_kt_flags, tvb, new_offset, 4, next32);
            new_offset += 4;

            rnum = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(tree, hf_kt_rnum, tvb, new_offset, 4, rnum);
            new_offset += 4;

            while (rnum > 0) {
                /* Create a sub-tree for each record */
                ti = proto_tree_add_item(tree, hf_kt_rec, tvb, new_offset, -1, ENC_NA);
                rec_tree = proto_item_add_subtree(ti, ett_kt_rec);
                rec_start_offset = new_offset;

                proto_tree_add_item(rec_tree, hf_kt_dbidx, tvb, new_offset, 2, ENC_BIG_ENDIAN);
                new_offset += 2;

                ksiz = tvb_get_ntohl(tvb, new_offset);
                proto_tree_add_uint(rec_tree, hf_kt_ksiz, tvb, new_offset, 4, ksiz);
                new_offset += 4;

                proto_tree_add_item(rec_tree, hf_kt_key, tvb, new_offset, ksiz, ENC_NA);
                if (kt_present_key_val_as_ascii) {
                    pi = proto_tree_add_item(rec_tree, hf_kt_key_str, tvb, new_offset, ksiz, ENC_ASCII|ENC_NA);
                    PROTO_ITEM_SET_GENERATED(pi);
                }
                new_offset += ksiz;

                proto_item_set_len(ti, new_offset - rec_start_offset);
                rnum--;
            }
        } else { /* response - no records */
            pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE);
            PROTO_ITEM_SET_GENERATED(pi);
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]");

            proto_tree_add_uint(tree, hf_kt_hits, tvb, new_offset, 4, next32);
            new_offset += 4;
        }
    } else { /* response - one or more records */
        pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE);
        PROTO_ITEM_SET_GENERATED(pi);
        col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]");

        rnum = tvb_get_ntohl(tvb, new_offset);
        proto_tree_add_uint(tree, hf_kt_hits, tvb, new_offset, 4, rnum);
        new_offset += 4;

        while (rnum > 0) {
            /* Create a sub-tree for each record */
            ti = proto_tree_add_item(tree, hf_kt_rec, tvb, new_offset, -1, ENC_NA);
            rec_tree = proto_item_add_subtree(ti, ett_kt_rec);
            rec_start_offset = new_offset;

            proto_tree_add_item(rec_tree, hf_kt_dbidx, tvb, new_offset, 2, ENC_BIG_ENDIAN);
            new_offset += 2;

            ksiz = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(rec_tree, hf_kt_ksiz, tvb, new_offset, 4, ksiz);
            new_offset += 4;

            vsiz = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(rec_tree, hf_kt_vsiz, tvb, new_offset, 4, vsiz);
            new_offset += 4;

            xt = tvb_get_ntoh64(tvb, new_offset);
            ts.secs = (time_t)(xt&0xFFFFFFFF);
            ts.nsecs = 0;
            proto_tree_add_time(rec_tree, hf_kt_xt_resp, tvb, new_offset, 8, &ts);
            new_offset += 8;

            proto_tree_add_item(rec_tree, hf_kt_key, tvb, new_offset, ksiz, ENC_NA);
            if (kt_present_key_val_as_ascii) {
                pi = proto_tree_add_item(rec_tree, hf_kt_key_str, tvb, new_offset, ksiz, ENC_ASCII|ENC_NA);
                PROTO_ITEM_SET_GENERATED(pi);
            }
            new_offset += ksiz;

            proto_tree_add_item(rec_tree, hf_kt_val, tvb, new_offset, vsiz, ENC_NA);
            if (kt_present_key_val_as_ascii) {
                pi = proto_tree_add_item(rec_tree, hf_kt_val_str, tvb, new_offset, vsiz, ENC_ASCII|ENC_NA);
                PROTO_ITEM_SET_GENERATED(pi);
            }
            new_offset += vsiz;

            proto_item_set_len(ti, new_offset - rec_start_offset);
            rnum--;
        }
    }

    return new_offset;
}
示例#19
0
static int
dissect_lisp_tcp_membership_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *message_tree,
                                    guint offset, guint16 type, guint16 data_len, proto_item *tim)
{
    guint32 iid, sid, rid;
    guint8 err;
    guint64 siteid;
    guint16 afi;

    /* EID AFI (2 bytes) */
    proto_tree_add_item(message_tree, hf_lisp_tcp_message_eid_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
    offset += 2;
    data_len -= 2;

    /* Instance ID (4 bytes) */
    iid = tvb_get_ntohl(tvb, offset);
    proto_tree_add_item(message_tree, hf_lisp_tcp_message_iid, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset += 4;
    data_len -= 4;
    proto_item_append_text(tim, ", IID: %u", iid);

    switch (type) {
    case MEMBERSHIP_BASE + 1:
    case MEMBERSHIP_BASE + 2:
        /* Subscribe ID (4 bytes) */
        sid = tvb_get_ntohl(tvb, offset);
        proto_tree_add_item(message_tree, hf_lisp_tcp_message_sid, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
        data_len -= 4;
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Sub ID: %u", sid);
        proto_item_append_text(tim, ", Sub ID: %u", sid);

        if (type == MEMBERSHIP_BASE + 2) {
            /* Error code (1 byte) */
            err = tvb_get_guint8(tvb, offset);
            proto_tree_add_item(message_tree, hf_lisp_tcp_message_err, tvb, offset, 1, ENC_BIG_ENDIAN);
            offset += 1;
            data_len -= 1;
            proto_item_append_text(tim, ", Error code: %s",
                                   val_to_str(err, lisp_tcp_membership_subscribe_errors, "Unknown error code (%u)"));
        }

        break;

    case MEMBERSHIP_BASE + 4:
    case MEMBERSHIP_BASE + 5:
        /* Site ID (8 bytes) */
        siteid = tvb_get_ntoh64(tvb, offset);
        proto_tree_add_item(message_tree, hf_lisp_tcp_message_site_id, tvb, offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
        data_len -= 8;
        proto_item_append_text(tim, ", Site-ID: %"G_GINT64_MODIFIER"u", siteid);

        /* RLOC AFI (2 bytes) */
        afi = tvb_get_ntohs(tvb, offset);
        proto_tree_add_item(message_tree, hf_lisp_tcp_message_rloc_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
        data_len -= 2;

        switch (afi) {
        case AFNUM_INET:
            proto_tree_add_item(message_tree, hf_lisp_tcp_message_rloc_ipv4, tvb, offset, INET_ADDRLEN, ENC_NA);
            proto_item_append_text(tim, ", RLOC: %s", tvb_ip_to_str(tvb, offset));
            col_append_fstr(pinfo->cinfo, COL_INFO, " [%u] %s", iid, tvb_ip_to_str(tvb, offset));
            offset += INET_ADDRLEN;
            data_len -= INET_ADDRLEN;
            break;
        case AFNUM_INET6:
            proto_tree_add_item(message_tree, hf_lisp_tcp_message_rloc_ipv6, tvb, offset, INET6_ADDRLEN, ENC_NA);
            proto_item_append_text(tim, ", RLOC: %s", tvb_ip6_to_str(tvb, offset));
            col_append_fstr(pinfo->cinfo, COL_INFO, " [%u] %s", iid, tvb_ip6_to_str(tvb, offset));
            offset += INET6_ADDRLEN;
            data_len -= INET6_ADDRLEN;
            break;
        }

        break;

    case MEMBERSHIP_BASE + 7:
    case MEMBERSHIP_BASE + 8:
        /* Request ID (4 bytes) */
        rid = tvb_get_ntohl(tvb, offset);
        proto_tree_add_item(message_tree, hf_lisp_tcp_message_rid, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
        data_len -= 4;
        proto_item_append_text(tim, ", Req ID: %u", rid);
        break;
    }

    if (data_len) {
        proto_tree_add_item(message_tree, hf_lisp_tcp_message_data, tvb, offset, data_len, ENC_NA);
        offset += data_len;
        expert_add_info_format(pinfo, message_tree, &ei_lisp_tcp_undecoded, "Work-in-progress");
    }

    return offset;
}
示例#20
0
/* Broadcasts are searches, offers or promises.
 *
 * Searches are sent by
 * a peer when it needs a file (ie. while applying its policy, when it needs
 * files such as installers to install software.)
 *
 * Each broadcast relates to one file and each file is identified only by its
 * checksum - no file names are ever used. A search times out after 10 seconds
 * (configurable) and the peer will then attempt to act on any offers by
 * downloading (via push or pull - see dissect_ldss_transfer) from those peers.
 *
 * If no offers are received, the search fails and the peer fetches the file
 * from a remote server, generally a HTTP server on the other side of a WAN.
 * The protocol exists to minimize the number of WAN downloads needed.
 *
 * While downloading from WAN the peer sends promises to inform other peers
 * when it will be available for them to download. This prevents multiple peers
 * simultaneously downloading the same file. Promises also inform other peers
 * how much download bandwidth is being used by their download. Other peers use
 * this information and the configured knowledge of the WAN bandwidth to avoid
 * saturating the WAN link, as file downloads are a non-time-critical and
 * non-business-critical network function. LDSS is intended for networks of
 * 5-20 machines connected by slow WAN link. The current implementation of the
 * protocol allows administrator to configure "time windows" when WAN usage is
 * throttled/unthrottled, though this isn't visible in LDSS.
 *
 * Once a WAN download or a LAN transfer (see below above dissect_ldss_transfer)
 * has complete the peer will offer the file to other peers on the LAN so they
 * don't need to download it themselves.
 *
 * Peers also notify when they shut down in case any other peer is waiting for
 * a file. */
static int
dissect_ldss_broadcast(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint16	messageID;
	guint8 digest_type;
	guint8 compression;
	guint32 cookie;
	guint8 *digest;
	guint64	size;
	guint64	offset;
	guint32	targetTime;
	guint16 port;
	guint16	rate;
	guint16 messageDetail = INFERRED_NONE;

	proto_tree	*ti, *ldss_tree;

	const gchar *packet_type, *packet_detail;

	messageID   = tvb_get_ntohs  (tvb,  0);
	digest_type = tvb_get_guint8 (tvb,  2);
	compression = tvb_get_guint8 (tvb,  3);
	cookie      = tvb_get_ntohl  (tvb,  4);
	digest      = (guint8 *)tvb_memdup (NULL, tvb,  8, DIGEST_LEN);
	size	    = tvb_get_ntoh64 (tvb, 40);
	offset	    = tvb_get_ntoh64 (tvb, 48);
	targetTime  = tvb_get_ntohl  (tvb, 56);
	port        = tvb_get_ntohs  (tvb, 64);
	rate	    = tvb_get_ntohs  (tvb, 66);

	packet_type = val_to_str_const(messageID, ldss_message_id_value, "unknown");

	if (messageID == MESSAGE_ID_WILLSEND) {
		if (cookie == 0) {
			/* Shutdown: Dishonor promises from this peer. Current
			 * implementation abuses WillSend for this. */
			messageDetail = INFERRED_PEERSHUTDOWN;
		}
		else if (size == 0 && offset == 0) {
			/* NeedFile search failed - going to WAN */
			messageDetail = INFERRED_WANDOWNLOAD;
		}
		else if (size > 0) {
			/* Size is known (not always the case) */
			if (size == offset) {
				/* File is available for pull on this peer's TCP port */
				messageDetail = INFERRED_OFFER;
			}
			else {
				/* WAN download progress announcement from this peer */
				messageDetail = INFERRED_PROMISE;
			}
		}
	}
	else if (messageID == MESSAGE_ID_NEEDFILE) {
		messageDetail = INFERRED_SEARCH;
	}
	packet_detail = val_to_str_const(messageDetail, ldss_inferred_info, "unknown");

	/* Set the info column */
	col_add_fstr(pinfo->cinfo, COL_INFO, "LDSS Broadcast (%s%s)",
			     packet_type,
			     packet_detail);

	/* If we have a non-null tree (ie we are building the proto_tree
	 * instead of just filling out the columns), then give more detail. */
	if (tree) {
		ti = proto_tree_add_item(tree, proto_ldss,
					 tvb, 0, (tvb_captured_length(tvb) > 72) ? tvb_captured_length(tvb) : 72, ENC_NA);
		ldss_tree = proto_item_add_subtree(ti, ett_ldss_broadcast);

		proto_tree_add_item(ldss_tree, hf_ldss_message_id,
				    tvb, 0, 2, ENC_BIG_ENDIAN);
		ti = proto_tree_add_uint(ldss_tree, hf_ldss_message_detail,
					 tvb, 0, 0, messageDetail);
		PROTO_ITEM_SET_GENERATED(ti);
		proto_tree_add_item(ldss_tree, hf_ldss_digest_type,
				    tvb, 2,	    1,	ENC_BIG_ENDIAN);
		proto_tree_add_item(ldss_tree, hf_ldss_compression,
				    tvb, 3,	    1,	ENC_BIG_ENDIAN);
		proto_tree_add_uint_format_value(ldss_tree, hf_ldss_cookie,
						 tvb, 4,	    4,	FALSE,
						 "0x%x%s",
						 cookie,
						 (cookie == 0)
						 ? " - shutdown (promises from this peer are no longer valid)"
						 : "");
		proto_tree_add_item(ldss_tree, hf_ldss_digest,
				    tvb, 8,	    DIGEST_LEN, ENC_NA);
		proto_tree_add_item(ldss_tree, hf_ldss_size,
				    tvb, 40,    8,	ENC_BIG_ENDIAN);
		proto_tree_add_item(ldss_tree, hf_ldss_offset,
				    tvb, 48,    8,	ENC_BIG_ENDIAN);
		proto_tree_add_uint_format_value(ldss_tree, hf_ldss_target_time,
						 tvb, 56,    4,	FALSE,
						 "%d:%02d:%02d",
						 (int)(targetTime / 3600),
						 (int)((targetTime / 60) % 60),
						 (int)(targetTime % 60));
		proto_tree_add_item(ldss_tree, hf_ldss_reserved_1,
				    tvb, 60,    4,	ENC_BIG_ENDIAN);
		proto_tree_add_uint_format_value(ldss_tree, hf_ldss_port,
						 tvb, 64,    2,	FALSE,
						 "%d%s",
						 port,
						 (messageID == MESSAGE_ID_WILLSEND &&
						  size > 0 &&
						  size == offset)
						 ? " - file can be pulled at this TCP port"
						 : (messageID == MESSAGE_ID_NEEDFILE
						    ? " - file can be pushed to this TCP port"
						    : ""));
		proto_tree_add_uint_format_value(ldss_tree, hf_ldss_rate,
						 tvb, 66,    2,	FALSE,
						 "%ld",
						 (rate > 0)
						 ? (long)floor(exp(rate * G_LN2 / 2048))
						 : 0);
		proto_tree_add_item(ldss_tree, hf_ldss_priority,
				    tvb, 68, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(ldss_tree, hf_ldss_property_count,
				    tvb, 70, 2, ENC_BIG_ENDIAN);
		if (tvb_reported_length(tvb) > 72) {
			proto_tree_add_item(ldss_tree, hf_ldss_properties,
					    tvb, 72, tvb_captured_length(tvb) - 72, ENC_NA);
		}
	}

	/* Finally, store the broadcast and register ourselves to dissect
	 * any pushes or pulls that result from this broadcast. All data
	 * is pushed/pulled over TCP using the port from the broadcast
	 * packet's port field.
	 * Track each by a TCP conversation with the remote end wildcarded.
	 * The TCP conv tracks back to a broadcast conv to determine what it
	 * is in response to.
	 *
	 * These steps only need to be done once per packet, so a variable
	 * tracks the highest frame number seen. Handles the case of first frame
	 * being frame zero. */
	if (messageDetail != INFERRED_PEERSHUTDOWN &&
	    (highest_num_seen == 0 ||
	     highest_num_seen < pinfo->num)) {

		ldss_broadcast_t *data;

		/* Populate data from the broadcast */
		data = wmem_new0(wmem_file_scope(), ldss_broadcast_t);
		data->num = pinfo->num;
		data->ts = pinfo->abs_ts;
		data->message_id = messageID;
		data->message_detail = messageDetail;
		data->port = port;
		data->size = size;
		data->offset = offset;
		data->compression = compression;

		data->file = wmem_new0(wmem_file_scope(), ldss_file_t);
		data->file->digest = digest;
		data->file->digest_type = digest_type;

		data->broadcaster = wmem_new0(wmem_file_scope(), ldss_broadcaster_t);
		copy_address(&data->broadcaster->addr, &pinfo->src);
		data->broadcaster->port = port;

		/* Dissect any future pushes/pulls */
		if (port > 0) {
			prepare_ldss_transfer_conv(data);
		}

		/* Record that the frame was processed */
		highest_num_seen = pinfo->num;
	}

	return tvb_captured_length(tvb);
}
示例#21
0
static void
dissect_btmcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item *main_item;
    proto_tree *main_tree;
    proto_item *pitem;
    gint        offset = 0;
    guint32     op_code;
    guint32     response_code;
    guint32     mdl_id;
    guint32     mdep_id;
    guint32     bluetooth_clock_sync_time;
    guint64     timestamp_sync_time;

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

    switch (pinfo->p2p_dir) {
        case P2P_DIR_SENT:
            col_add_str(pinfo->cinfo, COL_INFO, "Sent ");
            break;
        case P2P_DIR_RECV:
            col_add_str(pinfo->cinfo, COL_INFO, "Rcvd ");
            break;
        default:
            col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
                pinfo->p2p_dir);
            break;
    }

    main_item = proto_tree_add_item(tree, proto_btmcap, tvb, offset, -1, ENC_NA);
    main_tree = proto_item_add_subtree(main_item, ett_btmcap);

    pitem = proto_tree_add_item(main_tree, hf_btmcap_op_code, tvb, offset, 1, ENC_BIG_ENDIAN);
    op_code = tvb_get_guint8(tvb, offset);
    offset += 1;

    col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(op_code, op_code_vals, "Unknown Op Code"));
    if (op_code >= 0x11 && op_code <= 0x20) {
        proto_item_append_text(pitem, " (Clock Sync)");
        col_append_fstr(pinfo->cinfo, COL_INFO, " (Clock Sync)");
    } else {
        proto_item_append_text(pitem, " (Standard)");
        col_append_fstr(pinfo->cinfo, COL_INFO, " (Standard)");
    }

    if (op_code & 0x01) {
        /* isRequest */
        switch(op_code) {
            case 0x01: /* MD_CREATE_MDL_REQ */
            case 0x03: /* MD_RECONNECT_MDL_REQ */
            case 0x05: /* MD_ABORT_MDL_REQ */
            case 0x07: /* MD_DELETE_MDL_REQ */
                pitem = proto_tree_add_item(main_tree, hf_btmcap_mdl_id, tvb, offset, 2, ENC_BIG_ENDIAN);
                mdl_id = tvb_get_ntohs(tvb, offset);
                offset += 2;

                col_append_fstr(pinfo->cinfo, COL_INFO, " - MDL ID: %u", mdl_id);
                if (mdl_id == 0xFFFF) {
                    proto_item_append_text(pitem, " (Indicates all MDLs)");
                    col_append_fstr(pinfo->cinfo, COL_INFO, " (Indicates all MDLs)");
                } else if (mdl_id >= 0x0001 && mdl_id <= 0xFEFF) {
                    proto_item_append_text(pitem, " (Dynamic Range)");
                    col_append_fstr(pinfo->cinfo, COL_INFO, " (Dynamic Range)");
                } else if (mdl_id == 0x0000) {
                    proto_item_append_text(pitem, " (Reserved)");
                    col_append_fstr(pinfo->cinfo, COL_INFO, " (Reserved)");
                }

                if (op_code != 0x07 && mdl_id == 0xFFFF) {
                    expert_add_info_format(pinfo, pitem, PI_PROTOCOL, PI_WARN,
                            " The value 0xFFFF is not a valid MDL ID for this request and shall not be used.");
                    }

                if (op_code == 0x01) {
                    /* only MD_CREATE_MDL_REQ */
                    pitem = proto_tree_add_item(main_tree, hf_btmcap_mdep_id, tvb, offset, 1, ENC_BIG_ENDIAN);
                    mdep_id = tvb_get_guint8(tvb, offset);
                    offset += 1;

                    if (mdep_id <= 0x7F) {
                        proto_item_append_text(pitem, " (Available for use)");
                    } else {
                        proto_item_append_text(pitem, " (Reserved)");
                    }

                    proto_tree_add_item(main_tree, hf_btmcap_configuration, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;
                }
                break;
            case 0x11: /* MD_SYNC_CAP_REQ */
                pitem = proto_tree_add_item(main_tree, hf_btmcap_timestamp_required_accuracy, tvb, offset, 2, ENC_BIG_ENDIAN);
                proto_item_append_text(pitem, " ppm");
                offset += 2;
                break;
            case 0x13: /* MD_SYNC_SET_REQ */
                proto_tree_add_item(main_tree, hf_btmcap_timestamp_update_information, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;

                pitem = proto_tree_add_item(main_tree, hf_btmcap_bluetooth_clock_sync_time, tvb, offset, 4, ENC_BIG_ENDIAN);
                bluetooth_clock_sync_time = tvb_get_ntohl(tvb, offset);
                if (bluetooth_clock_sync_time == 0xFFFFFFFF)
                    proto_item_append_text(pitem, " (Instant Synchronization)");
                else
                    proto_item_append_text(pitem, " (Baseband Half-Slot Instant)");;
                offset += 4;

                pitem = proto_tree_add_item(main_tree, hf_btmcap_timestamp_sync_time, tvb, offset, 8, ENC_BIG_ENDIAN);
                timestamp_sync_time = tvb_get_ntoh64(tvb, offset);
                if (timestamp_sync_time == G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF))
                    proto_item_append_text(pitem, " (No Time Synchronization)");
                else
                    proto_item_append_text(pitem, " (Time-Stamp Clock Instant)");
                offset += 8;
                break;
            case 0x15: /* MD_SYNC_INFO_IND */
                pitem = proto_tree_add_item(main_tree, hf_btmcap_bluetooth_clock_sync_time, tvb, offset, 4, ENC_BIG_ENDIAN);
                proto_item_append_text(pitem, " (Baseband Half-Slot Instant)");
                offset += 4;

                pitem = proto_tree_add_item(main_tree, hf_btmcap_timestamp_sync_time, tvb, offset, 8, ENC_BIG_ENDIAN);
                proto_item_append_text(pitem, " (Time-Stamp Clock Instant)");
                offset += 8;

                pitem = proto_tree_add_item(main_tree, hf_btmcap_timestamp_sample_accuracy, tvb, offset, 2, ENC_BIG_ENDIAN);
                proto_item_append_text(pitem, " us");
                offset += 2;
                break;
        }
    } else {
        /* isResponse */

        proto_tree_add_item(main_tree, hf_btmcap_response_code, tvb, offset, 1, ENC_BIG_ENDIAN);
        response_code = tvb_get_guint8(tvb, offset);
        offset += 1;

        col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", val_to_str(response_code, response_code_vals, "Unknown ResponseCode"));

        if (op_code >= 0x11 && op_code <= 0x20) {
            /* Clock Sync */
            switch(op_code) {
                case 0x12: /* MD_SYNC_CAP_RSP */
                    pitem = proto_tree_add_item(main_tree, hf_btmcap_bluetooth_clock_access_resolution, tvb, offset, 1, ENC_BIG_ENDIAN);
                    proto_item_append_text(pitem, " (Baseband half-slots)");
                    offset += 1;

                    pitem = proto_tree_add_item(main_tree, hf_btmcap_sync_lead_time, tvb, offset, 2, ENC_BIG_ENDIAN);
                    proto_item_append_text(pitem, " ms");
                    offset += 2;

                    pitem = proto_tree_add_item(main_tree, hf_btmcap_timestamp_native_resolution, tvb, offset, 2, ENC_BIG_ENDIAN);
                    proto_item_append_text(pitem, " us");
                    offset += 2;

                    pitem = proto_tree_add_item(main_tree, hf_btmcap_timestamp_native_accuracy, tvb, offset, 2, ENC_BIG_ENDIAN);
                    proto_item_append_text(pitem, " ppm");
                    offset += 2;
                    break;
                case 0x14: /* MD_SYNC_SET_RSP */
                    pitem = proto_tree_add_item(main_tree, hf_btmcap_bluetooth_clock_sync_time, tvb, offset, 4, ENC_BIG_ENDIAN);
                    bluetooth_clock_sync_time = tvb_get_ntohl(tvb, offset);
                    if (bluetooth_clock_sync_time == 0xFFFFFFFF)
                        proto_item_append_text(pitem, " (Instant Synchronization)");
                    else
                        proto_item_append_text(pitem, " (Baseband Half-Slot Instant)");
                    offset += 4;

                    pitem = proto_tree_add_item(main_tree, hf_btmcap_timestamp_sync_time, tvb, offset, 8, ENC_BIG_ENDIAN);
                    timestamp_sync_time = tvb_get_ntoh64(tvb, offset);
                    if (timestamp_sync_time == G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF))
                        proto_item_append_text(pitem, " (No Time Synchronization)");
                    else
                        proto_item_append_text(pitem, " (Time-Stamp Clock Instant)");
                    offset += 8;

                    pitem = proto_tree_add_item(main_tree, hf_btmcap_timestamp_sample_accuracy, tvb, offset, 2, ENC_BIG_ENDIAN);
                    proto_item_append_text(pitem, " us");
                    offset += 2;
                    break;
            }
        } else {
            /* Standard Op Code */
            pitem = proto_tree_add_item(main_tree, hf_btmcap_mdl_id, tvb, offset, 2, ENC_BIG_ENDIAN);
            mdl_id = tvb_get_ntohs(tvb, offset);
            offset += 2;

            col_append_fstr(pinfo->cinfo, COL_INFO, " - %u", mdl_id);
            if (mdl_id == 0xFFFF) {
                proto_item_append_text(pitem, " (Indicates all MDLs)");
                col_append_fstr(pinfo->cinfo, COL_INFO, " (Indicates all MDLs)");
            } else if (mdl_id >= 0x0001 && mdl_id <= 0xFEFF) {
                proto_item_append_text(pitem, " (Dynamic Range)");
                col_append_fstr(pinfo->cinfo, COL_INFO, " (Dynamic Range)");
            } else if (mdl_id == 0x0000) {
                proto_item_append_text(pitem, " (Reserved)");
                col_append_fstr(pinfo->cinfo, COL_INFO, " (Reserved)");
            }

            if ((op_code == 0x03 || op_code == 0x05 || op_code == 0x07) && tvb_length_remaining(tvb, offset)) {
                    expert_add_info_format(pinfo, pitem, PI_PROTOCOL, PI_WARN,
                            "The Response Parameters for MD_RECONNECT_MDL_RSP shall have length zero.");
            } else if (tvb_length_remaining(tvb, offset)) {
                pitem = proto_tree_add_item(main_tree, hf_btmcap_response_parameters, tvb, offset, -1, ENC_NA);
                if (response_code != 0x00) {
                    expert_add_info_format(pinfo, pitem, PI_PROTOCOL, PI_WARN,
                            "When the Response Code is not Success, the Response Parameters shall have length zero.");
                }
                offset += tvb_length_remaining(tvb, offset);
            }
        }
    }

    if (tvb_length_remaining(tvb, offset)) {
        pitem = proto_tree_add_item(main_tree, hf_btmcap_data, tvb, offset, -1, ENC_NA);
        expert_add_info_format(pinfo, pitem, PI_PROTOCOL, PI_WARN,
                "Unexpected data");
    }
}
示例#22
0
static void
dissect_nbd_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	guint32 magic, error, packet;
	guint32 handle[2];
	guint64 from;
	int offset=0;
	proto_tree *tree=NULL;
	proto_item *item=NULL;
	conversation_t *conversation;
	nbd_conv_info_t *nbd_info;
	nbd_transaction_t *nbd_trans=NULL;
	emem_tree_key_t hkey[3];

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

	col_clear(pinfo->cinfo, COL_INFO);

	item = proto_tree_add_item(parent_tree, proto_nbd, tvb, 0, -1, ENC_NA);
	tree = proto_item_add_subtree(item, ett_nbd);


	magic=tvb_get_ntohl(tvb, offset);
	proto_tree_add_item(tree, hf_nbd_magic, tvb, offset, 4, ENC_BIG_ENDIAN);
	offset+=4;


	/* grab what we need to do the request/response matching */
	switch(magic){
	case NBD_REQUEST_MAGIC:
	case NBD_RESPONSE_MAGIC:
		handle[0]=tvb_get_ntohl(tvb, offset+4);
		handle[1]=tvb_get_ntohl(tvb, offset+8);
		break;
	default:
		return;
	}

	conversation = find_or_create_conversation(pinfo);

	/*
	 * Do we already have a state structure for this conv
	 */
	nbd_info = (nbd_conv_info_t *)conversation_get_proto_data(conversation, proto_nbd);
	if (!nbd_info) {
		/* No.  Attach that information to the conversation, and add
		 * it to the list of information structures.
		 */
		nbd_info = se_new(nbd_conv_info_t);
		nbd_info->unacked_pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "nbd_unacked_pdus");
		nbd_info->acked_pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "nbd_acked_pdus");

		conversation_add_proto_data(conversation, proto_nbd, nbd_info);
	}
	if(!pinfo->fd->flags.visited){
		if(magic==NBD_REQUEST_MAGIC){
			/* This is a request */
			nbd_trans=se_new(nbd_transaction_t);
			nbd_trans->req_frame=pinfo->fd->num;
			nbd_trans->rep_frame=0;
			nbd_trans->req_time=pinfo->fd->abs_ts;
			nbd_trans->type=tvb_get_ntohl(tvb, offset);
			nbd_trans->datalen=tvb_get_ntohl(tvb, offset+20);

			hkey[0].length=2;
			hkey[0].key=handle;
			hkey[1].length=0;

			se_tree_insert32_array(nbd_info->unacked_pdus, hkey, (void *)nbd_trans);
		} else if(magic==NBD_RESPONSE_MAGIC){
			hkey[0].length=2;
			hkey[0].key=handle;
			hkey[1].length=0;

			nbd_trans=(nbd_transaction_t *)se_tree_lookup32_array(nbd_info->unacked_pdus, hkey);
			if(nbd_trans){
				nbd_trans->rep_frame=pinfo->fd->num;

				hkey[0].length=1;
				hkey[0].key=&nbd_trans->rep_frame;
				hkey[1].length=2;
				hkey[1].key=handle;
				hkey[2].length=0;
				se_tree_insert32_array(nbd_info->acked_pdus, hkey, (void *)nbd_trans);
				hkey[0].length=1;
				hkey[0].key=&nbd_trans->req_frame;
				hkey[1].length=2;
				hkey[1].key=handle;
				hkey[2].length=0;
				se_tree_insert32_array(nbd_info->acked_pdus, hkey, (void *)nbd_trans);
			}
		}
	} else {
		packet=pinfo->fd->num;
		hkey[0].length=1;
		hkey[0].key=&packet;
		hkey[1].length=2;
		hkey[1].key=handle;
		hkey[2].length=0;

		nbd_trans=(nbd_transaction_t *)se_tree_lookup32_array(nbd_info->acked_pdus, hkey);
	}
	/* The bloody handles are reused !!! eventhough they are 64 bits.
	 * So we must verify we got the "correct" one
	 */
	if( (magic==NBD_RESPONSE_MAGIC)
	&&  (nbd_trans)
	&&  (pinfo->fd->num<nbd_trans->req_frame) ){
		/* must have been the wrong one */
		nbd_trans=NULL;
	}

	if(!nbd_trans){
		/* create a "fake" nbd_trans structure */
		nbd_trans=ep_new(nbd_transaction_t);
		nbd_trans->req_frame=0;
		nbd_trans->rep_frame=0;
		nbd_trans->req_time=pinfo->fd->abs_ts;
		nbd_trans->type=0xff;
		nbd_trans->datalen=0;
	}

	/* print state tracking in the tree */
	if(magic==NBD_REQUEST_MAGIC){
		/* This is a request */
		if(nbd_trans->rep_frame){
			proto_item *it;

			it=proto_tree_add_uint(tree, hf_nbd_response_in, tvb, 0, 0, nbd_trans->rep_frame);
			PROTO_ITEM_SET_GENERATED(it);
		}
	} else if(magic==NBD_RESPONSE_MAGIC){
		/* This is a reply */
		if(nbd_trans->req_frame){
			proto_item *it;
			nstime_t ns;

			it=proto_tree_add_uint(tree, hf_nbd_response_to, tvb, 0, 0, nbd_trans->req_frame);
			PROTO_ITEM_SET_GENERATED(it);

			nstime_delta(&ns, &pinfo->fd->abs_ts, &nbd_trans->req_time);
			it=proto_tree_add_time(tree, hf_nbd_time, tvb, 0, 0, &ns);
			PROTO_ITEM_SET_GENERATED(it);
		}
	}


	switch(magic){
	case NBD_REQUEST_MAGIC:
		proto_tree_add_item(tree, hf_nbd_type, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset+=4;

		proto_tree_add_item(tree, hf_nbd_handle, tvb, offset, 8, ENC_BIG_ENDIAN);
		offset+=8;

		from=tvb_get_ntoh64(tvb, offset);
		proto_tree_add_item(tree, hf_nbd_from, tvb, offset, 8, ENC_BIG_ENDIAN);
		offset+=8;

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

		switch(nbd_trans->type){
		case NBD_CMD_WRITE:
			col_add_fstr(pinfo->cinfo, COL_INFO, "Write Request  Offset:0x%" G_GINT64_MODIFIER "x Length:%d", from, nbd_trans->datalen);
			break;
		case NBD_CMD_READ:
			col_add_fstr(pinfo->cinfo, COL_INFO, "Read Request  Offset:0x%" G_GINT64_MODIFIER "x Length:%d", from, nbd_trans->datalen);
			break;
		case NBD_CMD_DISC:
			col_set_str(pinfo->cinfo, COL_INFO, "Disconnect Request");
			break;
		}

		if(nbd_trans->type==NBD_CMD_WRITE){
			proto_tree_add_item(tree, hf_nbd_data, tvb, offset, nbd_trans->datalen, ENC_NA);
		}
		break;
	case NBD_RESPONSE_MAGIC:
		item=proto_tree_add_uint(tree, hf_nbd_type, tvb, 0, 0, nbd_trans->type);
		PROTO_ITEM_SET_GENERATED(item);

		error=tvb_get_ntohl(tvb, offset);
		proto_tree_add_item(tree, hf_nbd_error, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset+=4;

		proto_tree_add_item(tree, hf_nbd_handle, tvb, offset, 8, ENC_BIG_ENDIAN);
		offset+=8;

		col_add_fstr(pinfo->cinfo, COL_INFO, "%s Response  Error:%d", (nbd_trans->type==NBD_CMD_WRITE)?"Write":"Read", error);

		if(nbd_trans->type==NBD_CMD_READ){
			proto_tree_add_item(tree, hf_nbd_data, tvb, offset, nbd_trans->datalen, ENC_NA);
		}
		break;
	}

	return;
}