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; } }
/* * 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 ); } }
static void dissect_hello_restart_clv(tvbuff_t *tvb, proto_tree *tree, int offset, int id_length, int length) { int restart_options=0; proto_tree *flags_tree; proto_item *restart_flags_item; proto_item *hold_time_item; const char *sep; const guint8 *neighbor_id; if (length >= 1) { restart_options = tvb_get_guint8(tvb, offset); restart_flags_item = proto_tree_add_uint ( tree, hf_isis_hello_clv_restart_flags, tvb, offset, 1, restart_options); flags_tree = proto_item_add_subtree(restart_flags_item, ett_isis_hello_clv_restart_flags); proto_tree_add_boolean (flags_tree, hf_isis_hello_clv_restart_flags_sa, tvb, offset, 1, restart_options ); proto_tree_add_boolean (flags_tree, hf_isis_hello_clv_restart_flags_ra, tvb, offset, 1, restart_options ); proto_tree_add_boolean (flags_tree, hf_isis_hello_clv_restart_flags_rr, tvb, offset, 1, restart_options ); /* Append an indication of which flags are set in the restart * options */ sep = initial_sep; APPEND_BOOLEAN_FLAG(ISIS_MASK_RESTART_SA(restart_options), restart_flags_item, "%sSA"); APPEND_BOOLEAN_FLAG(ISIS_MASK_RESTART_RA(restart_options), restart_flags_item, "%sRA"); APPEND_BOOLEAN_FLAG(ISIS_MASK_RESTART_RR(restart_options), restart_flags_item, "%sRR"); if (sep != initial_sep) { proto_item_append_text (restart_flags_item, ")"); } } /* The Remaining Time field should only be present if the RA flag is * set */ if (length >= 3 && ISIS_MASK_RESTART_RA(restart_options)) { hold_time_item = proto_tree_add_uint ( tree, hf_isis_hello_clv_restart_remain_time, tvb, offset+1, 2, tvb_get_ntohs(tvb, offset+1) ); proto_item_append_text( hold_time_item, "s" ); } /* The Restarting Neighbor ID should only be present if the RA flag is * set. */ if (length >= 3 + id_length && ISIS_MASK_RESTART_RA(restart_options)) { neighbor_id = tvb_get_ptr(tvb, offset+3, id_length); proto_tree_add_bytes_format( tree, hf_isis_hello_clv_restart_neighbor, tvb, offset+3, id_length, neighbor_id, "Restarting Neighbor ID: %s", print_system_id( neighbor_id, id_length ) ); } }
/* * 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; } }
static void esis_dissect_redirect_pdu( guint8 len, tvbuff_t *tvb, proto_tree *tree) { int offset = 0; int tmpl = 0; if (tree) { offset += ESIS_HDR_FIXED_LENGTH; tmpl = (int) tvb_get_guint8(tvb, offset); proto_tree_add_text( tree, tvb, offset, tmpl + 1, "### Destination Address Section ###" ); proto_tree_add_text( tree, tvb, offset++, 1, "DAL: %2u Octets", tmpl); proto_tree_add_text( tree, tvb, offset, tmpl, " DA : %s", print_nsap_net( tvb_get_ptr(tvb, offset, tmpl), tmpl ) ); offset += tmpl; len -= ( tmpl + 1 ); tmpl = (int) tvb_get_guint8(tvb, offset); proto_tree_add_text( tree, tvb, offset, tmpl + 1, "### Subnetwork Address Section ###"); proto_tree_add_text( tree, tvb, offset++, 1, "BSNPAL: %2u Octets", tmpl); proto_tree_add_text( tree, tvb, offset, tmpl, " BSNPA: %s", print_system_id( tvb_get_ptr(tvb, offset, tmpl), tmpl ) ); offset += tmpl; len -= ( tmpl + 1 ); tmpl = (int) tvb_get_guint8(tvb, offset); if ( 0 == tmpl ) { proto_tree_add_text( tree, tvb, offset, 1, "### No Network Entity Title Section ###" ); offset++; len--; } else { proto_tree_add_text( tree, tvb, offset, 1, "### Network Entity Title Section ###" ); proto_tree_add_text( tree, tvb, offset++, 1, "NETL: %2u Octets", tmpl ); proto_tree_add_text( tree, tvb, offset, tmpl, " NET: %s", print_nsap_net( tvb_get_ptr(tvb, offset, tmpl), tmpl ) ); offset += tmpl; len -= ( tmpl + 1 ); } dissect_osi_options( len, tvb, offset, tree ); } }
/* * Name: dissect_osi_options() * * Description: * Main entry area for esis de-mangling. This will build the * main esis tree data and call the sub-protocols as needed. * * Input: * guchar : length of option section * tvbuff_t * : tvbuff containing packet data * int : offset into packet where we are (packet_data[offset]== start * of what we care about) * proto_tree * : tree of display data. May be NULL. * * Output: * void, but we will add to the proto_tree if it is not NULL. */ void dissect_osi_options( guchar opt_len, tvbuff_t *tvb, int offset, proto_tree *tree) { proto_item *ti; proto_tree *osi_option_tree = NULL; guchar parm_len = 0; guchar parm_type = 0; guint8 octet; if (tree) { if ( 0 == opt_len ) { proto_tree_add_text( tree, tvb, offset, 0, "### No Options for this PDU ###" ); return; } ti = proto_tree_add_text( tree, tvb, offset, opt_len, "### Option Section ###" ); osi_option_tree = proto_item_add_subtree( ti, ott_osi_options ); while ( 0 < opt_len ) { parm_type = (int) tvb_get_guint8(tvb, offset); offset++; parm_len = (int) tvb_get_guint8(tvb, offset); offset++; switch ( parm_type ) { case OSI_OPT_QOS_MAINTANANCE: octet = tvb_get_guint8(tvb, offset); dissect_option_qos( (guchar) (octet&OSI_OPT_QOS_MASK), (guchar) (octet&OSI_OPT_QOS_SUB_MASK), offset, parm_len, tvb, osi_option_tree ); break; case OSI_OPT_SECURITY: octet = tvb_get_guint8(tvb, offset); if ( clnp_decode_atn_options ){ dissect_option_atn_security_label(octet,parm_len,tvb, offset, osi_option_tree ); }else { proto_tree_add_text( osi_option_tree, tvb, offset, parm_len, "Security type: %s", val_to_str( octet&OSI_OPT_SEC_MASK, osi_opt_sec_vals, "Unknown (0x%x)") ); } break; case OSI_OPT_PRIORITY: octet = tvb_get_guint8(tvb, offset); if ( OSI_OPT_MAX_PRIORITY >= octet ) { proto_tree_add_text( osi_option_tree, tvb, offset, parm_len, "Priority : %u", octet ); } else { proto_tree_add_text( osi_option_tree, tvb, offset, parm_len, "Priority : %u ( Invalid )", octet ); } break; case OSI_OPT_ADDRESS_MASK: proto_tree_add_text( osi_option_tree, tvb, offset, parm_len, "Address Mask: %s", print_area( tvb_get_ptr(tvb, offset, parm_len), parm_len ) ); break; case OSI_OPT_SNPA_MASK: proto_tree_add_text( osi_option_tree, tvb, offset, parm_len, "SNPA Mask : %s", print_system_id( tvb_get_ptr(tvb, offset, parm_len), parm_len )); break; case OSI_OPT_ES_CONFIG_TIMER: proto_tree_add_text( osi_option_tree, tvb, offset, parm_len, "ESCT : %u seconds", tvb_get_ntohs( tvb, offset ) ); break; case OSI_OPT_PADDING: proto_tree_add_text( osi_option_tree, tvb, offset, parm_len, "Padding : %u Octets", parm_len ) ; break; case OSI_OPT_SOURCE_ROUTING: case OSI_OPT_RECORD_OF_ROUTE: dissect_option_route( parm_type, offset, parm_len, tvb, osi_option_tree ); break; case OSI_OPT_REASON_OF_DISCARD: dissect_option_rfd( tvb_get_guint8(tvb, offset), tvb_get_guint8(tvb, offset + 1), offset, parm_len, tvb, osi_option_tree ); break; } opt_len -= parm_len + 2; offset += parm_len; } } } /* dissect-osi-options */
gchar * tvb_print_system_id( tvbuff_t *tvb, const gint offset, int length ) { return( print_system_id(wmem_packet_scope(), tvb_get_ptr(tvb, offset, length), length) ); }
/* * 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); } }
/* * Name: isis_dissect_isis_csnp() * * Description: * Tear apart a L1 or L2 CSNP 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 offset : our offset into packet data. * int : type (l1 csnp, l2 csnp) * 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_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int type, int header_length, int id_length) { proto_item *ti; proto_tree *csnp_tree = NULL; guint16 pdu_length; int len; if (tree) { ti = proto_tree_add_text(tree, tvb, offset, -1, PROTO_STRING_CSNP); csnp_tree = proto_item_add_subtree(ti, ett_isis_csnp); } pdu_length = tvb_get_ntohs(tvb, offset); if (tree) { proto_tree_add_uint(csnp_tree, hf_isis_csnp_pdu_length, tvb, offset, 2, pdu_length); } offset += 2; if (tree) { proto_tree_add_text(csnp_tree, tvb, offset, id_length + 1, "Source-ID: %s", print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length+1 ) ); } 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; proto_tree_add_text(csnp_tree, tvb, offset, id_length + 2, "Start LSP-ID: %s", print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) ); col_append_fstr(pinfo->cinfo, COL_INFO, ", Start LSP-ID: %s", print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) ); offset += id_length + 2; proto_tree_add_text(csnp_tree, tvb, offset, id_length + 2, "End LSP-ID: %s", print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) ); col_append_fstr(pinfo->cinfo, COL_INFO, ", End LSP-ID: %s", print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) ); offset += id_length + 2; len = pdu_length - header_length; if (len < 0) { return; } /* Call into payload dissector */ if (type == ISIS_TYPE_L1_CSNP ) { isis_dissect_clvs(tvb, csnp_tree, offset, clv_l1_csnp_opts, len, id_length, ett_isis_csnp_clv_unknown ); } else { isis_dissect_clvs(tvb, csnp_tree, offset, clv_l2_csnp_opts, len, id_length, ett_isis_csnp_clv_unknown ); } }