コード例 #1
0
/*
 * Name: isis_dissect_area_address_clv()
 *
 * Description:
 *	Take an area address CLV and display it pieces.  An area address
 *	CLV is n, x byte hex strings.
 *
 * Input:
 *	tvbuff_t * : tvbuffer for packet data
 *	proto_tree * : protocol display tree to fill out.  May be NULL
 *	int : offset into packet data where we are.
 *	int : length of clv we are decoding
 *
 * Output:
 *	void, but we will add to proto tree if !NULL.
 */
void
isis_dissect_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
	int length)
{
	int		arealen,area_idx;

	while ( length > 0 ) {
		arealen = tvb_get_guint8(tvb, offset);
		length--;
		if (length<=0) {
			isis_dissect_unknown(tvb, tree, offset,
				"short address (no length for payload)");
			return;
		}
		if ( arealen > length) {
			isis_dissect_unknown(tvb, tree, offset,
				"short address, packet says %d, we have %d left",
				arealen, length );
			return;
		}

		if ( tree ) {
			proto_item *ti;
	
			/*
			 * Throw an exception rather than putting in a
			 * partial address.
			 */
			tvb_ensure_bytes_exist ( tvb, offset, arealen + 1 );

			ti = proto_tree_add_text ( tree, tvb, offset, arealen + 1,
				"Area address (%d): ", arealen );

			/*
			 * Lets turn the area address into "standard"
			 * xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx format string.
	                 * this is a private routine as the print_nsap_net in
			 * epan/osi_utils.c is incomplete and we need only
			 * a subset - actually some nice placing of dots ....
			 */
			for (area_idx = 0; area_idx < arealen; area_idx++) {
				proto_item_append_text(ti, "%02x",
				    tvb_get_guint8(tvb, offset+area_idx+1));
				if (((area_idx & 1) == 0) &&
				    (area_idx + 1 < arealen)) {
					proto_item_append_text(ti, ".");
				}
			}
		}
		offset += arealen + 1;
		length -= arealen;	/* length already adjusted for len fld*/
	}
}
コード例 #2
0
/*
 * Name: isis_dissect_authentication_clv()
 *
 * Description:
 *	Take apart the CLV that hold authentication information.  This
 *	is currently 1 octet auth type.
 *      the two defined authentication types
 *	  are 1 for a clear text password and
 *           54 for a HMAC-MD5 digest
 *
 * Input:
 *	tvbuff_t * : tvbuffer for packet data
 *	proto_tree * : protocol display tree to fill out.  May be NULL
 *	int : offset into packet data where we are.
 *	int : length of clv we are decoding
 *
 * Output:
 *	void, but we will add to proto tree if !NULL.
 */
void
isis_dissect_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
	int length)
{
	guchar pw_type;
	int auth_unsupported;
	proto_item *ti;

	if ( length <= 0 ) {
		return;
	}

	pw_type = tvb_get_guint8(tvb, offset);
	offset += 1;
	length--;
	auth_unsupported = FALSE;

	switch (pw_type) {
	case 1:
		ti = proto_tree_add_text ( tree, tvb, offset - 1, length + 1,
		    "clear text (1), password (length %d) = ", length);
		if ( length > 0 ) {
		  proto_item_append_text(ti, "%s",
		    tvb_format_text(tvb, offset, length));
                } else {
		  proto_item_append_text(ti, "no clear-text password found!!!");
		}
		break;
	case 54:
		ti = proto_tree_add_text ( tree, tvb, offset - 1, length + 1,
		    "hmac-md5 (54), password (length %d) = ", length);

		if ( length == 16 ) {
		  proto_item_append_text(ti, "0x%02x", tvb_get_guint8(tvb, offset));
		  offset += 1;
		  length--;
		  while (length > 0) {
		    proto_item_append_text(ti, "%02x", tvb_get_guint8(tvb, offset));
		    offset += 1;
		    length--;
		  }
		} else {
		  proto_item_append_text(ti,
		      "illegal hmac-md5 digest format (must be 16 bytes)");
		}
		break;
	default:
		ti = proto_tree_add_text ( tree, tvb, offset - 1, length + 1,
		    "type 0x%02x (0x%02x): ", pw_type, length );
		auth_unsupported=TRUE;
		break;
	}

       	if ( auth_unsupported ) {
		isis_dissect_unknown(tvb, tree, offset,
       			"Unknown authentication type" );
	}
}
コード例 #3
0
/*
 * Name: isis_dissect_clvs()
 *
 * Description:
 *	Dispatch routine to shred all the CLVs in a packet.  We just
 *	walk through the clv entries in the packet.  For each one, we
 *	search the passed in valid clv's for this protocol (opts) for
 *	a matching code.  If found, we add to the display tree and
 *	then call the dissector.  If it is not, we just post an
 *	"unknown" clv entry using the passed in unknown clv tree id.
 *
 * Input:
 *	tvbuff_t * : tvbuffer for packet data
 *	proto_tree * : protocol display tree to fill out.  May be NULL
 *	int : offset into packet data where we are.
 *	isis_clv_handle_t * : NULL dissector terminated array of codes
 *		and handlers (along with tree text and tree id's).
 *	int : length of CLV area.
 *	int : length of IDs in packet.
 *	int : unknown clv tree id
 *
 * Output:
 *	void, but we will add to proto tree if !NULL.
 */
void
isis_dissect_clvs(tvbuff_t *tvb, proto_tree *tree, int offset,
	const isis_clv_handle_t *opts, int len, int id_length,
	int unknown_tree_id)
{
	guint8 code;
	guint8 length;
	int q;
	proto_item	*ti;
	proto_tree	*clv_tree;
	int 		adj;

	while ( len > 0 ) {
		code = tvb_get_guint8(tvb, offset);
		offset += 1;

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

		adj = (sizeof(code) + sizeof(length) + length);
		len -= adj;
		if ( len < 0 ) {
			isis_dissect_unknown(tvb, tree, offset,
				"Short CLV header (%d vs %d)",
				adj, len + adj );
			return;
		}
		q = 0;
		while ((opts[q].dissect != NULL )&&( opts[q].optcode != code )){
			q++;
		}
		if ( opts[q].dissect ) {
			if (tree) {
				/* adjust by 2 for code/len octets */
				ti = proto_tree_add_text(tree, tvb, offset - 2,
					length + 2, "%s (%u)",
					opts[q].tree_text, length );
				clv_tree = proto_item_add_subtree(ti,
					*opts[q].tree_id );
			} else {
				clv_tree = NULL;
			}
			opts[q].dissect(tvb, clv_tree, offset,
				id_length, length);
		} else {
			if (tree) {
				ti = proto_tree_add_text(tree, tvb, offset - 2,
					length + 2, "Unknown code %u (%u)",
					code, length);
				clv_tree = proto_item_add_subtree(ti,
					unknown_tree_id );
			} else {
				clv_tree = NULL;
			}
		}
		offset += length;
	}
}
コード例 #4
0
static void
dissect_hello_ptp_adj_clv(tvbuff_t *tvb,
                          proto_tree *tree, int offset, int id_length, int length)
{
    static const value_string adj_state_vals[] = {
        { 0, "Up" },
        { 1, "Initializing" },
        { 2, "Down" },
        { 0, NULL }
    };
    guint8 adj_state;
    const char *adj_state_str;

    adj_state = tvb_get_guint8(tvb, offset);
    adj_state_str = val_to_str(adj_state, adj_state_vals, "Unknown (%u)");
    switch(length) {
    case 1:
        proto_tree_add_text ( tree, tvb, offset, 1,
                              "Adjacency State: %s", adj_state_str );
        break;
    case 5:
        proto_tree_add_text ( tree, tvb, offset, 1,
                              "Adjacency State: %s", adj_state_str );
        proto_tree_add_text ( tree, tvb, offset+1, 4,
                              "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
        break;
    case 11:
        proto_tree_add_text ( tree, tvb, offset, 1,
                              "Adjacency State: %s", adj_state_str );
        proto_tree_add_text ( tree, tvb, offset+1, 4,
                              "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
        proto_tree_add_text ( tree, tvb, offset+5, id_length,
                              "Neighbor SystemID: %s",
                              print_system_id( tvb_get_ptr(tvb, offset+5, id_length), id_length ) );
        break;
    case 15:
        proto_tree_add_text ( tree, tvb, offset, 1,
                              "Adjacency State: %s", adj_state_str );
        proto_tree_add_text ( tree, tvb, offset+1, 4,
                              "Extended Local circuit ID: 0x%08x", tvb_get_ntohl(tvb, offset+1) );
        proto_tree_add_text ( tree, tvb, offset+5, id_length,
                              "Neighbor SystemID: %s",
                              print_system_id( tvb_get_ptr(tvb, offset+5, id_length), id_length ) );
        proto_tree_add_text ( tree, tvb, offset+5+id_length, 4,
                              "Neighbor Extended Local circuit ID: 0x%08x",
                              tvb_get_ntohl(tvb, offset+5+id_length) );
        break;
    default:
        isis_dissect_unknown(tvb, tree, offset,
                             "malformed TLV (%d vs 1,5,11,15)", length );
        return;
    }
}
コード例 #5
0
/*
 * Name: isis_dissect_isis_psnp()
 *
 * Description:
 *	Tear apart a L1 or L2 PSNP header and then call into payload dissect
 *	to pull apart the lsp id payload.
 *
 * Input:
 *	tvbuff_t * : tvbuffer for packet data
 *	proto_tree * : protocol display tree to add to.  May be NULL.
 *	int : our offset into packet data
 *	int : type (l1 psnp, l2 psnp)
 *	int : header length of packet.
 *	int : length of IDs in packet.
 *
 * Output:
 *      void, but we will add to proto tree if !NULL.
 */
void
isis_dissect_isis_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
	int type, int header_length, int id_length)
{
	proto_item	*ti;
	proto_tree	*psnp_tree = NULL;
	guint16		pdu_length;
	int 		len;

	if (tree) {
		ti = proto_tree_add_text(tree, tvb, offset, -1,
		    PROTO_STRING_PSNP);
		psnp_tree = proto_item_add_subtree(ti, ett_isis_psnp);
	}

	pdu_length = tvb_get_ntohs(tvb, offset);
	if (tree) {
		proto_tree_add_uint(psnp_tree, hf_isis_psnp_pdu_length, tvb,
			offset, 2, pdu_length);
	}
	offset += 2;

	if (tree) {
		proto_tree_add_text(psnp_tree, tvb, offset, id_length + 1,
			"Source-ID: %s",
			print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length + 1 ) );
	}
	if (check_col(pinfo->cinfo, COL_INFO)) {
		col_append_fstr(pinfo->cinfo, COL_INFO, ", Source-ID: %s",
			print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length+1 ) );
	}
	offset += id_length + 1;

	len = pdu_length - header_length;
	if (len < 0) {
		isis_dissect_unknown(tvb, tree, offset,
			"packet header length %d went beyond packet",
			header_length );
		return;
	}
	/* Call into payload dissector */
	if (type == ISIS_TYPE_L1_PSNP ) {
		isis_dissect_clvs(tvb, psnp_tree, offset,
			clv_l1_psnp_opts, len, id_length,
			ett_isis_psnp_clv_unknown );
	} else {
		isis_dissect_clvs(tvb, psnp_tree, offset,
			clv_l2_psnp_opts, len, id_length,
			ett_isis_psnp_clv_unknown );
	}
}
コード例 #6
0
static void
dissect_snp_checksum_clv(tvbuff_t *tvb,
        proto_tree *tree, int offset, int id_length _U_, int length) {

	guint16 pdu_length,checksum, cacl_checksum=0;

	if (tree) {
                if ( length != 2 ) {
                        proto_tree_add_text ( tree, tvb, offset, length,
                                              "incorrect checksum length (%u), should be (2)", length );
                        return;
                }

    		checksum = tvb_get_ntohs(tvb, offset);    		

                /* the check_and_get_checksum() function needs to know how big
                 * the packet is. we can either pass through the pdu-len through several layers
                 * of dissectors and wrappers or extract the PDU length field from the PDU specific header
                 * which is offseted 8 bytes (relative to the beginning of the IS-IS packet) in SNPs */

    		pdu_length = tvb_get_ntohs(tvb, 8);   

                /* unlike the LSP checksum verification which starts at an offset of 12 we start at offset 0*/
		switch (check_and_get_checksum(tvb, 0, pdu_length, checksum, offset, &cacl_checksum))
		{

        		case NO_CKSUM :
                                proto_tree_add_text ( tree, tvb, offset, length,
                                                      "Checksum: 0x%04x [unused]", checksum);
       	 		break;
        		case DATA_MISSING :
          			isis_dissect_unknown(tvb, tree, offset,
                                                     "[packet length %d went beyond packet]",
                                                     tvb_length(tvb));
        		break;
        		case CKSUM_NOT_OK :
                                proto_tree_add_text ( tree, tvb, offset, length,
                                                      "Checksum: 0x%04x [incorrect, should be 0x%04x]",
                                                      checksum,
                                                      cacl_checksum);
        		break;
	        	case CKSUM_OK :
                                proto_tree_add_text ( tree, tvb, offset, length,
                                                      "Checksum: 0x%04x [correct]", checksum);
        		break;
        		default :
          			g_message("'check_and_get_checksum' returned an invalid value");
    		}
	}
}
コード例 #7
0
/*
 * Name: isis_dissect_te_router_id_clv()
 *
 * Description:
 *      Display the Traffic Engineering Router ID TLV #134.
 *      This TLV is like the IP Interface TLV, except that
 *      only _one_ IP address is present
 *
 * Input:
 *      tvbuff_t * : tvbuffer for packet data
 *      proto_tree * : protocol display tree to fill out.  May be NULL
 *      int : offset into packet data where we are.
 *      int : length of clv we are decoding
 *      int : tree id to use for proto tree.
 *
 * Output:
 *      void, but we will add to proto tree if !NULL.
 */
void
isis_dissect_te_router_id_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
	int length, int tree_id)
{
        if ( length <= 0 ) {
                return;
        }

        if ( length != 4 ) {
		isis_dissect_unknown(tvb, tree, offset,
                        "malformed Traffic Engineering Router ID (%d vs 4)",length );
                return;
        }
        if ( tree ) {
                proto_tree_add_item(tree, tree_id, tvb, offset, 4, FALSE);
        }
}
コード例 #8
0
/*
 * Name: dissect_snp_lsp_entries_clv()
 *
 * Description:
 *	All the snp packets use a common payload format.  We have up
 *	to n entries (based on length), which are made of:
 *		2         : remaining life time
 *		id_length : lsp id
 *		4         : sequence number
 *		2         : checksum
 *
 * Input:
 *	tvbuff_t * : tvbuffer for packet data
 *	proto_tree * : protocol display tree to fill out.  May be NULL
 *	int : offset into packet data where we are.
 *	int : length of IDs in packet.
 *	int : length of payload to decode.
 *
 * Output:
 *      void, but we will add to proto tree if !NULL.
 */
static void
dissect_snp_lsp_entries_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
	int id_length, int length)
{
        proto_tree *subtree,*ti;

	while ( length > 0 ) {
		if ( length < 2+id_length+2+4+2 ) {
			isis_dissect_unknown(tvb, tree, offset,
				"Short SNP header entry (%d vs %d)", length,
				2+id_length+2+4+2 );
			return;
		}

	        ti = proto_tree_add_text(tree, tvb, offset, 2+id_length+2+4+2,
                                    "LSP-ID: %s, Sequence: 0x%08x, Lifetime: %5us, Checksum: 0x%04x",
                                           print_system_id( tvb_get_ptr(tvb, offset+2, id_length+2), id_length+2 ),
                                           tvb_get_ntohl(tvb, offset+2+id_length+2),
                                           tvb_get_ntohs(tvb, offset),
                                           tvb_get_ntohs(tvb, offset+2+id_length+2+4));

                subtree = proto_item_add_subtree(ti,ett_isis_csnp_lsp_entry);

		proto_tree_add_text(subtree, tvb, offset+2, 8,
			"LSP-ID:             : %s",
			print_system_id( tvb_get_ptr(tvb, offset+2, id_length+2), id_length+2 ));

		proto_tree_add_text(subtree, tvb, offset+2+id_length+2, 4,
			"LSP Sequence Number : 0x%08x",
			tvb_get_ntohl(tvb, offset+2+id_length+2));

		proto_tree_add_text(subtree, tvb, offset, 2,
			"Remaining Lifetime  : %us",
			tvb_get_ntohs(tvb, offset));

		proto_tree_add_text(subtree, tvb, offset+2+id_length+2+4, 2,
			"LSP checksum        : 0x%04x",
			tvb_get_ntohs(tvb, offset+2+id_length+2+4));

		length -= 2+id_length+2+4+2;
		offset += 2+id_length+2+4+2;
	}

}
コード例 #9
0
/*
 * Name: isis_dissect_ip_int_clv()
 *
 * Description:
 *	Take apart the CLV that lists all the IP interfaces.  The
 *	meaning of which is slightly different for the different base packet
 *	types, but the display is not different.  What we have is n ip
 *	addresses, plain and simple.
 *
 * Input:
 *	tvbuff_t * : tvbuffer for packet data
 *	proto_tree * : protocol display tree to fill out.  May be NULL
 *	int : offset into packet data where we are.
 *	int : length of clv we are decoding
 *	int : tree id to use for proto tree.
 *
 * Output:
 *	void, but we will add to proto tree if !NULL.
 */
void
isis_dissect_ip_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
	int length, int tree_id)
{
	if ( length <= 0 ) {
		return;
	}

	while ( length > 0 ) {
		if ( length < 4 ) {
			isis_dissect_unknown(tvb, tree, offset,
				"Short IP interface address (%d vs 4)",length );
			return;
		}

		if ( tree ) {
			proto_tree_add_item(tree, tree_id, tvb, offset, 4, FALSE);
		}
		offset += 4;
		length -= 4;
	}
}
コード例 #10
0
/*
 * Name: isis_dissect_is_neighbors_clv()
 *
 * Description:
 *	Take apart a IS neighbor packet.  A neighbor is n 6 byte packets.
 *	(they tend to be an 802.3 MAC address, but its not required).
 *
 * Input:
 *	tvbuff_t * : tvbuffer for packet data
 *	proto_tree * : protocol display tree to fill out.  May be NULL
 *	int : offset into packet data where we are.
 *	int : length of IDs in packet.
 *	int : length of clv we are decoding
 *
 * Output:
 *	void, but we will add to proto tree if !NULL.
 */
static void
dissect_hello_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
                               int id_length _U_, int length)
{
    while ( length > 0 ) {
        if (length<6) {
            isis_dissect_unknown(tvb, tree, offset,
                                 "short is neighbor (%d vs 6)", length );
            return;
        }
        /*
         * Lets turn the area address into "standard" 0000.0000.etc
         * format string.
         */
        if ( tree ) {
            proto_tree_add_text ( tree, tvb, offset, 6,
                                  "IS Neighbor: %s", get_ether_name( tvb_get_ptr(tvb, offset, 6)) );
        }
        offset += 6;
        length -= 6;
    }
}
コード例 #11
0
/*
 * Name: isis_dissect_ipv6_int_clv()
 *
 * Description:
 *	Take apart the CLV that lists all the IPv6 interfaces.  The
 *	meaning of which is slightly different for the different base packet
 *	types, but the display is not different.  What we have is n ip
 *	addresses, plain and simple.
 *
 * Input:
 *	tvbuff_t * : tvbuffer for packet data
 *	proto_tree * : protocol display tree to fill out.  May be NULL
 *	int : offset into packet data where we are.
 *	int : length of clv we are decoding
 *	int : tree id to use for proto tree.
 *
 * Output:
 *	void, but we will add to proto tree if !NULL.
 */
void
isis_dissect_ipv6_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
	int length, int tree_id)
{
	guint8 addr [16];

	if ( length <= 0 ) {
		return;
	}

	while ( length > 0 ) {
		if ( length < 16 ) {
			isis_dissect_unknown(tvb, tree, offset,
				"Short IPv6 interface address (%d vs 16)",length );
			return;
		}
		tvb_memcpy(tvb, addr, offset, sizeof(addr));
		if ( tree ) {
			proto_tree_add_ipv6(tree, tree_id, tvb, offset, 16, addr);
		}
		offset += 16;
		length -= 16;
	}
}
コード例 #12
0
ファイル: packet-isis.c プロジェクト: AndresVelasco/wireshark
/*
 * Name: dissect_isis()
 *
 * Description:
 *	Main entry area for isis de-mangling.  This will build the
 *	main isis tree data and call the sub-protocols as needed.
 *
 * Input:
 *	tvbuff_t * : tvbuffer for packet data
 *	packet_info * : info for current packet
 *	proto_tree * : tree of display data.  May be NULL.
 *
 * Output:
 *	void, but we will add to the proto_tree if it is not NULL.
 */
static void
dissect_isis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_item *ti;
	proto_tree *isis_tree = NULL;
	int offset = 0;
	guint8 isis_version;
	guint8 isis_header_length;
	guint8 isis_type_reserved;
	guint8 isis_type;
	guint8 isis_system_id_len;

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

	isis_version = tvb_get_guint8(tvb, 2);
	if (isis_version != ISIS_REQUIRED_VERSION){
		col_add_fstr(pinfo->cinfo, COL_INFO,
				"Unknown ISIS version (%u vs %u)",
				isis_version, ISIS_REQUIRED_VERSION );
		isis_dissect_unknown(tvb, tree, 0,
			"Unknown ISIS version (%d vs %d)",
			isis_version, ISIS_REQUIRED_VERSION);
		return;
	}

	ti = proto_tree_add_item(tree, proto_isis, tvb, 0, -1, ENC_NA);
	isis_tree = proto_item_add_subtree(ti, ett_isis);

	if (tree) {
		proto_tree_add_item(isis_tree, hf_isis_irpd, tvb, offset, 1,
			ENC_BIG_ENDIAN );
	}
	offset += 1;

	isis_header_length = tvb_get_guint8(tvb, offset);
	if (tree) {
		proto_tree_add_uint(isis_tree, hf_isis_header_length, tvb,
			offset, 1, isis_header_length );
	}
	offset += 1;

	if (tree) {
		proto_tree_add_uint(isis_tree, hf_isis_version, tvb,
			offset, 1, isis_version );
	}
	offset += 1;

	isis_system_id_len = tvb_get_guint8(tvb, offset);
	if (tree) {
		proto_tree_add_uint(isis_tree, hf_isis_system_id_length, tvb,
			offset, 1, isis_system_id_len );
	}
	offset += 1;

	isis_type_reserved = tvb_get_guint8(tvb, offset);
	isis_type = isis_type_reserved & ISIS_TYPE_MASK;
	col_add_str(pinfo->cinfo, COL_INFO,
			val_to_str ( isis_type, isis_vals, "Unknown (0x%x)" ) );

	proto_tree_add_uint_format(isis_tree, hf_isis_type, tvb,
			offset, 1, isis_type,
			"PDU Type           : %s (R:%s%s%s)",
			val_to_str(isis_type, isis_vals, "Unknown (0x%x)"),
			(isis_type_reserved & ISIS_R8_MASK) ? "1" : "0",
			(isis_type_reserved & ISIS_R7_MASK) ? "1" : "0",
			(isis_type_reserved & ISIS_R6_MASK) ? "1" : "0");

	offset += 1;

	if (tree) {
		proto_tree_add_item(isis_tree, hf_isis_version2, tvb, offset, 1,
			ENC_BIG_ENDIAN );
	}
	offset += 1;

	if (tree) {
		proto_tree_add_item(isis_tree, hf_isis_reserved, tvb, offset, 1,
			ENC_BIG_ENDIAN );
	}
	offset += 1;

	if (tree) {
		proto_tree_add_item(isis_tree, hf_isis_max_area_adr, tvb, offset, 1,
			ENC_BIG_ENDIAN );
	}
	offset += 1;

	/*
	 * Interpret the system ID length.
	 */
	if (isis_system_id_len == 0)
		isis_system_id_len = 6;	/* zero means 6-octet ID field length */
	else if (isis_system_id_len == 255) {
		isis_system_id_len = 0;	/* 255 means null ID field */
		/* XXX - what about the LAN ID? */
	}
	/* XXX - otherwise, must be in the range 1 through 8 */

	switch (isis_type) {
	case ISIS_TYPE_L1_HELLO:
	case ISIS_TYPE_L2_HELLO:
	case ISIS_TYPE_PTP_HELLO:
		isis_dissect_isis_hello(tvb, pinfo, isis_tree, offset,
			isis_type, isis_header_length, isis_system_id_len);
		break;
	case ISIS_TYPE_L1_LSP:
	case ISIS_TYPE_L2_LSP:
		isis_dissect_isis_lsp(tvb, pinfo, isis_tree, offset,
			isis_type, isis_header_length, isis_system_id_len);
		break;
	case ISIS_TYPE_L1_CSNP:
	case ISIS_TYPE_L2_CSNP:
		isis_dissect_isis_csnp(tvb, pinfo, isis_tree, offset,
			isis_type, isis_header_length, isis_system_id_len);
		break;
	case ISIS_TYPE_L1_PSNP:
	case ISIS_TYPE_L2_PSNP:
		isis_dissect_isis_psnp(tvb, pinfo, isis_tree, offset,
			isis_type, isis_header_length, isis_system_id_len);
		break;
	default:
		isis_dissect_unknown(tvb, tree, offset,
			"Unknown ISIS packet type");
	}
} /* dissect_isis */
コード例 #13
0
/*
 * Name: isis_dissect_isis_hello()
 *
 * Description:
 *	This procedure rips apart the various types of ISIS hellos.  L1H and
 *	L2H's are identical for the most part, while the PTP hello has
 *	a shorter header.
 *
 * Input:
 *	tvbuff_t * : tvbuffer for packet data
 *	proto_tree * : protocol display tree to add to.  May be NULL.
 *	int offset : our offset into packet data.
 *	int : hello type, a la packet-isis.h ISIS_TYPE_* values
 *	int : header length of packet.
 *	int : length of IDs in packet.
 *
 * Output:
 *	void, will modify proto_tree if not NULL.
 */
void
isis_dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
                        int hello_type, int header_length, int id_length)
{
    proto_item	*ti;
    proto_tree	*hello_tree = NULL;
    int 		len;
    guint8		octet;
    const guint8	*source_id;
    guint16		pdu_length;
    const guint8	*lan_id;

    if (tree) {
        ti = proto_tree_add_text(tree, tvb, offset, -1, "ISIS HELLO");
        hello_tree = proto_item_add_subtree(ti, ett_isis_hello);
        octet = tvb_get_guint8(tvb, offset);
        proto_tree_add_uint_format(hello_tree,
                                   hf_isis_hello_circuit_reserved,
                                   tvb, offset, 1, octet,
                                   "Circuit type              : %s, reserved(0x%02x == 0)",
                                   val_to_str(octet&ISIS_HELLO_CTYPE_MASK,
                                              isis_hello_circuit_type_vals,
                                              "Unknown (0x%x)"),
                                   octet&ISIS_HELLO_CT_RESERVED_MASK
                                  );
    }
    offset += 1;

    if (tree) {
        source_id = tvb_get_ptr(tvb, offset, id_length);
        proto_tree_add_bytes_format(hello_tree, hf_isis_hello_source_id, tvb,
                                    offset, id_length, source_id,
                                    "System-ID {Sender of PDU} : %s",
                                    print_system_id( source_id, id_length ) );
    }
    if (check_col(pinfo->cinfo, COL_INFO)) {
        col_append_fstr(pinfo->cinfo, COL_INFO, ", System-ID: %s",
                        print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ) );
    }
    offset += id_length;

    if (tree) {
        proto_tree_add_item(hello_tree, hf_isis_hello_holding_timer, tvb,
                            offset, 2, ENC_BIG_ENDIAN);
    }
    offset += 2;

    pdu_length = tvb_get_ntohs(tvb, offset);
    if (tree) {
        proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, tvb,
                            offset, 2, pdu_length);
    }
    offset += 2;

    if (hello_type == ISIS_TYPE_PTP_HELLO) {
        if (tree) {
            proto_tree_add_item(hello_tree, hf_isis_hello_local_circuit_id, tvb,
                                offset, 1, ENC_BIG_ENDIAN );
        }
        offset += 1;
    } else {
        if (tree) {
            octet = tvb_get_guint8(tvb, offset);
            proto_tree_add_uint_format(hello_tree, hf_isis_hello_priority_reserved, tvb,
                                       offset, 1, octet,
                                       "Priority                  : %d, reserved(0x%02x == 0)",
                                       octet&ISIS_HELLO_PRIORITY_MASK,
                                       octet&ISIS_HELLO_P_RESERVED_MASK );
        }
        offset += 1;

        if (tree) {
            lan_id = tvb_get_ptr(tvb, offset, id_length+1);
            proto_tree_add_bytes_format(hello_tree, hf_isis_hello_lan_id, tvb,
                                        offset, id_length + 1, lan_id,
                                        "System-ID {Designated IS} : %s",
                                        print_system_id( lan_id, id_length + 1 ) );
        }
        offset += id_length + 1;
    }

    len = pdu_length;
    len -= header_length;
    if (len < 0) {
        isis_dissect_unknown(tvb, tree, offset,
                             "Packet header length %d went beyond packet",
                             header_length );
        return;
    }
    /*
     * Now, we need to decode our CLVs.  We need to pass in
     * our list of valid ones!
     */
    if (hello_type == ISIS_TYPE_L1_HELLO) {
        isis_dissect_clvs(tvb, hello_tree, offset,
                          clv_l1_hello_opts, len, id_length,
                          ett_isis_hello_clv_unknown);
    } else if (hello_type == ISIS_TYPE_L2_HELLO) {
        isis_dissect_clvs(tvb, hello_tree, offset,
                          clv_l2_hello_opts, len, id_length,
                          ett_isis_hello_clv_unknown);
    } else {
        isis_dissect_clvs(tvb, hello_tree, offset,
                          clv_ptp_hello_opts, len, id_length,
                          ett_isis_hello_clv_unknown);
    }
}