示例#1
0
/*
 * Dissect TPKT-encapsulated data in a TCP stream.
 */
void
dissect_tpkt_encap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
		   gboolean desegment, dissector_handle_t subdissector_handle)
{
	proto_item *ti = NULL;
	proto_tree *tpkt_tree = NULL;
	volatile int offset = 0;
	int length_remaining;
	int data_len;
	volatile int length;
	tvbuff_t *volatile next_tvb;
	const char *saved_proto;
	void *pd_save;

	/*
	 * If we're reassembling segmented TPKT PDUs, empty the COL_INFO
	 * column, so subdissectors can append information
	 * without having to worry about emptying the column.
	 *
	 * We use "col_add_str()" because the subdissector
	 * might be appending information to the column, in
	 * which case we'd have to zero the buffer out explicitly
	 * anyway.
	 */
	if (desegment)
		col_set_str(pinfo->cinfo, COL_INFO, "");

	while (tvb_reported_length_remaining(tvb, offset) != 0) {
		/*
		 * Is the first byte of this putative TPKT header
		 * a valid TPKT version number, i.e. 3?
		 */
		if (tvb_get_guint8(tvb, offset) != 3) {
			/*
			 * No, so don't assume this is a TPKT header;
			 * we might be in the middle of TPKT data,
			 * so don't get the length and don't try to
			 * do reassembly.
			 */
			col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
			col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
			if (tree) {
				ti = proto_tree_add_item(tree, proto_tpkt, tvb,
				    offset, -1, ENC_NA);
				tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
				proto_item_set_text(ti, "TPKT");

				proto_tree_add_text(tpkt_tree, tvb, offset, -1,
				    "Continuation data");
			}
			return;
		}

		length_remaining = tvb_length_remaining(tvb, offset);

		/*
		 * Can we do reassembly?
		 */
		if (desegment && pinfo->can_desegment) {
			/*
			 * Yes - is the TPKT header split across segment
			 * boundaries?
			 */
			if (length_remaining < 4) {
				/*
				 * Yes.  Tell the TCP dissector where the data
				 * for this message starts in the data it
				 * handed us and that we need "some more data."
				 * Don't tell it exactly how many bytes we need
				 * because if/when we ask for even more (after
				 * the header) that will break reassembly.
				 */
				pinfo->desegment_offset = offset;
				pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
				return;
			}
		}

		/*
		 * Get the length from the TPKT header.
		 */
		data_len = tvb_get_ntohs(tvb, offset + 2);

		/*
		 * Can we do reassembly?
		 */
		if (desegment && pinfo->can_desegment) {
			/*
			 * Yes - is the payload split across segment
			 * boundaries?
			 */
			if (length_remaining < data_len) {
				/*
				 * Yes.  Tell the TCP dissector where
				 * the data for this message starts in
				 * the data it handed us, and how many
				 * more bytes we need, and return.
				 */
				pinfo->desegment_offset = offset;
				pinfo->desegment_len =
				    data_len - length_remaining;
				return;
			}
		}

		/*
		 * Dissect the TPKT header.
		 * Save and restore "pinfo->current_proto".
		 */
		saved_proto = pinfo->current_proto;
		pinfo->current_proto = "TPKT";

		col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
		/*
		 * Don't add the TPKT header information if we're
		 * reassembling segmented TPKT PDUs or if this
		 * PDU isn't reassembled.
		 *
		 * XXX - the first is so that subdissectors can append
		 * information without getting TPKT stuff in the middle;
		 * why the second?
		 */
		if (!desegment && !pinfo->fragmented) {
			col_add_fstr(pinfo->cinfo, COL_INFO,
			    "TPKT Data length = %u", data_len);
		}

		if (tree) {
			ti = proto_tree_add_item(tree, proto_tpkt, tvb,
			    offset, 4, ENC_NA);
			tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
			proto_item_set_text(ti, "TPKT");

			/* Version */
			proto_tree_add_item(tpkt_tree, hf_tpkt_version, tvb,
			    offset, 1, ENC_BIG_ENDIAN);
			proto_item_append_text(ti, ", Version: 3");

			/* Reserved octet*/
			proto_tree_add_item(tpkt_tree, hf_tpkt_reserved, tvb,
			    offset + 1, 1, ENC_BIG_ENDIAN);

			/* Length */
			proto_tree_add_uint(tpkt_tree, hf_tpkt_length, tvb,
			    offset + 2, 2, data_len);
			proto_item_append_text(ti, ", Length: %u", data_len);
		}
		pinfo->current_proto = saved_proto;

		/* Skip the TPKT header. */
		offset += 4;
		data_len -= 4;

		/*
		 * Construct a tvbuff containing the amount of the payload
		 * we have available.  Make its reported length the
		 * amount of data in this TPKT packet.
		 *
		 * XXX - if reassembly isn't enabled. the subdissector
		 * will throw a BoundsError exception, rather than a
		 * ReportedBoundsError exception.  We really want
		 * a tvbuff where the length is "length", the reported
		 * length is "plen + 2", and the "if the snapshot length
		 * were infinite" length were the minimum of the
		 * reported length of the tvbuff handed to us and "plen+2",
		 * with a new type of exception thrown if the offset is
		 * within the reported length but beyond that third length,
		 * with that exception getting the "Unreassembled Packet"
		 * error.
		 */
		length = length_remaining - 4;
		if (length > data_len)
			length = data_len;
		next_tvb = tvb_new_subset(tvb, offset, length, data_len);

		/*
		 * Call the subdissector.
		 *
		 * If it gets an error that means there's no point in
		 * dissecting any more TPKT messages, rethrow the
		 * exception in question.
		 *
		 * If it gets any other error, report it and continue,
		 * as that means that TPKT message got an error, but
		 * that doesn't mean we should stop dissecting TPKT
		 * messages within this frame or chunk of reassembled
		 * data.
		 */
		pd_save = pinfo->private_data;
		TRY {
			call_dissector(subdissector_handle, next_tvb, pinfo,
			    tree);
		}
		CATCH_NONFATAL_ERRORS {
			/*  Restore the private_data structure in case one of the
			 *  called dissectors modified it (and, due to the exception,
			 *  was unable to restore it).
			 */
			pinfo->private_data = pd_save;

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

		/*
		 * Skip the payload.
		 */
		offset += length;
	}
}
示例#2
0
static void
dissect_status (packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 flags)
{
    proto_item *item;
    proto_tree *tree;

    item=proto_tree_add_uint(parent_tree, hf_sbccs_dib_status,
                                tvb, offset, 1, flags);
    tree=proto_item_add_subtree(item, ett_sbccs_dib_status);

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_attention, tvb, offset, 1, flags);
    if (flags & 0x80) {
        proto_item_append_text(item, "  Attention");
        col_append_str(pinfo->cinfo, COL_INFO, "  Attention");
    }
    flags &= (~( 0x80 ));

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_modifier, tvb, offset, 1, flags);
    if (flags & 0x40) {
        proto_item_append_text(item, "  Status Modifier");
        col_append_str(pinfo->cinfo, COL_INFO, "  Status Modifier");
    }
    flags &= (~( 0x40 ));

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_cue, tvb, offset, 1, flags);
    if (flags & 0x20) {
        proto_item_append_text(item, "  Control-Unit End");
        col_append_str(pinfo->cinfo, COL_INFO, "  Control-Unit End");
    }
    flags &= (~( 0x20 ));

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_busy, tvb, offset, 1, flags);
    if (flags & 0x10) {
        proto_item_append_text(item, "  Busy");
        col_append_str(pinfo->cinfo, COL_INFO, "  Busy");
    }
    flags &= (~( 0x10 ));

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_channelend, tvb, offset, 1, flags);
    if (flags & 0x08) {
        proto_item_append_text(item, "  Channel End");
        col_append_str(pinfo->cinfo, COL_INFO, "  Channel End");
    }
    flags &= (~( 0x08 ));

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_deviceend, tvb, offset, 1, flags);
    if (flags & 0x04) {
        proto_item_append_text(item, "  Device End");
        col_append_str(pinfo->cinfo, COL_INFO, "  Device End");
    }
    flags &= (~( 0x04 ));

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_unit_check, tvb, offset, 1, flags);
    if (flags & 0x02) {
        proto_item_append_text(item, "  Unit Check");
        col_append_str(pinfo->cinfo, COL_INFO, "  Unit Check");
    }
    flags &= (~( 0x02 ));

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_unit_exception, tvb, offset, 1, flags);
    if (flags & 0x01) {
        proto_item_append_text(item, "  Unit Exception");
        col_append_str(pinfo->cinfo, COL_INFO, "  Unit Exception");
    }
    /*flags &= (~( 0x01 ));*/

}
示例#3
0
static void
dissect_applemidi_common( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 command ) {

	guint16		 seq_num;
	guint8		 count;
	guint8		*name;
	gint		 offset			= 0;
	gint		 len;
	gint		 string_size;
	proto_tree	*applemidi_tree;
	proto_tree	*applemidi_tree_seq_num;


	col_set_str( pinfo->cinfo, COL_PROTOCOL, APPLEMIDI_DISSECTOR_SHORTNAME );

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

	col_add_fstr( pinfo->cinfo, COL_INFO, "%s", val_to_str( command, applemidi_commands, applemidi_unknown_command ) );

	if ( tree ) {
		proto_item *ti;
		ti = proto_tree_add_item( tree, proto_applemidi, tvb, 0, -1, ENC_NA  );
		applemidi_tree = proto_item_add_subtree( ti, ett_applemidi );

		proto_tree_add_item( applemidi_tree, hf_applemidi_signature, tvb, offset, 2, ENC_BIG_ENDIAN  );
		offset += 2;

		proto_tree_add_item( applemidi_tree, hf_applemidi_command, tvb, offset, 2, ENC_BIG_ENDIAN  );
		offset += 2;

		/* the format of packets for "IN", "NO", "OK" and "BY" is identical and contains
		 * the protocol version, a random number generated by the initiator of the session,
		 * the SSRC that is used by the respective sides RTP-entity and optionally the
		 * name of the participant */
		if ( ( APPLEMIDI_COMMAND_INVITATION == command ) ||
		     ( APPLEMIDI_COMMAND_INVITATION_REJECTED == command ) ||
		     ( APLLEMIDI_COMMAND_INVITATION_ACCEPTED == command ) ||
		     ( APPLEMIDI_COMMAND_ENDSESSION == command ) ) {

			proto_tree_add_item( applemidi_tree, hf_applemidi_protocol_version, tvb, offset, 4, ENC_BIG_ENDIAN  );
			offset += 4;

			proto_tree_add_item( applemidi_tree, hf_applemidi_token, tvb, offset, 4, ENC_BIG_ENDIAN  );
			offset += 4;

			proto_tree_add_item( applemidi_tree, hf_applemidi_ssrc, tvb, offset, 4, ENC_BIG_ENDIAN  );
			offset += 4;

			len = tvb_reported_length(tvb) - offset;

			/* Name is optional */
			if ( len > 0 ) {
				name = tvb_get_ephemeral_string( tvb, offset, len );
				string_size = (gint)( strlen( name ) + 1 );
				proto_tree_add_item( applemidi_tree, hf_applemidi_name, tvb, offset, string_size, ENC_UTF_8|ENC_NA );
				col_append_fstr( pinfo->cinfo, COL_INFO, ": peer = \"%s\"", name );
				offset += string_size;
			}

		/* the synchronization packet contains three 64bit timestamps,  and a value to define how
		 * many of the timestamps transmitted are valid */
		} else if ( APPLEMIDI_COMMAND_SYNCHRONIZATION == command ) {
			proto_tree_add_item( applemidi_tree, hf_applemidi_ssrc, tvb, offset, 4, ENC_BIG_ENDIAN );
			offset += 4;

			count = tvb_get_guint8( tvb, offset );
			proto_tree_add_item( applemidi_tree, hf_applemidi_count, tvb, offset, 1, ENC_BIG_ENDIAN );
			col_append_fstr( pinfo->cinfo, COL_INFO, ": count = %u", count );
			offset += 1;

			proto_tree_add_item( applemidi_tree, hf_applemidi_padding, tvb, offset, 3, ENC_BIG_ENDIAN );
			offset += 3;

			proto_tree_add_item( applemidi_tree, hf_applemidi_timestamp1, tvb, offset, 8, ENC_BIG_ENDIAN );
			offset += 8;

			proto_tree_add_item( applemidi_tree, hf_applemidi_timestamp2, tvb, offset, 8, ENC_BIG_ENDIAN );
			offset += 8;

			proto_tree_add_item( applemidi_tree, hf_applemidi_timestamp3, tvb, offset, 8, ENC_BIG_ENDIAN );
			offset += 8;
		/* With the receiver feedback packet, the recipient can tell the sender up to what sequence
		 * number in the RTP-stream the packets have been received; this can be used to shorten the
		 * recovery-journal-section in the RTP-session */
		} else if ( APPLEMIDI_COMMAND_RECEIVER_FEEDBACK == command ) {
			proto_tree_add_item( applemidi_tree, hf_applemidi_ssrc, tvb, offset, 4, ENC_BIG_ENDIAN );
			offset += 4;

			ti = proto_tree_add_item( applemidi_tree, hf_applemidi_sequence_num, tvb, offset, 4, ENC_BIG_ENDIAN );
			/* Apple includes a 32bit sequence-number, but the RTP-packet only specifies 16bit.
			 * this subtree and subitem are added to be able to associate the sequence-number
			 * here easier with the one specified in the corresponding RTP-packet */
			applemidi_tree_seq_num = proto_item_add_subtree( ti, ett_applemidi_seq_num );
			seq_num = tvb_get_ntohs( tvb, offset );
			proto_tree_add_uint( applemidi_tree_seq_num, hf_applemidi_rtp_sequence_num, tvb, offset, 2, seq_num );
			offset += 4;

			col_append_fstr( pinfo->cinfo, COL_INFO, ": seq = %u", seq_num );
		/* With the bitrate receive limit packet, the recipient can tell the sender to limit
		   the transmission to a certain bitrate.  This is important if the peer is a gateway
		   to a hardware-device that only supports a certain speed.  Like the MIDI 1.0 DIN-cable
		   MIDI-implementation which is limited to 31250.  */
		} else if ( APPLEMIDI_COMMAND_BITRATE_RECEIVE_LIMIT == command ) {
			proto_tree_add_item( applemidi_tree, hf_applemidi_ssrc, tvb, offset, 4, ENC_BIG_ENDIAN );
			offset += 4;

			proto_tree_add_item( applemidi_tree, hf_applemidi_rtp_bitrate_limit,
					     tvb, offset, 4, ENC_BIG_ENDIAN );
			offset += 4;
		}
		/* If there is any remaining data (possibly because an unknown command was encountered),
		 * we just dump it here */
		len = tvb_length_remaining( tvb, offset );
		if ( len > 0 ) {
			proto_tree_add_item( applemidi_tree, hf_applemidi_unknown_data, tvb, offset, len, ENC_NA );
		}
	}
}
示例#4
0
static void
dissect_ncp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
    gboolean is_tcp)
{
    proto_tree            *ncp_tree = NULL;
    proto_item            *ti;
    struct ncp_ip_header  ncpiph;
    struct ncp_ip_rqhdr   ncpiphrq;
    guint16               ncp_burst_seqno, ncp_ack_seqno;
    guint16               flags = 0;
    proto_tree            *flags_tree = NULL;
    int                   hdr_offset = 0;
    int                   commhdr = 0;
    int                   offset = 0;
    gint                  length_remaining;
    tvbuff_t              *next_tvb;
    guint32               testvar = 0, ncp_burst_command, burst_len, burst_off, burst_file;
    guint8                subfunction;
    guint32               nw_connection = 0, data_offset;
    guint16               data_len = 0;
    guint16               missing_fraglist_count = 0;
    mncp_rhash_value      *request_value = NULL;
    conversation_t        *conversation;
    proto_item            *expert_item;

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

    ncp_hdr = &header;

    ti = proto_tree_add_item(tree, proto_ncp, tvb, 0, -1, ENC_NA);
    ncp_tree = proto_item_add_subtree(ti, ett_ncp);
    if (is_tcp) {
        if (tvb_get_ntohl(tvb, hdr_offset) != NCPIP_RQST && tvb_get_ntohl(tvb, hdr_offset) != NCPIP_RPLY)
            commhdr += 1;
        /* Get NCPIP Header data */
        ncpiph.signature = tvb_get_ntohl(tvb, commhdr);
        proto_tree_add_uint(ncp_tree, hf_ncp_ip_sig, tvb, commhdr, 4, ncpiph.signature);
        ncpiph.length = (0x7fffffff & tvb_get_ntohl(tvb, commhdr+4));
        proto_tree_add_uint(ncp_tree, hf_ncp_ip_length, tvb, commhdr+4, 4, ncpiph.length);
        commhdr += 8;
        if (ncpiph.signature == NCPIP_RQST) {
            ncpiphrq.version = tvb_get_ntohl(tvb, commhdr);
            proto_tree_add_uint(ncp_tree, hf_ncp_ip_ver, tvb, commhdr, 4, ncpiphrq.version);
            commhdr += 4;
            ncpiphrq.rplybufsize = tvb_get_ntohl(tvb, commhdr);
            proto_tree_add_uint(ncp_tree, hf_ncp_ip_rplybufsize, tvb, commhdr, 4, ncpiphrq.rplybufsize);
            commhdr += 4;
        }
        /* Check to see if this is a valid offset, otherwise increment for packet signature */
        if (try_val_to_str(tvb_get_ntohs(tvb, commhdr), ncp_type_vals)==NULL) {
            /* Check to see if we have a valid type after packet signature length */
            if (try_val_to_str(tvb_get_ntohs(tvb, commhdr+8), ncp_type_vals)!=NULL) {
                proto_tree_add_item(ncp_tree, hf_ncp_ip_packetsig, tvb, commhdr, 8, ENC_NA);
                commhdr += 8;
            }
        }
    } else {
        /* Initialize this structure, we use it below */
        memset(&ncpiph, 0, sizeof(ncpiph));
    }

    header.type         = tvb_get_ntohs(tvb, commhdr);
    header.sequence     = tvb_get_guint8(tvb, commhdr+2);
    header.conn_low     = tvb_get_guint8(tvb, commhdr+3);
    header.task         = tvb_get_guint8(tvb, commhdr+4);
    header.conn_high    = tvb_get_guint8(tvb, commhdr+5);
    proto_tree_add_uint(ncp_tree, hf_ncp_type, tvb, commhdr, 2, header.type);
    nw_connection = (header.conn_high*256)+header.conn_low;

    /* Ok, we need to track the conversation so that we can
     * determine if a new server session is occuring for this
     * connection.
     */
    conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
        PT_NCP, (guint32) pinfo->srcport, (guint32) pinfo->destport,
        0);
    if ((ncpiph.length & 0x80000000) || ncpiph.signature == NCPIP_RPLY) {
        /* First time through we will record the initial connection and task
         * values
         */
        if (!pinfo->fd->flags.visited) {
            if (conversation != NULL) {
                /* find the record telling us the
                 * request made that caused this
                 * reply
                 */
                request_value = mncp_hash_lookup(conversation, nw_connection, header.task);
                /* if for some reason we have no
                 * conversation in our hash, create
                 * one */
                if (request_value == NULL) {
                    mncp_hash_insert(conversation, nw_connection, header.task, pinfo);
                }
            } else {
                /* It's not part of any conversation
                 * - create a new one.
                 */
                conversation = conversation_new(pinfo->fd->num, &pinfo->src,
                    &pinfo->dst, PT_NCP, (guint32) pinfo->srcport, (guint32) pinfo->destport, 0);
                mncp_hash_insert(conversation, nw_connection, header.task, pinfo);
            }
            /* If this is a request packet then we
             * might have a new task
             */
            if (ncpiph.signature == NCPIP_RPLY) {
                /* Now on reply packets we have to
                 * use the state of the original
                 * request packet, so look up the
                 * request value and check the task number
                 */
                /*request_value = mncp_hash_lookup(conversation, nw_connection, header.task);*/
            }
        } else {
            /* Get request value data */
            request_value = mncp_hash_lookup(conversation, nw_connection, header.task);
            if (request_value) {
                if ((request_value->session_start_packet_num == pinfo->fd->num) && ncp_echo_conn) {
                    expert_add_info_format(pinfo, NULL, &ei_ncp_new_server_session, "Detected New Server Session. Connection %d, Task %d", nw_connection, header.task);
                }
            }
        }
    } else {
        if (!pinfo->fd->flags.visited) {
            if (conversation != NULL) {
                /* find the record telling us the
                 * request made that caused this
                 * reply
                 */
                request_value = mncp_hash_lookup(conversation, nw_connection, header.task);
                /* if for some reason we have no
                 * conversation in our hash, create
                 * one */
                if (request_value == NULL) {
                    mncp_hash_insert(conversation, nw_connection, header.task, pinfo);
                }
            } else {
                /* It's not part of any conversation
                 * - create a new one.
                 */
                conversation = conversation_new(pinfo->fd->num, &pinfo->src,
                    &pinfo->dst, PT_NCP, (guint32) pinfo->srcport, (guint32) pinfo->destport, 0);
                mncp_hash_insert(conversation, nw_connection, header.task, pinfo);
            }
            /* find the record telling us the request
             * made that caused this reply
             */
        } else {
            request_value = mncp_hash_lookup(conversation, nw_connection, header.task);
            if (request_value) {
                if ((request_value->session_start_packet_num == pinfo->fd->num) && ncp_echo_conn) {
                    expert_add_info_format(pinfo, NULL, &ei_ncp_new_server_session, "Detected New Server Session. Connection %d, Task %d", nw_connection, header.task);
                }
            }
        }
    }

    tap_queue_packet(ncp_tap.hdr, pinfo, ncp_hdr);

    col_add_str(pinfo->cinfo, COL_INFO,
        val_to_str(header.type, ncp_type_vals, "Unknown type (0x%04x)"));

    /*
     * Process the packet-type-specific header.
     */
    switch (header.type) {

    case NCP_BROADCAST_SLOT:    /* Server Broadcast */
        proto_tree_add_uint(ncp_tree, hf_ncp_seq, tvb, commhdr + 2, 1, header.sequence);
        proto_tree_add_uint(ncp_tree, hf_ncp_connection,tvb, commhdr + 3, 3, nw_connection);
        proto_tree_add_item(ncp_tree, hf_ncp_task, tvb, commhdr + 4, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(ncp_tree, hf_ncp_oplock_flag, tvb, commhdr + 9, 1, tvb_get_guint8(tvb, commhdr+9));
        proto_tree_add_item(ncp_tree, hf_ncp_oplock_handle, tvb, commhdr + 10, 4, ENC_BIG_ENDIAN);
        if ((tvb_get_guint8(tvb, commhdr+9)==0x24) && ncp_echo_file) {
            expert_add_info_format(pinfo, NULL, &ei_ncp_oplock_handle, "Server requesting station to clear oplock on handle - %08x", tvb_get_ntohl(tvb, commhdr+10));
        }
        break;

    case NCP_LIP_ECHO:    /* Lip Echo Packet */
        proto_tree_add_item(ncp_tree, hf_lip_echo, tvb, commhdr, 13, ENC_ASCII|ENC_NA);
        break;

    case NCP_BURST_MODE_XFER:    /* Packet Burst Packet */
        /*
         * XXX - we should keep track of whether there's a burst
         * outstanding on a connection and, if not, treat the
         * beginning of the data as a burst header.
         *
         * The burst header contains:
         *
         *    4 bytes of little-endian function number:
         *        1 = read, 2 = write;
         *
         *    4 bytes of file handle;
         *
         *    8 reserved bytes;
         *
         *    4 bytes of big-endian file offset;
         *
         *    4 bytes of big-endian byte count.
         *
         * The data follows for a burst write operation.
         *
         * The first packet of a burst read reply contains:
         *
         *    4 bytes of little-endian result code:
         *       0: No error
         *       1: Initial error
         *       2: I/O error
         *       3: No data read;
         *
         *    4 bytes of returned byte count (big-endian?).
         *
         * The data follows.
         *
         * Each burst of a write request is responded to with a
         * burst packet with a 2-byte little-endian result code:
         *
         *    0: Write successful
         *    4: Write error
         */
        flags = tvb_get_guint8(tvb, commhdr + 2);

        ti = proto_tree_add_uint(ncp_tree, hf_ncp_system_flags,
            tvb, commhdr + 2, 1, flags);
        flags_tree = proto_item_add_subtree(ti, ett_ncp_system_flags);

        proto_tree_add_item(flags_tree, hf_ncp_system_flags_abt,
            tvb, commhdr + 2, 1, ENC_BIG_ENDIAN);
        if (flags & ABT) {
            proto_item_append_text(ti, "  ABT");
        }
        flags&=(~( ABT ));

        proto_tree_add_item(flags_tree, hf_ncp_system_flags_bsy,
            tvb, commhdr + 2, 1, ENC_BIG_ENDIAN);
        if (flags & BSY) {
            proto_item_append_text(ti, "  BSY");
        }
        flags&=(~( BSY ));

        proto_tree_add_item(flags_tree, hf_ncp_system_flags_eob,
            tvb, commhdr + 2, 1, ENC_BIG_ENDIAN);
        if (flags & EOB) {
            proto_item_append_text(ti, "  EOB");
        }
        flags&=(~( EOB ));

        proto_tree_add_item(flags_tree, hf_ncp_system_flags_lst,
            tvb, commhdr + 2, 1, ENC_BIG_ENDIAN);
        if (flags & LST) {
            proto_item_append_text(ti, "  LST");
        }
        flags&=(~( LST ));

        proto_tree_add_item(flags_tree, hf_ncp_system_flags_sys,
            tvb, commhdr + 2, 1, ENC_BIG_ENDIAN);
        if (flags & SYS) {
            proto_item_append_text(ti, "  SYS");
        }
        flags&=(~( SYS ));


        proto_tree_add_item(ncp_tree, hf_ncp_stream_type,
            tvb, commhdr + 3, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(ncp_tree, hf_ncp_src_connection,
            tvb, commhdr + 4, 4, ENC_BIG_ENDIAN);
        proto_tree_add_item(ncp_tree, hf_ncp_dst_connection,
            tvb, commhdr + 8, 4, ENC_BIG_ENDIAN);
        proto_tree_add_item(ncp_tree, hf_ncp_packet_seqno,
            tvb, commhdr + 12, 4, ENC_BIG_ENDIAN);
        proto_tree_add_item(ncp_tree, hf_ncp_delay_time,
            tvb, commhdr + 16, 4, ENC_BIG_ENDIAN);
        ncp_burst_seqno = tvb_get_ntohs(tvb, commhdr+20);
        proto_tree_add_item(ncp_tree, hf_ncp_burst_seqno,
            tvb, commhdr + 20, 2, ENC_BIG_ENDIAN);
        ncp_ack_seqno = tvb_get_ntohs(tvb, commhdr+22);
        proto_tree_add_item(ncp_tree, hf_ncp_ack_seqno,
            tvb, commhdr + 22, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ncp_tree, hf_ncp_burst_len,
            tvb, commhdr + 24, 4, ENC_BIG_ENDIAN);
        data_offset = tvb_get_ntohl(tvb, commhdr + 28);
        proto_tree_add_uint(ncp_tree, hf_ncp_data_offset,
            tvb, commhdr + 28, 4, data_offset);
        data_len = tvb_get_ntohs(tvb, commhdr + 32);
        proto_tree_add_uint(ncp_tree, hf_ncp_data_bytes,
            tvb, commhdr + 32, 2, data_len);
        missing_fraglist_count = tvb_get_ntohs(tvb, commhdr + 34);
        proto_tree_add_item(ncp_tree, hf_ncp_missing_fraglist_count,
            tvb, commhdr + 34, 2, ENC_BIG_ENDIAN);
        offset = commhdr + 36;
        if (!(flags & SYS) && ncp_burst_seqno == ncp_ack_seqno &&
            data_offset == 0) {
            /*
             * This is either a Burst Read or Burst Write
             * command.  The data length includes the burst
             * mode header, plus any data in the command
             * (there shouldn't be any in a read, but there
             * might be some in a write).
             */
            if (data_len < 4)
                return;
            ncp_burst_command = tvb_get_ntohl(tvb, offset);
            proto_tree_add_item(ncp_tree, hf_ncp_burst_command,
                tvb, offset, 4, ENC_BIG_ENDIAN);
            offset += 4;
            data_len -= 4;

            if (data_len < 4)
                return;
            burst_file = tvb_get_ntohl(tvb, offset);
            proto_tree_add_item(ncp_tree, hf_ncp_burst_file_handle,
                tvb, offset, 4, ENC_BIG_ENDIAN);
            offset += 4;
            data_len -= 4;

            if (data_len < 8)
                return;
            proto_tree_add_item(ncp_tree, hf_ncp_burst_reserved,
                tvb, offset, 8, ENC_NA);
            offset += 8;
            data_len -= 8;

            if (data_len < 4)
                return;
            burst_off = tvb_get_ntohl(tvb, offset);
            proto_tree_add_uint(ncp_tree, hf_ncp_burst_offset,
                tvb, offset, 4, burst_off);
            offset += 4;
            data_len -= 4;

            if (data_len < 4)
                return;
            burst_len = tvb_get_ntohl(tvb, offset);
            proto_tree_add_uint(ncp_tree, hf_ncp_burst_len,
                tvb, offset, 4, burst_len);
            offset += 4;
            data_len -= 4;

            col_add_fstr(pinfo->cinfo, COL_INFO,
                "%s %d bytes starting at offset %d in file 0x%08x",
                val_to_str(ncp_burst_command,
                    burst_command, "Unknown (0x%08x)"),
                    burst_len, burst_off, burst_file);
            break;
        } else {
            if (tvb_get_guint8(tvb, commhdr + 2) & 0x10) {
                col_set_str(pinfo->cinfo, COL_INFO, "End of Burst");
            }
        }
        break;

    case NCP_ALLOCATE_SLOT:        /* Allocate Slot Request */
        length_remaining = tvb_length_remaining(tvb, commhdr + 4);
        if (length_remaining > 4) {
            testvar = tvb_get_ntohl(tvb, commhdr+4);
            if (testvar == 0x4c495020) {
                proto_tree_add_item(ncp_tree, hf_lip_echo, tvb, commhdr+4, 13, ENC_ASCII|ENC_NA);
                break;
            }
        }
        /* otherwise fall through */

    case NCP_POSITIVE_ACK:        /* Positive Acknowledgement */
    case NCP_SERVICE_REQUEST:    /* Server NCP Request */
    case NCP_SERVICE_REPLY:        /* Server NCP Reply */
    case NCP_WATCHDOG:        /* Watchdog Packet */
    case NCP_DEALLOCATE_SLOT:    /* Deallocate Slot Request */
    default:
        proto_tree_add_uint(ncp_tree, hf_ncp_seq, tvb, commhdr + 2, 1, header.sequence);
        proto_tree_add_uint(ncp_tree, hf_ncp_connection,tvb, commhdr + 3, 3, nw_connection);
        proto_tree_add_item(ncp_tree, hf_ncp_task, tvb, commhdr + 4, 1, ENC_BIG_ENDIAN);
        break;
    }

    /*
     * Process the packet body.
     */
    switch (header.type) {

    case NCP_ALLOCATE_SLOT:        /* Allocate Slot Request */
        length_remaining = tvb_length_remaining(tvb, commhdr + 4);
        if (length_remaining > 4) {
            testvar = tvb_get_ntohl(tvb, commhdr+4);
            if (testvar == 0x4c495020) {
                proto_tree_add_text(ncp_tree, tvb, commhdr, -1,
                    "Lip Echo Packet");
                /*break;*/
            }
        }
        next_tvb = tvb_new_subset_remaining(tvb, commhdr);
        dissect_ncp_request(next_tvb, pinfo, nw_connection,
            header.sequence, header.type, ncp_tree);
        break;

    case NCP_DEALLOCATE_SLOT:    /* Deallocate Slot Request */
        next_tvb = tvb_new_subset_remaining(tvb, commhdr);
        dissect_ncp_request(next_tvb, pinfo, nw_connection,
            header.sequence, header.type, ncp_tree);
        break;

    case NCP_SERVICE_REQUEST:    /* Server NCP Request */
    case NCP_BROADCAST_SLOT:    /* Server Broadcast Packet */
        next_tvb = tvb_new_subset_remaining(tvb, commhdr);
        if (tvb_get_guint8(tvb, commhdr+6) == 0x68) {
            subfunction = tvb_get_guint8(tvb, commhdr+7);
            switch (subfunction) {

            case 0x02:    /* NDS Frag Packet to decode */
                dissect_nds_request(next_tvb, pinfo,
                    nw_connection, header.sequence,
                    header.type, ncp_tree);
                break;

            case 0x01:    /* NDS Ping */
                dissect_ping_req(next_tvb, pinfo,
                    nw_connection, header.sequence,
                    header.type, ncp_tree);
                break;

            default:
                dissect_ncp_request(next_tvb, pinfo,
                    nw_connection, header.sequence,
                    header.type, ncp_tree);
                break;
             }
        } else {
            dissect_ncp_request(next_tvb, pinfo, nw_connection,
                header.sequence, header.type, ncp_tree);
        }
        break;

    case NCP_SERVICE_REPLY:        /* Server NCP Reply */
        next_tvb = tvb_new_subset_remaining(tvb, commhdr);
        nds_defrag(next_tvb, pinfo, nw_connection, header.sequence,
            header.type, ncp_tree, &ncp_tap);
        break;

    case NCP_POSITIVE_ACK:        /* Positive Acknowledgement */
        /*
         * XXX - this used to call "nds_defrag()", which would
         * clear out "frags".  Was that the right thing to
         * do?
         */
        next_tvb = tvb_new_subset_remaining(tvb, commhdr);
        dissect_ncp_reply(next_tvb, pinfo, nw_connection,
            header.sequence, header.type, ncp_tree, &ncp_tap);
        break;

    case NCP_WATCHDOG:        /* Watchdog Packet */
        /*
         * XXX - should the completion code be interpreted as
         * it is in "packet-ncp2222.inc"?  If so, this
         * packet should be handled by "dissect_ncp_reply()".
         */
        proto_tree_add_item(ncp_tree, hf_ncp_completion_code,
            tvb, commhdr + 6, 1, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(ncp_tree, hf_ncp_connection_status,
            tvb, commhdr + 7, 1, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(ncp_tree, hf_ncp_slot,
            tvb, commhdr + 8, 1, ENC_LITTLE_ENDIAN);
        proto_tree_add_item(ncp_tree, hf_ncp_control_code,
            tvb, commhdr + 9, 1, ENC_LITTLE_ENDIAN);
        /*
         * Display the rest of the packet as data.
         */
        if (tvb_offset_exists(tvb, commhdr + 10)) {
            call_dissector(data_handle,
                tvb_new_subset_remaining(tvb, commhdr + 10),
                pinfo, ncp_tree);
        }
        break;

    case NCP_BURST_MODE_XFER:    /* Packet Burst Packet */
        if (flags & SYS) {
            /*
             * System packet; show missing fragments if there
             * are any.
             */
            while (missing_fraglist_count != 0) {
                proto_tree_add_item(ncp_tree, hf_ncp_missing_data_offset,
                    tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                proto_tree_add_item(ncp_tree, hf_ncp_missing_data_count,
                    tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;
                missing_fraglist_count--;
            }
        } else {
            /*
             * XXX - do this by using -1 and -1 as the length
             * arguments to "tvb_new_subset()" and then calling
             * "tvb_set_reported_length()"?  That'll throw an
             * exception if "data_len" goes past the reported
             * length of the packet, but that's arguably a
             * feature in this case.
             */
            length_remaining = tvb_length_remaining(tvb, offset);
            if (length_remaining > data_len)
                length_remaining = data_len;
            if (data_len != 0) {
                call_dissector(data_handle,
                    tvb_new_subset(tvb, offset,
                    length_remaining, data_len),
                    pinfo, ncp_tree);
            }
        }
        break;

    case NCP_LIP_ECHO:        /* LIP Echo Packet */
        proto_tree_add_text(ncp_tree, tvb, commhdr, -1,
            "Lip Echo Packet");
        break;

    default:
        expert_item = proto_tree_add_text(ncp_tree, tvb, commhdr + 6, -1,
            "%s packets not supported yet",
            val_to_str(header.type, ncp_type_vals,
                "Unknown type (0x%04x)"));
        if (ncp_echo_err) {
            expert_add_info_format(pinfo, expert_item, &ei_ncp_type, "%s packets not supported yet", val_to_str(header.type, ncp_type_vals, "Unknown type (0x%04x)"));
        }
        break;
    }
}
示例#5
0
static void
dissect_file_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	proto_item  *volatile ti = NULL;
	guint	     cap_len = 0, frame_len = 0;
	proto_tree  *volatile tree;
	proto_item  *item;
	const gchar *cap_plurality, *frame_plurality;

	tree=parent_tree;

	pinfo->current_proto = "File";

	/* if FILE is not referenced from any filters we don't need to worry about
	   generating any tree items.  */
	if(!proto_field_is_referenced(tree, proto_file)) {
		tree=NULL;
	} else {
		proto_tree *fh_tree;
		gboolean old_visible;

		/* Put in frame header information. */
		cap_len = tvb_length(tvb);
		frame_len = tvb_reported_length(tvb);

		cap_plurality = plurality(cap_len, "", "s");
		frame_plurality = plurality(frame_len, "", "s");

		ti = proto_tree_add_protocol_format(tree, proto_file, tvb, 0, -1,
		    "File record %u: %u byte%s",
		    pinfo->fd->num, frame_len, frame_plurality);
		proto_item_append_text(ti, ", %u byte%s",
		    cap_len, cap_plurality);

		fh_tree = proto_item_add_subtree(ti, ett_file);

		proto_tree_add_int(fh_tree, hf_file_ftap_encap, tvb, 0, 0, pinfo->fd->lnk_t);

		proto_tree_add_uint(fh_tree, hf_file_record_number, tvb, 0, 0, pinfo->fd->num);

		proto_tree_add_uint_format(fh_tree, hf_file_record_len, tvb,
					   0, 0, frame_len, "Record Length: %u byte%s (%u bits)",
					   frame_len, frame_plurality, frame_len * 8);

		ti = proto_tree_add_boolean(fh_tree, hf_file_marked, tvb, 0, 0,pinfo->fd->flags.marked);
		PROTO_ITEM_SET_GENERATED(ti);

		ti = proto_tree_add_boolean(fh_tree, hf_file_ignored, tvb, 0, 0,pinfo->fd->flags.ignored);
		PROTO_ITEM_SET_GENERATED(ti);

		if(proto_field_is_referenced(tree, hf_file_protocols)) {
			/* we are going to be using proto_item_append_string() on
			 * hf_frame_protocols, and we must therefore disable the
			 * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by
			 * setting it as visible.
			 *
			 * See proto.h for details.
			 */
			old_visible = proto_tree_set_visible(fh_tree, TRUE);
			ti = proto_tree_add_string(fh_tree, hf_file_protocols, tvb, 0, 0, "");
			PROTO_ITEM_SET_GENERATED(ti);
			proto_tree_set_visible(fh_tree, old_visible);
		}

		if(pinfo->fd->pfd != 0){
			proto_item *ppd_item;
			guint num_entries = g_slist_length(pinfo->fd->pfd);
			guint i;
			ppd_item = proto_tree_add_uint(fh_tree, hf_file_num_p_prot_data, tvb, 0, 0, num_entries);
			PROTO_ITEM_SET_GENERATED(ppd_item);
			for(i=0; i<num_entries; i++){
				proto_tree_add_text (fh_tree, tvb, 0, 0, "%s",p_get_proto_name_and_key(wmem_file_scope(), pinfo, i));
			}
		}

#if 0
		if (show_file_off) {
			proto_tree_add_int64_format_value(fh_tree, hf_frame_file_off, tvb,
						    0, 0, pinfo->fd->file_off,
						    "%" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)",
						    pinfo->fd->file_off, pinfo->fd->file_off);
		}
#endif

		if(pinfo->fd->color_filter != NULL) {
			const color_filter_t *color_filter = (const color_filter_t *)pinfo->fd->color_filter;
			item = proto_tree_add_string(fh_tree, hf_file_color_filter_name, tvb,
						     0, 0, color_filter->filter_name);
			PROTO_ITEM_SET_GENERATED(item);
			item = proto_tree_add_string(fh_tree, hf_file_color_filter_text, tvb,
						     0, 0, color_filter->filter_text);
			PROTO_ITEM_SET_GENERATED(item);
		}
	}

	if (pinfo->fd->flags.ignored) {
		/* Ignored package, stop handling here */
		col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>");
		proto_tree_add_text (tree, tvb, 0, -1, "This record is marked as ignored");
		return;
	}

	/* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
	TRY {
#ifdef _MSC_VER
		/* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions
		   like memory access violations.
		   (a running debugger will be called before the except part below) */
                /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
                   stack in an inconsistent state thus causing a crash at some point in the
                   handling of the exception.
                   See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html
                */
		__try {
#endif
			if (!dissector_try_uint(file_encap_dissector_table, pinfo->fd->lnk_t,
						tvb, pinfo, parent_tree)) {

				col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
				col_add_fstr(pinfo->cinfo, COL_INFO, "FTAP_ENCAP = %d",
					     pinfo->fd->lnk_t);
				call_dissector(data_handle,tvb, pinfo, parent_tree);
			}
#ifdef _MSC_VER
		} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
			switch(GetExceptionCode()) {
			case(STATUS_ACCESS_VIOLATION):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
				break;
			case(STATUS_INTEGER_DIVIDE_BY_ZERO):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
				break;
			case(STATUS_STACK_OVERFLOW):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
				/* XXX - this will have probably corrupted the stack,
				   which makes problems later in the exception code */
				break;
				/* XXX - add other hardware exception codes as required */
			default:
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
			}
		}
#endif
	}
	CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
		show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	}
	ENDTRY;

    if(proto_field_is_referenced(tree, hf_file_protocols)) {
		wmem_strbuf_t *val = wmem_strbuf_new(wmem_packet_scope(), "");
		wmem_list_frame_t *frame;
		/* skip the first entry, it's always the "frame" protocol */
		frame = wmem_list_frame_next(wmem_list_head(pinfo->layers));
		if (frame) {
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		while (frame) {
			wmem_strbuf_append_c(val, ':');
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		proto_item_append_string(ti, wmem_strbuf_get_str(val));
	}

	/*  Call postdissectors if we have any (while trying to avoid another
	 *  TRY/CATCH)
	 */
	if (have_postdissector()) {
		TRY {
#ifdef _MSC_VER
			/* Win32: Visual-C Structured Exception Handling (SEH)
			   to trap hardware exceptions like memory access violations */
			/* (a running debugger will be called before the except part below) */
                        /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
                           stack in an inconsistent state thus causing a crash at some point in the
                           handling of the exception.
                           See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html
                        */
			__try {
#endif
				call_all_postdissectors(tvb, pinfo, parent_tree);
#ifdef _MSC_VER
			} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
				switch(GetExceptionCode()) {
				case(STATUS_ACCESS_VIOLATION):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
					break;
				case(STATUS_INTEGER_DIVIDE_BY_ZERO):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
					break;
				case(STATUS_STACK_OVERFLOW):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
					/* XXX - this will have probably corrupted the stack,
					   which makes problems later in the exception code */
					break;
					/* XXX - add other hardware exception codes as required */
				default:
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
				}
			}
#endif
		}
		CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
			show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
		}
		ENDTRY;
	}

	tap_queue_packet(file_tap, pinfo, NULL);


	if (pinfo->frame_end_routines) {
		g_slist_foreach(pinfo->frame_end_routines, &call_file_record_end_routine, NULL);
		g_slist_free(pinfo->frame_end_routines);
		pinfo->frame_end_routines = NULL;
	}
}
示例#6
0
static int
dissect_dtpt_sockaddr(tvbuff_t *tvb, guint offset, proto_tree *tree, int hfindex, int sockaddr_type)
{
	guint32	sockaddr_length = 0;
	proto_item	*sockaddr_item = NULL;
	proto_tree	*sockaddr_tree = NULL;
	guint32		sockaddr_len1 = 0;
	guint32		sockaddr_len2 = 0;

	switch (sockaddr_type) {
		case SOCKADDR_WITH_LEN:
			sockaddr_len1=4;
			sockaddr_len2=16;
		break;
		case SOCKADDR_CONNECT:
			sockaddr_len1=0;
			sockaddr_len2=30;
		break;
	}

	if (sockaddr_type == SOCKADDR_WITH_LEN)
		sockaddr_length = tvb_get_letohl(tvb, offset + 0);

	if (tree) {
		sockaddr_tree = proto_tree_add_subtree(tree, tvb, offset, sockaddr_len1+sockaddr_len2,
			ett_dtpt_sockaddr, NULL, proto_registrar_get_name(hfindex));

		if (sockaddr_type == SOCKADDR_WITH_LEN)
			proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_length,
						tvb, offset+0, 4, sockaddr_length);
	}

	offset += sockaddr_len1;

	if (sockaddr_tree) {
		switch (sockaddr_type) {
			case SOCKADDR_WITH_LEN: {
				guint16 family;

				family = tvb_get_letohs(tvb, offset);
				proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_family,
						tvb, offset, 2, family);
				switch (family) {
					case WINSOCK_AF_INET: {
						guint16 port;

						port = tvb_get_ntohs(tvb,offset+2);
						proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_port,
											tvb, offset+2,2,port);
						proto_tree_add_item(sockaddr_tree, hf_dtpt_sockaddr_address,
											tvb, offset+4,4,ENC_BIG_ENDIAN);
						proto_tree_add_item(sockaddr_tree, hf_dtpt_padding, tvb, offset+8, 8, ENC_NA);
						proto_item_append_text(sockaddr_item, ": %s:%d", tvb_ip_to_str(tvb,offset+4), port);
					}
					break;
				}
			}
			break;
			case SOCKADDR_CONNECT: {
				guint32	family;

				family = tvb_get_letohl(tvb, offset+0);
				proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_family,
						tvb, offset+0, 4, family);
				switch (family) {
					case WINSOCK_AF_INET: {
						guint16 port;

						proto_tree_add_item(sockaddr_tree, hf_dtpt_padding, tvb, offset+4, 4, ENC_NA);
						port = tvb_get_ntohs(tvb,offset+8);
						proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_port,
							tvb, offset+8,2,port);
						proto_tree_add_item(sockaddr_tree, hf_dtpt_sockaddr_address,
							tvb, offset+10,4,ENC_BIG_ENDIAN);
						proto_tree_add_item(sockaddr_tree, hf_dtpt_padding, tvb, offset+14, 16, ENC_NA);
						proto_item_append_text(sockaddr_item, ": %s:%d", tvb_ip_to_str(tvb,offset+10), port);
					}
					break;
				}
			}
			break;
		}

	}
	offset += sockaddr_len2;
	return offset;
}
示例#7
0
/* dissect the "IP" suboption */
static int
dissect_PNDCP_Suboption_IP(tvbuff_t *tvb, int offset, packet_info *pinfo, 
                            proto_tree *tree, proto_item *block_item, proto_item *dcp_item,
                            guint8 service_id, gboolean is_response)
{
    guint8 suboption;
    guint16 block_length;
    guint16 block_info;
    guint16 block_qualifier;
    guint32 ip;
    proto_item *item = NULL;


    /* SuboptionIPParameter */
    offset = dissect_pn_uint8 (tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip, &suboption);
    /* DCPBlockLength */
    offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_length, &block_length);

    switch(suboption) {
    case(PNDCP_SUBOPTION_IP_MAC):
        /* MACAddressValue? */
        pn_append_info(pinfo, dcp_item, ", MAC");
        proto_item_append_text(block_item, "IP/MAC");

        offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, block_length); 
        break;
    case(PNDCP_SUBOPTION_IP_IP):
        pn_append_info(pinfo, dcp_item, ", IP");
        proto_item_append_text(block_item, "IP/IP");

        /* BlockInfo? */
        if( ((service_id == PNDCP_SERVICE_ID_IDENTIFY) &&  is_response) ||
            ((service_id == PNDCP_SERVICE_ID_HELLO)    && !is_response) ||
            ((service_id == PNDCP_SERVICE_ID_GET)      &&  is_response)) {
            block_info = tvb_get_ntohs (tvb, offset);
            if (tree) {
                item = proto_tree_add_uint(tree, hf_pn_dcp_suboption_ip_block_info, tvb, offset, 2, block_info);
            }
            offset += 2;
            proto_item_append_text(block_item, ", BlockInfo: %s", val_to_str(block_info, pn_dcp_suboption_ip_block_info, "Undecoded"));
            block_length -= 2;
            if(block_info & 0x80) {
                expert_add_info_format(pinfo, item, PI_RESPONSE_CODE, PI_NOTE, "IP address conflict detected!");
            }
        }

        /* BlockQualifier? */
        if( (service_id == PNDCP_SERVICE_ID_SET) && !is_response) {
            offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
            proto_item_append_text(block_item, ", BlockQualifier: %s", val_to_str(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
            block_length -= 2;
        }

        /* IPParameterValue ... */

        /* IPAddress */
        offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_ip, &ip);
        proto_item_append_text(block_item, ", IP: %s", ip_to_str((guint8*)&ip));

        /* Subnetmask */
        offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_subnetmask, &ip);
        proto_item_append_text(block_item, ", Subnet: %s", ip_to_str((guint8*)&ip));

        /* StandardGateway */
        offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_standard_gateway, &ip);
        proto_item_append_text(block_item, ", Gateway: %s", ip_to_str((guint8*)&ip));
        break;
    default:
        offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, block_length); 
    }

    return offset;
}
示例#8
0
static int
dissect_banana_element(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) {
    proto_item *ti;
    proto_tree *list_tree;
    guint8 byte = 0;
    gint64 val = 0;
    gint val_len = 0;
    int start_offset = offset;
    int old_offset;
    int i;

    /* Accumulate our value/length 'til we hit a valid type */
    while (tvb_reported_length_remaining(tvb, offset) > 0) {
        byte = tvb_get_guint8(tvb, offset);
        offset++;

        if (byte & 0x80) {
            if (is_element(byte)) {
                break;
            } else {
                expert_add_info_format(pinfo, NULL, &ei_banana_unknown_type, "Unknown type %u", byte);
            }
        } else {
            val_len++;
            if (val_len > MAX_ELEMENT_VAL_LEN) {
                expert_add_info(pinfo, NULL, &ei_banana_too_many_value_bytes);
            }
            val += byte + (val << 7);
        }
    }

    /* Type */
    switch (byte) {
        case BE_LIST:
            if (val > MAX_ELEMENT_VAL) {
                expert_add_info_format(pinfo, NULL, &ei_banana_length_too_long, "List length %" G_GINT64_MODIFIER "d longer than we can handle", val);
            }
            ti = proto_tree_add_uint_format_value(tree, hf_banana_list, tvb, start_offset, offset - start_offset - 1, (guint32) val, "(%d items)", (gint) val);
            list_tree = proto_item_add_subtree(ti, ett_list);
            for (i = 0; i < val; i++) {
                old_offset = offset;
                offset += dissect_banana_element(tvb, pinfo, list_tree, offset);
                if (offset <= old_offset) {
                    return offset - start_offset;
                }
            }
            break;
        case BE_INT:
            if (val > MAX_ELEMENT_VAL) {
                expert_add_info_format(pinfo, NULL, &ei_banana_value_too_large, "Integer value %" G_GINT64_MODIFIER "d too large", val);
            }
            proto_tree_add_uint(tree, hf_banana_int, tvb, start_offset, offset - start_offset, (guint32) val);
            break;
        case BE_STRING:
            if (val > MAX_ELEMENT_VAL) {
                expert_add_info_format(pinfo, NULL, &ei_banana_length_too_long, "String length %" G_GINT64_MODIFIER "d longer than we can handle", val);
            }
            proto_tree_add_item(tree, hf_banana_string, tvb, offset, (guint32) val, ENC_ASCII|ENC_NA);
            offset += (gint) val;
            break;
        case BE_NEG_INT:
            if (val > MAX_ELEMENT_VAL) {
                expert_add_info_format(pinfo, NULL, &ei_banana_value_too_large, "Integer value -%" G_GINT64_MODIFIER "d too large", val);
            }
            proto_tree_add_int(tree, hf_banana_neg_int, tvb, start_offset, offset - start_offset, (gint32) val * -1);
            break;
        case BE_FLOAT:
            proto_tree_add_item(tree, hf_banana_float, tvb, offset, 8, ENC_BIG_ENDIAN);
            offset += 8;
            break;
        case BE_LG_INT:
            proto_tree_add_item(tree, hf_banana_lg_int, tvb, start_offset, offset - start_offset, ENC_NA);
            break;
        case BE_LG_NEG_INT:
            proto_tree_add_item(tree, hf_banana_lg_neg_int, tvb, start_offset, offset - start_offset, ENC_NA);
            break;
        case BE_PB:
            if (val_len > 1) {
                expert_add_info(pinfo, NULL, &ei_banana_pb_error);
            }
            /*
             * The spec says the pb dictionary value comes after the tag.
             * In real-world captures it comes before.
             */
            proto_tree_add_item(tree, hf_banana_pb, tvb, offset - 2, 1, ENC_BIG_ENDIAN);
            break;
        default:
            return 0;
            break;
    }
    return offset - start_offset;
}
示例#9
0
/* Code to actually dissect the packets */
static void
  dissect_ucd (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
  int pos, endtlvpos;
  guint8 type, length;
  guint8 tlvlen, tlvtype;
  proto_tree *ucd_tree;
  proto_item *ucd_item;
  proto_tree *tlv_tree;
  proto_item *tlv_item;
  gint len;
  guint8 upchid, symrate;
   
  len = tvb_reported_length_remaining (tvb, 0);
   upchid = tvb_get_guint8 (tvb, 0);
   
   /* if the upstream Channel ID is 0 then this is for Telephony Return) */
	if (upchid > 0)
	  col_add_fstr (pinfo->cinfo, COL_INFO,
			"UCD Message:  Channel ID = %u (U%u)", upchid,
			upchid - 1);
	else
	  col_add_fstr (pinfo->cinfo, COL_INFO,
			"UCD Message:  Channel ID = %u (Telephony Return)",
			upchid);
   
   if (tree)
     {
	ucd_item =
	proto_tree_add_protocol_format (tree, proto_docsis_ucd, tvb, 0, -1,
					"UCD Message");
	ucd_tree = proto_item_add_subtree (ucd_item, ett_docsis_ucd);
	proto_tree_add_item (ucd_tree, hf_docsis_ucd_upstream_chid, tvb, 0, 1,
			     ENC_BIG_ENDIAN);
	proto_tree_add_item (ucd_tree, hf_docsis_ucd_config_ch_cnt, tvb, 1, 1,
			     ENC_BIG_ENDIAN);
	proto_tree_add_item (ucd_tree, hf_docsis_ucd_mini_slot_size, tvb, 2, 1,
			     ENC_BIG_ENDIAN);
	proto_tree_add_item (ucd_tree, hf_docsis_ucd_down_chid, tvb, 3, 1,
			     ENC_BIG_ENDIAN);
	
	pos = 4;
	while (pos < len)
	  {
	  type = tvb_get_guint8 (tvb, pos);
	  tlv_item = proto_tree_add_text (ucd_tree, tvb, pos, -1,
					  "%s",
					  val_to_str(type, channel_tlv_vals,
						     "Unknown TLV (%u)"));  
	  tlv_tree = proto_item_add_subtree (tlv_item, ett_tlv);
	  proto_tree_add_uint (tlv_tree, hf_docsis_ucd_type,
			       tvb, pos, 1, type);
	  pos++;
	  length = tvb_get_guint8 (tvb, pos);
	  proto_tree_add_uint (tlv_tree, hf_docsis_ucd_length,
			       tvb, pos, 1, length);
	  pos++;
	  proto_item_set_len(tlv_item, length + 2);
	     switch (type)
	       {
		case UCD_SYMBOL_RATE:
		  if (length == 1)
		    {
		       symrate = tvb_get_guint8 (tvb, pos);
		       proto_tree_add_uint (tlv_tree, hf_docsis_ucd_symbol_rate,
					    tvb, pos, length, symrate * 160);
		    }
		  else
		    {
		       THROW (ReportedBoundsError);
		    }
		  pos = pos + length;
		  break;
		case UCD_FREQUENCY:
		  if (length == 4)
		    {
		       proto_tree_add_item (tlv_tree, hf_docsis_ucd_frequency, tvb,
					    pos, length, ENC_BIG_ENDIAN);
		       pos = pos + length;
		    }
		  else
		    {
		       THROW (ReportedBoundsError);
		    }
		  break;
		case UCD_PREAMBLE:
		  proto_tree_add_item (tlv_tree, hf_docsis_ucd_preamble_pat, tvb,
				       pos, length, ENC_NA);
		  pos = pos + length;
		  break;
		case UCD_BURST_DESCR:
		  proto_tree_add_item (tlv_tree, hf_docsis_ucd_iuc, tvb,
				       pos++, 1, ENC_BIG_ENDIAN);
		  endtlvpos = pos + length - 1;
		  while (pos < endtlvpos)
		    {
		       tlvtype = tvb_get_guint8 (tvb, pos++);
		       tlvlen = tvb_get_guint8 (tvb, pos++);
		       switch (tlvtype)
			 {
			  case UCD_MODULATION:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_mod_type, tvb,
						      pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_DIFF_ENCODING:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_diff_encoding,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_PREAMBLE_LEN:
			    if (tlvlen == 2)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_preamble_len,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_PREAMBLE_VAL_OFF:
			    if (tlvlen == 2)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_preamble_val_off,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_FEC:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_fec, tvb, pos,
						      tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_FEC_CODEWORD:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_fec_codeword,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_SCRAMBLER_SEED:
			    if (tlvlen == 2)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_scrambler_seed,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_MAX_BURST:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_max_burst, tvb,
						      pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_GUARD_TIME:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_guard_time,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_LAST_CW_LEN:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_last_cw_len,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_SCRAMBLER_ONOFF:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_scrambler_onoff,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			 }		/* switch(tlvtype) */
		       pos = pos + tlvlen;
		    }		/* while (pos < endtlvpos) */
		  break;
		case UCD_BURST_DESCR5:
		  /* DOCSIS 2.0 Upstream Channel Descriptor */
		  proto_tree_add_item (tlv_tree, hf_docsis_ucd_iuc, tvb,
				       pos++, 1, ENC_BIG_ENDIAN);
		  endtlvpos = pos + length - 1;
		  while (pos < endtlvpos)
		    {
		       tlvtype = tvb_get_guint8 (tvb, pos++);
		       tlvlen = tvb_get_guint8 (tvb, pos++);
		       switch (tlvtype)
			 {
			  case UCD_MODULATION:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_mod_type, tvb,
						      pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_DIFF_ENCODING:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_diff_encoding,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_PREAMBLE_LEN:
			    if (tlvlen == 2)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_preamble_len,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_PREAMBLE_VAL_OFF:
			    if (tlvlen == 2)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_preamble_val_off,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_FEC:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_fec, tvb, pos,
						      tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_FEC_CODEWORD:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_fec_codeword,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_SCRAMBLER_SEED:
			    if (tlvlen == 2)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_scrambler_seed,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_MAX_BURST:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_max_burst, tvb,
						      pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_GUARD_TIME:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_guard_time,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_LAST_CW_LEN:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_last_cw_len,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_SCRAMBLER_ONOFF:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_scrambler_onoff,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			    /* New cases added for DOCSIS 2.0 US Physical Burst Descriptor TLV */
			    /* #define UCD_RS_INT_DEPTH 12
			     *  * #define UCD_RS_INT_BLOCK 13
			     *  * #define UCD_PREAMBLE_TYPE 14
			     *  * #define UCD_SCMDA_SCRAMBLER_ONOFF 15
			     *  * #define UCD_SCDMA_CODES_PER_SUBFRAME 16
			     *  * #define UCD_SCDMA_FRAMER_INT_STEP_SIZE 17
			     *  * #define UCD_TCM_ENABLED 18
			     *  */
			  case UCD_RS_INT_DEPTH:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_rs_int_depth,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_RS_INT_BLOCK:
			    if (tlvlen == 2)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_rs_int_block,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_PREAMBLE_TYPE:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_preamble_type,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_SCMDA_SCRAMBLER_ONOFF:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_scdma_scrambler_onoff,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_SCDMA_CODES_PER_SUBFRAME:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_scdma_codes_per_subframe,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_SCDMA_FRAMER_INT_STEP_SIZE:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_scdma_framer_int_step_size,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_TCM_ENABLED:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_tcm_enabled,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			 }           /* switch(tlvtype) */
		       pos = pos + tlvlen;
		    }               /* while (pos < endtlvpos) */
		  break;
	       }                   /* switch(type) */
	  }                       /* while (pos < len) */
     }                           /* if (tree) */
   
}
示例#10
0
static int
dissect_kt_remove_bulk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
    guint32 next32, rnum, ksiz;
    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 (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 */
        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;
    }

    return new_offset;
}
示例#11
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_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);
}
示例#12
0
static int
dissect_kt_play_script(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
    guint32 next32, rnum, ksiz, vsiz, nsiz;
    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) {
            /* There's more data after the 32 bits. This is a 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;

            nsiz = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(tree, hf_kt_nsiz, tvb, new_offset, 4, nsiz);
            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;

            proto_tree_add_item(tree, hf_kt_name, tvb, new_offset, nsiz, ENC_ASCII|ENC_NA);
            new_offset += nsiz;

            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;

                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;

                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--;
            }
        } else {
            /* Nothing remaining after the 32 bits. This is a response with 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_rnum, 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;

            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;

            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;
}
示例#13
0
static int
dissect_vlan_info(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree)
{
	proto_item *ti;
	proto_tree *vlan_info_tree;
	proto_tree *status_tree;
	guint8 vlan_info_len;
	int vlan_info_left;
	guint8 status;
	guint8 vlan_name_len;
	guint8 type;
	int length;
	proto_tree *tlv_tree;

	vlan_info_len = tvb_get_guint8(tvb, offset);
	ti = proto_tree_add_text(tree, tvb, offset, vlan_info_len,
	    "VLAN Information");
	vlan_info_tree = proto_item_add_subtree(ti, ett_vtp_vlan_info);
	vlan_info_left = vlan_info_len;

	proto_tree_add_uint(vlan_info_tree, hf_vtp_vlan_info_len, tvb, offset, 1,
	    vlan_info_len);
	offset += 1;
	vlan_info_left -= 1;

	status = tvb_get_guint8(tvb, offset);
	ti = proto_tree_add_text(vlan_info_tree, tvb, offset, 1,
	    "Status: 0x%02x%s", status,
	    (status & VLAN_SUSPENDED) ? "(VLAN suspended)" : "");
	status_tree = proto_item_add_subtree(ti, ett_vtp_vlan_status);
	proto_tree_add_boolean(status_tree, hf_vtp_vlan_status_vlan_susp, tvb, offset, 1,
	    status);
	offset += 1;
	vlan_info_left -= 1;

	proto_tree_add_item(vlan_info_tree, hf_vtp_vlan_type, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;
	vlan_info_left -= 1;

	vlan_name_len = tvb_get_guint8(tvb, offset);
	proto_tree_add_item(vlan_info_tree, hf_vtp_vlan_name_len, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;
	vlan_info_left -= 1;

	proto_tree_add_item(vlan_info_tree, hf_vtp_isl_vlan_id, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;
	vlan_info_left -= 2;

	proto_tree_add_item(vlan_info_tree, hf_vtp_mtu_size, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;
	vlan_info_left -= 2;

	proto_tree_add_item(vlan_info_tree, hf_vtp_802_10_index, tvb, offset, 4, ENC_BIG_ENDIAN);
	offset += 4;
	vlan_info_left -= 4;

	/* VLAN name length appears to be rounded up to a multiple of 4. */
	vlan_name_len = 4*((vlan_name_len + 3)/4);
	proto_tree_add_item(vlan_info_tree, hf_vtp_vlan_name, tvb, offset, vlan_name_len, ENC_ASCII|ENC_NA);
	offset += vlan_name_len;
	vlan_info_left -= vlan_name_len;

	while (vlan_info_left > 0) {
		type = tvb_get_guint8(tvb, offset + 0);
		length = tvb_get_guint8(tvb, offset + 1);

		ti = proto_tree_add_text(vlan_info_tree, tvb, offset,
		    2 + length*2, "%s",
		    val_to_str(type, vlan_tlv_type_vals,
		      "Unknown TLV type: 0x%02x"));
		tlv_tree = proto_item_add_subtree(ti, ett_vtp_tlv);
		proto_tree_add_item(tlv_tree, hf_vtp_vlan_tlvtype, tvb, offset, 1, ENC_BIG_ENDIAN);
		proto_tree_add_item(tlv_tree, hf_vtp_vlan_tlvlength, tvb, offset+1, 1, ENC_BIG_ENDIAN);
		offset += 2;
		vlan_info_left -= 2;
		if (length > 0) {
			dissect_vlan_info_tlv(tvb, pinfo, offset, length*2, tlv_tree,
			    ti, type);
		}
		offset += length*2;
		vlan_info_left -= length*2;
	}

	return vlan_info_len;
}
示例#14
0
static void
dissect_vtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_item *ti;
	proto_tree *vtp_tree = NULL, *vtp_pruning_tree = NULL;
	int offset = 0;
	guint8 code;
	guint8 *upd_timestamp;
	int vlan_info_len;
	int pruning_vlan_id;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "VTP");
	set_vtp_info_col(tvb, pinfo);

	ti = proto_tree_add_item(tree, proto_vtp, tvb, offset, -1, ENC_NA);
	vtp_tree = proto_item_add_subtree(ti, ett_vtp);

	proto_tree_add_item(vtp_tree, hf_vtp_version, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	code = tvb_get_guint8(tvb, offset);
	proto_tree_add_item(vtp_tree, hf_vtp_code, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	switch (code) {

	case SUMMARY_ADVERT:
		proto_tree_add_item(vtp_tree, hf_vtp_followers, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		proto_tree_add_item(vtp_tree, hf_vtp_md_len, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		proto_tree_add_item(vtp_tree, hf_vtp_md, tvb, offset, 32, ENC_ASCII|ENC_NA);
		offset += 32;

		proto_tree_add_item(vtp_tree, hf_vtp_conf_rev_num, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;

		proto_tree_add_item(vtp_tree, hf_vtp_upd_id, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;

		upd_timestamp = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, 12, ENC_ASCII);
		proto_tree_add_string_format_value(vtp_tree, hf_vtp_upd_ts, tvb,
			offset, 12, (gchar*)upd_timestamp,
			"%.2s-%.2s-%.2s %.2s:%.2s:%.2s",
			&upd_timestamp[0], &upd_timestamp[2], &upd_timestamp[4],
			&upd_timestamp[6], &upd_timestamp[8], &upd_timestamp[10]);
		offset += 12;

		proto_tree_add_item(vtp_tree, hf_vtp_md5_digest, tvb, offset, 16, ENC_NA);
		break;

	case SUBSET_ADVERT:
		proto_tree_add_item(vtp_tree, hf_vtp_seq_num, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		proto_tree_add_item(vtp_tree, hf_vtp_md_len, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		proto_tree_add_item(vtp_tree, hf_vtp_md, tvb, offset, 32, ENC_ASCII|ENC_NA);
		offset += 32;

		proto_tree_add_item(vtp_tree, hf_vtp_conf_rev_num, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;

		while (tvb_reported_length_remaining(tvb, offset) > 0) {
			vlan_info_len =
				dissect_vlan_info(tvb, pinfo, offset, vtp_tree);
			if (vlan_info_len <= 0)
				break;
			offset += vlan_info_len;
		}
		break;

	case ADVERT_REQUEST:
		offset += 1;	/* skip reserved field */

		proto_tree_add_item(vtp_tree, hf_vtp_md_len, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		proto_tree_add_item(vtp_tree, hf_vtp_md, tvb, offset, 32, ENC_ASCII|ENC_NA);
		offset += 32;

		proto_tree_add_item(vtp_tree, hf_vtp_start_value, tvb, offset, 2, ENC_BIG_ENDIAN);
		break;

	case JOIN_MSG:
		offset += 1;	/* skip reserved/unused field */

		proto_tree_add_item(vtp_tree, hf_vtp_md_len, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		proto_tree_add_item(vtp_tree, hf_vtp_md, tvb, offset, 32, ENC_ASCII|ENC_NA);
		offset += 32;

		proto_tree_add_item(vtp_tree, hf_vtp_pruning_first_vid, tvb, offset, 2, ENC_BIG_ENDIAN);
		pruning_vlan_id = tvb_get_ntohs(tvb, offset);
		offset += 2;

		proto_tree_add_item(vtp_tree, hf_vtp_pruning_last_vid, tvb, offset,
			2, ENC_BIG_ENDIAN);
		offset += 2;

		ti = proto_tree_add_text (vtp_tree, tvb, offset, -1,
			"Advertised active (i.e. not pruned) VLANs");
		vtp_pruning_tree = proto_item_add_subtree(ti, ett_vtp_pruning);

		while (tvb_reported_length_remaining(tvb, offset) > 0) {
			guint8 vlan_usage_bitmap;
			int shift;

			vlan_usage_bitmap = tvb_get_guint8(tvb, offset);

			for (shift = 0; shift < 8; shift++) {
				if (vlan_usage_bitmap & (1<<7)) {
					proto_tree_add_uint(vtp_pruning_tree, hf_vtp_pruning_active_vid,
					tvb, offset, 1, pruning_vlan_id);
				}

				pruning_vlan_id += 1;
				vlan_usage_bitmap <<= 1;
			}

			offset += 1;
		}

		break;
	}
}
示例#15
0
/* Code to actually dissect the packets */
static void
dissect_mip( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  /* Set up structures we will need to add the protocol subtree and manage it */
  proto_item    *ti;
  proto_tree    *mip_tree=NULL;
  proto_item    *tf;
  proto_tree    *flags_tree;
  guint8         type;
  guint16        flags;
  gint           offset=0;
  tvbuff_t      *next_tvb;

  /* Make entries in Protocol column and Info column on summary display */

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

  type = tvb_get_guint8(tvb, offset);
  switch (type) {
  case MIP_REGISTRATION_REQUEST:
    col_add_fstr(pinfo->cinfo, COL_INFO,
               "Reg Request: HoA=%s HA=%s CoA=%s",
               tvb_ip_to_str(tvb, 4),
               tvb_ip_to_str(tvb, 8),
               tvb_ip_to_str(tvb, 12));

    if (tree) {
      ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, ENC_NA);
      mip_tree = proto_item_add_subtree(ti, ett_mip);

      /* type */
      proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
      offset++;

      /* flags */
      flags = tvb_get_guint8(tvb, offset);
      tf = proto_tree_add_uint(mip_tree, hf_mip_flags, tvb, offset, 1, flags);
      flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
      proto_tree_add_boolean(flags_tree, hf_mip_s, tvb, offset, 1, flags);
      proto_tree_add_boolean(flags_tree, hf_mip_b, tvb, offset, 1, flags);
      proto_tree_add_boolean(flags_tree, hf_mip_d, tvb, offset, 1, flags);
      proto_tree_add_boolean(flags_tree, hf_mip_m, tvb, offset, 1, flags);
      proto_tree_add_boolean(flags_tree, hf_mip_g, tvb, offset, 1, flags);
      proto_tree_add_boolean(flags_tree, hf_mip_v, tvb, offset, 1, flags);
      proto_tree_add_boolean(flags_tree, hf_mip_t, tvb, offset, 1, flags);
      proto_tree_add_boolean(flags_tree, hf_mip_x, tvb, offset, 1, flags);
      offset++;

      /* lifetime */
      proto_tree_add_item(mip_tree, hf_mip_life, tvb, offset, 2, ENC_BIG_ENDIAN);
      offset += 2;

      /* home address */
      proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* home agent address */
      proto_tree_add_item(mip_tree, hf_mip_haaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* Care of Address */
      proto_tree_add_item(mip_tree, hf_mip_coa, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* Identifier - assumed to be an NTP time here */
      proto_tree_add_item(mip_tree, hf_mip_ident, tvb, offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
      offset += 8;

    } /* if tree */
    break;
  case MIP_REGISTRATION_REPLY:
    col_add_fstr(pinfo->cinfo, COL_INFO,
               "Reg Reply: HoA=%s HA=%s, Code=%u",
               tvb_ip_to_str(tvb, 4),
               tvb_ip_to_str(tvb, 8),
               tvb_get_guint8(tvb,1));

    if (tree) {
      /* Add Subtree */
      ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, ENC_NA);
      mip_tree = proto_item_add_subtree(ti, ett_mip);

      /* Type */
      proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
      offset++;

      /* Reply Code */
      proto_tree_add_item(mip_tree, hf_mip_code, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset++;

      /* Registration Lifetime */
      proto_tree_add_item(mip_tree, hf_mip_life, tvb, offset, 2, ENC_BIG_ENDIAN);
      offset += 2;

      /* Home address */
      proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* Home Agent Address */
      proto_tree_add_item(mip_tree, hf_mip_haaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* Identifier - assumed to be an NTP time here */
      proto_tree_add_item(mip_tree, hf_mip_ident, tvb, offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
      offset += 8;
    } /* if tree */
    break;
  case MIP_NATT_TUNNEL_DATA:
    col_add_fstr(pinfo->cinfo, COL_INFO, "Tunnel Data: Next Header=%u",
               tvb_get_guint8(tvb,1));

    if (tree) {
      /* Add Subtree */
      ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, ENC_NA);
      mip_tree = proto_item_add_subtree(ti, ett_mip);

      /* Type */
      proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
      offset++;

      /* Next Header */
      proto_tree_add_item(mip_tree, hf_mip_nattt_nexthdr, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset++;

      /* reserved */
      proto_tree_add_item(mip_tree, hf_mip_nattt_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
      offset += 2;
    } /* if tree */
    else {
      offset += 4;
    }
    /* encapsulated payload */
    next_tvb = tvb_new_subset_remaining(tvb, 4);
    call_dissector(ip_handle, next_tvb, pinfo, mip_tree);
    offset += tvb_reported_length_remaining(tvb, offset);
    break;
  case MIP_REGISTRATION_REVOCATION:
    col_add_fstr(pinfo->cinfo, COL_INFO,
               "Reg Revocation: HoA=%s HDA=%s FDA=%s",
               tvb_ip_to_str(tvb, 4),
               tvb_ip_to_str(tvb, 8),
               tvb_ip_to_str(tvb, 12));

    if (tree) {
      ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, ENC_NA);
      mip_tree = proto_item_add_subtree(ti, ett_mip);

      /* type */
      proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
      offset++;

      /* reserved */
      proto_tree_add_item(mip_tree, hf_mip_rev_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset++;

      /* flags */
      flags = tvb_get_ntohs(tvb, offset);
      tf = proto_tree_add_uint(mip_tree, hf_mip_flags, tvb, offset, 2, flags);
      flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
      proto_tree_add_boolean(flags_tree, hf_mip_rev_a, tvb, offset, 2, flags);
      proto_tree_add_boolean(flags_tree, hf_mip_rev_i, tvb, offset, 2, flags);

      /* reserved */
      proto_tree_add_uint(flags_tree, hf_mip_rev_reserved, tvb, offset, 2, flags);
      offset += 2;

      /* home address */
      proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* home domain address */
      proto_tree_add_item(mip_tree, hf_mip_hda, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* foreign domain address */
      proto_tree_add_item(mip_tree, hf_mip_fda, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* revocation identifier */
      proto_tree_add_item(mip_tree, hf_mip_revid, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;
    } /* if tree */
    break;
  case MIP_REGISTRATION_REVOCATION_ACK:
      col_add_fstr(pinfo->cinfo, COL_INFO, "Reg Revocation Ack: HoA=%s",
               tvb_ip_to_str(tvb, 4));

    if (tree) {
      ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, ENC_NA);
      mip_tree = proto_item_add_subtree(ti, ett_mip);

      /* type */
      proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
      offset++;

      /* reserved */
      proto_tree_add_item(mip_tree, hf_mip_ack_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset++;

      /* flags */
      flags = tvb_get_ntohs(tvb, offset);
      tf = proto_tree_add_uint(mip_tree, hf_mip_flags, tvb, offset, 2, flags);
      flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
      proto_tree_add_boolean(flags_tree, hf_mip_ack_i, tvb, offset, 2, flags);

      /* reserved */
      proto_tree_add_uint(flags_tree, hf_mip_ack_reserved, tvb, offset, 2, flags);
      offset += 2;

      /* home address */
      proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;

      /* revocation identifier */
      proto_tree_add_item(mip_tree, hf_mip_revid, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset += 4;
    } /* if tree */
    break;
  } /* End switch */

  if (tree) {
    if (tvb_reported_length_remaining(tvb, offset) > 0)
      dissect_mip_extensions(tvb, offset, mip_tree);
  }
} /* dissect_mip */
示例#16
0
static void
mate_gog_tree(proto_tree* tree, packet_info *pinfo, tvbuff_t *tvb, mate_gog* gog, mate_gop* gop)
{
	proto_item *gog_item;
	proto_tree *gog_tree;
	proto_tree *gog_time_tree;
	proto_item *gog_gops_item;
	proto_tree *gog_gops_tree;
	mate_gop* gog_gops;
	proto_item *gog_gop_item;
	proto_tree *gog_gop_tree;
	mate_pdu* pdu;

	gog_item = proto_tree_add_uint(tree,gog->cfg->hfid,tvb,0,0,gog->id);
	gog_tree = proto_item_add_subtree(gog_item,gog->cfg->ett);

	gog_attrs_tree(gog_tree,pinfo,tvb,gog);

	if (gog->cfg->show_times) {
		gog_time_tree = proto_tree_add_subtree_format(gog_tree,tvb,0,0,gog->cfg->ett_times,NULL,"%s Times",gog->cfg->name);

		proto_tree_add_float(gog_time_tree, gog->cfg->hfid_start_time, tvb, 0, 0, gog->start_time);
		proto_tree_add_float(gog_time_tree, gog->cfg->hfid_last_time, tvb, 0, 0, gog->last_time - gog->start_time);
	}

	gog_gops_item = proto_tree_add_uint(gog_tree, gog->cfg->hfid_gog_num_of_gops, tvb, 0, 0, gog->num_of_gops);

	gog_gops_tree = proto_item_add_subtree(gog_gops_item, gog->cfg->ett_children);

	for (gog_gops = gog->gops; gog_gops; gog_gops = gog_gops->next) {

		if (gop != gog_gops) {
			if (gog->cfg->gop_tree_mode == GOP_FULL_TREE) {
				mate_gop_tree(gog_gops_tree, pinfo, tvb, gog_gops);
			} else {
				gog_gop_item = proto_tree_add_uint(gog_gops_tree,gog_gops->cfg->hfid,tvb,0,0,gog_gops->id);

				if (gog->cfg->gop_tree_mode == GOP_BASIC_TREE) {
					gog_gop_tree = proto_item_add_subtree(gog_gop_item, gog->cfg->ett_gog_gop);

					proto_tree_add_float(gog_gop_tree, hf_mate_started_at, tvb,0,0,gog_gops->start_time);

					proto_tree_add_float_format(gog_gop_tree, hf_mate_duration, tvb,0,0, gog_gops->last_time - gog_gops->start_time,
								    "%s Duration: %f", gog_gops->cfg->name, gog_gops->last_time - gog_gops->start_time);

					if (gog_gops->released)
						proto_tree_add_float_format(gog_gop_tree, hf_mate_released_time, tvb,0,0, gog_gops->release_time - gog_gops->start_time,
									    "%s has been released, Time: %f", gog_gops->cfg->name, gog_gops->release_time - gog_gops->start_time);

					proto_tree_add_uint(gog_gop_tree, hf_mate_number_of_pdus, tvb,0,0, gog_gops->num_of_pdus);

					if (gop->pdus && gop->cfg->pdu_tree_mode != GOP_NO_TREE) {
						proto_tree_add_uint(gog_gop_tree,gog->cfg->hfid_gog_gopstart,tvb,0,0,gog_gops->pdus->frame);

						for (pdu = gog_gops->pdus->next ; pdu; pdu = pdu->next) {
							if (pdu->is_stop) {
								proto_tree_add_uint(gog_gop_tree,gog->cfg->hfid_gog_gopstop,tvb,0,0,pdu->frame);
								break;
							}
						}
					}
				}

			}
		} else {
			 proto_tree_add_uint_format(gog_gops_tree,gop->cfg->hfid,tvb,0,0,gop->id,"current %s Gop: %d",gop->cfg->name,gop->id);
		}
	}
}
static void ras_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, h225_packet_info *pi)
{
	proto_item *hidden_item;
	conversation_t* conversation = NULL;
	h225ras_call_info_key h225ras_call_key;
	h225ras_call_t *h225ras_call = NULL;
	nstime_t delta;
	guint msg_category;

	if(pi->msg_type == H225_RAS && pi->msg_tag < 21) {
		/* make RAS request/response matching only for tags from 0 to 20 for now */

		msg_category = pi->msg_tag / 3;
		if(pi->msg_tag % 3 == 0) {		/* Request Message */
			conversation = find_or_create_conversation(pinfo);

			/* prepare the key data */
			h225ras_call_key.reqSeqNum = pi->requestSeqNum;
			h225ras_call_key.conversation = conversation;

			/* look up the request */
			h225ras_call = find_h225ras_call(&h225ras_call_key ,msg_category);

			if (h225ras_call != NULL) {
				/* We've seen requests with this reqSeqNum, with the same
				   source and destination, before - do we have
				   *this* request already? */
				/* Walk through list of ras requests with identical keys */
				do {
					if (pinfo->fd->num == h225ras_call->req_num) {
						/* We have seen this request before -> do nothing */
						break;
					}

					/* if end of list is reached, exit loop and decide if request is duplicate or not. */
					if (h225ras_call->next_call == NULL) {
						if ( (pinfo->fd->num > h225ras_call->rsp_num && h225ras_call->rsp_num != 0
						   && pinfo->fd->abs_ts.secs > (h225ras_call->req_time.secs + THRESHOLD_REPEATED_RESPONDED_CALL) )
						   ||(pinfo->fd->num > h225ras_call->req_num && h225ras_call->rsp_num == 0
						   && pinfo->fd->abs_ts.secs > (h225ras_call->req_time.secs + THRESHOLD_REPEATED_NOT_RESPONDED_CALL) ) )
						{
							/* if last request has been responded
							   and this request appears after last response (has bigger frame number)
							   and last request occured more than 300 seconds ago,
							   or if last request hasn't been responded
							   and this request appears after last request (has bigger frame number)
							   and last request occured more than 1800 seconds ago,
							   we decide that we have a new request */
							/* Append new ras call to list */
							h225ras_call = append_h225ras_call(h225ras_call, pinfo, &pi->guid, msg_category);
						} else {
							/* No, so it's a duplicate request.
							   Mark it as such. */
							pi->is_duplicate = TRUE;
							hidden_item = proto_tree_add_uint(tree, hf_h225_ras_dup, tvb, 0,0, pi->requestSeqNum);
							PROTO_ITEM_SET_HIDDEN(hidden_item);
						}
						break;
					}
					h225ras_call = h225ras_call->next_call;
				} while (h225ras_call != NULL );
			}
			else {
				h225ras_call = new_h225ras_call(&h225ras_call_key, pinfo, &pi->guid, msg_category);
			}

			/* add link to response frame, if available */
			if(h225ras_call && h225ras_call->rsp_num != 0){
				proto_item *ti =
				proto_tree_add_uint_format(tree, hf_h225_ras_rsp_frame, tvb, 0, 0, h225ras_call->rsp_num,
					                           "The response to this request is in frame %u",
					                           h225ras_call->rsp_num);
				PROTO_ITEM_SET_GENERATED(ti);
			}

  		/* end of request message handling*/
		}
		else { 					/* Confirm or Reject Message */
			conversation = find_conversation(pinfo->fd->num, &pinfo->src,
    				&pinfo->dst, pinfo->ptype, pinfo->srcport,
  				pinfo->destport, 0);
  			if (conversation != NULL) {
				/* look only for matching request, if
				   matching conversation is available. */
				h225ras_call_key.reqSeqNum = pi->requestSeqNum;
				h225ras_call_key.conversation = conversation;
				h225ras_call = find_h225ras_call(&h225ras_call_key ,msg_category);
				if(h225ras_call) {
					/* find matching ras_call in list of ras calls with identical keys */
					do {
						if (pinfo->fd->num == h225ras_call->rsp_num) {
							/* We have seen this response before -> stop now with matching ras call */
							break;
						}

						/* Break when list end is reached */
						if(h225ras_call->next_call == NULL) {
							break;
						}
						h225ras_call = h225ras_call->next_call;
					} while (h225ras_call != NULL) ;

					if (!h225ras_call) {
						return;
					}

					/* if this is an ACF, ARJ or DCF, DRJ, give guid to tap and make it filterable */
					if (msg_category == 3 || msg_category == 5) {
						pi->guid = h225ras_call->guid;
						hidden_item = proto_tree_add_guid(tree, hf_h225_guid, tvb, 0, GUID_LEN, &pi->guid);
						PROTO_ITEM_SET_HIDDEN(hidden_item);
					}

					if (h225ras_call->rsp_num == 0) {
						/* We have not yet seen a response to that call, so
						   this must be the first response; remember its
						   frame number. */
						h225ras_call->rsp_num = pinfo->fd->num;
					}
					else {
						/* We have seen a response to this call - but was it
						   *this* response? */
						if (h225ras_call->rsp_num != pinfo->fd->num) {
							/* No, so it's a duplicate response.
							   Mark it as such. */
							pi->is_duplicate = TRUE;
							hidden_item = proto_tree_add_uint(tree, hf_h225_ras_dup, tvb, 0,0, pi->requestSeqNum);
							PROTO_ITEM_SET_HIDDEN(hidden_item);
						}
					}

					if(h225ras_call->req_num != 0){
						proto_item *ti;
						h225ras_call->responded = TRUE;
						pi->request_available = TRUE;

						/* Indicate the frame to which this is a reply. */
						ti = proto_tree_add_uint_format(tree, hf_h225_ras_req_frame, tvb, 0, 0, h225ras_call->req_num,
							"This is a response to a request in frame %u", h225ras_call->req_num);
						PROTO_ITEM_SET_GENERATED(ti);

						/* Calculate RAS Service Response Time */
						nstime_delta(&delta, &pinfo->fd->abs_ts, &h225ras_call->req_time);
						pi->delta_time = delta; /* give it to tap */

						/* display Ras Service Response Time and make it filterable */
						ti = proto_tree_add_time(tree, hf_h225_ras_deltatime, tvb, 0, 0, &(pi->delta_time));
						PROTO_ITEM_SET_GENERATED(ti);
					}
				}
			}
		}
	}
}
示例#18
0
static void
mate_gop_tree(proto_tree* tree, packet_info *pinfo, tvbuff_t *tvb, mate_gop* gop)
{
	proto_item *gop_item;
	proto_tree *gop_time_tree;
	proto_tree *gop_tree;
	proto_item *gop_pdu_item;
	proto_tree *gop_pdu_tree;
	mate_pdu* gop_pdus;
	float rel_time;
	float pdu_rel_time;
	const gchar* pdu_str;
	const gchar* type_str;
	guint32 pdu_item;

	gop_item = proto_tree_add_uint(tree,gop->cfg->hfid,tvb,0,0,gop->id);
	gop_tree = proto_item_add_subtree(gop_item, gop->cfg->ett);

	if (gop->gop_key) proto_tree_add_string(gop_tree,hf_mate_gop_key,tvb,0,0,gop->gop_key);

	gop_attrs_tree(gop_tree,pinfo,tvb,gop);

	if (gop->cfg->show_times) {
		gop_time_tree = proto_tree_add_subtree_format(gop_tree,tvb,0,0,gop->cfg->ett_times,NULL,"%s Times",gop->cfg->name);

		proto_tree_add_float(gop_time_tree, gop->cfg->hfid_start_time, tvb, 0, 0, gop->start_time);

		if (gop->released) {
			proto_tree_add_float(gop_time_tree, gop->cfg->hfid_stop_time, tvb, 0, 0, gop->release_time - gop->start_time);
			proto_tree_add_float(gop_time_tree, gop->cfg->hfid_last_time, tvb, 0, 0, gop->last_time - gop->start_time);
		} else {
			proto_tree_add_float(gop_time_tree, gop->cfg->hfid_last_time, tvb, 0, 0, gop->last_time - gop->start_time);
		}
	}

	gop_pdu_item = proto_tree_add_uint(gop_tree, gop->cfg->hfid_gop_num_pdus, tvb, 0, 0,gop->num_of_pdus);

	if (gop->cfg->pdu_tree_mode != GOP_NO_TREE) {

		gop_pdu_tree = proto_item_add_subtree(gop_pdu_item, gop->cfg->ett_children);

		rel_time = gop->start_time;

		type_str = (gop->cfg->pdu_tree_mode == GOP_FRAME_TREE ) ? "in frame:" : "id:";

		for (gop_pdus = gop->pdus; gop_pdus; gop_pdus = gop_pdus->next) {

			pdu_item = (gop->cfg->pdu_tree_mode == GOP_FRAME_TREE ) ? gop_pdus->frame : gop_pdus->id;

			if (gop_pdus->is_start) {
				pdu_str = "Start ";
			} else if (gop_pdus->is_stop) {
				pdu_str = "Stop ";
			} else if (gop_pdus->after_release) {
				pdu_str = "After stop ";
			} else {
				pdu_str = "";
			}

			pdu_rel_time = gop_pdus->time_in_gop != 0.0 ? gop_pdus->time_in_gop - rel_time : (float) 0.0;

			proto_tree_add_uint_format(gop_pdu_tree,gop->cfg->hfid_gop_pdu,tvb,0,0,pdu_item,
						   "%sPDU: %s %i (%f : %f)",pdu_str, type_str,
						   pdu_item, gop_pdus->time_in_gop,
						   pdu_rel_time);

			rel_time = gop_pdus->time_in_gop;

		}
	}
}
示例#19
0
/* -----------------------------
	from netatalk/etc/afpd/status.c
*/
static gint
dissect_dsi_reply_get_status(tvbuff_t *tvb, proto_tree *tree, gint offset)
{
	proto_tree      *sub_tree;
	proto_item	*ti;

	guint16 ofs;
	guint16 flag;
	guint16 sign_ofs = 0;
	guint16 adr_ofs = 0;
	guint16 dir_ofs = 0;
	guint16 utf_ofs = 0;
	guint8	nbe;
	guint8  len;
	guint8  i;

	if (!tree)
		return offset;

	ti = proto_tree_add_text(tree, tvb, offset, -1, "Get Status");
	tree = proto_item_add_subtree(ti, ett_dsi_status);

	ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_MACHOFF);
	proto_tree_add_text(tree, tvb, offset +AFPSTATUS_MACHOFF, 2, "Machine offset: %d", ofs);

	ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
	proto_tree_add_text(tree, tvb, offset +AFPSTATUS_VERSOFF, 2, "Version offset: %d", ofs);

	ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
	proto_tree_add_text(tree, tvb, offset +AFPSTATUS_UAMSOFF, 2, "UAMS offset: %d", ofs);

	ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
	proto_tree_add_text(tree, tvb, offset +AFPSTATUS_ICONOFF, 2, "Icon offset: %d", ofs);

	ofs = offset +AFPSTATUS_FLAGOFF;
	ti = proto_tree_add_item(tree, hf_dsi_server_flag, tvb, ofs, 2, ENC_BIG_ENDIAN);
	sub_tree = proto_item_add_subtree(ti, ett_dsi_status_server_flag);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_copyfile      , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_passwd        , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_no_save_passwd, tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_srv_msg       , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_srv_sig       , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_tcpip         , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_notify        , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_reconnect     , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_directory     , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_utf8_name     , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_uuid          , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_ext_sleep     , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_fast_copy     , tvb, ofs, 2, ENC_BIG_ENDIAN);

	proto_tree_add_item(tree, hf_dsi_server_name, tvb, offset +AFPSTATUS_PRELEN, 1, ENC_ASCII|ENC_NA);

	flag = tvb_get_ntohs(tvb, ofs);
	if ((flag & AFPSRVRINFO_SRVSIGNATURE)) {
		ofs = offset +AFPSTATUS_PRELEN +tvb_get_guint8(tvb, offset +AFPSTATUS_PRELEN) +1;
		if ((ofs & 1))
			ofs++;

		sign_ofs = tvb_get_ntohs(tvb, ofs);
		proto_tree_add_text(tree, tvb, ofs, 2, "Signature offset: %d", sign_ofs);
		sign_ofs += offset;

		if ((flag & AFPSRVRINFO_TCPIP)) {
			ofs += 2;
			adr_ofs =  tvb_get_ntohs(tvb, ofs);
			proto_tree_add_text(tree, tvb, ofs, 2, "Network address offset: %d", adr_ofs);
			adr_ofs += offset;
		}

		if ((flag & AFPSRVRINFO_SRVDIRECTORY)) {
			ofs += 2;
			dir_ofs =  tvb_get_ntohs(tvb, ofs);
			proto_tree_add_text(tree, tvb, ofs, 2, "Directory services offset: %d", dir_ofs);
			dir_ofs += offset;
		}
		if ((flag & AFPSRVRINFO_SRVUTF8)) {
			ofs += 2;
			utf_ofs =  tvb_get_ntohs(tvb, ofs);
			proto_tree_add_text(tree, tvb, ofs, 2, "UTF8 server name offset: %d", utf_ofs);
			utf_ofs += offset;
		}
	}

	ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_MACHOFF);
	if (ofs)
		proto_tree_add_item(tree, hf_dsi_server_type, tvb, ofs, 1, ENC_ASCII|ENC_NA);

	ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
	if (ofs) {
		nbe = tvb_get_guint8(tvb, ofs);
		ti = proto_tree_add_text(tree, tvb, ofs, 1, "Version list: %d", nbe);
		ofs++;
		sub_tree = proto_item_add_subtree(ti, ett_dsi_vers);
		for (i = 0; i < nbe; i++) {
			len = tvb_get_guint8(tvb, ofs);
			proto_tree_add_item(sub_tree, hf_dsi_server_vers, tvb, ofs, 1, ENC_ASCII|ENC_NA);
			ofs += len + 1;
		}
	}

	ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
	if (ofs) {
		nbe = tvb_get_guint8(tvb, ofs);
		ti = proto_tree_add_text(tree, tvb, ofs, 1, "UAMS list: %d", nbe);
		ofs++;
		sub_tree = proto_item_add_subtree(ti, ett_dsi_uams);
		for (i = 0; i < nbe; i++) {
			len = tvb_get_guint8(tvb, ofs);
			proto_tree_add_item(sub_tree, hf_dsi_server_uams, tvb, ofs, 1, ENC_ASCII|ENC_NA);
			ofs += len + 1;
		}
	}

	ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
	if (ofs)
		proto_tree_add_item(tree, hf_dsi_server_icon, tvb, ofs, 256, ENC_NA);

	if (sign_ofs) {
		proto_tree_add_item(tree, hf_dsi_server_signature, tvb, sign_ofs, 16, ENC_NA);
	}

	if (adr_ofs) {
		proto_tree *adr_tree;
		unsigned char *tmp;
		guint16 net;
		guint8  node;
		guint16 port;

		ofs = adr_ofs;
		nbe = tvb_get_guint8(tvb, ofs);
		ti = proto_tree_add_text(tree, tvb, ofs, 1, "Address list: %d", nbe);
		ofs++;
		adr_tree = proto_item_add_subtree(ti, ett_dsi_addr);
		for (i = 0; i < nbe; i++) {
			guint8 type;

			len = tvb_get_guint8(tvb, ofs);
			type =  tvb_get_guint8(tvb, ofs +1);
			switch (type) {
			case 1:	/* IP */
				ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip: %s", tvb_ip_to_str(tvb, ofs+2));
				break;
			case 2: /* IP + port */
				port = tvb_get_ntohs(tvb, ofs+6);
				ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s:%d", tvb_ip_to_str(tvb, ofs+2), port);
				break;
			case 3: /* DDP, atalk_addr_to_str want host order not network */
				net  = tvb_get_ntohs(tvb, ofs+2);
				node = tvb_get_guint8(tvb, ofs +4);
				port = tvb_get_guint8(tvb, ofs +5);
				ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ddp: %u.%u:%u",
					net, node, port);
				break;
			case 4: /* DNS */
			case 5: /* SSH tunnel */
				if (len > 2) {
					tmp = tvb_get_string(wmem_packet_scope(), tvb, ofs +2, len -2);
					ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "%s: %s",
								(type==4)?"dns":"ssh tunnel", tmp);
					break;
				}
				else {
					ti = proto_tree_add_text(adr_tree, tvb, ofs, len,"Malformed address type %d", type);
				}
				break;
			case 6: /* IP6 */
				ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip6: %s",
				                tvb_ip6_to_str(tvb, ofs+2));
				break;
			case 7: /* IP6 + 2bytes port */
				port = tvb_get_ntohs(tvb, ofs+ 2+INET6_ADDRLEN);
				ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip6 %s:%d",
						tvb_ip6_to_str(tvb, ofs+2), port);
				break;
			default:
				ti = proto_tree_add_text(adr_tree, tvb, ofs, len,"Unknown type : %d", type);
				break;
			}
			len -= 2;
			sub_tree = proto_item_add_subtree(ti,ett_dsi_addr_line);
			proto_tree_add_item(sub_tree, hf_dsi_server_addr_len, tvb, ofs, 1, ENC_BIG_ENDIAN);
			ofs++;
			proto_tree_add_item(sub_tree, hf_dsi_server_addr_type, tvb, ofs, 1, ENC_BIG_ENDIAN);
			ofs++;
			proto_tree_add_item(sub_tree, hf_dsi_server_addr_value,tvb, ofs, len, ENC_NA);
			ofs += len;
		}
	}

	if (dir_ofs) {
		ofs = dir_ofs;
		nbe = tvb_get_guint8(tvb, ofs);
		ti = proto_tree_add_text(tree, tvb, ofs, 1, "Directory services list: %d", nbe);
		ofs++;
		sub_tree = proto_item_add_subtree(ti, ett_dsi_directory);
		for (i = 0; i < nbe; i++) {
			len = tvb_get_guint8(tvb, ofs);
			proto_tree_add_item(sub_tree, hf_dsi_server_directory, tvb, ofs, 1, ENC_ASCII|ENC_NA);
			ofs += len + 1;
		}
	}
	if (utf_ofs) {
		guint16 ulen;
		char *tmp;

		ofs = utf_ofs;
		ulen = tvb_get_ntohs(tvb, ofs);
		tmp = tvb_get_string(wmem_packet_scope(), tvb, ofs + 2, ulen);
		ti = proto_tree_add_text(tree, tvb, ofs, ulen + 2, "UTF8 server name: %s", tmp);
		sub_tree = proto_item_add_subtree(ti, ett_dsi_utf8_name);
		proto_tree_add_uint(sub_tree, hf_dsi_utf8_server_name_len, tvb, ofs, 2, ulen);
		ofs += 2;
		proto_tree_add_string(sub_tree, hf_dsi_utf8_server_name, tvb, ofs, ulen, tmp);
		ofs += ulen;
	}

	return ofs;
}
示例#20
0
static void
dissect_mtp3_routing_label(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mtp3_tree,
    mtp3_addr_pc_t *mtp3_addr_opc, mtp3_addr_pc_t *mtp3_addr_dpc)
{
  guint32 label, dpc, opc;
  proto_item *label_item, *label_dpc_item, *label_opc_item;
  proto_item *hidden_item;
  proto_tree *label_tree;
  proto_tree *pc_subtree;
  int hf_dpc_string;
  int hf_opc_string;


  switch (mtp3_standard) {
  case ITU_STANDARD:
    label_item = proto_tree_add_text(mtp3_tree, tvb, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, "Routing label");
    label_tree = proto_item_add_subtree(label_item, ett_mtp3_label);

    label = tvb_get_letohl(tvb, ROUTING_LABEL_OFFSET);

    opc = (label & ITU_OPC_MASK) >> 14;
    dpc =  label & ITU_DPC_MASK;

    hidden_item = proto_tree_add_uint(label_tree, hf_mtp3_itu_pc, tvb, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, opc);
    PROTO_ITEM_SET_HIDDEN(hidden_item);
    hidden_item = proto_tree_add_uint(label_tree, hf_mtp3_itu_pc, tvb, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, dpc);
    PROTO_ITEM_SET_HIDDEN(hidden_item);

    label_dpc_item = proto_tree_add_uint(label_tree, hf_mtp3_itu_dpc, tvb, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, label);
    if (mtp3_pc_structured())
      proto_item_append_text(label_dpc_item, " (%s)", mtp3_pc_to_str(dpc));

    if(mtp3_addr_dpc->ni == MTP3_NI_INT0) {
      pc_subtree = proto_item_add_subtree(label_dpc_item, ett_mtp3_label_dpc);
      analyze_q708_ispc(tvb, pc_subtree, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, dpc);
    }


    label_opc_item = proto_tree_add_uint(label_tree, hf_mtp3_itu_opc, tvb, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, label);
    if (mtp3_pc_structured())
      proto_item_append_text(label_opc_item, " (%s)", mtp3_pc_to_str(opc));

    if(mtp3_addr_opc->ni == MTP3_NI_INT0) {
      pc_subtree = proto_item_add_subtree(label_opc_item, ett_mtp3_label_opc);
      analyze_q708_ispc(tvb, pc_subtree, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, opc);
    }

    proto_tree_add_uint(label_tree, hf_mtp3_itu_sls, tvb, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, label);
    break;

  case ANSI_STANDARD:
  case CHINESE_ITU_STANDARD:
    if (mtp3_standard == ANSI_STANDARD)
    {
      hf_dpc_string = hf_mtp3_ansi_dpc;
      hf_opc_string = hf_mtp3_ansi_opc;
    } else /* CHINESE_ITU_STANDARD */ {
      hf_dpc_string = hf_mtp3_chinese_dpc;
      hf_opc_string = hf_mtp3_chinese_opc;
    }

    /* Create the Routing Label Tree */
    label_item = proto_tree_add_text(mtp3_tree, tvb, ROUTING_LABEL_OFFSET, ANSI_ROUTING_LABEL_LENGTH, "Routing label");
    label_tree = proto_item_add_subtree(label_item, ett_mtp3_label);


    /* create and fill the DPC tree */
    dissect_mtp3_3byte_pc(tvb, ANSI_DPC_OFFSET, label_tree, ett_mtp3_label_dpc, hf_dpc_string, hf_mtp3_dpc_network,
			  hf_mtp3_dpc_cluster, hf_mtp3_dpc_member, hf_mtp3_24bit_dpc, hf_mtp3_24bit_pc);
    /* Store dpc for mtp3_addr below */
    dpc = tvb_get_letoh24(tvb, ANSI_DPC_OFFSET);

    /* create and fill the OPC tree */
    dissect_mtp3_3byte_pc(tvb, ANSI_OPC_OFFSET, label_tree, ett_mtp3_label_opc, hf_opc_string, hf_mtp3_opc_network,
			  hf_mtp3_opc_cluster, hf_mtp3_opc_member, hf_mtp3_24bit_opc, hf_mtp3_24bit_pc);
    /* Store opc for mtp3_addr below */
    opc = tvb_get_letoh24(tvb, ANSI_OPC_OFFSET);

    /* SLS */
    if (mtp3_standard == ANSI_STANDARD) {
      if (mtp3_use_ansi_5_bit_sls)
	proto_tree_add_item(label_tree, hf_mtp3_ansi_5_bit_sls, tvb, ANSI_SLS_OFFSET, SLS_LENGTH, ENC_NA);
      else
	proto_tree_add_item(label_tree, hf_mtp3_ansi_8_bit_sls, tvb, ANSI_SLS_OFFSET, SLS_LENGTH, ENC_NA);
    } else /* CHINESE_ITU_STANDARD */ {
      proto_tree_add_item(label_tree, hf_mtp3_chinese_itu_sls, tvb, ANSI_SLS_OFFSET, SLS_LENGTH, ENC_NA);
    }
    break;

  case JAPAN_STANDARD:
    label_item = proto_tree_add_text(mtp3_tree, tvb, ROUTING_LABEL_OFFSET, JAPAN_ROUTING_LABEL_LENGTH, "Routing label");
    label_tree = proto_item_add_subtree(label_item, ett_mtp3_label);

    label_dpc_item = proto_tree_add_item(label_tree, hf_mtp3_japan_dpc, tvb, ROUTING_LABEL_OFFSET, JAPAN_PC_LENGTH, ENC_LITTLE_ENDIAN);
    dpc = tvb_get_letohs(tvb, ROUTING_LABEL_OFFSET);
    if (mtp3_pc_structured()) {
      proto_item_append_text(label_dpc_item, " (%s)", mtp3_pc_to_str(dpc));
    }

    label_opc_item = proto_tree_add_item(label_tree, hf_mtp3_japan_opc, tvb, JAPAN_OPC_OFFSET, JAPAN_PC_LENGTH, ENC_LITTLE_ENDIAN);
    opc = tvb_get_letohs(tvb, JAPAN_OPC_OFFSET);
    if (mtp3_pc_structured()) {
      proto_item_append_text(label_opc_item, " (%s)", mtp3_pc_to_str(opc));
    }

    hidden_item = proto_tree_add_item(label_tree, hf_mtp3_japan_pc, tvb, ROUTING_LABEL_OFFSET, JAPAN_PC_LENGTH, ENC_LITTLE_ENDIAN);
    PROTO_ITEM_SET_HIDDEN(hidden_item);
    hidden_item = proto_tree_add_item(label_tree, hf_mtp3_japan_pc, tvb, JAPAN_OPC_OFFSET, JAPAN_PC_LENGTH, ENC_LITTLE_ENDIAN);
    PROTO_ITEM_SET_HIDDEN(hidden_item);

    if (mtp3_use_japan_5_bit_sls) {
	proto_tree_add_item(label_tree, hf_mtp3_japan_5_bit_sls, tvb, JAPAN_SLS_OFFSET, JAPAN_SLS_SPARE_LENGTH, ENC_NA);
	proto_tree_add_item(label_tree, hf_mtp3_japan_5_bit_sls_spare, tvb, JAPAN_SLS_OFFSET, JAPAN_SLS_SPARE_LENGTH, ENC_NA);
    } else {
	proto_tree_add_item(label_tree, hf_mtp3_japan_4_bit_sls, tvb, JAPAN_SLS_OFFSET, JAPAN_SLS_SPARE_LENGTH, ENC_NA);
	proto_tree_add_item(label_tree, hf_mtp3_japan_4_bit_sls_spare, tvb, JAPAN_SLS_OFFSET, JAPAN_SLS_SPARE_LENGTH, ENC_NA);
    }

    break;
  default:
    DISSECTOR_ASSERT_NOT_REACHED();
  }

  mtp3_addr_opc->type = (Standard_Type)mtp3_standard;
  mtp3_addr_opc->pc = opc;
  SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc);

  mtp3_addr_dpc->type = (Standard_Type)mtp3_standard;
  mtp3_addr_dpc->pc = dpc;
  SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc);
}
示例#21
0
/* dissect the "control" suboption */
static int
dissect_PNDCP_Suboption_Control(tvbuff_t *tvb, int offset, packet_info *pinfo, 
                                proto_tree *tree, proto_item *block_item, proto_item *dcp_item, 
                                guint8 service_id _U_, gboolean is_response _U_)
{
    guint8 suboption;
    guint16 block_length;
    guint16 block_qualifier;
    gchar *info_str;
    guint8 block_error;
    proto_item *item = NULL;


    offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_control, &suboption);
    offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_length, &block_length);

    switch(suboption) {
    case(PNDCP_SUBOPTION_CONTROL_START_TRANS):
        pn_append_info(pinfo, dcp_item, ", Start-Trans");
        proto_item_append_text(block_item, "Control/Start-Transaction");
        offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
        break;
    case(PNDCP_SUBOPTION_CONTROL_END_TRANS):
        pn_append_info(pinfo, dcp_item, ", End-Trans");
        proto_item_append_text(block_item, "Control/End-Transaction");
        offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
        break;
    case(PNDCP_SUBOPTION_CONTROL_SIGNAL):
        pn_append_info(pinfo, dcp_item, ", Signal");
        proto_item_append_text(block_item, "Control/Signal");
        offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
        block_length -= 2;

        offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, block_length); 
        break;
    case(PNDCP_SUBOPTION_CONTROL_RESPONSE):
        proto_item_append_text(block_item, "Control/Response");
        offset = dissect_PNDCP_Option(tvb, offset, pinfo, tree, block_item, hf_pn_dcp_suboption_control_response, 
            FALSE /* append_col */);
        block_error = tvb_get_guint8 (tvb, offset);
        if (tree) {
            item = proto_tree_add_uint(tree, hf_pn_dcp_block_error, tvb, offset, 1, block_error);
        }
        offset += 1;
        if(block_error != 0) {
            expert_add_info_format(pinfo, item, PI_RESPONSE_CODE, PI_CHAT,
                "%s", val_to_str(block_error, pn_dcp_block_error, "Unknown"));
        }
        info_str = ep_strdup_printf(", Response(%s)", val_to_str(block_error, pn_dcp_block_error, "Unknown"));
        pn_append_info(pinfo, dcp_item, info_str);
        proto_item_append_text(block_item, ", BlockError: %s", val_to_str(block_error, pn_dcp_block_error, "Unknown"));

        break;
    case(PNDCP_SUBOPTION_CONTROL_FACT_RESET):
        pn_append_info(pinfo, dcp_item, ", Reset FactorySettings");
        proto_item_append_text(block_item, "Control/Reset FactorySettings");
        offset       += 2;
        block_length -= 2;
        break;
    default:
        offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, block_length); 
    }

    return offset;
}
/* Code to actually dissect the packets */
static void
dissect_canopen(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item *ti, *cob_ti, *type_ti;
    proto_tree *canopen_tree = NULL;
    proto_tree *canopen_cob_tree = NULL;
    proto_tree *canopen_type_tree = NULL;
    guint function_code = -1;
    guint node_id = -1;
    guint32 id = -1;
    guint32 time_stamp_msec = -1;
    guint32 time_stamp_days = -1;
    guint msg_type_id = -1;
    nstime_t time_stamp;
    guint8 can_data_len;

    can_data_len = tvb_get_guint8(tvb, 4);
    id = tvb_get_ntohl(tvb, 0);

    node_id = (guint)(id & 0x7F);
    function_code = (guint)((id >> 7) & 0xF);

    if (tvb_length(tvb) < 1)
        return;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "CANopen");
    col_clear(pinfo->cinfo, COL_INFO);
    canopen_detect_msg_type(function_code, node_id, &msg_type_id);
	if(node_id == 0 ){
		/* brodcast */
		col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(function_code, CAN_open_bcast_msg_type_vals, "Unknown (%u)"));
	}else{
		/*pet-to-per */
		col_add_fstr(pinfo->cinfo, COL_INFO, "p2p %s", val_to_str(function_code, CAN_open_p2p_msg_type_vals, "Unknown (%u)"));
	}
    col_append_fstr(pinfo->cinfo, COL_INFO, "   %s", tvb_bytes_to_str_punct(tvb, CO_PDO_DATA_OFFSET, can_data_len, ' '));

    if (tree) {

        ti = proto_tree_add_item(tree, proto_canopen, tvb, 0, 1, ENC_NA);

        canopen_tree = proto_item_add_subtree(ti, ett_canopen);

        /* add COB-ID with function code and node id */
        cob_ti = proto_tree_add_item(canopen_tree, hf_canopen_cob_id, tvb, 0, 4, ENC_BIG_ENDIAN);
        canopen_cob_tree = proto_item_add_subtree(cob_ti, ett_canopen);

        /* add function code */
        proto_tree_add_item(canopen_cob_tree, hf_canopen_function_code, tvb, 0, 4, ENC_BIG_ENDIAN);

        /* add node id */
        proto_tree_add_item(canopen_cob_tree, hf_canopen_node_id, tvb, 0, 4, ENC_BIG_ENDIAN);

        /* add CANopen frame type */
		if(node_id == 0 ){
			/* brodcast */
			type_ti = proto_tree_add_string(canopen_tree, hf_canopen_type, tvb, 0, 4, val_to_str(function_code, CAN_open_bcast_msg_type_vals, "Unknown (%u)"));
		}else{
			/*pet-to-per */
			type_ti = proto_tree_add_string(canopen_tree, hf_canopen_type, tvb, 0, 4, val_to_str(function_code, CAN_open_p2p_msg_type_vals, "Unknown (%u)"));
		}
        canopen_type_tree = proto_item_add_subtree(type_ti, ett_canopen);

        switch(msg_type_id)
        {
        case MT_NMT_CTRL:
            proto_tree_add_item(canopen_type_tree,
                hf_canopen_nmt_ctrl_cs, tvb, CO_NMT_CTRL_CS_OFFSET, 1, ENC_BIG_ENDIAN);

            proto_tree_add_item(canopen_type_tree,
                hf_canopen_nmt_ctrl_node_id, tvb, CO_NMT_CTRL_NODE_ID_OFFSET, 1, ENC_BIG_ENDIAN);
            break;
        case MT_NMT_GUARD:
            proto_tree_add_item(canopen_type_tree,
                hf_canopen_nmt_guard_state, tvb, CO_NMT_GUARD_STATE_OFFSET, 1, ENC_BIG_ENDIAN);
            break;
        case MT_SYNC:
            break;
        case MT_TIME_STAMP:
            /* calculate the real time stamp */
            time_stamp_msec = tvb_get_letohl(tvb, CO_PDO_DATA_OFFSET);
            time_stamp_days = tvb_get_ntohs(tvb, CO_PDO_DATA_OFFSET + 4);
            time_stamp.secs = (time_stamp_days + TS_DAYS_BETWEEN_1970_AND_1984)
                * TS_SECONDS_IN_PER_DAY + (time_stamp_msec / 1000);
            time_stamp.nsecs = (time_stamp_msec % 1000) * TS_NANOSEC_PER_MSEC;

            proto_tree_add_time(canopen_type_tree,
                hf_canopen_time_stamp, tvb, CO_TIME_STAMP_MS_OFFSET, 6, &time_stamp);

            proto_tree_add_uint(canopen_type_tree,
                hf_canopen_time_stamp_ms, tvb, CO_TIME_STAMP_MS_OFFSET, 4, time_stamp_msec);

            proto_tree_add_uint(canopen_type_tree,
                hf_canopen_time_stamp_days, tvb, CO_TIME_STAMP_DAYS_OFFSET, 2, time_stamp_days);

            break;
        case MT_EMERGENCY:
            proto_tree_add_item(canopen_type_tree,
                hf_canopen_em_err_code, tvb, CO_EM_ERR_CODE_OFFSET, 2, ENC_BIG_ENDIAN);

            proto_tree_add_item(canopen_type_tree,
                hf_canopen_em_err_reg, tvb, CO_EM_ERR_REG_OFFSET, 1, ENC_BIG_ENDIAN);

            proto_tree_add_item(canopen_type_tree,
                hf_canopen_em_err_field, tvb, CO_EM_ERR_FIELD_OFFSET, 4, ENC_NA);
            break;
        case MT_PDO:
            if(can_data_len)
            {
                proto_tree_add_item(canopen_type_tree,
                    hf_canopen_pdo_data, tvb, CO_PDO_DATA_OFFSET, can_data_len, ENC_NA);
            }
            else
            {
                proto_tree_add_string(canopen_type_tree, hf_canopen_pdo_data_string, tvb, CO_PDO_DATA_OFFSET, 0, "empty");
            }
            break;
        case MT_SDO:
            proto_tree_add_item(canopen_type_tree,
                hf_canopen_sdo_cmd, tvb, CO_SDO_CMD_OFFSET, 1, ENC_BIG_ENDIAN);

            proto_tree_add_item(canopen_type_tree,
                hf_canopen_sdo_main_idx, tvb, CO_SDO_MAIN_IDX_OFFSET, 2, ENC_BIG_ENDIAN);

            proto_tree_add_item(canopen_type_tree,
                hf_canopen_sdo_sub_idx, tvb, CO_SDO_MAIN_SUB_OFFSET, 1, ENC_BIG_ENDIAN);

            proto_tree_add_item(canopen_type_tree,
                hf_canopen_sdo_data, tvb, CO_SDO_DATA_OFFSET, 4, ENC_NA);
            break;
        }

    }
}
示例#23
0
static void
dissect_aarp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
  guint16     ar_hrd;
  guint16     ar_pro;
  guint8      ar_hln;
  guint8      ar_pln;
  guint16     ar_op;
  proto_tree  *aarp_tree;
  proto_item  *ti;
  const gchar *op_str;
  int         sha_offset, spa_offset, tha_offset, tpa_offset;
  gchar       *sha_str, *spa_str, /* *tha_str, */ *tpa_str;

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

  ar_hrd = tvb_get_ntohs(tvb, AR_HRD);
  ar_pro = tvb_get_ntohs(tvb, AR_PRO);
  ar_hln = tvb_get_guint8(tvb, AR_HLN);
  ar_pln = tvb_get_guint8(tvb, AR_PLN);
  ar_op  = tvb_get_ntohs(tvb, AR_OP);

  /* Get the offsets of the addresses. */
  sha_offset = MIN_AARP_HEADER_SIZE;
  spa_offset = sha_offset + ar_hln;
  tha_offset = spa_offset + ar_pln;
  tpa_offset = tha_offset + ar_hln;

  /* Extract the addresses.  */
  sha_str = tvb_aarphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd);
  spa_str = tvb_aarpproaddr_to_str(tvb, spa_offset, ar_pln, ar_pro);
#if 0
  /* TODO: tha_str is currently not shown nor parsed */
  tha_str = tvb_aarphrdaddr_to_str(tvb, tha_offset, ar_hln, ar_hrd);
#endif
  tpa_str = tvb_aarpproaddr_to_str(tvb, tpa_offset, ar_pln, ar_pro);

  switch (ar_op) {
    case AARP_REQUEST:
    case AARP_REQUEST_SWAPPED:
      col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s?  Tell %s", tpa_str, spa_str);
      break;
    case AARP_REPLY:
    case AARP_REPLY_SWAPPED:
      col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s", spa_str, sha_str);
      break;
    case AARP_PROBE:
    case AARP_PROBE_SWAPPED:
      col_add_fstr(pinfo->cinfo, COL_INFO, "Is there a %s", tpa_str);
      break;
    default:
      col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown AARP opcode 0x%04x", ar_op);
      break;
  }

  if (tree) {
    if ((op_str = match_strval(ar_op, op_vals)))
      ti = proto_tree_add_protocol_format(tree, proto_aarp, tvb, 0,
				      MIN_AARP_HEADER_SIZE + 2*ar_hln +
				      2*ar_pln, "AppleTalk Address Resolution Protocol (%s)", op_str);
    else
      ti = proto_tree_add_protocol_format(tree, proto_aarp, tvb, 0,
				      MIN_AARP_HEADER_SIZE + 2*ar_hln +
				      2*ar_pln,
				      "AppleTalk Address Resolution Protocol (opcode 0x%04x)", ar_op);
    aarp_tree = proto_item_add_subtree(ti, ett_aarp);
    proto_tree_add_uint(aarp_tree, hf_aarp_hard_type, tvb, AR_HRD, 2,
			       ar_hrd);
    proto_tree_add_uint(aarp_tree, hf_aarp_proto_type, tvb, AR_PRO, 2,
			       ar_pro);
    proto_tree_add_uint(aarp_tree, hf_aarp_hard_size, tvb, AR_HLN, 1,
			       ar_hln);
    proto_tree_add_uint(aarp_tree, hf_aarp_proto_size, tvb, AR_PLN, 1,
			       ar_pln);
    proto_tree_add_uint(aarp_tree, hf_aarp_opcode, tvb, AR_OP, 2,
			       ar_op);
    if (ar_hln != 0) {
      proto_tree_add_item(aarp_tree,
	AARP_HW_IS_ETHER(ar_hrd, ar_hln) ? hf_aarp_src_hw_mac : hf_aarp_src_hw,
	tvb, sha_offset, ar_hln, ENC_NA);
    }

    if (ar_pln != 0) {
      if (AARP_PRO_IS_ATALK(ar_pro, ar_pln)) {
        proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_src_proto_id, tvb,
					  spa_offset, ar_pln, NULL,
					  "%s", spa_str);
      } else {
        proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_src_proto, tvb,
					  spa_offset, ar_pln, NULL,
					  "%s", spa_str);
      }
    }

    if (ar_hln != 0) {
      proto_tree_add_item(aarp_tree,
	AARP_HW_IS_ETHER(ar_hrd, ar_hln) ? hf_aarp_dst_hw_mac : hf_aarp_dst_hw,
	tvb, tha_offset, ar_hln, ENC_NA);
    }

    if (ar_pln != 0) {
      if (AARP_PRO_IS_ATALK(ar_pro, ar_pln)) {
        proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_dst_proto_id, tvb,
					  tpa_offset, ar_pln,
					  NULL, "%s", tpa_str);
      } else {
        proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_dst_proto, tvb,
					  tpa_offset, ar_pln,
					  NULL, "%s", tpa_str);
      }
    }
  }
}
示例#24
0
/* This function is only called from the IGMP dissector */
int
dissect_igap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
{
    proto_tree *tree;
    proto_item *item;
    guint8 type, tsecs, subtype, asize, msize;
    guchar account[ACCOUNT_SIZE+1], message[MESSAGE_SIZE+1];

    if (!proto_is_protocol_enabled(find_protocol_by_id(proto_igap))) {
	/* we are not enabled, skip entire packet to be nice
	   to the igmp layer. (so clicking on IGMP will display the data)
	   */
	return offset + tvb_length_remaining(tvb, offset);
    }

    item = proto_tree_add_item(parent_tree, proto_igap, tvb, offset, -1, ENC_NA);
    tree = proto_item_add_subtree(item, ett_igap);

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

    type = tvb_get_guint8(tvb, offset);
    if (check_col(pinfo->cinfo, COL_INFO)) {
	col_add_str(pinfo->cinfo, COL_INFO,
		     val_to_str(type, igap_types, "Unknown Type: 0x%02x"));
    }
    proto_tree_add_uint(tree, hf_type, tvb, offset, 1, type);
    offset += 1;

    tsecs = tvb_get_guint8(tvb, offset);
    proto_tree_add_uint_format(tree, hf_max_resp, tvb, offset, 1, tsecs,
	"Max Response Time: %.1f sec (0x%02x)", tsecs * 0.1, tsecs);
    offset += 1;

    igmp_checksum(tree, tvb, hf_checksum, hf_checksum_bad, pinfo, 0);
    offset += 2;

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

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

    subtype = tvb_get_guint8(tvb, offset);
    proto_tree_add_uint(tree, hf_subtype, tvb, offset, 1, subtype);
    offset += 2;

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

    asize = tvb_get_guint8(tvb, offset);
    proto_tree_add_uint(tree, hf_asize, tvb, offset, 1, asize);
    offset += 1;

    msize = tvb_get_guint8(tvb, offset);
    proto_tree_add_uint(tree, hf_msize, tvb, offset, 1, msize);
    offset += 3;

    if (asize > 0) {
    	if (asize > ACCOUNT_SIZE) {
    	    /* Bogus account size.
    	       XXX - flag this? */
    	    asize = ACCOUNT_SIZE;
    	}
	tvb_memcpy(tvb, account, offset, asize);
	account[asize] = '\0';
	proto_tree_add_string(tree, hf_account, tvb, offset, asize, account);
    }
    offset += ACCOUNT_SIZE;

    if (msize > 0) {
    	if (msize > MESSAGE_SIZE) {
    	    /* Bogus message size.
    	       XXX - flag this? */
    	    msize = MESSAGE_SIZE;
    	}
	tvb_memcpy(tvb, message, offset, msize);
	switch (subtype) {
	case IGAP_SUBTYPE_PASSWORD_JOIN:
	case IGAP_SUBTYPE_PASSWORD_LEAVE:
	    /* Challenge field is user's password */
	    message[msize] = '\0';
	    proto_tree_add_text(tree, tvb, offset, msize,
				"User password: %s", message);
	    break;
	case IGAP_SUBTYPE_CHALLENGE_RESPONSE_JOIN:
	case IGAP_SUBTYPE_CHALLENGE_RESPONSE_LEAVE:
	    /* Challenge field is the results of MD5 calculation */
	    proto_tree_add_text(tree, tvb, offset, msize,
				"Result of MD5 calculation: 0x%s",
				bytes_to_str(message, msize));
	    break;
	case IGAP_SUBTYPE_CHALLENGE:
	    /* Challenge field is the challenge value */
	    proto_tree_add_text(tree, tvb, offset, msize,
				"Challenge: 0x%s",
				bytes_to_str(message, msize));
	    break;
	case IGAP_SUBTYPE_AUTH_MESSAGE:
	    /* Challenge field indicates the result of the authenticaion */
	    proto_tree_add_text(tree, tvb, offset, msize,
				"Authentication result: %s (0x%x)",
				val_to_str(message[0], igap_auth_result,
				"Unknown"), message[0]);
	    break;
	case IGAP_SUBTYPE_ACCOUNTING_MESSAGE:
	    /* Challenge field indicates the accounting status */
	    proto_tree_add_text(tree, tvb, offset, msize,
				"Accounting status: %s (0x%x)",
				val_to_str(message[0], igap_account_status,
				"Unknown"), message[0]);
	    break;
	default:
	    proto_tree_add_text(tree, tvb, offset, msize,
				"Message: (Unknown)");
	}
    }
    offset += MESSAGE_SIZE;

    if (item) proto_item_set_len(item, offset);
    return offset;
}
示例#25
0
/* generic juniper header dissector  */
static int
dissect_juniper_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *ti, guint8 *flags)
{
  proto_item *tisub;
  guint8     direction,l2hdr_presence,proto,ext_type,ext_len;
  guint16    ext_total_len,ext_offset=6,hdr_len;
  guint32    magic_number,ext_val;

  proto_tree *juniper_ext_subtree = NULL, *juniper_ext_subtree_item = NULL;

  magic_number = tvb_get_ntoh24(tvb, 0);
  *flags = tvb_get_guint8(tvb, 3);
  direction = *flags & JUNIPER_FLAG_PKT_IN;
  l2hdr_presence = *flags & JUNIPER_FLAG_NO_L2;

  juniper_subtree = proto_item_add_subtree(ti, ett_juniper);

  /* be liberal with magic-number detection -
   * some older JUNOS releases (e.g. 6.4),
   * which are still in the field do not generate magic-numbers */
  if (magic_number != JUNIPER_PCAP_MAGIC) {
    proto_tree_add_text (juniper_subtree, tvb, 0, 0, "no Magic-Number found !");
    return 0;
  }

  proto_tree_add_text (juniper_subtree, tvb, 0, 3,
                       "Magic-Number: 0x%06x", magic_number);

  proto_tree_add_uint_format (juniper_subtree, hf_juniper_direction, tvb, 3, 1,
                              direction, "Direction: %s",
                              val_to_str(direction,juniper_direction_vals,"Unknown"));

  proto_tree_add_uint_format (juniper_subtree, hf_juniper_l2hdr_presence, tvb, 3, 1,
                              l2hdr_presence, "L2-header: %s",
                              val_to_str(l2hdr_presence,juniper_l2hdr_presence_vals,"Unknown"));

  /* calculate hdr_len before cookie, payload */

  /* meta-info extensions (JUNOS >= 7.5) ? */
  if ((*flags & JUNIPER_FLAG_EXT) == JUNIPER_FLAG_EXT) {
    ext_total_len = tvb_get_ntohs(tvb,4);
    hdr_len = 6 + ext_total_len; /* MGC,flags,ext_total_len */

    tisub = proto_tree_add_uint (juniper_subtree, hf_juniper_ext_total_len, tvb, 4, 2, ext_total_len);
    juniper_ext_subtree = proto_item_add_subtree(tisub, ett_juniper);

    while (ext_total_len > EXT_TLV_HEADER_SIZE) {
      ext_type = tvb_get_guint8(tvb, ext_offset);
      ext_len = tvb_get_guint8(tvb, ext_offset+1);

      if (ext_len == 0 || ext_len > (ext_total_len - EXT_TLV_HEADER_SIZE)) /* a few sanity checks */
        break;

      tisub = proto_tree_add_text (juniper_ext_subtree, tvb, ext_offset, EXT_TLV_HEADER_SIZE + ext_len,
                                   "%s Extension TLV #%u, length: %u",
                                   val_to_str(ext_type, ext_tlv_vals, "Unknown"),
                                   ext_type,
                                   ext_len);

      ext_val = juniper_ext_get_tlv_value(tvb, ext_type, ext_len, ext_offset+EXT_TLV_HEADER_SIZE);
      juniper_ext_subtree_item = proto_item_add_subtree(tisub, ett_juniper);

      switch (ext_type) {
      case EXT_TLV_IFD_MEDIATYPE:
        proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifmt,
                                    tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
        break;
      case EXT_TLV_TTP_IFD_MEDIATYPE:
        proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ttp_ifmt,
                                    tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
        break;
      case EXT_TLV_IFL_ENCAPS:
        proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifle,
                                    tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
        break;
      case EXT_TLV_TTP_IFL_ENCAPS:
        proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ttp_ifle,
                                    tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
        break;

      case EXT_TLV_IFL_IDX:
        proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifl,
                            tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
        break;

      case EXT_TLV_IFL_UNIT:
        proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_unit,
                            tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
        break;
      case EXT_TLV_IFD_IDX:
        proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifd,
                            tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
        break;
      case EXT_TLV_IFD_NAME: /* FIXME print ifname string - lets fall-through for now */
      default:
        proto_item_append_text(tisub, "Unknown");
        break;
      }

      ext_offset += EXT_TLV_HEADER_SIZE + ext_len;
      ext_total_len -= EXT_TLV_HEADER_SIZE + ext_len;
    }

  } else
    hdr_len = 4; /* MGC,flags */

  if ((*flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) { /* no link header present ? */
    proto = tvb_get_letohl(tvb,hdr_len); /* proto is stored in host-order */
    dissect_juniper_payload_proto(tvb, pinfo, tree, ti, proto, hdr_len + 4);
    return -1;
  }

  return hdr_len; /* bytes parsed */

}
示例#26
0
static int
dissect_gssapi_work(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
		    gboolean is_verifier, gssapi_encrypt_info_t* encrypt_info)
{
	proto_item *volatile item;
	proto_tree *volatile subtree;
	volatile int return_offset = 0;
	gssapi_conv_info_t *volatile gss_info;
	gssapi_oid_value *oidvalue;
	dissector_handle_t handle;
	conversation_t *conversation;
	tvbuff_t *oid_tvb;
	int len, start_offset, oid_start_offset;
	volatile int offset;
	gint8 appclass;
	gboolean pc, ind_field;
	gint32 tag;
	guint32 len1;
	const char *oid;
	fragment_head *fd_head=NULL;
	gssapi_frag_info_t *fi;
	tvbuff_t *volatile gss_tvb=NULL;
	asn1_ctx_t asn1_ctx;

	start_offset=0;
	offset=0;
	asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
	/*
	 * We don't know whether the data is encrypted, so say it's
	 * not, for now.  The subdissector must set gssapi_data_encrypted
	 * if it is.
	 */
	encrypt_info->gssapi_data_encrypted = FALSE;


	/*
	 * We need a conversation for later
	 */
	conversation = find_or_create_conversation(pinfo);

	gss_info = (gssapi_conv_info_t *)conversation_get_proto_data(conversation, proto_gssapi);
	if (!gss_info) {
		gss_info = wmem_new(wmem_file_scope(), gssapi_conv_info_t);
		gss_info->oid=NULL;
		gss_info->do_reassembly=FALSE;
		gss_info->frags=wmem_tree_new(wmem_file_scope());

		conversation_add_proto_data(conversation, proto_gssapi, gss_info);
	}

	item = proto_tree_add_item(
		tree, proto_gssapi, tvb, offset, -1, ENC_NA);

	subtree = proto_item_add_subtree(item, ett_gssapi);

	/*
	 * Catch the ReportedBoundsError exception; the stuff we've been
	 * handed doesn't necessarily run to the end of the packet, it's
	 * an item inside a packet, so if it happens to be malformed (or
	 * we, or a dissector we call, has a bug), so that an exception
	 * is thrown, we want to report the error, but return and let
	 * our caller dissect the rest of the packet.
	 *
	 * If it gets a BoundsError, we can stop, as there's nothing more
	 * in the packet after our blob to see, so we just re-throw the
	 * exception.
	 */
	TRY {
		gss_tvb=tvb;


		/* First of all, if it's the first time we see this packet
		 * then check whether we are in the middle of reassembly or not
		 */
		if( (!pinfo->fd->flags.visited)
		&&  (gss_info->do_reassembly)
		&&  (gssapi_reassembly) ){
			fi=(gssapi_frag_info_t *)wmem_tree_lookup32(gss_info->frags, gss_info->first_frame);
			if(!fi){
				goto done;
			}
			wmem_tree_insert32(gss_info->frags, pinfo->fd->num, fi);
			fd_head=fragment_add(&gssapi_reassembly_table,
				tvb, 0, pinfo, fi->first_frame, NULL,
				gss_info->frag_offset,
				tvb_captured_length(tvb), TRUE);
			gss_info->frag_offset+=tvb_captured_length(tvb);

			/* we need more fragments */
			if(!fd_head){
				goto done;
			}

			/* this blob is now fully reassembled */
			gss_info->do_reassembly=FALSE;
			fi->reassembled_in=pinfo->fd->num;

			gss_tvb=tvb_new_chain(tvb, fd_head->tvb_data);
			add_new_data_source(pinfo, gss_tvb, "Reassembled GSSAPI");
		}
		/* We have seen this packet before.
		 * Is this blob part of reassembly or a normal blob ?
		 */
		if( (pinfo->fd->flags.visited)
		&&  (gssapi_reassembly) ){
			fi=(gssapi_frag_info_t *)wmem_tree_lookup32(gss_info->frags, pinfo->fd->num);
			if(fi){
				fd_head=fragment_get(&gssapi_reassembly_table,
					pinfo, fi->first_frame, NULL);
				if(fd_head && (fd_head->flags&FD_DEFRAGMENTED)){
					if(pinfo->fd->num==fi->reassembled_in){
					        proto_item *frag_tree_item;
						gss_tvb=tvb_new_chain(tvb, fd_head->tvb_data);
						add_new_data_source(pinfo, gss_tvb, "Reassembled GSSAPI");
						show_fragment_tree(fd_head, &gssapi_frag_items, tree, pinfo, tvb, &frag_tree_item);
					} else {
						proto_item *it;
						it=proto_tree_add_uint(tree, hf_gssapi_reassembled_in, tvb, 0, 0, fi->reassembled_in);
					        PROTO_ITEM_SET_GENERATED(it);
						goto done;
					}
				}
			}
		}

		/* Read header */
		offset = get_ber_identifier(gss_tvb, offset, &appclass, &pc, &tag);
		offset = get_ber_length(gss_tvb, offset, &len1, &ind_field);


		if (!(appclass == BER_CLASS_APP && pc && tag == 0)) {
		  /* It could be NTLMSSP, with no OID.  This can happen
		     for anything that microsoft calls 'Negotiate' or GSS-SPNEGO */
			if ((tvb_captured_length_remaining(gss_tvb, start_offset)>7) && (tvb_strneql(gss_tvb, start_offset, "NTLMSSP", 7) == 0)) {
				return_offset = call_dissector(ntlmssp_handle,
							tvb_new_subset_remaining(gss_tvb, start_offset),
							pinfo, subtree);
				goto done;
			}
			/* Maybe it's new NTLMSSP payload */
			if ((tvb_captured_length_remaining(gss_tvb, start_offset)>16) &&
			   ((tvb_memeql(gss_tvb, start_offset, "\x01\x00\x00\x00", 4) == 0))) {
				return_offset = call_dissector(ntlmssp_payload_handle,
							tvb_new_subset_remaining(gss_tvb, start_offset),
							pinfo, subtree);
				encrypt_info->gssapi_data_encrypted = TRUE;
				goto done;
			}
			if ((tvb_captured_length_remaining(gss_tvb, start_offset)==16) &&
			   ((tvb_memeql(gss_tvb, start_offset, "\x01\x00\x00\x00", 4) == 0))) {
				if( is_verifier ) {
					return_offset = call_dissector(ntlmssp_verf_handle,
									tvb_new_subset_remaining(gss_tvb, start_offset),
									pinfo, subtree);
				}
				else if( encrypt_info->gssapi_encrypted_tvb ) {
					return_offset = call_dissector_with_data(ntlmssp_data_only_handle,
									tvb_new_subset_remaining(encrypt_info->gssapi_encrypted_tvb, 0),
									pinfo, subtree, &encrypt_info->gssapi_decrypted_tvb);
					encrypt_info->gssapi_data_encrypted = TRUE;
				}
		   		goto done;
		  	}

		  /* Maybe it's new GSSKRB5 CFX Wrapping */
		  if ((tvb_captured_length_remaining(gss_tvb, start_offset)>2) &&
		      ((tvb_memeql(gss_tvb, start_offset, "\04\x04", 2) == 0) ||
		       (tvb_memeql(gss_tvb, start_offset, "\05\x04", 2) == 0))) {
		    return_offset = call_dissector_with_data(spnego_krb5_wrap_handle,
						   tvb_new_subset_remaining(gss_tvb, start_offset),
						   pinfo, subtree, encrypt_info);
		    goto done;
		  }

		  /*
		   * If we do not recognise an Application class,
		   * then we are probably dealing with an inner context
		   * token or a wrap token, and we should retrieve the
		   * gssapi_oid_value pointer from the per-frame data or,
		   * if there is no per-frame data (as would be the case
		   * the first time we dissect this frame), from the
		   * conversation that exists or that we created from
		   * pinfo (and then make it per-frame data).
		   * We need to make it per-frame data as there can be
		   * more than one GSS-API negotiation in a conversation.
		   *
		   * Note! We "cheat". Since we only need the pointer,
		   * we store that as the data.  (That's not really
		   * "cheating" - the per-frame data and per-conversation
		   * data code doesn't care what you supply as a data
		   * pointer; it just treats it as an opaque pointer, it
		   * doesn't dereference it or free what it points to.)
		   */
		  oidvalue = (gssapi_oid_value *)p_get_proto_data(wmem_file_scope(), pinfo, proto_gssapi, 0);
		  if (!oidvalue && !pinfo->fd->flags.visited)
		  {
		    /* No handle attached to this frame, but it's the first */
		    /* pass, so it'd be attached to the conversation. */
		    oidvalue = gss_info->oid;
		    if (gss_info->oid)
		      p_add_proto_data(wmem_file_scope(), pinfo, proto_gssapi, 0, gss_info->oid);
		  }
		  if (!oidvalue)
		  {
			  proto_tree_add_expert_format(subtree, pinfo, &ei_gssapi_unknown_header, gss_tvb, start_offset, 0,
					      "Unknown header (class=%d, pc=%d, tag=%d)",
					      appclass, pc, tag);
		    return_offset = tvb_captured_length(gss_tvb);
		    goto done;
		  } else {
		    tvbuff_t *oid_tvb_local;

		    oid_tvb_local = tvb_new_subset_remaining(gss_tvb, start_offset);
		    if (is_verifier)
			handle = oidvalue->wrap_handle;
		    else
			handle = oidvalue->handle;
		    len = call_dissector_with_data(handle, oid_tvb_local, pinfo, subtree, encrypt_info);
		    if (len == 0)
			return_offset = tvb_captured_length(gss_tvb);
		    else
			return_offset = start_offset + len;
		    goto done; /* We are finished here */
		  }
		}

		/* Read oid */
		oid_start_offset=offset;
		offset=dissect_ber_object_identifier_str(FALSE, &asn1_ctx, subtree, gss_tvb, offset, hf_gssapi_oid, &oid);
		oidvalue = gssapi_lookup_oid_str(oid);


		/* Check if we need reassembly of this blob.
		 * Only try reassembly for OIDs we recognize
		 * and when we have the entire tvb
		 *
		 * SMB will sometimes split one large GSSAPI blob
		 * across multiple SMB/SessionSetup commands.
		 * While we should look at the uid returned in the response
		 * to the first SessionSetup and use that as a key
		 * instead for simplicity we assume there will not be several
		 * such authentication at once on a single tcp session
		 */
		if( (!pinfo->fd->flags.visited)
		&&  (oidvalue)
		&&  (tvb_captured_length(gss_tvb)==tvb_reported_length(gss_tvb))
		&&  (len1>(guint32)tvb_captured_length_remaining(gss_tvb, oid_start_offset))
		&&  (gssapi_reassembly) ){
			fi=wmem_new(wmem_file_scope(), gssapi_frag_info_t);
			fi->first_frame=pinfo->fd->num;
			fi->reassembled_in=0;
			wmem_tree_insert32(gss_info->frags, pinfo->fd->num, fi);

			fragment_add(&gssapi_reassembly_table,
				gss_tvb, 0, pinfo, pinfo->fd->num, NULL,
				0, tvb_captured_length(gss_tvb), TRUE);
			fragment_set_tot_len(&gssapi_reassembly_table,
				pinfo, pinfo->fd->num, NULL, len1+oid_start_offset);

			gss_info->do_reassembly=TRUE;
			gss_info->first_frame=pinfo->fd->num;
			gss_info->frag_offset=tvb_captured_length(gss_tvb);
			goto done;
		}


		/*
		 * Hand off to subdissector.
		 */

		if ((oidvalue == NULL) ||
		    !proto_is_protocol_enabled(oidvalue->proto)) {
			/* No dissector for this oid */
			proto_tree_add_item(subtree, hf_gssapi_token_object, gss_tvb, oid_start_offset, -1, ENC_NA);

			return_offset = tvb_captured_length(gss_tvb);
			goto done;
		}

		/* Save a pointer to the data for the OID for the
		 * GSSAPI protocol for this conversation.
		 */

		/*
		 * Now add the proto data ...
		 * but only if it is not already there.
		 */
		if(!gss_info->oid){
		  gss_info->oid=oidvalue;
		}

		if (is_verifier) {
			handle = oidvalue->wrap_handle;
			if (handle != NULL) {
				oid_tvb = tvb_new_subset_remaining(gss_tvb, offset);
				len = call_dissector_with_data(handle, oid_tvb, pinfo, subtree, encrypt_info);
				if (len == 0)
					return_offset = tvb_captured_length(gss_tvb);
				else
					return_offset = offset + len;
			} else {
				proto_tree_add_item(subtree, hf_gssapi_auth_verifier, gss_tvb, offset, -1, ENC_NA);
				return_offset = tvb_captured_length(gss_tvb);
			}
		} else {
			handle = oidvalue->handle;
			if (handle != NULL) {
				oid_tvb = tvb_new_subset_remaining(gss_tvb, offset);
				len = call_dissector_with_data(handle, oid_tvb, pinfo, subtree, encrypt_info);
				if (len == 0)
					return_offset = tvb_captured_length(gss_tvb);
				else
					return_offset = offset + len;
			} else {
				proto_tree_add_item(subtree, hf_gssapi_auth_credentials, gss_tvb, offset, -1, ENC_NA);
				return_offset = tvb_captured_length(gss_tvb);
			}
		}

	 done:
		;
	} 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.
		 */
		show_exception(gss_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
	} ENDTRY;

	proto_item_set_len(item, return_offset);
	return return_offset;
}
示例#27
0
static int
dissect_report_segment(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ltp_tree, int frame_offset) {
	guint64 rpt_sno;
	guint64 chkp_sno;
	guint64 upper_bound;
	guint64 lower_bound;
	int rcpt_clm_cnt;
	guint64 offset;
	guint64 length;

	int rpt_sno_size;
	int chkp_sno_size;
	int upper_bound_size;
	int lower_bound_size;
	int rcpt_clm_cnt_size;
	int offset_size;
	int length_size;

	int segment_offset = 0;
	int i;

	proto_item *ltp_rpt_item;
	proto_item *ltp_rpt_clm_item;

	proto_tree *ltp_rpt_tree;
	proto_tree *ltp_rpt_clm_tree;

	/* Create the subtree for report segment under the main LTP tree and all the report segment fields under it */
	ltp_rpt_tree = proto_tree_add_subtree(ltp_tree, tvb, frame_offset, -1, ett_rpt_segm, &ltp_rpt_item, "Report Segment");

	/* Extract the report segment info */
	rpt_sno = evaluate_sdnv_64(tvb, frame_offset, &rpt_sno_size);
	proto_tree_add_uint64(ltp_rpt_tree, hf_ltp_rpt_sno, tvb, frame_offset + segment_offset, rpt_sno_size, rpt_sno);
	segment_offset += rpt_sno_size;

	chkp_sno = evaluate_sdnv_64(tvb, frame_offset + segment_offset, &chkp_sno_size);
	proto_tree_add_uint64(ltp_rpt_tree, hf_ltp_rpt_chkp, tvb, frame_offset + segment_offset, chkp_sno_size, chkp_sno);
	segment_offset += chkp_sno_size;

	upper_bound = evaluate_sdnv(tvb, frame_offset + segment_offset, &upper_bound_size);
	proto_tree_add_uint64(ltp_rpt_tree, hf_ltp_rpt_ub, tvb, frame_offset + segment_offset, upper_bound_size, upper_bound);
	segment_offset += upper_bound_size;

	lower_bound = evaluate_sdnv(tvb, frame_offset + segment_offset, &lower_bound_size);
	proto_tree_add_uint64(ltp_rpt_tree, hf_ltp_rpt_lb, tvb, frame_offset + segment_offset, lower_bound_size, lower_bound);
	segment_offset += lower_bound_size;

	rcpt_clm_cnt = evaluate_sdnv(tvb, frame_offset + segment_offset, &rcpt_clm_cnt_size);
	if (rcpt_clm_cnt < 0){
		proto_item_set_end(ltp_rpt_item, tvb, frame_offset + segment_offset);
		expert_add_info_format(pinfo, ltp_tree, &ei_ltp_neg_reception_claim_count,
				"Negative reception claim count: %d", rcpt_clm_cnt);
		return 0;
	}
	/* Each reception claim is at least 2 bytes, so if the count is larger than the
	 * max number of claims we can possibly squeeze into the remaining tvbuff, then
	 * the packet is malformed.
	 */
	if (rcpt_clm_cnt > tvb_reported_length_remaining(tvb, frame_offset + segment_offset) / 2) {
		proto_item_set_end(ltp_rpt_item, tvb, frame_offset + segment_offset);
		expert_add_info_format(pinfo, ltp_tree, &ei_ltp_mal_reception_claim,
				"Reception claim count impossibly large: %d > %d", rcpt_clm_cnt,
				tvb_reported_length_remaining(tvb, frame_offset + segment_offset) / 2);
		return 0;
	}
	proto_tree_add_uint(ltp_rpt_tree, hf_ltp_rpt_clm_cnt, tvb, frame_offset + segment_offset, rcpt_clm_cnt_size, rcpt_clm_cnt);
	segment_offset += rcpt_clm_cnt_size;

	ltp_rpt_clm_tree = proto_tree_add_subtree(ltp_rpt_tree, tvb, frame_offset + segment_offset, -1, ett_rpt_clm, &ltp_rpt_clm_item, "Reception claims");

	/* There can be multiple reception claims in the same report segment */
	for(i = 0; i<rcpt_clm_cnt; i++){
		offset = evaluate_sdnv(tvb,frame_offset + segment_offset, &offset_size);
		proto_tree_add_uint64_format(ltp_rpt_clm_tree, hf_ltp_rpt_clm_off, tvb, frame_offset + segment_offset, offset_size, offset,
				"Offset[%d] : %"G_GINT64_MODIFIER"d", i, offset);
		segment_offset += offset_size;

		length = evaluate_sdnv(tvb,frame_offset + segment_offset, &length_size);
		proto_tree_add_uint64_format(ltp_rpt_clm_tree, hf_ltp_rpt_clm_len, tvb, frame_offset + segment_offset, length_size, length,
				"Length[%d] : %"G_GINT64_MODIFIER"d",i, length);
		segment_offset += length_size;
	}
	proto_item_set_end(ltp_rpt_clm_item, tvb, frame_offset + segment_offset);
	proto_item_set_end(ltp_rpt_item, tvb, frame_offset + segment_offset);
	return segment_offset;
}
示例#28
0
/* Code to dissect extensions */
static void
dissect_mip_extensions( tvbuff_t *tvb, int offset, proto_tree *tree)
{
  proto_item   *ti;
  proto_tree   *exts_tree=NULL;
  proto_tree   *ext_tree;
  proto_tree   *tf;
  proto_tree   *ext_flags_tree;
  proto_tree   *tp;
  proto_tree   *pmipv4_tree;
  gint          ext_len;
  guint8        ext_type;
  guint8        ext_subtype=0;
  guint8        pmipv4skipext_subscriberid_type;
  guint16       flags;
  gint          hdrLen;
  guint32       cvse_vendor_id;
  guint16       cvse_vendor_type;
  guint16       nvse_vendor_type;
  int           cvse_local_offset= 0;
  int           nvse_local_offset= 0;

  /* None of this really matters if we don't have a tree */
  if (!tree) return;

  /* Add our tree, if we have extensions */
  ti = proto_tree_add_text(tree, tvb, offset, -1, "Extensions");
  exts_tree = proto_item_add_subtree(ti, ett_mip_exts);

  /* And, handle each extension */
  while (tvb_reported_length_remaining(tvb, offset) > 0) {

    /* Get our extension info */
    ext_type = tvb_get_guint8(tvb, offset);
    if (ext_type == GEN_AUTH_EXT || ext_type == PMIPv4_NON_SKIP_EXT) {
      /*
       * Very nasty . . breaks normal extensions, since the length is
       * in the wrong place :(
       */
      ext_subtype = tvb_get_guint8(tvb, offset + 1);
      ext_len = tvb_get_ntohs(tvb, offset + 2);
      hdrLen = 4;
    }
    else if(ext_type==CVSE_EXT){
      /*
       * CVSE also breaks since it added reserved field before
       * the length field
      */
      ext_len = tvb_get_ntohs(tvb, offset + 2);
      hdrLen = 4;
    }
    else {
      ext_len = tvb_get_guint8(tvb, offset + 1);
      hdrLen = 2;
    }

    ti = proto_tree_add_text(exts_tree, tvb, offset, ext_len + hdrLen,
                 "Extension: %s",
                 val_to_str(ext_type, mip_ext_types,
                            "Unknown Extension %u"));
    ext_tree = proto_item_add_subtree(ti, ett_mip_ext);

    proto_tree_add_uint(ext_tree, hf_mip_ext_type, tvb, offset, 1, ext_type);
    offset++;
    if (ext_type != GEN_AUTH_EXT &&
        ext_type != PMIPv4_NON_SKIP_EXT &&
        ext_type != CVSE_EXT) {
      /* Another nasty hack since GEN_AUTH_EXT and PMIPv4_NON_SKIP_EXT broke everything */
      proto_tree_add_uint(ext_tree, hf_mip_ext_len, tvb, offset, 1, ext_len);
      offset++;
    }

    switch (ext_type) {
    case MH_AUTH_EXT:
    case MF_AUTH_EXT:
    case FH_AUTH_EXT:
      /* All these extensions look the same.  4 byte SPI followed by a key */
      proto_tree_add_item(ext_tree, hf_mip_aext_spi, tvb, offset, 4, ENC_BIG_ENDIAN);
      proto_tree_add_item(ext_tree, hf_mip_aext_auth, tvb, offset+4, ext_len-4, ENC_NA);
      break;
    case MN_NAI_EXT:
      proto_tree_add_item(ext_tree, hf_mip_next_nai, tvb, offset,
                          ext_len, ENC_ASCII|ENC_NA);
      break;

    case GEN_AUTH_EXT:      /* RFC 3012 */
      /*
       * Very nasty . . breaks normal extensions, since the length is
       * in the wrong place :(
       */
      proto_tree_add_uint(ext_tree, hf_mip_gaext_stype, tvb, offset, 1, ext_subtype);
      offset++;
      proto_tree_add_uint(ext_tree, hf_mip_ext_len, tvb, offset, 2, ext_len);
      offset+=2;
      /* SPI */
      proto_tree_add_item(ext_tree, hf_mip_aext_spi, tvb, offset, 4, ENC_BIG_ENDIAN);
      /* Key */
      proto_tree_add_item(ext_tree, hf_mip_aext_auth, tvb, offset + 4,
                          ext_len - 4, ENC_NA);

      break;
        case REV_SUPP_EXT:      /* RFC 3543 */
      /* flags */
      flags = tvb_get_ntohs(tvb, offset);
      tf = proto_tree_add_uint(ext_tree, hf_mip_rext_flags, tvb, offset, 2, flags);
      ext_flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
      proto_tree_add_boolean(ext_flags_tree, hf_mip_rext_i, tvb, offset, 2, flags);

      /* reserved */
      proto_tree_add_uint(ext_flags_tree, hf_mip_rext_reserved, tvb, offset, 2, flags);
      /* registration revocation timestamp */
      proto_tree_add_item(ext_tree, hf_mip_rext_tstamp, tvb, offset + 2, 4, ENC_BIG_ENDIAN);
      break;
    case DYN_HA_EXT:      /* RFC 4433 */
      /* subtype */
      proto_tree_add_item(ext_tree, hf_mip_dhaext_stype, tvb, offset, 1, ENC_BIG_ENDIAN);
      /* Home Agent */
      proto_tree_add_item(ext_tree, hf_mip_dhaext_addr, tvb, offset + 1, 4, ENC_BIG_ENDIAN);
      break;
    case MSG_STR_EXT:
      /* sub-type */
      proto_tree_add_item(ext_tree, hf_mip_mstrext_stype, tvb, offset, 1, ENC_BIG_ENDIAN);

      /* text */
      proto_tree_add_item(ext_tree, hf_mip_mstrext_text, tvb, offset + 1, ext_len-1, ENC_ASCII|ENC_NA);
      break;
    case UDP_TUN_REQ_EXT:   /* RFC 3519 */
      /* sub-type */
      proto_tree_add_item(ext_tree, hf_mip_utrqext_stype, tvb, offset, 1, ENC_BIG_ENDIAN);

      /* reserved 1 */
      proto_tree_add_item(ext_tree, hf_mip_utrqext_reserved1, tvb, offset + 1, 1, ENC_BIG_ENDIAN);

      /* flags */
      flags = tvb_get_guint8(tvb, offset + 2);
      tf = proto_tree_add_uint(ext_tree, hf_mip_utrqext_flags, tvb, offset + 2, 1, flags);
      ext_flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
      proto_tree_add_boolean(ext_flags_tree, hf_mip_utrqext_f, tvb, offset + 2, 1, flags);
      proto_tree_add_boolean(ext_flags_tree, hf_mip_utrqext_r, tvb, offset + 2, 1, flags);

      /* reserved 2 */
      proto_tree_add_uint(ext_flags_tree, hf_mip_utrqext_reserved2, tvb, offset + 2, 1, flags);
      /* encapsulation */
      proto_tree_add_item(ext_tree, hf_mip_utrqext_encap_type, tvb, offset + 3, 1, ENC_BIG_ENDIAN);

      /* reserved 3 */
      proto_tree_add_item(ext_tree, hf_mip_utrqext_reserved3, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
      break;
    case UDP_TUN_REP_EXT:   /* RFC 3519 */
      /* sub-type */
      proto_tree_add_item(ext_tree, hf_mip_utrpext_stype, tvb, offset, 1, ENC_BIG_ENDIAN);

      /* code */
      proto_tree_add_item(ext_tree, hf_mip_utrpext_code, tvb, offset + 1, 1, ENC_BIG_ENDIAN);

      /* flags */
      flags = tvb_get_ntohs(tvb, offset+2);
      tf = proto_tree_add_uint(ext_tree, hf_mip_utrpext_flags, tvb, offset + 2, 2, flags);
      ext_flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
      proto_tree_add_boolean(ext_flags_tree, hf_mip_utrpext_f, tvb, offset + 2, 2, flags);

      /* reserved */
      proto_tree_add_uint(ext_flags_tree, hf_mip_utrpext_reserved, tvb, offset + 2, 2, flags);

      /* keepalive interval */
      proto_tree_add_item(ext_tree, hf_mip_utrpext_keepalive, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
      break;
    case PMIPv4_NON_SKIP_EXT:   /* draft-leung-mip4-proxy-mode */
      /* sub-type */
      proto_tree_add_uint(ext_tree, hf_mip_pmipv4nonskipext_stype, tvb, offset, 1, ext_subtype);
      offset++;
          /* len */
      proto_tree_add_uint(ext_tree, hf_mip_ext_len, tvb, offset, 2, ext_len);
      offset+=2;
      if(ext_subtype == 1){
        /* Sub-type == 1 : PMIPv4 Per-Node Authentication Method */
        proto_tree_add_item(ext_tree, hf_mip_pmipv4nonskipext_pernodeauthmethod, tvb, offset, 1, ENC_BIG_ENDIAN);
      }
      break;
    case PMIPv4_SKIP_EXT:   /* draft-leung-mip4-proxy-mode */
      /* sub-type */
      ext_subtype = tvb_get_guint8(tvb, offset);
      tp = proto_tree_add_text(ext_tree, tvb, offset, ext_len,
                   "PMIPv4 Sub-Type: %s",
                   val_to_str(ext_subtype, mip_pmipv4skipext_stypes, "Unknown Sub-Type %u"));
      pmipv4_tree = proto_item_add_subtree(tp, ett_mip_pmipv4_ext);
      proto_tree_add_uint(pmipv4_tree, hf_mip_pmipv4skipext_stype, tvb, offset, 1, ext_subtype);

      if (ext_subtype == PMIPv4_SKIPEXT_STYPE_INTERFACE_ID) {
        proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_interfaceid, tvb, offset + 1, ext_len-1, ENC_NA);
      } else if (ext_subtype == PMIPv4_SKIPEXT_STYPE_DEVICE_ID) {
        proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_deviceid_type, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_deviceid_id, tvb, offset + 2, ext_len - 2, ENC_NA);
      } else if (ext_subtype == PMIPv4_SKIPEXT_STYPE_SUBSCRIBER_ID) {
        pmipv4skipext_subscriberid_type = tvb_get_guint8(tvb, offset + 1);
        proto_tree_add_uint(pmipv4_tree, hf_mip_pmipv4skipext_subscriberid_type, tvb, offset + 1, 1, pmipv4skipext_subscriberid_type);
        if (pmipv4skipext_subscriberid_type == 1) {
          proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_subscriberid_id, tvb, offset + 2, ext_len - 2, ENC_NA);
        }
      } else if (ext_subtype == PMIPv4_SKIPEXT_STYPE_ACCESS_TECHNOLOGY) {
        proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_accesstechnology_type, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
      }
      break;

    case OLD_CVSE_EXT:      /* RFC 3115 */
    case CVSE_EXT:          /* RFC 3115 */
      /*
       * Very nasty . . breaks normal extensions, since the length is
       * in the wrong place :(
       */
      proto_tree_add_item(ext_tree, hf_mip_cvse_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset++;
      proto_tree_add_uint(ext_tree, hf_mip_ext_len, tvb, offset, 2, ext_len);
      offset+=2;
      /* Vendor/Org ID */
      /*Vendor ID & cvse type & cvse value are included in ext_len, so do not increment offset for them here.*/
      cvse_local_offset = offset;
      proto_tree_add_item(ext_tree, hf_mip_cvse_vendor_org_id, tvb, cvse_local_offset, 4, ENC_BIG_ENDIAN);
      cvse_vendor_id = tvb_get_ntohl(tvb, cvse_local_offset);
      cvse_local_offset+=4;
      /*Vendor CVSE Type*/
      if( cvse_vendor_id == VENDOR_VERIZON ){
        /*Verizon CVSE type*/
           proto_tree_add_item(ext_tree, hf_mip_cvse_verizon_cvse_type, tvb, cvse_local_offset, 2, ENC_BIG_ENDIAN);
      }
      else{
        /*CVSE Type of Other vendor, just show raw numbers currently*/
        cvse_vendor_type = tvb_get_ntohs(tvb, cvse_local_offset);
        proto_tree_add_uint(ext_tree, hf_mip_cvse_vendor_cvse_type, tvb, cvse_local_offset, 2, cvse_vendor_type);
      }
      cvse_local_offset+=2;
      /* Vendor-CVSE-Value */
      /* Vendor CVSE Type+Vendor/Org ID = 6 bytes*/
      proto_tree_add_item(ext_tree, hf_mip_cvse_vendor_cvse_value, tvb, cvse_local_offset, ext_len - 6, ENC_NA);
      break;

    case OLD_NVSE_EXT:      /* RFC 3115 */
    case NVSE_EXT:          /* RFC 3115 */
      proto_tree_add_item(ext_tree, hf_mip_nvse_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);

      /* Vendor/Org ID */
      /*Vendor ID & nvse type & nvse value are included in ext_len, so do not increment offset for them here.*/
      nvse_local_offset = offset + hdrLen;
      proto_tree_add_item(ext_tree, hf_mip_nvse_vendor_org_id, tvb, nvse_local_offset, 4, ENC_BIG_ENDIAN);
      nvse_local_offset+=4;

      /*Vendor NVSE Type*/
      nvse_vendor_type = tvb_get_ntohs(tvb, nvse_local_offset);
      proto_tree_add_uint(ext_tree, hf_mip_nvse_vendor_nvse_type, tvb, nvse_local_offset, 2, nvse_vendor_type);
      nvse_local_offset+=2;

      /* Vendor-NVSE-Value */
      proto_tree_add_item(ext_tree, hf_mip_nvse_vendor_nvse_value, tvb, nvse_local_offset, ext_len - 8, ENC_NA);
      break;

    case MF_CHALLENGE_EXT:  /* RFC 3012 */
      /* The default dissector is good here.  The challenge is all hex anyway. */
    default:
      proto_tree_add_item(ext_tree, hf_mip_ext, tvb, offset, ext_len, ENC_NA);
      break;
    } /* ext type */

    offset += ext_len;
  } /* while data remaining */

} /* dissect_mip_extensions */
示例#29
0
/*
 * XXX - do reassembly, using the EOM flag.  (Then do that in the Netware
 * SPX implementation, too.)
 *
 * XXX - hand off to subdissectors based on the socket number.
 */
static void
dissect_spp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*spp_tree = NULL;
	proto_item	*ti;
	tvbuff_t	*next_tvb;
	guint8		conn_ctrl;
	proto_tree	*cc_tree;
	guint8		datastream_type;
	const char	*datastream_type_string;
	guint16         spp_seq;
	const char	*spp_msg_string;
	guint16		low_socket, high_socket;

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

	if (tree) {
		ti = proto_tree_add_item(tree, proto_spp, tvb, 0, SPP_HEADER_LEN, ENC_NA);
		spp_tree = proto_item_add_subtree(ti, ett_spp);
	}

	conn_ctrl = tvb_get_guint8(tvb, 0);
	spp_msg_string = spp_conn_ctrl(conn_ctrl);
	if (check_col(pinfo->cinfo, COL_INFO))
		col_append_fstr(pinfo->cinfo, COL_INFO, " %s", spp_msg_string);
	if (tree) {
		ti = proto_tree_add_uint_format(spp_tree, hf_spp_connection_control, tvb,
						0, 1, conn_ctrl,
						"Connection Control: %s (0x%02X)",
						spp_msg_string, conn_ctrl);
		cc_tree = proto_item_add_subtree(ti, ett_spp_connctrl);
		proto_tree_add_boolean(cc_tree, hf_spp_connection_control_sys, tvb,
				       0, 1, conn_ctrl);
		proto_tree_add_boolean(cc_tree, hf_spp_connection_control_send_ack, tvb,
				       0, 1, conn_ctrl);
		proto_tree_add_boolean(cc_tree, hf_spp_connection_control_attn, tvb,
				       0, 1, conn_ctrl);
		proto_tree_add_boolean(cc_tree, hf_spp_connection_control_eom, tvb,
				       0, 1, conn_ctrl);
	}

	datastream_type = tvb_get_guint8(tvb, 1);
	datastream_type_string = spp_datastream(datastream_type);
	if (datastream_type_string != NULL) {
		if (check_col(pinfo->cinfo, COL_INFO))
			col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
			    datastream_type_string);
	}
	if (tree) {
		if (datastream_type_string != NULL) {
			proto_tree_add_uint_format(spp_tree, hf_spp_datastream_type, tvb,
						   1, 1, datastream_type,
						   "Datastream Type: %s (0x%02X)",
						   datastream_type_string,
						   datastream_type);
		} else {
			proto_tree_add_uint_format(spp_tree, hf_spp_datastream_type, tvb,
						   1, 1, datastream_type,
						   "Datastream Type: 0x%02X",
						   datastream_type);
		}
		proto_tree_add_item(spp_tree, hf_spp_src_id, tvb,  2, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(spp_tree, hf_spp_dst_id, tvb,  4, 2, ENC_BIG_ENDIAN);
	}
	spp_seq = tvb_get_ntohs(tvb, 6);
	if (tree) {
		proto_tree_add_uint(spp_tree, hf_spp_seq_nr, tvb,  6, 2, spp_seq);
		proto_tree_add_item(spp_tree, hf_spp_ack_nr, tvb,  8, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(spp_tree, hf_spp_all_nr, tvb, 10, 2, ENC_BIG_ENDIAN);
	}

	if (tvb_reported_length_remaining(tvb, SPP_HEADER_LEN) > 0) {
		if (pinfo->srcport > pinfo->destport) {
			low_socket = pinfo->destport;
			high_socket = pinfo->srcport;
		} else {
			low_socket = pinfo->srcport;
			high_socket = pinfo->destport;
		}

		next_tvb = tvb_new_subset_remaining(tvb, SPP_HEADER_LEN);
		if (dissector_try_uint(spp_socket_dissector_table, low_socket,
		    next_tvb, pinfo, tree))
			return;
		if (dissector_try_uint(spp_socket_dissector_table, high_socket,
		    next_tvb, pinfo, tree))
			return;
		call_dissector(data_handle, next_tvb, pinfo, tree);
	}
}
示例#30
0
/*
 * Dissect ASCII TPKT-encapsulated data in a TCP stream.
 */
void
dissect_asciitpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
		  dissector_handle_t subdissector_handle)
{
    proto_item *ti = NULL;
    proto_tree *tpkt_tree = NULL;
    volatile int offset = 0;
    int length_remaining;
    int data_len;
    volatile int mgcp_packet_len = 0;
    int mgcp_version = 0;
    int mgcp_reserved = 0;
    volatile int length;
    tvbuff_t *volatile next_tvb;
    const char *saved_proto;
    guint8 string[4];
    void *pd_save;

    /*
     * If we're reassembling segmented TPKT PDUs, empty the COL_INFO
     * column, so subdissectors can append information
     * without having to worry about emptying the column.
     *
     * We use "col_add_str()" because the subdissector
     * might be appending information to the column, in
     * which case we'd have to zero the buffer out explicitly
     * anyway.
     */
    if (tpkt_desegment)
        col_set_str(pinfo->cinfo, COL_INFO, "");

    while (tvb_reported_length_remaining(tvb, offset) != 0) {
        /*
         * Is the first byte of this putative TPKT header
         * a valid TPKT version number, i.e. 3?
         */
        if (tvb_get_guint8(tvb, offset) != 48) {
            /*
             * No, so don't assume this is a TPKT header;
             * we might be in the middle of TPKT data,
             * so don't get the length and don't try to
             * do reassembly.
             */
            col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
            col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
            if (tree) {
                ti = proto_tree_add_item(tree, proto_tpkt, tvb,
                    offset, -1, ENC_NA);
                tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
                proto_item_set_text(ti, "TPKT");

                proto_tree_add_text(tpkt_tree, tvb, offset, -1,
                    "Continuation data");
            }
            return;
        }

        length_remaining = tvb_length_remaining(tvb, offset);

        /*
         * Get the length from the TPKT header.
         */

        tvb_memcpy(tvb, (guint8 *)string, offset, 2);
        mgcp_version = parseVersionText(string);
        tvb_memcpy(tvb, (guint8 *)string, offset +2, 2);
        mgcp_reserved = parseReservedText(string);
        tvb_memcpy(tvb, (guint8 *)string, offset + 4, 4);
        mgcp_packet_len = parseLengthText(string);
        data_len = mgcp_packet_len;

        /*
         * Dissect the TPKT header.
         * Save and restore "pinfo->current_proto".
         */
        saved_proto = pinfo->current_proto;
        pinfo->current_proto = "TPKT";

        col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
        /*
         * Don't add the TPKT header information if we're
         * reassembling segmented TPKT PDUs or if this
         * PDU isn't reassembled.
         *
         * XXX - the first is so that subdissectors can append
         * information without getting TPKT stuff in the middle;
         * why the second?
         */
        if (!tpkt_desegment && !pinfo->fragmented) {
            col_add_fstr(pinfo->cinfo, COL_INFO,
                "TPKT Data length = %u", data_len);
        }

        if (tree) {
            ti = proto_tree_add_item(tree, proto_tpkt, tvb,
                offset, 8, ENC_NA);
            tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
            proto_item_set_text(ti, "TPKT");

            /* Version */
            proto_tree_add_uint(tpkt_tree, hf_tpkt_version, tvb,
                            offset, 2, mgcp_version);

            /* Reserved octet*/
            proto_tree_add_uint(tpkt_tree, hf_tpkt_reserved, tvb,
                            offset + 2, 2, mgcp_reserved);

            /* Length */
            proto_tree_add_uint(tpkt_tree, hf_tpkt_length, tvb,
                            offset + 4, 4, mgcp_packet_len);
        }
        pinfo->current_proto = saved_proto;

        /* Skip the TPKT header. */
        offset += TEXT_LAYER_LENGTH;
        length = length_remaining - TEXT_LAYER_LENGTH;
        if (length > data_len)
            length = data_len;

        next_tvb = tvb_new_subset(tvb, offset,length, data_len);

        /*
         * Call the subdissector.
         *
         * If it gets an error that means there's no point in
         * dissecting any more TPKT messages, rethrow the
         * exception in question.
         *
         * If it gets any other error, report it and continue, as that
         * means that TPKT message got an error, but that doesn't mean
         * we should stop dissecting TPKT messages within this frame
         * or chunk of reassembled data.
         */
	pd_save = pinfo->private_data;
        TRY {
            call_dissector(subdissector_handle, next_tvb, pinfo,
                tree);
        }
        CATCH_NONFATAL_ERRORS {
	    /*  Restore the private_data structure in case one of the
	     *  called dissectors modified it (and, due to the exception,
	     *  was unable to restore it).
	     */
	    pinfo->private_data = pd_save;

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

        /*
         * Skip the payload.
         */
        offset += data_len;
    }
}