예제 #1
0
/* Experimental approach based upon the one used for PPP */
static gboolean heur_dissect_at(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    const gchar at_magic1[2] = {0x0d, 0x0a};
    const gchar at_magic2[3] = {0x0d, 0x0d, 0x0a};
    const gchar at_magic3[2] = {'A', 'T'};

    if (((tvb_memeql(tvb, 0, at_magic1, sizeof(at_magic1)) == 0) ||
            (tvb_memeql(tvb, 0, at_magic2, sizeof(at_magic2)) == 0) ||
            (tvb_memeql(tvb, 0, at_magic3, sizeof(at_magic3)) == 0)) &&
            allowed_chars(tvb)) {
        dissect_at(tvb, pinfo, tree);
        return (TRUE);
    }
    return (FALSE);
}
예제 #2
0
static guint get_http2_message_len( packet_info *pinfo, tvbuff_t *tvb, int offset )
{
        (void)(pinfo); /* Avoid the unused parameter warning */

        if ( tvb_memeql( tvb, offset, kMagicHello, MAGIC_FRAME_LENGTH ) == 0 ) {
                return MAGIC_FRAME_LENGTH;
        }

        return (guint)tvb_get_ntohs(tvb, offset) + FRAME_HEADER_LENGTH;
}
예제 #3
0
    guint
    get_pdu_len(packet_info *, tvbuff_t *tvb, int offset)
    {
      if ( tvb_memeql(tvb, 0, reinterpret_cast<const guint8*>(DCPS_MAGIC) ,4) != 0)
        return 0;

      TransportHeader header =
        demarshal_data<TransportHeader>(tvb, offset);

      return header.length_ + static_cast<guint>(header.max_marshaled_size());
    }
예제 #4
0
static void dissect_hadoop_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint offset  = 0;
    guint length  = 0;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "HADOOP");
    /* Clear out stuff in the info column */
    col_clear(pinfo->cinfo, COL_INFO);
    
    if (tree) 
    {
        proto_item *ti = NULL;
        proto_tree *hadoop_tree = NULL;
    
        /* check the packet length */           
        guint auth = tvb_get_ntohl(tvb, offset);
    
        ti = proto_tree_add_item(tree, proto_hadoop, tvb, 0, -1, ENC_NA);
        hadoop_tree = proto_item_add_subtree(ti, ett_hadoop);
        
        /* first setup packet starts with "hrpc" */
        if (!tvb_memeql(tvb, offset, (const guint8 *)REQUEST_STR, sizeof(REQUEST_STR) - 1)) 
        {
            dissect_hadoop_handshake(tvb, &offset, hadoop_tree);
        } 
        else 
        {
            /* second authentication packet */
            if (auth + 4 != tvb_reported_length(tvb)) 
			{
				        // TODO ??????????????????
                    /* authentication length (read out of first 4 bytes) */
                    //length = tvb_get_ntohl(tvb, offset);
                    //proto_tree_add_item(hdfs_tree, hf_hdfs_authlen, tvb, offset, 4, ENC_ASCII|ENC_NA);
                    offset += 4;
            
                    /* authentication (length the number we just got) */
                    //proto_tree_add_item(hdfs_tree, hf_hdfs_auth, tvb, offset, length, ENC_ASCII|ENC_NA);
                    //offset += length;
					dissect_hadoop_rpc(tvb, &offset, hadoop_tree, pinfo);
			    // IpcConnectionContextProto
			    //dissect_rpc_packet (tvb, &offset, hadoop_tree, 
                //	   string("hadoop.common.IpcConnectionContextProto"), string("IpcConnectionContextProto") );
            }

            offset += 4; // length
            dissect_hadoop_rpc(tvb, &offset, hadoop_tree, pinfo);
        }
    } // end of if (tree)
    
    //return tvb_length(tvb);
}
예제 #5
0
static gboolean
dissect_ymsg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

  if (tvb_memeql(tvb, 0, "YMSG", 4) == -1) {
    /* Not a Yahoo Messenger packet. */
    return FALSE;
  }
  
  tcp_dissect_pdus(tvb, pinfo, tree, ymsg_desegment, 8, get_ymsg_pdu_len,
                   dissect_ymsg_pdu);
  return TRUE;
}
예제 #6
0
static void
cms_verify_msg_digest(proto_item *pi, tvbuff_t *content, const char *alg, tvbuff_t *tvb, int offset)
{
  sha1_context sha1_ctx;
  md5_state_t md5_ctx;
  int i= 0, buffer_size = 0;

  /* we only support two algorithms at the moment  - if we do add SHA2
     we should add a registration process to use a registration process */

  if(strcmp(alg, HASH_SHA1) == 0) {

    sha1_starts(&sha1_ctx);

    sha1_update(&sha1_ctx, tvb_get_ptr(content, 0, tvb_length(content)),
		tvb_length(content));

    sha1_finish(&sha1_ctx, digest_buf);

    buffer_size = SHA1_BUFFER_SIZE;

  } else if(strcmp(alg, HASH_MD5) == 0) {

    md5_init(&md5_ctx);

    md5_append(&md5_ctx, tvb_get_ptr(content, 0, tvb_length(content)),
	       tvb_length(content));

    md5_finish(&md5_ctx, digest_buf);

    buffer_size = MD5_BUFFER_SIZE;
  }

  if(buffer_size) {
    /* compare our computed hash with what we have received */

    if(tvb_bytes_exist(tvb, offset, buffer_size) &&
       (tvb_memeql(tvb, offset, digest_buf, buffer_size) != 0)) {
      proto_item_append_text(pi, " [incorrect, should be ");
      for(i = 0; i < buffer_size; i++)
	proto_item_append_text(pi, "%02X", digest_buf[i]);

      proto_item_append_text(pi, "]");
    }
    else
      proto_item_append_text(pi, " [correct]");
  } else {
    proto_item_append_text(pi, " [unable to verify]");
  }

}
예제 #7
0
/* Code to actually dissect the packets */
static void
dissect_ismp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	int offset = 0;
	guint16 message_type = 0;
	guint8 code_length = 0;
	guint8 weird_stuff[3] = { 0x42, 0x42, 0x03 };

/* Set up structures needed to add the protocol subtree and manage it */
	proto_item *ti;
	proto_tree *ismp_tree;

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

	/*
	 * XXX - I've seen captures with packets that have the ISMP
	 * Ethernet frame type, but with the payload being 0x42 0x42 0x03
	 * followed by what appears to be an ISMP frame.
	 *
	 * 0x4242 is not a valid ISMP version number.
	 */
	if (tvb_memeql(tvb, offset, weird_stuff, sizeof weird_stuff) == 0)
		offset += 3;	/* skip the weird stuff, for now */
	if (tree) {
		/* create display subtree for ismp */
		ti = proto_tree_add_item(tree, proto_ismp, tvb, offset, -1, FALSE);

		ismp_tree = proto_item_add_subtree(ti, ett_ismp);

		/* add an items to the subtree */
		proto_tree_add_item(ismp_tree, hf_ismp_version, tvb, offset, 2, FALSE);
		offset += 2;
		message_type = tvb_get_ntohs(tvb, offset);
		proto_tree_add_item(ismp_tree, hf_ismp_message_type, tvb, offset, 2, FALSE);
		offset += 2;
		proto_tree_add_item(ismp_tree, hf_ismp_seq_num, tvb, offset, 2, FALSE);
		offset += 2;
		code_length = tvb_get_guint8(tvb, offset);
		proto_tree_add_item(ismp_tree, hf_ismp_code_length, tvb, offset, 1, FALSE);
		offset += 1;
		proto_tree_add_item(ismp_tree, hf_ismp_auth_data, tvb, offset, code_length, FALSE);
		offset += code_length;
		
		/* if Enterasys Discover Protocol, dissect it */
		if(message_type == ISMPTYPE_EDP)
			dissect_ismp_edp(tvb, pinfo, offset, tree);
	}

}
예제 #8
0
/* Parses the parameters of a function.
   Parses the type length which is always in 2 bytes.
   Next the type which is the previously found length.
   If this type is variable length it then reads the length of the data
   from 2 bytes and then the data.
   Otherwise reads just the data. */
static void
dissect_params (tvbuff_t *tvb, proto_tree *hdfs_tree, guint offset, int params) {

    guint length;
    int i =  0;
    const guint8* type_name;
    for (i = 0; i < params; i++) {

        /* get length that we just dissected */
        length = tvb_get_ntohs(tvb, offset);

        /* 2 bytes = parameter type length */
        proto_tree_add_item(hdfs_tree, hf_hdfs_namelentwo, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;

        /* length bytes = parameter type */
        proto_tree_add_item(hdfs_tree, hf_hdfs_paramtype, tvb, offset, length, ENC_ASCII|ENC_NA);
        offset += length;

        if (offset >= length && (!tvb_memeql(tvb, offset - length, "long", length) || !tvb_memeql(tvb, offset - length, "int", length) ||
                                 !tvb_memeql(tvb, offset - length, "short", length) || !tvb_memeql(tvb, offset - length, "char", length) ||
                                 !tvb_memeql(tvb, offset - length, "byte", length) || !tvb_memeql(tvb, offset - length, "float", length)
                                 || !tvb_memeql(tvb, offset - length, "double", length) || !tvb_memeql(tvb, offset - length, "boolean", length))) {

            if (!tvb_memeql(tvb, offset - length, "boolean", length)) {
                length = 1;
            } else if (!tvb_memeql(tvb, offset - length, "short", length)) {
                length = 2;
            } else {
                length = sizeof(type_name);
            }

            proto_tree_add_item(hdfs_tree, hf_hdfs_paramvalnum, tvb, offset, length, ENC_BIG_ENDIAN);
            offset += length;

        } else {
            /* get length */
            length = tvb_get_ntohs(tvb, offset);

            /* 2 bytes = parameter value length */
            proto_tree_add_item(hdfs_tree, hf_hdfs_namelentwo, tvb, offset, 2, ENC_BIG_ENDIAN);
            offset += 2;

            proto_tree_add_item(hdfs_tree, hf_hdfs_paramval, tvb, offset, length, ENC_ASCII|ENC_NA);
            offset += length;

            if (!tvb_memeql(tvb, offset - length, "org.apache.hadoop.fs.permission.FsPermission", length)) {
                proto_tree_add_item(hdfs_tree, hf_hdfs_fileperm, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;
            }
        }
    }
}
예제 #9
0
/* Code to actually dissect the packets */
static int
dissect_wol(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint len;
    gint offset;
    guint8 sync[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
    guint8 *mac;
    const guint8 *passwd;

/* Set up structures needed to add the protocol subtree and manage it */
    proto_item *ti;
    proto_item *mti;
    proto_tree *wol_tree;
    proto_tree *mac_tree;

/*  First, if at all possible, do some heuristics to check if the packet cannot
 *  possibly belong to your protocol.  This is especially important for
 *  protocols directly on top of TCP or UDP where port collisions are
 *  common place (e.g., even though your protocol uses a well known port,
 *  someone else may set up, for example, a web server on that port which,
 *  if someone analyzed that web server's traffic in Wireshark, would result
 *  in Wireshark handing an HTTP packet to your dissector).  For example:
 */
    /* Check that there's enough data */
    len = tvb_length(tvb);
    if ( len < 102 )    /* wol's smallest packet size is 102 */
        return (0);

    /* Get some values from the packet header, probably using tvb_get_*() */

    /* Regardless of what the AMD white paper states, don't search the entire
     * tvb for the synchronization stream.  My feeling is that this could be
     * quite expensive and seriously hinder Wireshark performance.  For now,
     * unless we need to change it later, just compare the 1st 6 bytes. */
    if ( tvb_memeql(tvb, 0, sync, 6) != 0 )
        return (0);

    /* So far so good.  Now get the next 6 bytes, which we'll assume is the
     * target's MAC address, and do 15 memory chunk comparisons, since if this
     * is a real MagicPacket, the target's MAC will be duplicated 16 times. */
    mac = ep_tvb_memdup(tvb, 6, 6);
    for ( offset = 12; offset < 102; offset += 6 )
        if ( tvb_memeql(tvb, offset, mac, 6) != 0 )
            return (0);

    /* OK, we're going to assume it's a MagicPacket.  If there's a password,
     * grab it now, and in case there's any extra bytes after the only 3 valid
     * and expected lengths, truncate the length so the extra byte(s) aren't
     * included as being part of the WOL payload. */
    if ( len >= 106 && len < 108 )
    {
        len = 106;
        passwd = tvb_ip_to_str(tvb, 102);
    }
    else if ( len >= 108 )
    {
        len = 108;
        passwd = ether_to_str(ep_tvb_memdup(tvb, 102, 6));
    }
    else
    {
        len = 102;
        passwd = NULL;
    }

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

/* This field shows up as the "Info" column in the display; you should use
   it, if possible, to summarize what's in the packet, so that a user looking
   at the list of packets can tell what type of packet it is. See section 1.5
   for more information.

   Before changing the contents of a column you should make sure the column is
   active by calling "check_col(pinfo->cinfo, COL_*)". If it is not active
   don't bother setting it.

   If you are setting the column to a constant string, use "col_set_str()",
   as it's more efficient than the other "col_set_XXX()" calls.

   If you're setting it to a string you've constructed, or will be
   appending to the column later, use "col_add_str()".

   "col_add_fstr()" can be used instead of "col_add_str()"; it takes
   "printf()"-like arguments.  Don't use "col_add_fstr()" with a format
   string of "%s" - just use "col_add_str()" or "col_set_str()", as it's
   more efficient than "col_add_fstr()".

   If you will be fetching any data from the packet before filling in
   the Info column, clear that column first, in case the calls to fetch
   data from the packet throw an exception because they're fetching data
   past the end of the packet, so that the Info column doesn't have data
   left over from the previous dissector; do

    col_clear(pinfo->cinfo, COL_INFO);

   */

    if ( check_col(pinfo->cinfo, COL_INFO) )
    {
        col_add_fstr(pinfo->cinfo, COL_INFO, "MagicPacket for %s (%s)",
            get_ether_name(mac), ether_to_str(mac));

        /* NOTE: ether-wake uses a dotted-decimal format for specifying a
         * 4-byte password or an Ethernet mac address format for specifying
         * a 6-byte password, so display them in that format, even if the
         * password isn't really an IP or MAC address. */
        if ( passwd )
            col_append_fstr(pinfo->cinfo, COL_INFO, ", password %s", passwd);
    }

/* A protocol dissector can be called in 2 different ways:

    (a) Operational dissection

        In this mode, Wireshark is only interested in the way protocols
        interact, protocol conversations are created, packets are
        reassembled and handed over to higher-level protocol dissectors.
        In this mode Wireshark does not build a so-called "protocol
        tree".

    (b) Detailed dissection

        In this mode, Wireshark is also interested in all details of
        a given protocol, so a "protocol tree" is created.

   Wireshark distinguishes between the 2 modes with the proto_tree pointer:
    (a) <=> tree == NULL
    (b) <=> tree != NULL

   In the interest of speed, if "tree" is NULL, avoid building a
   protocol tree and adding stuff to it, or even looking at any packet
   data needed only if you're building the protocol tree, if possible.

   Note, however, that you must fill in column information, create
   conversations, reassemble packets, build any other persistent state
   needed for dissection, and call subdissectors regardless of whether
   "tree" is NULL or not.  This might be inconvenient to do without
   doing most of the dissection work; the routines for adding items to
   the protocol tree can be passed a null protocol tree pointer, in
   which case they'll return a null item pointer, and
   "proto_item_add_subtree()" returns a null tree pointer if passed a
   null item pointer, so, if you're careful not to dereference any null
   tree or item pointers, you can accomplish this by doing all the
   dissection work.  This might not be as efficient as skipping that
   work if you're not building a protocol tree, but if the code would
   have a lot of tests whether "tree" is null if you skipped that work,
   you might still be better off just doing all that work regardless of
   whether "tree" is null or not. */
    if (tree) {

/* NOTE: The offset and length values in the call to
   "proto_tree_add_item()" define what data bytes to highlight in the hex
   display window when the line in the protocol tree display
   corresponding to that item is selected.

   Supplying a length of -1 is the way to highlight all data from the
   offset to the end of the packet. */

/* create display subtree for the protocol */
        ti = proto_tree_add_item(tree, proto_wol, tvb, 0, len, FALSE);
        proto_item_append_text(ti, ", MAC: %s (%s)", get_ether_name(mac),
            ether_to_str(mac));
        if ( passwd )
            proto_item_append_text(ti, ", password: %s", passwd);
        wol_tree = proto_item_add_subtree(ti, ett_wol);

/* add an item to the subtree, see section 1.6 for more information */
        proto_tree_add_item(wol_tree, hf_wol_sync, tvb, 0, 6, FALSE);

/* Continue adding tree items to process the packet here */
        mti = proto_tree_add_text(wol_tree, tvb, 6, 96, "MAC: %s (%s)",
            get_ether_name(mac), ether_to_str(mac));
        mac_tree = proto_item_add_subtree(mti, ett_wol_macblock);
        for ( offset = 6; offset < 102; offset += 6 )
            proto_tree_add_ether(mac_tree, hf_wol_mac, tvb, offset, 6, mac);

        if ( len == 106 )
            proto_tree_add_bytes_format(wol_tree, hf_wol_passwd, tvb, offset,
                4, passwd, "Password: %s", passwd);
        else if ( len == 108 )
            proto_tree_add_bytes_format(wol_tree, hf_wol_passwd, tvb, offset,
                6, passwd, "Password: %s", passwd);
    }

/* If this protocol has a sub-dissector call it here, see section 1.8 */

/* Return the amount of data this dissector was able to dissect */
    if ( pinfo->ethertype == ETHERTYPE_WOL )
        return (len);

    /* Heuristic dissectors return TRUE/FALSE. */
    return (TRUE);
}
예제 #10
0
static void
dissect_http2_frame_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
{
        proto_item *ti;
        proto_tree *http2_tree;
        guint32 offset = 0;
    
        http2_frame_header frame;

        /* tvb_memeql makes certain there are enough bytes in the buffer.
         * returns -1 if there are not enough bytes or if there is not a
         * match.  Returns 0 on a match */
        if ( tvb_memeql( tvb, offset, kMagicHello, MAGIC_FRAME_LENGTH ) == 0 )
        {
                col_append_sep_str( pinfo->cinfo, COL_INFO, ", ", "Magic" );
                
                ti = proto_tree_add_item(tree, proto_http2, tvb, offset, MAGIC_FRAME_LENGTH, ENC_NA);
                proto_item_append_text( ti, ", Magic" );
                
                http2_tree = proto_item_add_subtree(ti, ett_http2);
                
                proto_tree_add_item(http2_tree, hf_http2_magic, tvb,
                                    offset, MAGIC_FRAME_LENGTH, ENC_BIG_ENDIAN);
                return;
        }


        frame.length   = tvb_get_ntohs( tvb, offset + 0 );
        frame.type     = tvb_get_guint8( tvb, offset + 2 );
        frame.flags    = tvb_get_guint8( tvb, offset + 3 );
        frame.streamid = tvb_get_ntohl( tvb, offset + 4 );

        col_append_sep_fstr( pinfo->cinfo, COL_INFO, ", ", "%s",
                             val_to_str( frame.type, frametypenames, "Unknown (0x%02X)" ) );

    
        /* create display subtree for the protocol */
        ti = proto_tree_add_item(tree, proto_http2, tvb, offset, FRAME_HEADER_LENGTH + frame.length, ENC_NA);

        proto_item_append_text( ti, ", %s", val_to_str( frame.type, frametypenames, "Unknown (0x%02X)" ) );
        proto_item_append_text( ti, ", Length: %d, Flags: %d, streamid: %d",
                                frame.length, frame.flags, frame.streamid );
    
        http2_tree = proto_item_add_subtree(ti, ett_http2);

        /* Add an item to the subtree, see section 1.6 of README.developer for more
         * information. */
        proto_tree_add_item(http2_tree, hf_http2_length, tvb,
                            offset + 0, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(http2_tree, hf_http2_type, tvb,
                            offset + 2, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(http2_tree, hf_http2_flags, tvb,
                            offset + 3, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(http2_tree, hf_http2_streamid, tvb,
                            offset + 4, 4, ENC_BIG_ENDIAN);
        proto_tree_add_item(http2_tree, hf_http2_payload, tvb,
                            offset + 8, frame.length, ENC_BIG_ENDIAN);

        offset += frame.length + FRAME_HEADER_LENGTH;

        return;
}
예제 #11
0
static void
dissect_isdn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree *isdn_tree;
	proto_item *ti;
	static const guint8 v120_sabme[3] = { 0x08, 0x01, 0x7F };
	static const guint8 ppp[2] = { 0xFF, 0x03 };
	circuit_t *circuit;

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

	if (pinfo->pseudo_header->isdn.uton) {
		col_set_str(pinfo->cinfo, COL_RES_DL_DST, "Network");
		col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "User");
	} else {
		col_set_str(pinfo->cinfo, COL_RES_DL_DST, "User");
		col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "Network");
	}

	pinfo->ctype = CT_ISDN;
	pinfo->circuit_id = pinfo->pseudo_header->isdn.channel;

	if (tree) {
		ti = proto_tree_add_item(tree, proto_isdn, tvb, 0, 0, ENC_NA);
		isdn_tree = proto_item_add_subtree(ti, ett_isdn);

		proto_tree_add_uint(isdn_tree, hf_isdn_channel, tvb, 0, 0,
		    pinfo->pseudo_header->isdn.channel);
	}

	/*
	 * Set up a circuit for this channel, and assign it a dissector.
	 */
	circuit = find_circuit(pinfo->ctype, pinfo->circuit_id, pinfo->fd->num);
	if (circuit == NULL)
		circuit = circuit_new(pinfo->ctype, pinfo->circuit_id,
		    pinfo->fd->num);

	if (circuit_get_dissector(circuit) == NULL) {
		/*
		 * We don't yet know the type of traffic on the circuit.
		 */
		switch (pinfo->pseudo_header->isdn.channel) {

		case 0:
			/*
			 * D-channel.  Dissect it with whatever protocol
			 * the user specified, or the default of LAPD if
			 * they didn't specify one.
			 */
			switch (dchannel_protocol) {

			case DCHANNEL_LAPD:
				circuit_set_dissector(circuit, lapd_handle);
				break;

			case DCHANNEL_DPNSS:
				circuit_set_dissector(circuit,
				    dpnss_link_handle);
				break;
			}
			break;

		default:
			/*
			 * B-channel.
			 *
			 * We don't know yet whether the datastream is
			 * V.120 or not; this heuristic tries to figure
			 * that out.
			 *
			 * We cannot glean this from the Q.931 SETUP message,
			 * because no commercial V.120 implementation I've
			 * seen actually sets the V.120 protocol discriminator
			 * (that, or I'm misreading the spec badly).
			 *
			 * TODO: close the circuit after a close on the B
			 * channel is detected.
			 *
			 *	-Bert Driehuis (from the i4btrace reader;
			 *	 this heuristic was moved from there to
			 *	 here)
			 *
			 * XXX - I don't know that one can guarantee that
			 * the SABME will appear in the first frame on
			 * the channels, so we probably can't just say
			 * "it must be PPP" if we don't immediately see
			 * the V.120 SABME frame, so we do so only if
			 * we see the 0xFF 0x03.  Unfortunately, that
			 * won't do the right thing if the PPP-over-HDLC
			 * headers aren't being used....
			 */
			if (tvb_memeql(tvb, 0, v120_sabme, 3) == 0) {
				/*
				 * We assume this is V.120.
				 */
				circuit_set_dissector(circuit, v120_handle);
			} else if (tvb_memeql(tvb, 0, ppp, 2) == 0) {
				/*
				 * We assume this is PPP.
				 */
				circuit_set_dissector(circuit, ppp_hdlc_handle);
			}
			break;
		}
	}

	if (!try_circuit_dissector(pinfo->ctype, pinfo->circuit_id,
		pinfo->fd->num, tvb, pinfo, tree, NULL))
		call_dissector(data_handle, tvb, pinfo, tree);
}
예제 #12
0
/* This function checks the first 16 bytes of the "header" that it looks sane
 * and returns TRUE if this looks like iFCP and FALSE if it doesn't.
 */
static gboolean
ifcp_header_test(tvbuff_t *tvb, int offset)
{
    guint16 flen, flen1;

    /* we can only do this test if we have 16 bytes or more */
    if(tvb_length_remaining(tvb, offset)<iFCP_MIN_HEADER_LEN){
        return FALSE;
    }

    /*
    * As per the iFCP standard, the following tests must PASS:
    * 1)  Frame Length field validation -- 15 < Frame Length < 545;
    * 2)  Comparison of Frame Length field to its ones complement; and
    * 3)  A valid EOF is found in the word preceding the start of the next
    *     iFCP header as indicated by the Frame Length field, to be tested
    *     as follows:
    *     1)  Bits 24-31 and 16-23 contain identical legal EOF values (the
    *         list of legal EOF values is in the FC Frame Encapsulation
    *         [21]); and
    *     2)  Bits 8-15 and 0-7 contain the ones complement of the EOF
    *         value found in bits 24-31.
    *
    * As per the iFCP standard, in addition, at least 3 of the following
    * set of tests must be performed to identify that we've located the
    * start of an iFCP frame.
    * a)  Protocol# ones complement field (1 test);
    * b)  Version ones complement field (1 test);
    * c)  Replication of encapsulation word 0 in word 1 (1 test);
    * d)  Reserved field and its ones complement (2 tests);
    * e)  Flags field and its ones complement (2 tests);
    *    f)  CRC field is equal to zero (1 test); (DON'T DO THIS TEST!)
    * g)  SOF fields and ones complement fields (4 tests);
    * h)  Format and values of FC header (1 test);
    * i)  CRC of FC Frame (2 tests);
    * j)  FC Frame Encapsulation header information in the next iFCP Frame
    *     (1 test).
    *
    * At least 3 of the 16 tests listed above SHALL be performed. Failure
    * of any of the above tests actually performed SHALL indicate an
    * encapsulation error and the FC Frame SHALL NOT be forwarded on to
    * the FC Entity.
    */


    /*
     * Tests a, b and c
     */
    if(tvb_memeql(tvb, offset, ifcp_header_4_bytes, 4) != 0){
        return FALSE;
        }

    /* check the frame length */
    flen=tvb_get_ntohs(tvb, offset+12)&0x03FF;
    if((flen < 15) || (flen > 545)){
        return FALSE;
    }

    /* check the complement of the frame length */
    flen1=tvb_get_ntohs(tvb, offset+14)&0x03FF;
    if(flen!=((~flen1)&0x03FF)){
        return FALSE;
    }


    /* this should be good enough for our heuristics */
    return TRUE;
}
예제 #13
0
static proto_tree *
add_integer_tree(proto_tree *tree, tvbuff_t *tvb, int offset,
                 int name_length, int value_length, guint8 tag)
{
    proto_tree *subtree;
    guint8      bool_val;

    switch (tag) {

    case TAG_BOOLEAN:
        if (value_length != 1) {
            subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                     1 + 2 + name_length + 2 + value_length,
                                     ett_ipp_attr, NULL, "%s: Invalid boolean (length is %u, should be 1)",
                                     tvb_format_text(tvb, offset + 1 + 2, name_length),
                                     value_length);
        } else {
            bool_val = tvb_get_guint8(tvb,
                                      offset + 1 + 2 + name_length + 2);
            subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                     1 + 2 + name_length + 2 + value_length,
                                     ett_ipp_attr, NULL, "%s: %s",
                                     tvb_format_text(tvb, offset + 1 + 2, name_length),
                                     val_to_str(bool_val, bool_vals, "Unknown (0x%02x)"));
        }
        break;

    case TAG_INTEGER:
    case TAG_ENUM:
        if (value_length != 4) {
            subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                     1 + 2 + name_length + 2 + value_length,
                                     ett_ipp_attr, NULL, "%s: Invalid integer (length is %u, should be 4)",
                                     tvb_format_text(tvb, offset + 1 + 2, name_length),
                                     value_length);
        } else {
            const char *name_val;
            /* Some fields in IPP are really unix timestamps but IPP
             * transports these as 4 byte integers.
             * A simple heuristic to make the display of these fields
             * more human readable is to assume that if the field name
             * ends in '-time' then assume they are timestamps instead
             * of integers.
             */
            name_val=tvb_get_ptr(tvb, offset + 1 + 2, name_length);
            if ((name_length > 5) && name_val && !tvb_memeql(tvb, offset + 1 + 2 + name_length - 5, "-time", 5)) {
                subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                         1 + 2 + name_length + 2 + value_length,
                                         ett_ipp_attr, NULL, "%s: %s",
                                         format_text(name_val, name_length),
                                         abs_time_secs_to_str(wmem_packet_scope(), tvb_get_ntohl(tvb, offset + 1 + 2 + name_length + 2),
                                                              ABSOLUTE_TIME_LOCAL,
                                                              TRUE));

            }
            else if ((name_length > 5) && name_val && !tvb_memeql(tvb, offset + 1 + 2, "printer-state", 13)) {
                subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                         1 + 2 + name_length + 2 + value_length,
                                         ett_ipp_attr, NULL, "%s: %s",
                                         format_text(name_val, name_length),
                                         val_to_str_const(tvb_get_ntohl(tvb, offset + 1 + 2 + name_length + 2),
                                                          printer_state_vals,
                                                          "Unknown Printer State"));
            }
            else if ((name_length > 5) && name_val && !tvb_memeql(tvb, offset + 1 + 2, "job-state", 9)) {
                subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                         1 + 2 + name_length + 2 + value_length,
                                         ett_ipp_attr, NULL, "%s: %s",
                                         format_text(name_val, name_length),
                                         val_to_str_const(tvb_get_ntohl(tvb, offset + 1 + 2 + name_length + 2),
                                                          job_state_vals,
                                                          "Unknown Job State"));
            }
            else {
                subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                         1 + 2 + name_length + 2 + value_length,
                                         ett_ipp_attr, NULL, "%s: %u",
                                         format_text(name_val, name_length),
                                         tvb_get_ntohl(tvb, offset + 1 + 2 + name_length + 2));
            }
        }
        break;

    default:
        subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                 1 + 2 + name_length + 2 + value_length,
                                 ett_ipp_attr, NULL, "%s: Unknown integer type 0x%02x",
                                 tvb_format_text(tvb, offset + 1 + 2, name_length),
                                 tag);
        break;
    }
    return subtree;
}
예제 #14
0
/* This routine attempts to locate the position of the next header in the
 * provided segment
 */
static guint
get_next_fcip_header_offset (tvbuff_t *tvb, packet_info *pinfo, gint offset)
{
    gint       bytes_remaining = tvb_reported_length_remaining (tvb, offset);
    gint       frame_len;
    guint16    flen, flen1;
    fcip_eof_t eof, eofc;

    /*
     * As per the FCIP standard, the following tests must PASS:
     * 1)  Frame Length field validation -- 15 < Frame Length < 545;
     * 2)  Comparison of Frame Length field to its ones complement; and
     * 3)  A valid EOF is found in the word preceding the start of the next
     *     FCIP header as indicated by the Frame Length field, to be tested
     *     as follows:
     *     1)  Bits 24-31 and 16-23 contain identical legal EOF values (the
     *         list of legal EOF values is in the FC Frame Encapsulation
     *         [21]); and
     *     2)  Bits 8-15 and 0-7 contain the ones complement of the EOF
     *         value found in bits 24-31.
     *
     * As per the FCIP standard, in addition, at least 3 of the following set
     * of tests must be performed to identify that we've located the start of
     * an FCIP frame.
     * a)  Protocol# ones complement field (1 test);
     * b)  Version ones complement field (1 test);
     * c)  Replication of encapsulation word 0 in word 1 (1 test);
     * d)  Reserved field and its ones complement (2 tests);
     * e)  Flags field and its ones complement (2 tests);
     *    f)  CRC field is equal to zero (1 test); (DON'T DO THIS TEST!)
     * g)  SOF fields and ones complement fields (4 tests);
     * h)  Format and values of FC header (1 test);
     * i)  CRC of FC Frame (2 tests);
     * j)  FC Frame Encapsulation header information in the next FCIP Frame
     *     (1 test).
     *
     * At least 3 of the 16 tests listed above SHALL be performed. Failure
     * of any of the above tests actually performed SHALL indicate an
     * encapsulation error and the FC Frame SHALL NOT be forwarded on to
     * the FC Entity.
     */

NXT_BYTE: while (bytes_remaining) {
        if (bytes_remaining < FCIP_ENCAP_HEADER_LEN) {
            if(fcip_desegment && pinfo->can_desegment) {
                /*
                 * This frame doesn't have all of the data for
                 * the message header, but we can do reassembly on it.
                 *
                 * 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 -2;
            }
        }

        /* I check that we have a valid header before checking for the frame
         * length and the other initial tests.
         */

        /*
         * Tests a, b and c
         */
        if (tvb_memeql(tvb, offset, fcip_header_8_bytes, 8) != 0) {
            offset++;
            bytes_remaining--;
            goto NXT_BYTE;
        }

        flen = (tvb_get_ntohs (tvb, offset+12)) & 0x03FF;
        frame_len = (tvb_get_ntohs (tvb, offset+12) & 0x03FF)*4;

        if ((flen < 15) || (flen > 545)) {
            /* Frame length check failed. Skip byte and try again */
            offset++;
            bytes_remaining--;
            goto NXT_BYTE;
        }

        flen1 = (tvb_get_ntohs (tvb, offset+14)) & 0x03FF;

        if ((flen & 0x03FF) != ((~flen1)&0x03FF)) {
            /* frame_len and its one's complement are not the same */
            offset++;
            bytes_remaining--;
            goto NXT_BYTE;
        }

        /* Valid EOF check */
        if (tvb_bytes_exist (tvb, offset+(frame_len-1)*4, 4)) {
            eof = (fcip_eof_t)tvb_get_guint8 (tvb, offset+(frame_len-1)*4);
            eofc = (fcip_eof_t)tvb_get_guint8 (tvb, offset+(frame_len-1)*4+2);

            if ((eof != FCIP_EOFn) && (eof != FCIP_EOFt) && (eof != FCIP_EOFrt)
                && (eof != FCIP_EOFdt) && (eof != FCIP_EOFni) &&
                (eof != FCIP_EOFdti) && (eof != FCIP_EOFrti) &&
                (eof != FCIP_EOFa)) {
                offset++;
                bytes_remaining--;
                goto NXT_BYTE;
            }

            if ((eof != ~eofc) ||
                (eof != tvb_get_guint8 (tvb, offset+(frame_len-1)*4+1)) ||
                (eofc != tvb_get_guint8 (tvb, offset+(frame_len-1)*4+3))) {
                offset++;
                bytes_remaining--;
                goto NXT_BYTE;
            }
        }

        /* Test d */
        if ((tvb_get_guint8 (tvb, offset+9) != 0) ||
            (tvb_get_guint8 (tvb, offset+11) != 0xFF)) {
            /* Failed */
            offset++;
            bytes_remaining--;
            goto NXT_BYTE;
        }

        /* Test e */


        /* Test f
         * We don't test this since some implementations actually provide
         * a CRC here.
         */

        if (bytes_remaining >= (frame_len)) {
            if (tvb_bytes_exist (tvb, offset+frame_len, 8)) {
                /* The start of the next header matches what we wish to see */
                if (tvb_memeql (tvb, offset+frame_len, fcip_header_8_bytes,
                                8) == 0) {
                    return (offset);
                }
                else {
                    offset++;
                    bytes_remaining--;
                    goto NXT_BYTE;
                }
            }
            else {
                return (offset);
            }
        }
        else {
            if(fcip_desegment && pinfo->can_desegment) {
                /*
                 * This frame doesn't have all of the data for
                 * this message, but we can do reassembly on it.
                 *
                 * 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 = frame_len - bytes_remaining;
                return -2;
            }
            else {
                return (offset);
            }
        }
    }

    return (-1);                /* Unable to find FCIP header */
}
예제 #15
0
/* For details see ICAO doc 9705 Edition 3 SV5 5.6.2.2.2.2 */
static void
dissect_option_atn_security_label(
 const guchar sub_type,
 guchar length,
 tvbuff_t *tvb, 
 guint offset, 
 proto_tree *tree ) {
  proto_item *ti;
  proto_tree *atn_sl_tree = NULL; 
  guchar len = 0;
  guint8 tag_name = 0;
  guint  security_info_end = 0;

	
  /* check for ATN security label */
  if( OSI_OPT_SECURITY_ATN_SR != sub_type ){
     return; } /*  FALLTHROUGH */ 

  /* check Security Registration Length */
  len =  tvb_get_guint8(tvb, ++offset);
  if( OSI_OPT_SECURITY_ATN_SR_LEN != len ){
    return;  } /*  FALLTHROUGH */     

   /* check Security Registration ID */
   if (tvb_memeql(tvb, ++offset , atn_security_registration_val, OSI_OPT_SECURITY_ATN_SR_LEN )){
     return; }  /*  FALLTHROUGH */
   
  ti = proto_tree_add_text( tree, tvb, offset, length,
                            "%s", 
												val_to_str( sub_type, osi_opt_sec_atn_sr_vals, "Unknown (0x%x)"));
											
  atn_sl_tree = proto_item_add_subtree( ti, ott_osi_qos );
  offset+=OSI_OPT_SECURITY_ATN_SR_LEN ;    
		
		/* Security Information length */
   len = tvb_get_guint8(tvb, offset);

   if(OSI_OPT_SECURITY_ATN_SI_MAX_LEN < len){
     /*  FALLTHROUGH */
     return;}

   offset++;

   security_info_end = offset + len;
   while( offset < security_info_end ){

     /* check tag name length*/
     len = tvb_get_guint8(tvb, offset ); /* check tag name length*/
     if( len != 1 ){
         return; } /*  FALLTHROUGH */
     
     offset++;
     
     tag_name = tvb_get_guint8(tvb, offset);
     offset++;

     switch(tag_name){
     case OSI_OPT_SECURITY_ATN_TT:
       /* check tag set length*/
       len = tvb_get_guint8(tvb, offset); 
       if( len != OSI_OPT_SECURITY_ATN_TT_LEN ){
         return; } /*  FALLTHROUGH */

       offset ++;

			 proto_tree_add_uint_format(atn_sl_tree, hf_clnp_atntt, tvb, offset, 1,
                                 tvb_get_guint8(tvb, offset ),
                                 "%s: %s", 
																	val_to_str(  OSI_OPT_SECURITY_ATN_TT, osi_opt_sec_atn_si_vals, "Unknown (0x%x)"),
																	val_to_str( tvb_get_guint8(tvb, offset ), osi_opt_sec_atn_tt_vals, "Unknown (0x%x)") );
						
  			offset += len ;

       break;
     case OSI_OPT_SECURITY_ATN_SC:
       /* check tag set length*/
       len = tvb_get_guint8(tvb, offset ); 
       if( len != OSI_OPT_SECURITY_ATN_SC_LEN ){
         /*  FALLTHROUGH */
         return;
       }
       offset ++;
			 proto_tree_add_uint_format(atn_sl_tree, hf_clnp_atnsc, tvb, offset, 1,
                                 tvb_get_guint8(tvb, offset ),
                                 "%s: %s", 
																	val_to_str(  OSI_OPT_SECURITY_ATN_SC, osi_opt_sec_atn_si_vals, "Unknown (0x%x)"),
																	val_to_str( tvb_get_guint8(tvb, offset ), osi_opt_sec_atn_sc_vals, "Unknown (0x%x)") );

       offset += len ;

       break;
     default:
       /*  FALLTHROUGH */
       return;
     }

   }
 
}
예제 #16
0
static void
dissect_dvb_eit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

	guint       offset = 0, length = 0;
	guint       descriptor_len, descriptor_end;
	guint16     evt_id;

	proto_item *ti;
	proto_tree *dvb_eit_tree;
	proto_item *ei;
	proto_tree *dvb_eit_event_tree;
	proto_item *duration_item;

	nstime_t    start_time;

	col_set_str(pinfo->cinfo, COL_INFO, "Event Information Table (EIT)");

	ti = proto_tree_add_item(tree, proto_dvb_eit, tvb, offset, -1, ENC_NA);
	dvb_eit_tree = proto_item_add_subtree(ti, ett_dvb_eit);

	offset += packet_mpeg_sect_header(tvb, offset, dvb_eit_tree, &length, NULL);
	length -= 4;

	proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_service_id,                  tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_reserved,                    tvb, offset, 1, ENC_BIG_ENDIAN);
	proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_version_number,              tvb, offset, 1, ENC_BIG_ENDIAN);
	proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_current_next_indicator,      tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_section_number,              tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_last_section_number,         tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_transport_stream_id,         tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_original_network_id,         tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_segment_last_section_number, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	proto_tree_add_item(dvb_eit_tree, hf_dvb_eit_last_table_id, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	if (offset >= length) {
		packet_mpeg_sect_crc(tvb, pinfo, dvb_eit_tree, 0, offset);

		return;
	}

	/* Parse all the events */
	while (offset < length) {

		evt_id = tvb_get_ntohs(tvb, offset);
		ei = proto_tree_add_text(dvb_eit_tree, tvb, offset, 12, "Event 0x%04hx", evt_id);
		dvb_eit_event_tree = proto_item_add_subtree(ei, ett_dvb_eit_event);

		proto_tree_add_item(dvb_eit_event_tree, hf_dvb_eit_event_id, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		if (tvb_memeql(tvb, offset, "\xFF\xFF\xFF\xFF\xFF", 5)) {
			if (packet_mpeg_sect_mjd_to_utc_time(tvb, offset, &start_time) < 0) {
				proto_tree_add_text(tree, tvb, offset, 5, "Unparseable time");
			} else {
				proto_tree_add_time_format(dvb_eit_event_tree, hf_dvb_eit_start_time, tvb, offset,
					5, &start_time,
					"Start Time: %s UTC", abs_time_to_str(&start_time, ABSOLUTE_TIME_UTC, FALSE));
			}
		} else {
			proto_tree_add_text(tree, tvb, offset, 5, "Start Time: Undefined (0xFFFFFFFFFF)");
		}
		offset += 5;

		duration_item = proto_tree_add_item(dvb_eit_event_tree, hf_dvb_eit_duration, tvb, offset, 3, ENC_BIG_ENDIAN);
		proto_item_append_text(duration_item, " (%02u:%02u:%02u)",
			MPEG_SECT_BCD44_TO_DEC(tvb_get_guint8(tvb, offset)),
			MPEG_SECT_BCD44_TO_DEC(tvb_get_guint8(tvb, offset + 1)),
			MPEG_SECT_BCD44_TO_DEC(tvb_get_guint8(tvb, offset + 2)));
		offset += 3;

		proto_tree_add_item(dvb_eit_event_tree, hf_dvb_eit_running_status,          tvb, offset, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(dvb_eit_event_tree, hf_dvb_eit_free_ca_mode,            tvb, offset, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(dvb_eit_event_tree, hf_dvb_eit_descriptors_loop_length, tvb, offset, 2, ENC_BIG_ENDIAN);
		descriptor_len = tvb_get_ntohs(tvb, offset) & DVB_EIT_DESCRIPTORS_LOOP_LENGTH_MASK;
		offset += 2;

		descriptor_end = offset + descriptor_len;
		while (offset < descriptor_end)
			offset += proto_mpeg_descriptor_dissect(tvb, offset, dvb_eit_event_tree);

	}

	offset += packet_mpeg_sect_crc(tvb, pinfo, dvb_eit_tree, 0, offset);
	proto_item_set_len(ti, offset);
}
예제 #17
0
/* entry point */
static gboolean dissect_pktgen(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item *ti = NULL;
    proto_item *tmp = NULL;
    proto_tree *pktgen_tree = NULL;
    guint32 offset = 0;
    nstime_t tstamp;

    /* check for min size */
    if(tvb_length(tvb) < 16) { 	/* Not a PKTGEN packet. */
	return FALSE;
    }
    
    /* check for magic number */
    if(tvb_memeql(tvb, 0, pktgen_magic, 4) == -1) { /* Not a PKTGEN packet. */
	return FALSE;
    }
        
    /* Make entries in Protocol column and Info column on summary display */
    
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "PKTGEN");
    
    if(check_col(pinfo->cinfo, COL_INFO)) {
	col_add_fstr(pinfo->cinfo, COL_INFO, "Seq: %u", tvb_get_ntohl(tvb, 4));
    }
    
    if(tree) {
	
	/* create display subtree for the protocol */
	
	ti = proto_tree_add_item(tree, proto_pktgen, tvb, 0, -1, FALSE);
	
	pktgen_tree = proto_item_add_subtree(ti, ett_pktgen);
	
	/* add items to the subtree */
	
	proto_tree_add_item(pktgen_tree, hf_pktgen_magic, tvb, offset, 4, FALSE);
	offset+=4;

	proto_tree_add_item(pktgen_tree, hf_pktgen_seqnum, tvb, offset, 4, FALSE);
	offset+=4;

	tstamp.secs = tvb_get_ntohl(tvb, offset);
	tmp = proto_tree_add_item(pktgen_tree, hf_pktgen_tvsec, tvb, offset, 4, FALSE);
	PROTO_ITEM_SET_GENERATED(tmp);
	offset+=4;

	tstamp.nsecs = tvb_get_ntohl(tvb, offset) /* microsecond on the wire so... */ * 1000;
	tmp = proto_tree_add_item(pktgen_tree, hf_pktgen_tvusec, tvb, offset, 4, FALSE);
	PROTO_ITEM_SET_GENERATED(tmp);
	offset+=4;
	
	proto_tree_add_time(pktgen_tree, hf_pktgen_timestamp, tvb, offset - 8, 8, &tstamp);
	
#if 0
	if(tvb_length_remaining(tvb, offset)) /* random data */
	    proto_tree_add_text(pktgen_tree, tvb, offset, -1, "Data (%u bytes)",
				tvb_length_remaining(tvb, offset));
#else
	if(tvb_length_remaining(tvb, offset)) /* random data */
	    call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo,
		pktgen_tree);
#endif
    }

    return TRUE;
}
예제 #18
0
static int
dissect_mpls_y1711(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree      *mpls_y1711_tree = NULL;
    struct mplsinfo *mplsinfo        = pinfo->private_data;
    proto_item      *ti              = NULL;
    int              functype        = -1;
    int              offset          = 0;

    const guint8 allone[]  = { 0xff, 0xff };
    const guint8 allzero[] = { 0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00,
                               0x00, 0x00, 0x00, 0x00, 0x00 };

    /*
     * if called with main tree == null just set col info with func type
     * string and return
     */
    if (!tree) {
        if (check_col(pinfo->cinfo, COL_INFO)) {
            if (tvb_bytes_exist(tvb, offset, 1)) {
                functype = tvb_get_guint8(tvb, offset);
                col_append_fstr(pinfo->cinfo, COL_INFO, " (Y.1711: %s)",
                                (functype == 0x01) ? "CV" :
                                (functype == 0x02) ? "FDI" :
                                (functype == 0x03) ? "BDI" :
                                (functype == 0x07) ? "FDD" :
                                "reserved/unknown");
            }
        }
        return 0;
    }

    /* sanity checks */
    if (!tvb_bytes_exist(tvb, offset, 44)) {
        /*
         * ITU-T Y.1711, 5.3: PDUs must have a minimum payload length of
         * 44 bytes
         */
        proto_tree_add_text(tree, tvb, offset, -1,
                            "Error: must have a minimum payload "
                            "length of 44 bytes");
        return 0;
    }

    ti = proto_tree_add_text(tree, tvb, offset, 44, "Y.1711 OAM");
    mpls_y1711_tree = proto_item_add_subtree(ti, ett_mpls_y1711);

    if (!mpls_y1711_tree)
        return 0;

    /* checks for exp, bos and ttl encoding */
    if (mplsinfo->label != LABEL_OAM_ALERT)
        proto_tree_add_text(mpls_y1711_tree, tvb, offset - 4, 3,
                            "Warning: Y.1711 but no OAM alert label (%d) ?!",
                            LABEL_OAM_ALERT);

    if (mplsinfo->exp != 0)
        proto_tree_add_text(mpls_y1711_tree, tvb, offset - 2, 1,
                            "Warning: Exp bits should be 0 for Y.1711");

    if (mplsinfo->bos != 1)
        proto_tree_add_text(mpls_y1711_tree, tvb, offset - 2, 1,
                            "Warning: S bit should be 1 for Y.1711");

    if (mplsinfo->ttl != 1)
        proto_tree_add_text(mpls_y1711_tree, tvb, offset - 1, 1,
                            "Warning: TTL should be 1 for Y.1711");

    /* starting dissection */
    functype = tvb_get_guint8(tvb, offset);
    proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_function_type, tvb,
                        offset, 1,
                        ENC_LITTLE_ENDIAN);
    offset++;

    switch (functype) {
    case 0x01: /* CV */
    {
        guint32 lsrid_ipv4addr;

        /* 3 octets reserved (all 0x00) */
        if (tvb_memeql(tvb, offset, allzero, 3) == -1) {
            proto_tree_add_text(mpls_y1711_tree, tvb, offset, 3,
                                "Error: these bytes are reserved and "
                                "must be 0x00");
        }
        offset += 3;

        /* ttsi (ipv4 flavor as in RFC 2373) */
        if (tvb_memeql(tvb, offset, allzero, 10) == -1) {
            proto_tree_add_text(mpls_y1711_tree, tvb, offset, 10,
                                "Error: these bytes are padding "
                                "and must be 0x00");
        }
        offset += 10;

        if (tvb_memeql(tvb, offset, allone, 2) == -1) {
            proto_tree_add_text(mpls_y1711_tree, tvb, offset, 2,
                                "Error: these bytes are padding "
                                "and must be 0xFF");
        }
        offset += 2;

        lsrid_ipv4addr = tvb_get_ipv4(tvb, offset);
        proto_tree_add_text(mpls_y1711_tree, tvb, offset, 4, "LSR ID: %s",
                            ip_to_str((guint8 *) &lsrid_ipv4addr));
        offset += 4;

        proto_tree_add_text(mpls_y1711_tree, tvb, offset, 4, "LSP ID: %d",
                            tvb_get_ntohl(tvb, offset));
        offset += 4;

        /* 18 octets of padding (all 0x00) */
        if (tvb_memeql(tvb, offset, allzero, 18) == -1) {
            proto_tree_add_text(mpls_y1711_tree, tvb, offset, 18,
                                "Error: these bytes are padding "
                                "and must be 0x00");
        }
        offset += 18;
    }
    break;

    case 0x02: /* FDI */
    case 0x03: /* BDI */
    {
        guint32 lsrid_ipv4addr;

        /* 1 octets reserved (all 0x00) */
        if (tvb_memeql(tvb, offset, allzero, 1) == -1) {
            proto_tree_add_text(mpls_y1711_tree, tvb, offset, 3,
                                "Error: this byte is reserved "
                                "and must be 0x00");
        }
        offset++;

        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_defect_type, tvb,
                            offset, 2,
                            ENC_LITTLE_ENDIAN);
        offset += 2;

        /*
         * ttsi (ipv4 flavor as in RFC 2373) is optional if not used must
         * be set to all 0x00
         */
        if (tvb_memeql(tvb, offset, allzero, 20) == 0) {
            proto_tree_add_text(mpls_y1711_tree, tvb, offset, 20,
                                "TTSI not preset (optional for FDI/BDI)");
            offset += 20;
        } else {
            if (tvb_memeql(tvb, offset, allzero, 10) == -1) {
                proto_tree_add_text(mpls_y1711_tree, tvb, offset, 10,
                                    "Error: these bytes are padding and "
                                    "must be 0x00");
            }
            offset += 10;

            if (tvb_memeql(tvb, offset, allone, 2) == -1) {
                proto_tree_add_text(mpls_y1711_tree, tvb, offset, 2,
                                    "Error: these bytes are padding and "
                                    "must be 0xFF");
            }
            offset += 2;

            lsrid_ipv4addr = tvb_get_ipv4(tvb, offset);
            proto_tree_add_text(mpls_y1711_tree, tvb, offset, 4, "LSR ID: %s",
                                ip_to_str((guint8 *) &lsrid_ipv4addr));
            offset += 4;

            proto_tree_add_text(mpls_y1711_tree, tvb, offset, 4, "LSP ID: %d",
                                tvb_get_ntohl(tvb, offset));
            offset += 4;
        }

        /* defect location */
        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_defect_location, tvb,
                            offset, 4,
                            ENC_LITTLE_ENDIAN);
        offset += 4;

        /* 14 octets of padding (all 0x00) */
        if (tvb_memeql(tvb, offset, allzero, 14) == -1) {
            proto_tree_add_text(mpls_y1711_tree, tvb, offset, 14,
                                "Error: these bytes are padding "
                                "and must be 0x00");
        }
        offset += 14;
    }
    break;

    case 0x07: /* FDD */
    {
        guint32 lsrid_ipv4addr;

        /* 3 octets reserved (all 0x00) */
        if (tvb_memeql(tvb, offset, allzero, 3) == -1) {
            proto_tree_add_text(mpls_y1711_tree, tvb, offset, 3,
                                "Error: these bytes are "
                                "reserved and must be 0x00");
        }
        offset += 3;

        /* ttsi (ipv4 flavor as in RFC 2373) */
        if (tvb_memeql(tvb, offset, allzero, 10) == -1) {
            proto_tree_add_text(mpls_y1711_tree, tvb, offset, 10,
                                "Error: these bytes are padding and "
                                "must be 0x00");
        }
        offset += 10;

        if (tvb_memeql(tvb, offset, allone, 2) == -1) {
            proto_tree_add_text(mpls_y1711_tree, tvb, offset, 2,
                                "Error: these bytes are padding and "
                                "must be 0xFF");
        }
        offset += 2;

        lsrid_ipv4addr = tvb_get_ipv4(tvb, offset);
        proto_tree_add_text(mpls_y1711_tree, tvb, offset, 4, "LSR ID: %s",
                            ip_to_str((guint8 *)&lsrid_ipv4addr));
        offset += 4;

        proto_tree_add_text(mpls_y1711_tree, tvb, offset, 4, "LSP ID: %d",
                            tvb_get_ntohl(tvb,offset));
        offset += 4;

        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_frequency, tvb,
                            offset, 1,
                            ENC_LITTLE_ENDIAN);
        offset++;

        /* 17 octets of padding (all 0x00) */
        if (tvb_memeql(tvb, offset, allzero, 17) == -1) {
            proto_tree_add_text(mpls_y1711_tree, tvb, offset, 17,
                                "Error: these bytes are padding and "
                                "must be 0x00");
        }
        offset += 17;
    }
    break;

    default:
        proto_tree_add_text(mpls_y1711_tree, tvb, offset - 1, -1,
                            "Unknown MPLS Y.1711 PDU");
        return offset;
    }

    /* BIP16 */
    proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_bip16, tvb, offset, 2,
                        ENC_LITTLE_ENDIAN);
    offset += 2;

    return offset;
}
예제 #19
0
static void
dissect_ntp_std(tvbuff_t *tvb, proto_tree *ntp_tree, guint8 flags)
{
	proto_tree      *flags_tree;
	proto_item	*tf;
	guint8		 stratum;
	guint8		 ppoll;
	gint8		 precision;
	double		 rootdelay;
	double		 rootdispersion;
	guint32		 refid_addr;
	const gchar	*buffc;
	gchar           *buff;
	int		 i;
	int		 macofs;
	gint		 maclen;

	tf = proto_tree_add_uint(ntp_tree, hf_ntp_flags, tvb, 0, 1, flags);

	/* Adding flag subtree and items */
	flags_tree = proto_item_add_subtree(tf, ett_ntp_flags);
	proto_tree_add_uint(flags_tree, hf_ntp_flags_li, tvb, 0, 1, flags);
	proto_tree_add_uint(flags_tree, hf_ntp_flags_vn, tvb, 0, 1, flags);
	proto_tree_add_uint(flags_tree, hf_ntp_flags_mode, tvb, 0, 1, flags);

	/* Stratum, 1byte field represents distance from primary source
	 */
	stratum = tvb_get_guint8(tvb, 1);
	if (stratum == 0) {
		buffc="Peer Clock Stratum: unspecified or invalid (%u)";
	} else if (stratum == 1) {
		buffc="Peer Clock Stratum: primary reference (%u)";
	} else if ((stratum >= 2) && (stratum <= 15)) {
		buffc="Peer Clock Stratum: secondary reference (%u)";
	} else if (stratum == 16) {
		buffc="Peer Clock Stratum: unsynchronized (%u)";
	} else {
		buffc="Peer Clock Stratum: reserved: %u";
	}
	proto_tree_add_uint_format(ntp_tree, hf_ntp_stratum, tvb, 1, 1,
				   stratum, buffc, stratum);
	/* Poll interval, 1byte field indicating the maximum interval
	 * between successive messages, in seconds to the nearest
	 * power of two.
	 */
	ppoll = tvb_get_guint8(tvb, 2);
	if ((ppoll >= 4) && (ppoll <= 17)) {
		proto_tree_add_uint_format(ntp_tree, hf_ntp_ppoll, tvb, 2, 1,
				   ppoll,
				   "Peer Polling Interval: %u (%u sec)",
				   ppoll,
				   1 << ppoll);
	} else {
		proto_tree_add_uint_format(ntp_tree, hf_ntp_ppoll, tvb, 2, 1,
				   ppoll,
				   "Peer Polling Interval: invalid (%u)",
				   ppoll);
	}

	/* Precision, 1byte field indicating the precision of the
	 * local clock, in seconds to the nearest power of two.
	 */
	precision = tvb_get_guint8(tvb, 3);
	proto_tree_add_int_format(ntp_tree, hf_ntp_precision, tvb, 3, 1,
				   precision,
				   "Peer Clock Precision: %8.6f sec",
				   pow(2, precision));

	/* Root Delay is a 32-bit signed fixed-point number indicating
	 * the total roundtrip delay to the primary reference source,
	 * in seconds with fraction point between bits 15 and 16.
	 */
	rootdelay = ((gint16)tvb_get_ntohs(tvb, 4)) +
			(tvb_get_ntohs(tvb, 6) / 65536.0);
	proto_tree_add_double_format(ntp_tree, hf_ntp_rootdelay, tvb, 4, 4,
				   rootdelay,
				   "Root Delay: %9.4f sec",
				   rootdelay);

	/* Root Dispersion, 32-bit unsigned fixed-point number indicating
	 * the nominal error relative to the primary reference source, in
	 * seconds with fraction point between bits 15 and 16.
	 */
	rootdispersion = ((gint16)tvb_get_ntohs(tvb, 8)) +
				(tvb_get_ntohs(tvb, 10) / 65536.0);
	proto_tree_add_double_format(ntp_tree, hf_ntp_rootdispersion, tvb, 8, 4,
				   rootdispersion,
				   "Root Dispersion: %9.4f sec",
				   rootdispersion);

	/* Now, there is a problem with secondary servers.  Standards
	 * asks from stratum-2 - stratum-15 servers to set this to the
	 * low order 32 bits of the latest transmit timestamp of the
	 * reference source.
	 * But, all V3 and V4 servers set this to IP address of their
	 * higher level server. My decision was to resolve this address.
	 */
	buff = ep_alloc(NTP_TS_SIZE);
	if (stratum <= 1) {
		g_snprintf (buff, NTP_TS_SIZE, "Unidentified reference source '%.4s'",
			tvb_get_ephemeral_string(tvb, 12, 4));
		for (i = 0; primary_sources[i].id; i++) {
			if (tvb_memeql(tvb, 12, primary_sources[i].id, 4) == 0) {
				g_snprintf(buff, NTP_TS_SIZE, "%s",
					primary_sources[i].data);
				break;
			}
		}
	} else {
		int buffpos;
		refid_addr = tvb_get_ipv4(tvb, 12);
		buffpos = g_snprintf(buff, NTP_TS_SIZE, "%s", get_hostname (refid_addr));
		if (buffpos >= NTP_TS_SIZE) {
			buff[NTP_TS_SIZE-4]='.';
			buff[NTP_TS_SIZE-3]='.';
			buff[NTP_TS_SIZE-2]='.';
			buff[NTP_TS_SIZE-1]=0;
		}
	}
	proto_tree_add_bytes_format(ntp_tree, hf_ntp_refid, tvb, 12, 4,
				    NULL, "Reference ID: %s", buff);

	/* Reference Timestamp: This is the time at which the local clock was
	 * last set or corrected.
	 */
	proto_tree_add_item(ntp_tree, hf_ntp_reftime, tvb, 16, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);

	/* Originate Timestamp: This is the time at which the request departed
	 * the client for the server.
	 */
	proto_tree_add_item(ntp_tree, hf_ntp_org, tvb, 24, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);

	/* Receive Timestamp: This is the time at which the request arrived at
	 * the server.
	 */
	proto_tree_add_item(ntp_tree, hf_ntp_rec, tvb, 32, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);

	/* Transmit Timestamp: This is the time at which the reply departed the
	 * server for the client.
	 */
	proto_tree_add_item(ntp_tree, hf_ntp_xmt, tvb, 40, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);

	/* MAX_MAC_LEN is the largest message authentication code
	 * (MAC) length.  If we have more data left in the packet
	 * after the header than that, the extra data is NTP4
	 * extensions; parse them as such.
	 */
	macofs = 48;
	while (tvb_reported_length_remaining(tvb, macofs) > (gint)MAX_MAC_LEN)
		macofs = dissect_ntp_ext(tvb, ntp_tree, macofs);

	/* When the NTP authentication scheme is implemented, the
	 * Key Identifier and Message Digest fields contain the
	 * message authentication code (MAC) information defined in
	 * Appendix C of RFC-1305. Will print this as hex code for now.
	 */
	if (tvb_reported_length_remaining(tvb, macofs) >= 4)
		proto_tree_add_item(ntp_tree, hf_ntp_keyid, tvb, macofs, 4,
				    ENC_NA);
	macofs += 4;
	maclen = tvb_reported_length_remaining(tvb, macofs);
	if (maclen > 0)
		proto_tree_add_item(ntp_tree, hf_ntp_mac, tvb, macofs,
				    maclen, ENC_NA);
}
예제 #20
0
static int
dissect_headers(proto_tree *tree, tvbuff_t *tvb, int offset, packet_info *pinfo)
{
    proto_tree *hdrs_tree   = NULL;
    proto_tree *hdr_tree    = NULL;
    proto_item *hdr         = NULL;
    proto_item *handle_item;
    gint        item_length = -1;
    guint8      hdr_id, i;

    if (tvb_length_remaining(tvb, offset) > 0) {
        proto_item *hdrs;
        hdrs      = proto_tree_add_text(tree, tvb, offset, item_length, "Headers");
        hdrs_tree = proto_item_add_subtree(hdrs, ett_btobex_hdrs);
    }
    else {
        return offset;
    }

    while (tvb_length_remaining(tvb, offset) > 0) {
        hdr_id = tvb_get_guint8(tvb, offset);

        switch(0xC0 & hdr_id)
        {
            case 0x00: /* null terminated unicode */
                item_length = tvb_get_ntohs(tvb, offset+1);
                break;
            case 0x40:  /* byte sequence */
                item_length = tvb_get_ntohs(tvb, offset+1);
                break;
            case 0x80:  /* 1 byte */
                item_length = 2;
                break;
            case 0xc0:  /* 4 bytes */
                item_length = 5;
                break;
        }

        hdr = proto_tree_add_text(hdrs_tree, tvb, offset, item_length, "%s",
                                  val_to_str_ext_const(hdr_id, &header_id_vals_ext, "Unknown"));
        hdr_tree = proto_item_add_subtree(hdr, ett_btobex_hdr);

        proto_tree_add_item(hdr_tree, hf_hdr_id, tvb, offset, 1, ENC_BIG_ENDIAN);

        offset++;

        switch(0xC0 & hdr_id)
        {
            case 0x00: /* null terminated unicode */
                {
                    proto_tree_add_item(hdr_tree, hf_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN);
                    offset += 2;

                    if ((item_length - 3) > 0) {
                        char *str;

                        display_unicode_string(tvb, hdr_tree, offset, &str);
                        proto_item_append_text(hdr_tree, " (\"%s\")", str);
                        col_append_fstr(pinfo->cinfo, COL_INFO, " \"%s\"", str);
                    }
                    else {
                        col_append_str(pinfo->cinfo, COL_INFO, " \"\"");
                    }

                    offset += item_length - 3;
                }
                break;
            case 0x40:  /* byte sequence */
                proto_tree_add_item(hdr_tree, hf_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;

                handle_item = proto_tree_add_item(hdr_tree, hf_hdr_val_byte_seq, tvb, offset, item_length - 3, ENC_NA);

                if (((hdr_id == 0x46) || (hdr_id == 0x4a)) && (item_length == 19)) { /* target or who */
                    for(i=0; target_vals[i].strptr != NULL; i++) {
                        if (tvb_memeql(tvb, offset, target_vals[i].value, 16) == 0) {
                            proto_item_append_text(handle_item, ": %s", target_vals[i].strptr);
                            proto_item_append_text(hdr_tree, " (%s)", target_vals[i].strptr);
                            col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", target_vals[i].strptr);
                        }
                    }
                }

                if (!tvb_strneql(tvb, offset, "<?xml", 5))
                {
                    tvbuff_t* next_tvb = tvb_new_subset_remaining(tvb, offset);

                    call_dissector(xml_handle, next_tvb, pinfo, tree);
                }
                else if (is_ascii_str(tvb_get_ptr(tvb, offset,item_length - 3), item_length - 3))
                {
                    proto_item_append_text(hdr_tree, " (\"%s\")", tvb_get_ephemeral_string(tvb, offset,item_length - 3));
                    col_append_fstr(pinfo->cinfo, COL_INFO, " \"%s\"", tvb_get_ephemeral_string(tvb, offset,item_length - 3));
                }

                offset += item_length - 3;
                break;
            case 0x80:  /* 1 byte */
                proto_item_append_text(hdr_tree, " (%i)", tvb_get_ntohl(tvb, offset));
                proto_tree_add_item(hdr_tree, hf_hdr_val_byte, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset++;
                break;
            case 0xc0:  /* 4 bytes */
                proto_item_append_text(hdr_tree, " (%i)", tvb_get_ntohl(tvb, offset));
                proto_tree_add_item(hdr_tree, hf_hdr_val_long, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
            default:
                break;
        }
    }

    return offset;
}
예제 #21
0
static gboolean
dissect_yhoo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree      *yhoo_tree, *ti;
	int		 offset = 0;

	if (pinfo->srcport != TCP_PORT_YHOO && pinfo->destport != TCP_PORT_YHOO) {
		/* Not the Yahoo port - not a Yahoo Messenger packet. */
		return FALSE;
	}

	/* get at least a full packet structure */
	if ( tvb_length(tvb) < YAHOO_RAWPACKET_LEN ) {
		/* Not enough data captured; maybe it is a Yahoo
		   Messenger packet, but it contains too little data to
		   tell. */
		return FALSE;
	}

	if (tvb_memeql(tvb, offset, "YPNS", 4) != 0 &&
	    tvb_memeql(tvb, offset, "YHOO", 4) != 0) {
		/* Not a Yahoo Messenger packet. */
		return FALSE;
	}

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

	if (check_col(pinfo->cinfo, COL_INFO)) {
		col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %s",
			     ( tvb_memeql(tvb, offset + 0, "YPNS", 4) == 0 ) ? "Request" : "Response",
			     val_to_str(tvb_get_letohl(tvb, offset + 12),
					yhoo_service_vals, "Unknown Service: %u"));
	}

	if (tree) {
		ti = proto_tree_add_item(tree, proto_yhoo, tvb,
			offset, -1, ENC_NA);
		yhoo_tree = proto_item_add_subtree(ti, ett_yhoo);

		proto_tree_add_item(yhoo_tree, hf_yhoo_version, tvb,
			offset, 8, ENC_ASCII|ENC_NA);
		offset += 8;

		proto_tree_add_item(yhoo_tree, hf_yhoo_len, tvb,
			offset, 4, ENC_LITTLE_ENDIAN);
		offset += 4;

		proto_tree_add_item(yhoo_tree, hf_yhoo_service, tvb,
			offset, 4, ENC_LITTLE_ENDIAN);
		offset += 4;

		proto_tree_add_item(yhoo_tree, hf_yhoo_connection_id, tvb,
			offset, 4, ENC_LITTLE_ENDIAN);
		offset += 4;

		proto_tree_add_item(yhoo_tree, hf_yhoo_magic_id, tvb,
			offset, 4, ENC_LITTLE_ENDIAN);
		offset += 4;

		proto_tree_add_item(yhoo_tree, hf_yhoo_unknown1, tvb,
			offset, 4, ENC_LITTLE_ENDIAN);
		offset += 4;

		proto_tree_add_item(yhoo_tree, hf_yhoo_msgtype, tvb,
			offset, 4, ENC_LITTLE_ENDIAN);
		offset += 4;

		proto_tree_add_item(yhoo_tree, hf_yhoo_nick1, tvb,
			offset, 36, ENC_ASCII|ENC_NA);
		offset += 36;

		proto_tree_add_item(yhoo_tree, hf_yhoo_nick2, tvb,
			offset, 36, ENC_ASCII|ENC_NA);
		offset += 36;

		proto_tree_add_item(yhoo_tree, hf_yhoo_content, tvb, -1,
			offset, ENC_ASCII|ENC_NA);
	}

	return TRUE;
}
예제 #22
0
/* entry point */
static gboolean dissect_lanforge(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item *ti;
    proto_item *tmp;
    proto_tree *lanforge_tree;
    guint32 offset = 0;
    nstime_t tstamp;
    guint32 tss;
    guint32 tmpi;
    guint32 pld_len;

    /* check for min size */
    if(tvb_length(tvb) < 28) {  /* Not a LANforge packet. */
        return FALSE;
    }

    /* check for magic number */
    if(tvb_memeql(tvb, 4, lanforge_magic, 4) == -1) { /* Not a LANforge packet. */
       return FALSE;
    }

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

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

    if(check_col(pinfo->cinfo, COL_INFO)) {
        col_add_fstr(pinfo->cinfo, COL_INFO, "Seq: %u", tvb_get_ntohl(tvb, 16));
    }

    if(tree) {

        /* create display subtree for the protocol */

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

        lanforge_tree = proto_item_add_subtree(ti, ett_lanforge);

        /* add items to the subtree */

        proto_tree_add_item(lanforge_tree, hf_lanforge_crc, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset+=4;

        proto_tree_add_item(lanforge_tree, hf_lanforge_magic, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset+=4;

        proto_tree_add_item(lanforge_tree, hf_lanforge_src_session, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset+=2;

        proto_tree_add_item(lanforge_tree, hf_lanforge_dst_session, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset+=2;

        pld_len = tvb_get_ntohs(tvb, offset);
        tmp = proto_tree_add_item(lanforge_tree, hf_lanforge_pld_len_l, tvb, offset, 2, ENC_BIG_ENDIAN);
        PROTO_ITEM_SET_GENERATED(tmp);
        offset+=2;

        tmpi = tvb_get_guint8(tvb, offset);
        tmp = proto_tree_add_item(lanforge_tree, hf_lanforge_pld_len_h, tvb, offset, 1, ENC_BIG_ENDIAN);
        PROTO_ITEM_SET_GENERATED(tmp);
        offset+=1;
        pld_len |= (tmpi << 16);

        proto_tree_add_uint(lanforge_tree, hf_lanforge_pld_len, tvb, offset-3, 3, pld_len);

        proto_tree_add_item(lanforge_tree, hf_lanforge_pld_pattern, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset+=1;

        proto_tree_add_item(lanforge_tree, hf_lanforge_seq, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset+=4;

        tss = tvb_get_ntohl(tvb, offset);
        tstamp.secs = tss;
        tmp = proto_tree_add_item(lanforge_tree, hf_lanforge_tx_time_s, tvb, offset, 4, ENC_BIG_ENDIAN);
        PROTO_ITEM_SET_GENERATED(tmp);
        offset+=4;

        tss = tvb_get_ntohl(tvb, offset);
        tstamp.nsecs = tss;
        tmp = proto_tree_add_item(lanforge_tree, hf_lanforge_tx_time_ns, tvb, offset, 4, ENC_BIG_ENDIAN);
        PROTO_ITEM_SET_GENERATED(tmp);
        offset+=4;

        proto_tree_add_time(lanforge_tree, hf_lanforge_timestamp, tvb, offset - 8, 8, &tstamp);

#if 0
        if(tvb_reported_length_remaining(tvb, offset) > 0) /* random data */
            proto_tree_add_text(lanforge_tree, tvb, offset, -1, "Data (%u bytes)",
                                tvb_length_remaining(tvb, offset));
#else
        if(tvb_reported_length_remaining(tvb, offset) > 0) /* random data */
            call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo,
                lanforge_tree);
#endif
    }

    return TRUE;
}
예제 #23
0
static void
dissect_raw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  proto_tree	*fh_tree;
  proto_item	*ti;
  tvbuff_t	*next_tvb;

  /* load the top pane info. This should be overwritten by
     the next protocol in the stack */
  col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "N/A");
  col_set_str(pinfo->cinfo, COL_RES_DL_DST, "N/A");
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "N/A");
  col_set_str(pinfo->cinfo, COL_INFO, "Raw packet data");

  /* populate a tree in the second pane with the status of the link
     layer (ie none) */
  if (tree) {
    ti = proto_tree_add_item(tree, proto_raw, tvb, 0, 0, ENC_NA);
    fh_tree = proto_item_add_subtree(ti, ett_raw);
    proto_tree_add_text(fh_tree, tvb, 0, 0, "No link information available");
  }

  if (pinfo->fd->lnk_t == WTAP_ENCAP_RAW_IP4) {
    call_dissector(ip_handle, tvb, pinfo, tree);
  }
  else if (pinfo->fd->lnk_t == WTAP_ENCAP_RAW_IP6) {
    call_dissector(ipv6_handle, tvb, pinfo, tree);
  }
  else

  /* So far, the only time we get raw connection types are with Linux and
   * Irix PPP connections.  We can't tell what type of data is coming down
   * the line, so our safest bet is IP. - GCC
   */

  /* Currently, the Linux 2.1.xxx PPP driver passes back some of the header
   * sometimes.  This check should be removed when 2.2 is out.
   */
  if (tvb_get_ntohs(tvb, 0) == 0xff03) {
	call_dissector(ppp_hdlc_handle, tvb, pinfo, tree);
  }
  /* The Linux ISDN driver sends a fake MAC address before the PPP header
   * on its ippp interfaces... */
  else if (tvb_get_ntohs(tvb, 6) == 0xff03) {
	next_tvb = tvb_new_subset_remaining(tvb, 6);
	call_dissector(ppp_hdlc_handle, next_tvb, pinfo, tree);
  }
  /* ...except when it just puts out one byte before the PPP header... */
  else if (tvb_get_ntohs(tvb, 1) == 0xff03) {
	next_tvb = tvb_new_subset_remaining(tvb, 1);
	call_dissector(ppp_hdlc_handle, next_tvb, pinfo, tree);
  }
  /* ...and if the connection is currently down, it sends 10 bytes of zeroes
   * instead of a fake MAC address and PPP header. */
  else if (tvb_memeql(tvb, 0, zeroes,10) == 0) {
	next_tvb = tvb_new_subset_remaining(tvb, 10);
	call_dissector(ip_handle, next_tvb, pinfo, tree);
  }
  else {
	/*
	 * OK, is this IPv4 or IPv6?
	 */
	switch (tvb_get_guint8(tvb, 0) & 0xF0) {

	case 0x40:
	  /* IPv4 */
	  call_dissector(ip_handle, tvb, pinfo, tree);
	  break;

	case 0x60:
	  /* IPv6 */
	  call_dissector(ipv6_handle, tvb, pinfo, tree);
	  break;

	default:
	  /* None of the above. */
	  call_dissector(data_handle, tvb, pinfo, tree);
	  break;
	}
  }
}
예제 #24
0
static int
dissect_mpls_y1711(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
    struct mplsinfo *mplsinfo;
    int              offset          = 0;
    proto_item      *ti;
    proto_tree      *mpls_y1711_tree;
    int              functype;
    tvbuff_t        *data_tvb;

    static const guint8 allone[]  = { 0xff, 0xff };
    static const guint8 allzero[] = { 0x00, 0x00, 0x00, 0x00, 0x00,
                                      0x00, 0x00, 0x00, 0x00, 0x00,
                                      0x00, 0x00, 0x00, 0x00, 0x00,
                                      0x00, 0x00, 0x00, 0x00, 0x00 };

    /* Reject the packet if data is NULL */
    if (data == NULL)
        return 0;
    mplsinfo = (struct mplsinfo *)data;

    functype = tvb_get_guint8(tvb, offset);
    col_append_fstr(pinfo->cinfo, COL_INFO, " (Y.1711: %s)",
                    (functype == 0x01) ? "CV" :
                    (functype == 0x02) ? "FDI" :
                    (functype == 0x03) ? "BDI" :
                    (functype == 0x07) ? "FDD" :
                    "reserved/unknown");

    /* sanity checks */
    if (tvb_reported_length(tvb) < 44) {
        /*
         * ITU-T Y.1711, 5.3: PDUs must have a minimum payload length of
         * 44 bytes
         */
        proto_tree_add_expert(tree, pinfo, &ei_mpls_y1711_minimum_payload, tvb, offset, -1);
        data_tvb = tvb_new_subset_remaining(tvb, offset);
        call_dissector(data_handle, data_tvb, pinfo, tree);

        return tvb_reported_length(tvb);
    }

    ti = proto_tree_add_text(tree, tvb, offset, 44, "Y.1711 OAM");
    mpls_y1711_tree = proto_item_add_subtree(ti, ett_mpls_y1711);

    /* checks for exp, bos and ttl encoding */
    if (mplsinfo->label != MPLS_LABEL_OAM_ALERT)
        proto_tree_add_expert_format(mpls_y1711_tree, pinfo, &ei_mpls_y1711_no_OAM_alert_label, tvb, offset - 4, 3,
                                     "Warning: Y.1711 but no OAM alert label (%d) ?!", MPLS_LABEL_OAM_ALERT);

    if (mplsinfo->exp != 0)
        proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_exp_bits_not_zero, tvb, offset - 2, 1);

    if (mplsinfo->bos != 1)
        proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_s_bit_not_one, tvb, offset - 2, 1);

    if (mplsinfo->ttl != 1)
        proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_ttl_not_one, tvb, offset - 1, 1);

    /* starting dissection */
    functype = tvb_get_guint8(tvb, offset);
    proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_function_type, tvb,
                        offset, 1,
                        ENC_LITTLE_ENDIAN);
    offset++;

    switch (functype) {
    case 0x01: /* CV */
    {
        /* 3 octets reserved (all 0x00) */
        if (tvb_memeql(tvb, offset, allzero, 3) == -1) {
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_reserved_not_zero, tvb, offset, 3);
        }
        offset += 3;

        /* ttsi (ipv4 flavor as in RFC 2373) */
        if (tvb_memeql(tvb, offset, allzero, 10) == -1) {
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 10);
        }
        offset += 10;

        if (tvb_memeql(tvb, offset, allone, 2) == -1) {
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_ff, tvb, offset, 2);
        }
        offset += 2;

        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsr_id, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;

        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;

        /* 18 octets of padding (all 0x00) */
        if (tvb_memeql(tvb, offset, allzero, 18) == -1) {
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 18);
        }
        offset += 18;
    }
    break;

    case 0x02: /* FDI */
    case 0x03: /* BDI */
    {
        /* 1 octets reserved (all 0x00) */
        if (tvb_memeql(tvb, offset, allzero, 1) == -1) {
            proto_tree_add_expert_format(mpls_y1711_tree, pinfo, &ei_mpls_y1711_reserved_not_zero, tvb, offset, 3,
                                         "Error: this byte is reserved and must be 0x00");
        }
        offset++;

        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_defect_type, tvb,
                            offset, 2,
                            ENC_LITTLE_ENDIAN);
        offset += 2;

        /*
         * ttsi (ipv4 flavor as in RFC 2373) is optional if not used must
         * be set to all 0x00
         */
        if (tvb_memeql(tvb, offset, allzero, 20) == 0) {
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_ttsi_not_preset, tvb, offset, 20);
            offset += 20;
        } else {
            if (tvb_memeql(tvb, offset, allzero, 10) == -1) {
                proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 10);
            }
            offset += 10;

            if (tvb_memeql(tvb, offset, allone, 2) == -1) {
                proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_ff, tvb, offset, 2);
            }
            offset += 2;

            proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsr_id, tvb, offset, 4, ENC_BIG_ENDIAN);
            offset += 4;

            proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
            offset += 4;
        }

        /* defect location */
        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_defect_location, tvb,
                            offset, 4,
                            ENC_LITTLE_ENDIAN);
        offset += 4;

        /* 14 octets of padding (all 0x00) */
        if (tvb_memeql(tvb, offset, allzero, 14) == -1) {
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 14);
        }
        offset += 14;
    }
    break;

    case 0x07: /* FDD */
    {
        /* 3 octets reserved (all 0x00) */
        if (tvb_memeql(tvb, offset, allzero, 3) == -1) {
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_reserved_not_zero, tvb, offset, 3);
        }
        offset += 3;

        /* ttsi (ipv4 flavor as in RFC 2373) */
        if (tvb_memeql(tvb, offset, allzero, 10) == -1) {
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 10);
        }
        offset += 10;

        if (tvb_memeql(tvb, offset, allone, 2) == -1) {
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_ff, tvb, offset, 2);
        }
        offset += 2;

        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsr_id, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;

        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;

        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_frequency, tvb,
                            offset, 1,
                            ENC_LITTLE_ENDIAN);
        offset++;

        /* 17 octets of padding (all 0x00) */
        if (tvb_memeql(tvb, offset, allzero, 17) == -1) {
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 17);
        }
        offset += 17;
    }
    break;

    default:
        proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_unknown_pdu, tvb, offset - 1, -1);
        return offset;
    }

    /* BIP16 */
    proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_bip16, tvb, offset, 2,
                        ENC_LITTLE_ENDIAN);
    offset += 2;

    return offset;
}
예제 #25
0
static int
dissect_gssapi_work(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
		    gboolean is_verifier)
{
	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_data *fd_head=NULL;
	gssapi_frag_info_t *fi;
	tvbuff_t *volatile gss_tvb=NULL;
	asn1_ctx_t asn1_ctx;
	void *pd_save;

	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.
	 */
	pinfo->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 = se_new(gssapi_conv_info_t);
		gss_info->oid=NULL;
		gss_info->do_reassembly=FALSE;
		gss_info->frags=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "gssapi_frags");

		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.
	 */
	pd_save = pinfo->private_data;
	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 *)se_tree_lookup32(gss_info->frags, gss_info->first_frame);
			if(!fi){
				goto done;
			}
			se_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_length(tvb), TRUE);
			gss_info->frag_offset+=tvb_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_child_real_data(tvb, fd_head->data, fd_head->datalen, fd_head->datalen);
			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 *)se_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_child_real_data(tvb, fd_head->data, fd_head->datalen, fd_head->datalen);
						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_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_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);
				pinfo->gssapi_data_encrypted = TRUE;
				goto done;
			}
			if ((tvb_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( pinfo->gssapi_encrypted_tvb ) {
					return_offset = call_dissector(ntlmssp_data_only_handle,
									tvb_new_subset_remaining(pinfo->gssapi_encrypted_tvb, 0),
									pinfo, subtree);
					pinfo->gssapi_data_encrypted = TRUE;
				}
		   		goto done;
		  	}

		  /* Maybe it's new GSSKRB5 CFX Wrapping */
		  if ((tvb_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(spnego_krb5_wrap_handle,
						   tvb_new_subset_remaining(gss_tvb, start_offset),
						   pinfo, subtree);
		    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(pinfo->fd, 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(pinfo->fd, proto_gssapi, 0, gss_info->oid);
		  }
		  if (!oidvalue)
		  {
                    proto_tree_add_text(subtree, gss_tvb, start_offset, 0,
					  "Unknown header (class=%d, pc=%d, tag=%d)",
					  appclass, pc, tag);
		    return_offset = tvb_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(handle, oid_tvb_local, pinfo, subtree);
		    if (len == 0)
			return_offset = tvb_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_length(gss_tvb)==tvb_reported_length(gss_tvb))
		&&  (len1>(guint32)tvb_length_remaining(gss_tvb, oid_start_offset))
		&&  (gssapi_reassembly) ){
			fi=se_new(gssapi_frag_info_t);
			fi->first_frame=pinfo->fd->num;
			fi->reassembled_in=0;
			se_tree_insert32(gss_info->frags, pinfo->fd->num, fi);

			fragment_add(&gssapi_reassembly_table,
				gss_tvb, 0, pinfo, pinfo->fd->num, NULL,
				0, tvb_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_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_text(subtree, gss_tvb, oid_start_offset, -1,
					    "Token object");

			return_offset = tvb_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(handle, oid_tvb, pinfo,
				    subtree);
				if (len == 0)
					return_offset = tvb_length(gss_tvb);
				else
					return_offset = offset + len;
			} else {
				proto_tree_add_text(subtree, gss_tvb, offset, -1,
				    "Authentication verifier");
				return_offset = tvb_length(gss_tvb);
			}
		} else {
			handle = oidvalue->handle;
			if (handle != NULL) {
				oid_tvb = tvb_new_subset_remaining(gss_tvb, offset);
				len = call_dissector(handle, oid_tvb, pinfo,
				    subtree);
				if (len == 0)
					return_offset = tvb_length(gss_tvb);
				else
					return_offset = offset + len;
			} else {
				proto_tree_add_text(subtree, gss_tvb, offset, -1,
				    "Authentication credentials");
				return_offset = tvb_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.
		 *
		 * 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(gss_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
	} ENDTRY;

	proto_item_set_len(item, return_offset);
	return return_offset;
}
예제 #26
0
static void
dissect_hdfs_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint offset = 0;
    int success = 0;
    guint length = 0;


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

    if (tree) {

        proto_item *ti = NULL;
        proto_tree *hdfs_tree = NULL;

        ti = proto_tree_add_item(tree, proto_hdfs, tvb, 0, -1, ENC_NA);
        hdfs_tree = proto_item_add_subtree(ti, ett_hdfs);

        /* Response */
        if (pinfo->srcport == tcp_port) {
            /* 4 bytes = sequence number */
            proto_tree_add_item(hdfs_tree, hf_hdfs_packetno, tvb, offset, 4, ENC_BIG_ENDIAN);
            offset += 4;

            /* 4 bytes = status -> 0000 = success, 0001 = error, ffff = fatal */
            success = tvb_get_ntohl(tvb, offset);
            proto_tree_add_item(hdfs_tree, hf_hdfs_success, tvb, offset, 4, ENC_BIG_ENDIAN);
            offset += 4;

            if (success != 0) {
                return;
            }

            if (!tvb_memeql(tvb, offset + 2, "long", 4)) {
                dissect_resp_long (tvb, hdfs_tree,  offset);

            } else {

                /* name length = 2 B */
                length = tvb_get_ntohs(tvb, offset);
                proto_tree_add_item(hdfs_tree, hf_hdfs_namelentwo, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;

                /* length bytes = method name */
                proto_tree_add_item(hdfs_tree, hf_hdfs_objname, tvb, offset, length, ENC_ASCII|ENC_NA);
                offset += length;

                /* get length that we just dissected */
                length = tvb_get_ntohs(tvb, offset);

                /* 2 bytes = objects length */
                proto_tree_add_item(hdfs_tree, hf_hdfs_namelentwo, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;

                /* length bytes = object name */
                proto_tree_add_item(hdfs_tree, hf_hdfs_objname, tvb, offset, length, ENC_ASCII|ENC_NA);
                offset += length;

                /* responses about block location info */
                if (!tvb_memeql(tvb, offset - length, "org.apache.hadoop.hdfs.protocol.LocatedBlocks", length)) {
                    dissect_resp_locatedblocks (tvb, hdfs_tree, offset);

                    /* responses about file statuses */
                } else if (!tvb_memeql(tvb, offset - length, "org.apache.hadoop.hdfs.protocol.HdfsFileStatus", length)) {
                    dissect_resp_filestatus (tvb, hdfs_tree, offset);

                } else {
                    /* get length */
                    length = tvb_get_ntohs(tvb, offset);

                    /* 2 bytes = parameter value length */
                    proto_tree_add_item(hdfs_tree, hf_hdfs_namelentwo, tvb, offset, 2, ENC_BIG_ENDIAN);
                    offset += 2;

                    /* the value of the parameter */
                    proto_tree_add_item(hdfs_tree, hf_hdfs_paramval, tvb, offset, length, ENC_ASCII|ENC_NA);
                    /*offset += length;*/
                }
            }

            /* Request to namenode */
        } else {

            /* check the packet length */
            guint auth = tvb_get_ntohl(tvb, offset);

            /* first setup packet starts with "hrpc" */
            if (!tvb_memeql(tvb, offset, REQUEST_STR, sizeof(REQUEST_STR) - 1)) {

                proto_tree_add_item(hdfs_tree, hf_hdfs_sequenceno, tvb, offset, sizeof(REQUEST_STR) - 1, ENC_ASCII|ENC_NA);
                offset += sizeof(REQUEST_STR) - 1;

                proto_tree_add_item(hdfs_tree, hf_hdfs_pdu_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;

                proto_tree_add_item(hdfs_tree, hf_hdfs_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
                /*offset += 1;*/

            } else {
                /* second authentication packet */
                if (auth + 4 != tvb_reported_length(tvb)) {

                    /* authentication length (read out of first 4 bytes) */
                    length = tvb_get_ntohl(tvb, offset);
                    proto_tree_add_item(hdfs_tree, hf_hdfs_authlen, tvb, offset, 4, ENC_ASCII|ENC_NA);
                    offset += 4;

                    /* authentication (length the number we just got) */
                    proto_tree_add_item(hdfs_tree, hf_hdfs_auth, tvb, offset, length, ENC_ASCII|ENC_NA);
                    offset += length;
                }

                /* data packets */

                /* 4 bytes = length */
                proto_tree_add_item(hdfs_tree, hf_hdfs_len, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;

                /* 4 bytes = sequence number */
                proto_tree_add_item(hdfs_tree, hf_hdfs_packetno, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;

                /* dissect packet data */
                dissect_data (tvb, hdfs_tree, offset);
            }
        }
    }
}
예제 #27
0
static fragment_head *
force_reassemble_seq(reassembly_table *table, packet_info *pinfo, guint32 id)
{
	fragment_head *fd_head;
	fragment_item *fd_i;
	fragment_item *last_fd;
	guint32 dfpos, size, packet_lost, burst_lost, seq_num;
	guint8 *data;

	fd_head = fragment_get(table, pinfo, id, NULL);

	/* have we already seen this frame ?*/
	if (pinfo->fd->flags.visited) {
		if (fd_head != NULL && fd_head->flags & FD_DEFRAGMENTED) {
			return fd_head;
		} else {
			return NULL;
		}
	}

	if (fd_head==NULL){
		/* we must have it to continue */
		return NULL;
	}

	/* check for packet lost and count the burst of packet lost */
	packet_lost = 0;
	burst_lost = 0;
	seq_num = 0;
	for(fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
		if (seq_num != fd_i->offset) {
			packet_lost += fd_i->offset - seq_num;
			if ( (fd_i->offset - seq_num) > burst_lost ) {
				burst_lost = fd_i->offset - seq_num;
			}
		}
		seq_num = fd_i->offset + 1;
	}

	/* we have received an entire packet, defragment it and
	 * free all fragments
	 */
	size=0;
	last_fd=NULL;
	for(fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
	  if(!last_fd || last_fd->offset!=fd_i->offset){
	    size+=fd_i->len;
	  }
	  last_fd=fd_i;
	}

	data = (guint8 *) g_malloc(size);
	fd_head->tvb_data = tvb_new_real_data(data, size, size);
	fd_head->len = size;		/* record size for caller	*/

	/* add all data fragments */
	dfpos = 0;
	last_fd=NULL;
	for (fd_i=fd_head->next;fd_i && fd_i->len + dfpos <= size;fd_i=fd_i->next) {
	  if (fd_i->len) {
	    if(!last_fd || last_fd->offset!=fd_i->offset){
	      memcpy(data+dfpos,tvb_get_ptr(fd_i->tvb_data,0,fd_i->len),fd_i->len);
	      dfpos += fd_i->len;
	    } else {
	      /* duplicate/retransmission/overlap */
	      fd_i->flags    |= FD_OVERLAP;
	      fd_head->flags |= FD_OVERLAP;
	      if( (last_fd->len!=fd_i->datalen)
		  || tvb_memeql(last_fd->tvb_data, 0, tvb_get_ptr(fd_i->tvb_data, 0, last_fd->len), last_fd->len) ){
			fd_i->flags    |= FD_OVERLAPCONFLICT;
			fd_head->flags |= FD_OVERLAPCONFLICT;
	      }
	    }
	  }
	  last_fd=fd_i;
	}

	/* we have defragmented the pdu, now free all fragments*/
	for (fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
	  if(fd_i->tvb_data){
	    tvb_free(fd_i->tvb_data);
	    fd_i->tvb_data=NULL;
	  }
	}

	/* mark this packet as defragmented */
	fd_head->flags |= FD_DEFRAGMENTED;
	fd_head->reassembled_in=pinfo->fd->num;

	col_append_fstr(pinfo->cinfo, COL_INFO, " (t4-data Reassembled: %d pack lost, %d pack burst lost)", packet_lost, burst_lost);

	p_t38_packet_conv_info->packet_lost = packet_lost;
	p_t38_packet_conv_info->burst_lost = burst_lost;

	return fd_head;
}
예제 #28
0
static int
dissect_btsmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
    int          offset = 0;
    proto_item  *ti;
    proto_tree  *st;
    guint8      opcode;
    guint32     interface_id;
    guint32     adapter_id;
    gint        previous_proto;

    interface_id = HCI_INTERFACE_DEFAULT;
    adapter_id = HCI_ADAPTER_DEFAULT;
    previous_proto = (GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
    if (data && previous_proto == proto_btl2cap) {
        btl2cap_data_t *l2cap_data;

        l2cap_data = (btl2cap_data_t *) data;
        if (l2cap_data) {
            interface_id = l2cap_data->interface_id;
            adapter_id = l2cap_data->adapter_id;
        }
    }

    ti = proto_tree_add_item(tree, proto_btsmp, tvb, 0, tvb_captured_length(tvb), ENC_NA);
    st = proto_item_add_subtree(ti, ett_btsmp);

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

    switch (pinfo->p2p_dir) {
        case P2P_DIR_SENT:
            col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
            break;
        case P2P_DIR_RECV:
            col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
            break;
        default:
            col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection ");
            break;
    }

    if (tvb_reported_length(tvb) < 1)
        return FALSE;

    proto_tree_add_item(st, hf_btsmp_opcode, tvb, 0, 1, ENC_LITTLE_ENDIAN);
    opcode = tvb_get_guint8(tvb, 0);
    offset++;

    col_append_str(pinfo->cinfo, COL_INFO, val_to_str_const(opcode, opcode_vals, "<unknown>"));

    switch (opcode) {
    case 0x01: /* Pairing Request */
    case 0x02: /* Pairing Response */
    {
        col_append_str(pinfo->cinfo, COL_INFO, ": ");

        proto_tree_add_item(st, hf_btsmp_io_capabilities, tvb, offset, 1, ENC_LITTLE_ENDIAN);
        offset++;
        proto_tree_add_item(st, hf_btsmp_oob_data_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
        offset++;

        offset = dissect_btsmp_auth_req(tvb, offset, pinfo, st);

        proto_tree_add_item(st, hf_btsmp_max_enc_key_size, tvb, offset, 1, ENC_LITTLE_ENDIAN);
        offset++;

        offset = dissect_btsmp_key_dist(tvb, offset, pinfo, st, TRUE);
        offset = dissect_btsmp_key_dist(tvb, offset, pinfo, st, FALSE);
        break;
    }

    case 0x03: /* Pairing Confirm */
        proto_tree_add_item(st, hf_btsmp_cfm_value, tvb, offset, 16, ENC_NA);
        offset += 16;
        break;

    case 0x04: /* Pairing Random */
        proto_tree_add_item(st, hf_btsmp_random, tvb, offset, 16, ENC_NA);
        offset += 16;
        break;

    case 0x05: /* Pairing Failed */
        proto_tree_add_item(st, hf_btsmp_reason, tvb, offset, 1, ENC_LITTLE_ENDIAN);
        col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(tvb_get_guint8(tvb, offset), reason_vals, "<unknown>"));
        offset++;
        break;

    case 0x06: /* Encryption Information */
        proto_tree_add_item(st, hf_btsmp_long_term_key, tvb, offset, 16, ENC_NA);
        offset += 16;
        break;

    case 0x07: /* Master Identification */
        proto_tree_add_item(st, hf_btsmp_ediv, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        proto_tree_add_item(st, hf_btsmp_random, tvb, offset, 8, ENC_NA);
        offset += 8;
        break;

    case 0x08: /* Identity Information */
        proto_tree_add_item(st, hf_btsmp_id_resolving_key, tvb, offset, 16, ENC_NA);
        offset += 16;
        break;

    case 0x09: /* Identity Address Information */
        proto_tree_add_item(st, hf_address_type, tvb, offset, 1, ENC_NA);
        offset += 1;

        offset = dissect_bd_addr(hf_bd_addr, pinfo, st, tvb, offset, FALSE, interface_id, adapter_id, NULL);
        break;

    case 0x0A: /* Signing Information */
        proto_tree_add_item(st, hf_btsmp_signature_key, tvb, offset, 16, ENC_NA);
        offset += 16;
        break;

     case 0x0B: /* Security Request */
        col_append_str(pinfo->cinfo, COL_INFO, ": ");
        offset = dissect_btsmp_auth_req(tvb, offset, pinfo, st);
        break;

    case 0x0C: /* Pairing Public Key */ {
        proto_item  *sub_item;

        sub_item = proto_tree_add_item(st, hf_btsmp_public_key_x, tvb, offset, 32, ENC_NA);
        if (tvb_memeql(tvb, offset, debug_public_key_x, 32) == 0)
            proto_item_append_text(sub_item, " (Debug Key)");
        offset += 32;

        sub_item = proto_tree_add_item(st, hf_btsmp_public_key_y, tvb, offset, 32, ENC_NA);
        if (tvb_memeql(tvb, offset, debug_public_key_y, 32) == 0)
            proto_item_append_text(sub_item, " (Debug Key)");
        offset += 32;

        break;}
    case 0x0D: /* Pairing DHKey Check" */
        proto_tree_add_item(st, hf_btsmp_dhkey_check, tvb, offset, 16, ENC_NA);
        offset += 16;

        break;
    case 0x0E: /* Pairing Keypress Notification */
        proto_tree_add_item(st, hf_btsmp_notification_type, tvb, offset, 1, ENC_NA);
        col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(tvb_get_guint8(tvb, offset), notification_type_vals, "<unknown>"));
        offset += 1;

        break;
    default:
        break;
    }

    return offset;
}