/* * 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*/ } }
/* * 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" ); } }
/* * 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; } }
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_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"); } } }
/* * 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); } }
/* * 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; } }
/* * 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; } }
/* * 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; } }
/* * 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; } }
/* * 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 */
/* * 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); } }