--- ethereal-0.10.13.orig/epan/dissectors/packet-ospf.c 2005-12-10 12:40:02.000000000 -0200 +++ ethereal-0.10.13/epan/dissectors/packet-ospf.c 2005-12-11 20:13:21.000000000 -0200 @@ -199,6 +199,25 @@ static int proto_ospf = -1; +static int hf_ospf_options_v2 = -1; +static int hf_ospf_options_v2_e = -1; +static int hf_ospf_options_v2_mc = -1; +static int hf_ospf_options_v2_np = -1; +static int hf_ospf_options_v2_ea = -1; +static int hf_ospf_options_v2_dc = -1; +static int hf_ospf_options_v2_o = -1; +static int hf_ospf_options_v2_dn = -1; +static int hf_ospf_options_v3 = -1; +static int hf_ospf_options_v3_v6 = -1; +static int hf_ospf_options_v3_e = -1; +static int hf_ospf_options_v3_mc = -1; +static int hf_ospf_options_v3_n = -1; +static int hf_ospf_options_v3_r = -1; +static int hf_ospf_options_v3_dc = -1; +static int hf_ospf_dbd = -1; +static int hf_ospf_dbd_i = -1; +static int hf_ospf_dbd_m = -1; +static int hf_ospf_dbd_ms = -1; static gint ett_ospf = -1; static gint ett_ospf_hdr = -1; @@ -208,6 +227,9 @@ static gint ett_ospf_lsa = -1; static gint ett_ospf_lsa_router_link = -1; static gint ett_ospf_lsa_upd = -1; +static gint ett_ospf_options_v2 = -1; +static gint ett_ospf_options_v3 = -1; +static gint ett_ospf_dbd = -1; /* Trees for opaque LSAs */ static gint ett_ospf_lsa_mpls = -1; @@ -218,6 +240,74 @@ static gint ett_ospf_lsa_oif_tna = -1; static gint ett_ospf_lsa_oif_tna_stlv = -1; + + +static const true_false_string tfs_options_v2_dc = { + "Demand Circuits are supported", + "Demand circuits are NOT supported" +}; +static const true_false_string tfs_options_v2_ea = { + "External Attributes are supported", + "External attributes are NOT supported" +}; +static const true_false_string tfs_options_v2_np = { + "NSSA is supported", + "Nssa is NOT supported" +}; +static const true_false_string tfs_options_v2_mc = { + "Multicast Capable", + "NOT multicast capable" +}; +static const true_false_string tfs_options_v2_e = { + "ExternalRoputingCapability", + "NO ExternalRoutingCapability" +}; +static const true_false_string tfs_options_v2_o = { + "O-bit is SET", + "O-bit is CLEAR" +}; +static const true_false_string tfs_options_v2_dn = { + "DN-bit is SET", + "DN-bit is CLEAR" +}; + +static const true_false_string tfs_options_v3_v6 = { + "V6 is SET", + "V6 is NOT set" +}; +static const true_false_string tfs_options_v3_e = { + "E is SET", + "E is NOT set" +}; +static const true_false_string tfs_options_v3_mc = { + "MC is SET", + "MC is NOT set" +}; +static const true_false_string tfs_options_v3_n = { + "N is SET", + "N is NOT set" +}; +static const true_false_string tfs_options_v3_r = { + "R is SET", + "R is NOT set" +}; +static const true_false_string tfs_options_v3_dc = { + "DC is SET", + "DC is NOT set" +}; +static const true_false_string tfs_dbd_i = { + "I is SET", + "I is NOT set" +}; +static const true_false_string tfs_dbd_m = { + "M is SET", + "M is NOT set" +}; +static const true_false_string tfs_dbd_ms = { + "MS is SET", + "MS is NOT set" +}; + /*----------------------------------------------------------------------- * OSPF Filtering *-----------------------------------------------------------------------*/ @@ -373,7 +463,63 @@ {&ospf_filter[OSPFF_LS_MPLS_LINKCOLOR], { "MPLS/TE Link Resource Class/Color", "ospf.mpls.linkcolor", FT_UINT32, BASE_HEX, NULL, 0x0, "MPLS/TE Link Resource Class/Color", HFILL }}, - + {&hf_ospf_options_v2, + { "Options", "ospf.options.v2", FT_UINT8, BASE_HEX, + NULL, 0x0, "", HFILL }}, + {&hf_ospf_options_v2_e, + { "E", "ospf.options.v2.e", FT_BOOLEAN, 8, + TFS(&tfs_options_v2_e), OSPF_V2_OPTIONS_E, "", HFILL }}, + {&hf_ospf_options_v2_mc, + { "MC", "ospf.options.v2.mc", FT_BOOLEAN, 8, + TFS(&tfs_options_v2_mc), OSPF_V2_OPTIONS_MC, "", HFILL }}, + {&hf_ospf_options_v2_np, + { "NP", "ospf.options.v2.np", FT_BOOLEAN, 8, + TFS(&tfs_options_v2_np), OSPF_V2_OPTIONS_NP, "", HFILL }}, + {&hf_ospf_options_v2_ea, + { "EA", "ospf.options.v2.ea", FT_BOOLEAN, 8, + TFS(&tfs_options_v2_ea), OSPF_V2_OPTIONS_EA, "", HFILL }}, + {&hf_ospf_options_v2_dc, + { "DC", "ospf.options.v2.dc", FT_BOOLEAN, 8, + TFS(&tfs_options_v2_dc), OSPF_V2_OPTIONS_DC, "", HFILL }}, + {&hf_ospf_options_v2_o, + { "O", "ospf.options.v2.o", FT_BOOLEAN, 8, + TFS(&tfs_options_v2_o), OSPF_V2_OPTIONS_O, "", HFILL }}, + {&hf_ospf_options_v2_dn, + { "DN", "ospf.options.v2.dn", FT_BOOLEAN, 8, + TFS(&tfs_options_v2_dn), OSPF_V2_OPTIONS_DN, "", HFILL }}, + {&hf_ospf_options_v3, + { "Options", "ospf.options.v3", FT_UINT24, BASE_HEX, + NULL, 0x0, "", HFILL }}, + {&hf_ospf_options_v3_v6, + { "V6", "ospf.options.v3.v6", FT_BOOLEAN, 24, + TFS(&tfs_options_v3_v6), OSPF_V3_OPTIONS_V6, "", HFILL }}, + {&hf_ospf_options_v3_e, + { "E", "ospf.options.v3.e", FT_BOOLEAN, 24, + TFS(&tfs_options_v3_e), OSPF_V3_OPTIONS_E, "", HFILL }}, + {&hf_ospf_options_v3_mc, + { "MC", "ospf.options.v3.mc", FT_BOOLEAN, 24, + TFS(&tfs_options_v3_mc), OSPF_V3_OPTIONS_MC, "", HFILL }}, + {&hf_ospf_options_v3_n, + { "N", "ospf.options.v3.n", FT_BOOLEAN, 24, + TFS(&tfs_options_v3_n), OSPF_V3_OPTIONS_N, "", HFILL }}, + {&hf_ospf_options_v3_r, + { "R", "ospf.options.v3.r", FT_BOOLEAN, 24, + TFS(&tfs_options_v3_r), OSPF_V3_OPTIONS_R, "", HFILL }}, + {&hf_ospf_options_v3_dc, + { "DC", "ospf.options.v3.dc", FT_BOOLEAN, 24, + TFS(&tfs_options_v3_dc), OSPF_V3_OPTIONS_DC, "", HFILL }}, + {&hf_ospf_dbd, + { "DB Description", "ospf.dbd", FT_UINT8, BASE_HEX, + NULL, 0x0, "", HFILL }}, + {&hf_ospf_dbd_i, + { "I", "ospf.dbd.i", FT_BOOLEAN, 8, + TFS(&tfs_dbd_i), OSPF_DBD_FLAG_I, "", HFILL }}, + {&hf_ospf_dbd_m, + { "M", "ospf.dbd.m", FT_BOOLEAN, 8, + TFS(&tfs_dbd_m), OSPF_DBD_FLAG_M, "", HFILL }}, + {&hf_ospf_dbd_ms, + { "MS", "ospf.dbd.ms", FT_BOOLEAN, 8, + TFS(&tfs_dbd_ms), OSPF_DBD_FLAG_MS, "", HFILL }}, }; @@ -742,13 +888,45 @@ } static void +dissect_ospf_dbd (proto_tree *parent_tree, tvbuff_t *tvb, int offset) +{ + proto_item *item=NULL; + proto_tree *tree=NULL; + guint8 flags; + + flags = tvb_get_guint8 (tvb, offset); + if(parent_tree){ + item=proto_tree_add_uint(parent_tree, hf_ospf_dbd, + tvb, offset, 1, flags); + tree=proto_item_add_subtree(item, ett_ospf_dbd); + } + + proto_tree_add_boolean(tree, hf_ospf_dbd_i, tvb, offset, 1, flags); + if (flags&OSPF_DBD_FLAG_I){ + proto_item_append_text(item, " I"); + } + flags&=(~( OSPF_DBD_FLAG_I )); + + proto_tree_add_boolean(tree, hf_ospf_dbd_m, tvb, offset, 1, flags); + if (flags&OSPF_DBD_FLAG_M){ + proto_item_append_text(item, " M"); + } + flags&=(~( OSPF_DBD_FLAG_M )); + + proto_tree_add_boolean(tree, hf_ospf_dbd_ms, tvb, offset, 1, flags); + if (flags&OSPF_DBD_FLAG_MS){ + proto_item_append_text(item, " MS"); + } + flags&=(~( OSPF_DBD_FLAG_MS )); +} + + +static void dissect_ospf_db_desc(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version) { proto_tree *ospf_db_desc_tree=NULL; proto_item *ti; - guint8 flags; guint8 reserved; - char flags_string[20] = ""; if (tree) { ti = proto_tree_add_text(tree, tvb, offset, -1, "OSPF DB Description"); @@ -757,27 +935,13 @@ switch (version ) { case OSPF_VERSION_2: - proto_tree_add_text(ospf_db_desc_tree, tvb, offset, 2, "Interface MTU: %u", tvb_get_ntohs(tvb, offset)); dissect_ospf_options(tvb, offset + 2, ospf_db_desc_tree, version); - flags = tvb_get_guint8(tvb, offset + 3); - if (flags & OSPF_DBD_FLAG_MS) - strcat(flags_string, "MS"); - if (flags & OSPF_DBD_FLAG_M) { - if (flags_string[0] != '\0') - strcat(flags_string, "/"); - strcat(flags_string, "M"); - } - if (flags & OSPF_DBD_FLAG_I) { - if (flags_string[0] != '\0') - strcat(flags_string, "/"); - strcat(flags_string, "I"); - } - proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 3, 1, "Flags: 0x%x (%s)", - flags, flags_string); + dissect_ospf_dbd(ospf_db_desc_tree, tvb, offset+3); + proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 4, 4, "DD Sequence: %u", tvb_get_ntohl(tvb, offset + 4)); @@ -799,21 +963,7 @@ proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 6, 1, (reserved == 0 ? "Reserved: %u" : "Reserved: %u [incorrect, should be 0]"), reserved); - flags = tvb_get_guint8(tvb, offset + 7); - if (flags & OSPF_DBD_FLAG_MS) - strcat(flags_string, "MS"); - if (flags & OSPF_DBD_FLAG_M) { - if (flags_string[0] != '\0') - strcat(flags_string, "/"); - strcat(flags_string, "M"); - } - if (flags & OSPF_DBD_FLAG_I) { - if (flags_string[0] != '\0') - strcat(flags_string, "/"); - strcat(flags_string, "I"); - } - proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 7, 1, "Flags: 0x%x (%s)", - flags, flags_string); + dissect_ospf_dbd(ospf_db_desc_tree, tvb, offset+7); proto_tree_add_text(ospf_db_desc_tree, tvb, offset + 8, 4, "DD Sequence: %u", tvb_get_ntohl(tvb, offset + 8)); @@ -2165,103 +2315,128 @@ static void -dissect_ospf_options(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version) +dissect_ospf_v2_options (proto_tree *parent_tree, tvbuff_t *tvb, int offset) { - guint8 options_ospfv2; - guint32 options_ospfv3; - char options_string[20] = ""; - - /* ATTENTION !!! no check for length of options string - with OSPFv3 maximum length is 14 characters */ + proto_item *item=NULL; + proto_tree *tree=NULL; + guint8 flags; + + flags = tvb_get_guint8 (tvb, offset); + if(parent_tree){ + item=proto_tree_add_uint(parent_tree, hf_ospf_options_v2, + tvb, offset, 1, flags); + tree=proto_item_add_subtree(item, ett_ospf_options_v2); + } - switch ( version ) { + proto_tree_add_boolean(tree, hf_ospf_options_v2_o, tvb, offset, 1, flags); + if (flags&OSPF_V2_OPTIONS_O){ + proto_item_append_text(item, " O"); + } + flags&=(~( OSPF_V2_OPTIONS_O )); - case OSPF_VERSION_2: - options_ospfv2 = tvb_get_guint8(tvb, offset); + proto_tree_add_boolean(tree, hf_ospf_options_v2_dc, tvb, offset, 1, flags); + if (flags&OSPF_V2_OPTIONS_DC){ + proto_item_append_text(item, " DC"); + } + flags&=(~( OSPF_V2_OPTIONS_DC )); - if (options_ospfv2 & OSPF_V2_OPTIONS_E) - strcat(options_string, "E"); + proto_tree_add_boolean(tree, hf_ospf_options_v2_ea, tvb, offset, 1, flags); + if (flags&OSPF_V2_OPTIONS_EA){ + proto_item_append_text(item, " EA"); + } + flags&=(~( OSPF_V2_OPTIONS_EA )); - if (options_ospfv2 & OSPF_V2_OPTIONS_MC) { - if (options_string[0] != '\0') - strcat(options_string, "/"); - strcat(options_string, "MC"); - } + proto_tree_add_boolean(tree, hf_ospf_options_v2_np, tvb, offset, 1, flags); + if (flags&OSPF_V2_OPTIONS_NP){ + proto_item_append_text(item, " NP"); + } + flags&=(~( OSPF_V2_OPTIONS_NP )); - if (options_ospfv2 & OSPF_V2_OPTIONS_NP) { - if (options_string[0] != '\0') - strcat(options_string, "/"); - strcat(options_string, "NP"); - } + proto_tree_add_boolean(tree, hf_ospf_options_v2_mc, tvb, offset, 1, flags); + if (flags&OSPF_V2_OPTIONS_MC){ + proto_item_append_text(item, " MC"); + } + flags&=(~( OSPF_V2_OPTIONS_MC )); - if (options_ospfv2 & OSPF_V2_OPTIONS_EA) { - if (options_string[0] != '\0') - strcat(options_string, "/"); - strcat(options_string, "EA"); - } + proto_tree_add_boolean(tree, hf_ospf_options_v2_e, tvb, offset, 1, flags); + if (flags&OSPF_V2_OPTIONS_E){ + proto_item_append_text(item, " E"); + } + flags&=(~( OSPF_V2_OPTIONS_E )); - if (options_ospfv2 & OSPF_V2_OPTIONS_DC) { - if (options_string[0] != '\0') - strcat(options_string, "/"); - strcat(options_string, "DC"); - } + proto_tree_add_boolean(tree, hf_ospf_options_v2_dn, tvb, offset, 1, flags); + if (flags&OSPF_V2_OPTIONS_DN){ + proto_item_append_text(item, " DN"); + } + flags&=(~( OSPF_V2_OPTIONS_DN )); +} - if (options_ospfv2 & OSPF_V2_OPTIONS_O) { - if (options_string[0] != '\0') - strcat(options_string, "/"); - strcat(options_string, "O"); - } +static void +dissect_ospf_v3_options (proto_tree *parent_tree, tvbuff_t *tvb, int offset) +{ + proto_item *item=NULL; + proto_tree *tree=NULL; + guint32 flags; + + flags = tvb_get_ntoh24 (tvb, offset); + if(parent_tree){ + item=proto_tree_add_uint(parent_tree, hf_ospf_options_v3, + tvb, offset, 3, flags); + tree=proto_item_add_subtree(item, ett_ospf_options_v3); + } - if (options_ospfv2 & OSPF_V2_OPTIONS_DN) { - if (options_string[0] != '\0') - strcat(options_string, "/"); - strcat(options_string, "DN"); - } + proto_tree_add_boolean(tree, hf_ospf_options_v3_dc, tvb, offset, 3, flags); + if (flags&OSPF_V3_OPTIONS_DC){ + proto_item_append_text(item, " DC"); + } + flags&=(~( OSPF_V3_OPTIONS_DC )); - proto_tree_add_text(tree, tvb, offset, 1, "Options: 0x%x (%s)", - options_ospfv2, options_string); - break; + proto_tree_add_boolean(tree, hf_ospf_options_v3_r, tvb, offset, 3, flags); + if (flags&OSPF_V3_OPTIONS_R){ + proto_item_append_text(item, " R"); + } + flags&=(~( OSPF_V3_OPTIONS_R )); + proto_tree_add_boolean(tree, hf_ospf_options_v3_n, tvb, offset, 3, flags); + if (flags&OSPF_V3_OPTIONS_N){ + proto_item_append_text(item, " N"); + } + flags&=(~( OSPF_V3_OPTIONS_N )); - case OSPF_VERSION_3: + proto_tree_add_boolean(tree, hf_ospf_options_v3_mc, tvb, offset, 3, flags); + if (flags&OSPF_V3_OPTIONS_MC){ + proto_item_append_text(item, " MC"); + } + flags&=(~( OSPF_V3_OPTIONS_MC )); - options_ospfv3 = tvb_get_ntoh24(tvb, offset); + proto_tree_add_boolean(tree, hf_ospf_options_v3_e, tvb, offset, 3, flags); + if (flags&OSPF_V3_OPTIONS_E){ + proto_item_append_text(item, " E"); + } + flags&=(~( OSPF_V3_OPTIONS_E )); - if (options_ospfv3 & OSPF_V3_OPTIONS_V6) - strcat(options_string, "V6"); + proto_tree_add_boolean(tree, hf_ospf_options_v3_v6, tvb, offset, 3, flags); + if (flags&OSPF_V3_OPTIONS_V6){ + proto_item_append_text(item, " V6"); + } + flags&=(~( OSPF_V3_OPTIONS_V6 )); - if (options_ospfv3 & OSPF_V3_OPTIONS_E) { - if (options_string[0] != '\0') - strcat(options_string, "/"); - strcat(options_string, "E"); - } +} - if (options_ospfv3 & OSPF_V3_OPTIONS_MC) { - if (options_string[0] != '\0') - strcat(options_string, "/"); - strcat(options_string, "MC"); - } - if (options_ospfv3 & OSPF_V3_OPTIONS_N) { - if (options_string[0] != '\0') - strcat(options_string, "/"); - strcat(options_string, "N"); - } +static void +dissect_ospf_options(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 version) +{ + switch ( version ) { - if (options_ospfv3 & OSPF_V3_OPTIONS_R) { - if (options_string[0] != '\0') - strcat(options_string, "/"); - strcat(options_string, "R"); - } + case OSPF_VERSION_2: + dissect_ospf_v2_options (tree, tvb, offset); + break; - if (options_ospfv3 & OSPF_V3_OPTIONS_DC) { - if (options_string[0] != '\0') - strcat(options_string, "/"); - strcat(options_string, "DC"); - } - proto_tree_add_text(tree, tvb, offset, 3, "Options: 0x%x (%s)", - options_ospfv3, options_string); + case OSPF_VERSION_3: + dissect_ospf_v3_options (tree, tvb, offset); break; } @@ -2321,39 +2496,28 @@ static void dissect_ospf_v3_address_prefix(tvbuff_t *tvb, int offset, int prefix_length, proto_tree *tree) { - guint8 value; - guint8 position; - guint8 bufpos; - gchar *buffer; - gchar *bytebuf; - guint8 bytes_to_process; - int start_offset; + int bytes_to_process; + struct e_in6_addr prefix; - start_offset=offset; - position=0; - bufpos=0; bytes_to_process=((prefix_length+31)/32)*4; - buffer=ep_alloc(32+7); - while (bytes_to_process > 0 ) { - - value=tvb_get_guint8(tvb, offset); - - if ( (position > 0) && ( (position%2) == 0 ) ) - buffer[bufpos++]=':'; - - bytebuf=ep_alloc(3); - g_snprintf(bytebuf, 3, "%02x",value); - buffer[bufpos++]=bytebuf[0]; - buffer[bufpos++]=bytebuf[1]; - - position++; - offset++; - bytes_to_process--; + if (prefix_length > 128) { + proto_tree_add_text(tree, tvb, offset, bytes_to_process, + "Address Prefix: length is invalid (%d, should be <= 128)", + prefix_length); + return; } - buffer[bufpos]=0; - proto_tree_add_text(tree, tvb, start_offset, ((prefix_length+31)/32)*4, "Address Prefix: %s",buffer); + memset(prefix.bytes, 0, sizeof prefix.bytes); + if (bytes_to_process != 0) { + tvb_memcpy(tvb, prefix.bytes, offset, bytes_to_process); + if (prefix_length % 8) { + prefix.bytes[bytes_to_process - 1] &= + ((0xff00 >> (prefix_length % 8)) & 0xff); + } + } + proto_tree_add_text(tree, tvb, offset, bytes_to_process, + "Address Prefix: %s", ip6_to_str(&prefix)); } @@ -2376,7 +2540,10 @@ &ett_ospf_lsa_mpls_link_stlv, &ett_ospf_lsa_mpls_link_stlv_admingrp, &ett_ospf_lsa_oif_tna, - &ett_ospf_lsa_oif_tna_stlv + &ett_ospf_lsa_oif_tna_stlv, + &ett_ospf_options_v2, + &ett_ospf_options_v3, + &ett_ospf_dbd }; proto_ospf = proto_register_protocol("Open Shortest Path First",