Add filterable expert info.
authorMichael Mann <mmann78@netscape.net>
Sat, 25 May 2013 03:27:31 +0000 (03:27 -0000)
committerMichael Mann <mmann78@netscape.net>
Sat, 25 May 2013 03:27:31 +0000 (03:27 -0000)
svn path=/trunk/; revision=49573

epan/dissectors/packet-bootp.c
epan/dissectors/packet-dhcpv6.c

index 2d1031d38c14f049c7db2cf395de02c5b8842fb2..d5e460cc3fd3c6933d86e346db526f3f9430f86f 100644 (file)
@@ -462,6 +462,46 @@ static gint ett_bootp_option82_suboption9 = -1;
 static gint ett_bootp_option125_suboption = -1;
 static gint ett_bootp_fqdn = -1;
 
+static expert_field ei_bootp_bad_length0 = EI_INIT;
+static expert_field ei_bootp_bad_length1 = EI_INIT;
+static expert_field ei_bootp_bad_length2 = EI_INIT;
+static expert_field ei_bootp_bad_length4 = EI_INIT;
+static expert_field ei_bootp_bad_length6 = EI_INIT;
+static expert_field ei_bootp_bad_length7 = EI_INIT;
+static expert_field ei_bootp_bad_length3_6 = EI_INIT;
+static expert_field ei_bootp_bad_length_ge1 = EI_INIT;
+static expert_field ei_bootp_bad_length_ge2 = EI_INIT;
+static expert_field ei_bootp_bad_length_ge3 = EI_INIT;
+static expert_field ei_bootp_bad_length_ge5 = EI_INIT;
+static expert_field ei_bootp_bad_length_ge11 = EI_INIT;
+static expert_field ei_bootp_bad_length_ge31 = EI_INIT;
+static expert_field ei_bootp_bad_length_lt5 = EI_INIT;
+static expert_field ei_bootp_opt_length_not_mult2 = EI_INIT;
+static expert_field ei_bootp_opt_length_not_mult4 = EI_INIT;
+static expert_field ei_bootp_opt_length_not_mult8 = EI_INIT;
+static expert_field ei_bootp_opt_length_not_mult4_plus1 = EI_INIT;
+static expert_field ei_bootp_missing_subopt_length = EI_INIT;
+static expert_field ei_bootp_missing_subopt_value = EI_INIT;
+static expert_field ei_bootp_mal_duid = EI_INIT;
+static expert_field hf_bootp_opt_overload_file_end_missing = EI_INIT;
+static expert_field hf_bootp_opt_overload_sname_end_missing = EI_INIT;
+static expert_field hf_bootp_subopt_unknown_type = EI_INIT;
+static expert_field ei_bootp_option77_user_class_len = EI_INIT;
+static expert_field ei_bootp_option77_user_class_malformed = EI_INIT;
+static expert_field ei_bootp_option_civic_location_bad_cattype = EI_INIT;
+static expert_field ei_bootp_bad_length_even = EI_INIT;
+static expert_field ei_bootp_option_dhcp_name_service_invalid = EI_INIT;
+static expert_field ei_bootp_option_sip_server_address_encoding = EI_INIT;
+static expert_field ei_bootp_option_classless_static_route = EI_INIT;
+static expert_field ei_bootp_option_classless_static_bad_router_length = EI_INIT;
+static expert_field ei_bootp_invalid_length = EI_INIT;
+static expert_field ei_bootp_option125_enterprise_malformed = EI_INIT;
+static expert_field ei_bootp_option_6RD_malformed = EI_INIT;
+static expert_field ei_bootp_option82_vi_cl_tag_unknown = EI_INIT;
+static expert_field ei_bootp_suboption_invalid = EI_INIT;
+static expert_field ei_bootp_secs_le = EI_INIT;
+static expert_field ei_bootp_end_option_missing = EI_INIT;
+
 /* RFC2937 The Name Service Search Option for DHCP */
 #define RFC2937_LOCAL_NAMING_INFORMATION                           0
 #define RFC2937_DOMAIN_NAME_SERVER_OPTION                          6
@@ -1256,8 +1296,7 @@ bootp_handle_basic_types(packet_info *pinfo, proto_tree *tree, proto_item *item,
 
        case ipv4:
                if (total_len != 4) {
-                       expert_add_info_format(pinfo, item, PI_PROTOCOL,
-                               PI_ERROR, "length isn't 4");
+                       expert_add_info(pinfo, item, &ei_bootp_bad_length4);
                        break;
                }
 
@@ -1271,7 +1310,7 @@ bootp_handle_basic_types(packet_info *pinfo, proto_tree *tree, proto_item *item,
        case ipv4_list:
                for (i = offset, left = total_len; left > 0; i += 4, left -= 4) {
                        if (left < 4) {
-                               expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_ERROR, "Option length isn't a multiple of 4");
+                               expert_add_info(pinfo, item, &ei_bootp_opt_length_not_mult4);
                                break;
                        }
 
@@ -1294,7 +1333,7 @@ bootp_handle_basic_types(packet_info *pinfo, proto_tree *tree, proto_item *item,
 
        case val_boolean:
                if (total_len != 1) {
-                       expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_ERROR, "length isn't 1");
+                       expert_add_info(pinfo, item, &ei_bootp_bad_length1);
                        break;
                }
 
@@ -1307,7 +1346,7 @@ bootp_handle_basic_types(packet_info *pinfo, proto_tree *tree, proto_item *item,
 
        case val_u_byte:
                if (total_len != 1) {
-                       expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_ERROR, "length isn't 1");
+                       expert_add_info(pinfo, item, &ei_bootp_bad_length1);
                        break;
                }
 
@@ -1320,7 +1359,7 @@ bootp_handle_basic_types(packet_info *pinfo, proto_tree *tree, proto_item *item,
 
        case val_u_short:
                if (total_len != 2) {
-                       expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_ERROR, "length isn't 2");
+                       expert_add_info(pinfo, item, &ei_bootp_bad_length2);
                        break;
                }
 
@@ -1333,7 +1372,7 @@ bootp_handle_basic_types(packet_info *pinfo, proto_tree *tree, proto_item *item,
 
        case val_u_le_short:
                if (total_len != 2) {
-                       expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_ERROR, "length isn't 2");
+                       expert_add_info(pinfo, item, &ei_bootp_bad_length2);
                        break;
                }
 
@@ -1347,7 +1386,7 @@ bootp_handle_basic_types(packet_info *pinfo, proto_tree *tree, proto_item *item,
        case val_u_short_list:
                for (i = offset, left = total_len; left > 0; i += 2, left -= 2) {
                        if (left < 2) {
-                               expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_ERROR, "Option length isn't a multiple of 2");
+                               expert_add_info(pinfo, item, &ei_bootp_opt_length_not_mult2);
                                break;
                        }
 
@@ -1361,7 +1400,7 @@ bootp_handle_basic_types(packet_info *pinfo, proto_tree *tree, proto_item *item,
 
        case val_u_long:
                if (total_len != 4) {
-                       expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_ERROR, "length isn't 4");
+                       expert_add_info(pinfo, item, &ei_bootp_bad_length4);
                        break;
                }
 
@@ -1374,7 +1413,7 @@ bootp_handle_basic_types(packet_info *pinfo, proto_tree *tree, proto_item *item,
 
        case time_in_s_secs:
                if (total_len != 4) {
-                  expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_ERROR, "length isn't 4");
+                       expert_add_info(pinfo, item, &ei_bootp_bad_length4);
                        break;
                }
 
@@ -1391,7 +1430,7 @@ bootp_handle_basic_types(packet_info *pinfo, proto_tree *tree, proto_item *item,
 
        case time_in_u_secs:
                if (total_len != 4) {
-                       expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_ERROR, "length isn't 4");
+                       expert_add_info(pinfo, item, &ei_bootp_bad_length4);
                        break;
                }
 
@@ -1596,7 +1635,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                for (i = optoff, optleft = optlen;
                        optleft > 0; i += 8, optleft -= 8) {
                        if (optleft < 8) {
-                               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't a multiple of 8");
+                               expert_add_info(pinfo, vti, &ei_bootp_opt_length_not_mult8);
                                break;
                        }
 
@@ -1609,7 +1648,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                for (i = optoff, optleft = optlen;
                        optleft > 0; i += 8, optleft -= 8) {
                        if (optleft < 8) {
-                               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't a multiple of 8");
+                               expert_add_info(pinfo, vti, &ei_bootp_opt_length_not_mult8);
                                break;
                        }
 
@@ -1662,7 +1701,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
 
        case 52:        /* Option Overload */
                if (optlen < 1) {
-                  expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't >= 1");
+                       expert_add_info(pinfo, vti, &ei_bootp_bad_length_ge1);
                        break;
                }
 
@@ -1689,8 +1728,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                                }
                                if (!o52at_end)
                                {
-                                       expert_add_info_format(pinfo, oti, PI_PROTOCOL,
-                                               PI_ERROR, "file overload end option missing");
+                                       expert_add_info(pinfo, oti, &hf_bootp_opt_overload_file_end_missing);
                                }
                        }
                        if (byte & OPT_OVERLOAD_SNAME) {
@@ -1711,8 +1749,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                                }
                                if (!o52at_end)
                                {
-                                       expert_add_info_format(pinfo, oti, PI_PROTOCOL,
-                                               PI_ERROR, "sname overload end option missing");
+                                       expert_add_info(pinfo, oti, &hf_bootp_opt_overload_sname_end_missing);
                                }
                        }
                        /* The final end option is not in overload */
@@ -1818,7 +1855,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                        switch (duidtype) {
                        case DUID_LLT:
                                if (optlen < 8) {
-                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "DUID: malformed option");
+                                       expert_add_info(pinfo, vti, &ei_bootp_mal_duid);
                                        break;
                                }
                                hwtype=tvb_get_ntohs(tvb, optoff + 2);
@@ -1836,7 +1873,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                                break;
                        case DUID_EN:
                                if (optlen < 6) {
-                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "DUID: malformed option");
+                                       expert_add_info(pinfo, vti, &ei_bootp_mal_duid);
                                        break;
                                }
                                enterprise = tvb_get_ntohl(tvb, optoff+2);
@@ -1852,7 +1889,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                                break;
                        case DUID_LL:
                                if (optlen < 4) {
-                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "DUID: malformed option");
+                                       expert_add_info(pinfo, vti, &ei_bootp_mal_duid);
                                        break;
                                }
                                hwtype=tvb_get_ntohs(tvb, optoff + 2);
@@ -1875,7 +1912,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                proto_item *vtix;
                proto_tree *o77_v_tree;
                if (optlen < 2) {
-                       expert_add_info_format(pinfo, v_tree, PI_PROTOCOL, PI_ERROR, "length isn't >= 2 (length = %i)", optlen);
+                       expert_add_info(pinfo, v_tree, &ei_bootp_bad_length_ge2);
                        break;
                }
                optleft = optlen;
@@ -1890,12 +1927,12 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                                        tvb, optoff + i, 1, ENC_BIG_ENDIAN);
 
                        if (byte == 0) {
-                               expert_add_info_format(pinfo, vtix, PI_PROTOCOL, PI_ERROR, "UC_Len_%u isn't >= 1 (UC_Len_%u = 0)", user_class_instance_index, user_class_instance_index);
+                               expert_add_info_format_text(pinfo, vtix, &ei_bootp_option77_user_class_len, "UC_Len_%u isn't >= 1 (UC_Len_%u = 0)", user_class_instance_index, user_class_instance_index);
                                break;
                        }
                        optleft -= byte + 1;
                        if (optleft < 0) {
-                               expert_add_info_format(pinfo, vtix, PI_PROTOCOL, PI_ERROR, "User Class Information: malformed option");
+                               expert_add_info(pinfo, vtix, &ei_bootp_option77_user_class_malformed);
                                break;
                        }
 
@@ -1953,7 +1990,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
 
        case 78:        /* SLP Directory Agent Option RFC2610 Added by Greg Morris (gmorris@novell.com)*/
                if (optlen < 1) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't >= 1");
+                       expert_add_info(pinfo, vti, &ei_bootp_bad_length_ge1);
                        break;
                }
                optleft = optlen;
@@ -1970,7 +2007,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                }
                for (i = optoff; optleft > 0; i += 4, optleft -= 4) {
                        if (optleft < 4) {
-                               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't a multiple of 4");
+                               expert_add_info(pinfo, vti, &ei_bootp_opt_length_not_mult4);
                                break;
                        }
 
@@ -1988,7 +2025,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
 
        case 81:        /* Client Fully Qualified Domain Name */
                if (optlen < 3) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't >= 3");
+                       expert_add_info(pinfo, vti, &ei_bootp_bad_length_ge3);
                        break;
                }
                fqdn_flags = tvb_get_guint8(tvb, optoff);
@@ -2030,7 +2067,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                        for (i = optoff, optleft = optlen; optleft > 0;
                                i += 4, optleft -= 4) {
                                if (optleft < 4) {
-                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't a multiple of 4");
+                                       expert_add_info(pinfo, vti, &ei_bootp_opt_length_not_mult4);
                                        break;
                                }
 
@@ -2057,7 +2094,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
        case 90:        /* DHCP Authentication */
        case 210:       /* Was this used for authentication at one time? */
                if (optlen < 11) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't >= 11");
+                       expert_add_info(pinfo, vti, &ei_bootp_bad_length_ge11);
                        break;
                }
                optleft = optlen;
@@ -2110,7 +2147,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                                        break;
                                } else {
                                        if (optlen < 31) {
-                                               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't >= 31");
+                                               expert_add_info(pinfo, vti, &ei_bootp_bad_length_ge31);
                                                break;
                                        }
 
@@ -2171,7 +2208,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                                else
                                {
                                        optleft = 0;
-                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "Error with CAType");
+                                       expert_add_info(pinfo, vti, &ei_bootp_option_civic_location_bad_cattype);
                                }
                        }
                }
@@ -2179,9 +2216,9 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
 
        case 117:   /* The Name Service Search Option for DHCP (RFC 2937) */
                if (optlen < 2) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length (%u) isn't >= 2", optlen);
+                       expert_add_info(pinfo, vti, &ei_bootp_bad_length_ge2);
                } else if (optlen & 1) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length (%u) isn't even number", optlen);
+                       expert_add_info_format_text(pinfo, vti, &ei_bootp_bad_length_even, "length (%u) isn't even number", optlen);
                } else {
                        guint16 ns;
                        for (i = 0, ns = tvb_get_ntohs(tvb, optoff); i < optlen; i += 2, ns = tvb_get_ntohs(tvb, optoff + i)) {
@@ -2202,7 +2239,8 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                                        proto_tree_add_string(v_tree, hf_bootp_option_dhcp_name_service_search_option, tvb, optoff + i, 2, "Network Information Service+ Servers Option (65)");
                                        break;
                                default:
-                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "Invalid Name Service (%u). RFC 2937 defines only 0, 6, 41, 44, and 65 as possible values.", ns);
+                                       expert_add_info_format_text(pinfo, vti, &ei_bootp_option_dhcp_name_service_invalid,
+                                                               "Invalid Name Service (%u). RFC 2937 defines only 0, 6, 41, 44, and 65 as possible values.", ns);
                                        break;
                                }
                        }
@@ -2300,7 +2338,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                        case RFC_3361_ENC_FQDN: {
                                unsigned int consumedx = 0;
                                if (tvb_length(rfc3396_sip_server.tvb_composite) < 3) {
-                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't >= 3 (len = %u)", tvb_length(rfc3396_sip_server.tvb_composite));
+                                       expert_add_info_format_text(pinfo, vti, &ei_bootp_bad_length_ge3, "length isn't >= 3 (len = %u)", tvb_length(rfc3396_sip_server.tvb_composite));
                                        break;
                                }
 
@@ -2322,15 +2360,17 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                        }
                        case RFC_3361_ENC_IPADDR:
                                if (tvb_length(rfc3396_sip_server.tvb_composite) < 5) {
-                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't >= 5 (len = %u)", tvb_length(rfc3396_sip_server.tvb_composite));
+                                       expert_add_info_format_text(pinfo, vti, &ei_bootp_bad_length_ge5, "length isn't >= 5 (len = %u)", tvb_length(rfc3396_sip_server.tvb_composite));
                                        break;
                                }
                                /* x % 2^n == x & (2^n - 1) note : (assuming x is a positive integer) */
                                if ((tvb_length(rfc3396_sip_server.tvb_composite) - 1) & 3) {
                                        if (rfc3396_sip_server.total_number_of_block == 1)
-                                               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't a multiple of 4 plus 1 (len = %u).", tvb_length(rfc3396_sip_server.tvb_composite));
+                                               expert_add_info_format_text(pinfo, vti, &ei_bootp_opt_length_not_mult4_plus1, "length isn't a multiple of 4 plus 1 (len = %u).", tvb_length(rfc3396_sip_server.tvb_composite));
                                        else
-                                               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't a multiple of 4 plus 1 (len = %u). For your information with RFC 3396, the length is the length sum of all options 120 into this BOOTP packet.", tvb_length(rfc3396_sip_server.tvb_composite));
+                                               expert_add_info_format_text(pinfo, vti, &ei_bootp_opt_length_not_mult4_plus1, 
+                                                       "length isn't a multiple of 4 plus 1 (len = %u). For your information with RFC 3396, the length is the length sum of all options 120 into this BOOTP packet.",
+                                                       tvb_length(rfc3396_sip_server.tvb_composite));
                                        break;
                                }
                                while (offset < tvb_length(rfc3396_sip_server.tvb_composite)) {
@@ -2356,7 +2396,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                                }
                                break;
                        default:
-                               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "RFC 3361 defines only 0 and 1 for Encoding byte (Encoding = %u).", enc);
+                               expert_add_info_format_text(pinfo, vti, &ei_bootp_option_sip_server_address_encoding, "RFC 3361 defines only 0 and 1 for Encoding byte (Encoding = %u).", enc);
                                break;
                        }
                }
@@ -2368,14 +2408,14 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                optend = optoff + optlen;
                /* minimum length is 5 bytes */
                if (optlen < 5) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length < 5 bytes");
+                       expert_add_info(pinfo, vti, &ei_bootp_bad_length_ge5);
                        break;
                }
                while (optoff < optend) {
                        mask_width = tvb_get_guint8(tvb, optoff);
                        /* mask_width <= 32 */
                        if (mask_width > 32) {
-                               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "Mask width (%d) > 32", mask_width);
+                               expert_add_info_format_text(pinfo, vti, &ei_bootp_option_classless_static_route, "Mask width (%d) > 32", mask_width);
                                break;
                        }
                        significant_octets = (mask_width + 7) / 8;
@@ -2385,7 +2425,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                        optoff++;
                        /* significant octets + router(4) */
                        if (optend < optoff + significant_octets + 4) {
-                               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "Remaining length (%d) < %d bytes", optend - optoff, significant_octets + 4);
+                               expert_add_info_format_text(pinfo, vti, &ei_bootp_option_classless_static_bad_router_length, "Remaining length (%d) < %d bytes", optend - optoff, significant_octets + 4);
                                break;
                        }
                        if(mask_width == 0)
@@ -2450,7 +2490,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                                proto_tree_add_item(v_tree, hf_bootp_option_cl_dss_id, tvb, optoff+2+2+s_len, s_len, ENC_ASCII|ENC_NA);
                        }
                } else {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "Invalid length of DHCP option!");
+                       expert_add_info(pinfo, vti, &ei_bootp_invalid_length);
                }
                break;
 
@@ -2468,7 +2508,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                while (optleft > 0) {
 
                        if (optleft < 5) {
-                               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "Vendor Class: malformed option");
+                               expert_add_info(pinfo, vti, &ei_bootp_bad_length_lt5);
                                break;
                        }
 
@@ -2500,8 +2540,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                while (optleft > 0) {
 
                        if (optleft < 5) {
-                               expert_add_info_format(pinfo, vti, PI_PROTOCOL,
-                                       PI_ERROR, "Vendor-specific Information: malformed option");
+                               expert_add_info(pinfo, vti, &ei_bootp_bad_length_lt5);
                                break;
                        }
 
@@ -2519,8 +2558,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                        case 3561: /* ADSL Forum */
                                s_end = optoff + s_option_len;
                                if ( s_end > optend ) {
-                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL,
-                                               PI_ERROR, "no room left in option for enterprise %u data", enterprise);
+                                       expert_add_info_format_text(pinfo, vti, &ei_bootp_option125_enterprise_malformed, "no room left in option for enterprise %u data", enterprise);
                                        break;
                                }
 
@@ -2534,8 +2572,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                        case 4491: /* CableLab */
                                s_end = optoff + s_option_len;
                                if ( s_end > optend ) {
-                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL,
-                                          PI_ERROR, "no room left in option for enterprise %u data", enterprise);
+                                       expert_add_info_format_text(pinfo, vti, &ei_bootp_option125_enterprise_malformed, "no room left in option for enterprise %u data", enterprise);
                                        break;
                                }
 
@@ -2557,7 +2594,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
 
        case 212: {     /* 6RD option (RFC 5969) */
                if (optlen < 22) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "6RD: malformed option");
+                       expert_add_info(pinfo, vti, &ei_bootp_option_6RD_malformed);
                        break;
                }
 
@@ -2571,7 +2608,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                        optoff += 22;
                        for (i = optoff, optleft = optlen - 22; optleft > 0; i += 4, optleft -= 4) {
                                if (optleft < 4) {
-                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "Border Relay length isn't a multiple of 4");
+                                       expert_add_info(pinfo, vti, &ei_bootp_opt_length_not_mult4);
                                        break;
                                }
 
@@ -2694,8 +2731,8 @@ bootp_dhcp_decode_agent_info(packet_info *pinfo, proto_item *v_ti, proto_tree *v
        suboptoff++;
 
        if (suboptoff >= optend) {
-               expert_add_info_format(pinfo, v_ti, PI_PROTOCOL, PI_ERROR,
-                       "Suboption %d: no room left in option for suboption length", subopt);
+               expert_add_info_format_text(pinfo, v_ti, &ei_bootp_missing_subopt_length,
+                                                                       "Suboption %d: no room left in option for suboption length", subopt);
                return (optend);
        }
 
@@ -2709,8 +2746,8 @@ bootp_dhcp_decode_agent_info(packet_info *pinfo, proto_item *v_ti, proto_tree *v
 
        subopt_end = suboptoff+subopt_len;
        if (subopt_end > optend) {
-               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR,
-                       "Suboption %d: no room left in option for suboption value", subopt);
+               expert_add_info_format_text(pinfo, vti, &ei_bootp_missing_subopt_value,
+                                               "Suboption %d: no room left in option for suboption value", subopt);
                return (optend);
        }
 
@@ -2762,8 +2799,7 @@ bootp_dhcp_decode_agent_info(packet_info *pinfo, proto_item *v_ti, proto_tree *v
                                                                                          tvb_get_guint8(tvb, suboptoff), tvb_get_guint8(tvb, suboptoff+1));
                                                                        suboptoff+=2;
                                                                } else {
-                                                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR,
-                                                                               "Unknown tag %d (%d bytes)", tag, tag_len);
+                                                                       expert_add_info_format_text(pinfo, vti, &ei_bootp_option82_vi_cl_tag_unknown, "Unknown tag %d (%d bytes)", tag, tag_len);
                                                                        suboptoff += tag_len;
                                                                }
                                                        } else {
@@ -2772,8 +2808,7 @@ bootp_dhcp_decode_agent_info(packet_info *pinfo, proto_item *v_ti, proto_tree *v
                                                        break;
 
                                                default:
-                                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR,
-                                                                       "Invalid suboption %d (%d bytes)", vs_opt, vs_len);
+                                                       expert_add_info_format_text(pinfo, vti, &ei_bootp_suboption_invalid, "Invalid suboption %d (%d bytes)", vs_opt, vs_len);
                                                        suboptoff += vs_len;
                                                        break;
                                                }
@@ -2787,8 +2822,7 @@ bootp_dhcp_decode_agent_info(packet_info *pinfo, proto_item *v_ti, proto_tree *v
                                break;
                        case 151:
                                if (subopt_len != 7) {
-                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR,
-                                                                       "Invalid length (expected 7 bytes, found %d bytes)", subopt_len);
+                                       expert_add_info(pinfo, vti, &ei_bootp_bad_length7);
                                        break;
                                }
                                proto_tree_add_item(o82_v_tree, hf_bootp_option82_vrf_name_vpn_id_oui, tvb, suboptoff, 3, ENC_BIG_ENDIAN);
@@ -2805,7 +2839,7 @@ bootp_dhcp_decode_agent_info(packet_info *pinfo, proto_item *v_ti, proto_tree *v
                else {
                        if (bootp_handle_basic_types(pinfo, o82_v_tree, vti, tvb, o82_opt[idx].info.ftype,
                                                     suboptoff, subopt_len, o82_opt[idx].info.phf, &default_hfs) == 0) {
-                               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "ERROR, please report: Unknown subopt type handler %d", subopt);
+                               expert_add_info_format_text(pinfo, vti, &hf_bootp_subopt_unknown_type, "ERROR, please report: Unknown subopt type handler %d", subopt);
                        }
                }
        }
@@ -2894,8 +2928,8 @@ dissect_vendor_pxeclient_suboption(packet_info *pinfo, proto_item *v_ti, proto_t
        }
 
        if (suboptoff >= optend) {
-               expert_add_info_format(pinfo, v_ti, PI_PROTOCOL, PI_ERROR,
-                       "Suboption %d: no room left in option for suboption length", subopt);
+               expert_add_info_format_text(pinfo, v_ti, &ei_bootp_missing_subopt_length,
+                                                                       "Suboption %d: no room left in option for suboption length", subopt);
                return (optend);
        }
 
@@ -2916,7 +2950,7 @@ dissect_vendor_pxeclient_suboption(packet_info *pinfo, proto_item *v_ti, proto_t
                /* I may need to decode that properly one day */
                proto_tree_add_item(o43pxeclient_v_tree, hf_bootp_option43_pxeclient_boot_item, tvb, suboptoff, subopt_len, ENC_NA);
        } else if ((subopt < 1) || (subopt >= array_length(o43pxeclient_opt))) {
-               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "Unknown suboption %d (%d bytes)", subopt, subopt_len);
+               expert_add_info_format_text(pinfo, vti, &ei_bootp_suboption_invalid, "Unknown suboption %d (%d bytes)", subopt, subopt_len);
        } else if (o43pxeclient_opt[subopt].ftype == special) {
                /* I may need to decode that properly one day */
                if (o43pxeclient_opt[subopt].phf != NULL)
@@ -2927,7 +2961,7 @@ dissect_vendor_pxeclient_suboption(packet_info *pinfo, proto_item *v_ti, proto_t
                if (bootp_handle_basic_types(pinfo, o43pxeclient_v_tree, vti, tvb, o43pxeclient_opt[subopt].ftype,
                                                        suboptoff, subopt_len, o43pxeclient_opt[subopt].phf, &default_hfs) == 0)
                {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "ERROR, please report: Unknown subopt type handler %d", subopt);
+                       expert_add_info_format_text(pinfo, vti, &hf_bootp_subopt_unknown_type, "ERROR, please report: Unknown subopt type handler %d", subopt);
                }
        }
 
@@ -3196,8 +3230,8 @@ dissect_vendor_cablelabs_suboption(packet_info *pinfo, proto_item *v_ti, proto_t
        }
 
        if (suboptoff >= optend) {
-               expert_add_info_format(pinfo, v_ti, PI_PROTOCOL, PI_ERROR,
-                                      "Suboption %d: no room left in option for suboption length", subopt);
+               expert_add_info_format_text(pinfo, v_ti, &ei_bootp_missing_subopt_length,
+                                                                       "Suboption %d: no room left in option for suboption length", subopt);
                return (optend);
        }
 
@@ -3211,7 +3245,8 @@ dissect_vendor_cablelabs_suboption(packet_info *pinfo, proto_item *v_ti, proto_t
        suboptoff++;
 
        if (suboptoff+subopt_len > optend) {
-               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "Suboption %d: no room left in option for suboption value", subopt);
+               expert_add_info_format_text(pinfo, vti, &ei_bootp_missing_subopt_value,
+                                               "Suboption %d: no room left in option for suboption value", subopt);
                return (optend);
        }
 
@@ -3229,12 +3264,12 @@ dissect_vendor_cablelabs_suboption(packet_info *pinfo, proto_item *v_ti, proto_t
                        } else if (subopt_len == 6) {
                                proto_tree_add_item(o43cl_v_tree, hf_bootp_option43_cl_oui_string, tvb, suboptoff, subopt_len, ENC_ASCII|ENC_NA);
                        } else {
-                               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't 3 or 6");
+                               expert_add_info(pinfo, vti, &ei_bootp_bad_length3_6);
                        }
                        break;
                case 31: /* MTA MAC address */
                        if (subopt_len != 6) {
-                               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't 6");
+                               expert_add_info(pinfo, vti, &ei_bootp_bad_length6);
                                break;
                        }
 
@@ -3250,7 +3285,7 @@ dissect_vendor_cablelabs_suboption(packet_info *pinfo, proto_item *v_ti, proto_t
        else {
                if (bootp_handle_basic_types(pinfo, o43cl_v_tree, vti, tvb, o43cablelabs_opt[subopt].ftype,
                                                        suboptoff, subopt_len, o43cablelabs_opt[subopt].phf, &default_hfs) == 0) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "ERROR, please report: Unknown subopt type handler %d", subopt);
+                       expert_add_info_format_text(pinfo, vti, &hf_bootp_subopt_unknown_type, "ERROR, please report: Unknown subopt type handler %d", subopt);
                }
        }
 
@@ -3298,8 +3333,8 @@ dissect_vendor_alcatel_suboption(packet_info *pinfo, proto_item *v_ti, proto_tre
        }
 
        if (suboptoff >= optend) {
-               expert_add_info_format(pinfo, v_ti, PI_PROTOCOL, PI_ERROR,
-                                                       "Suboption %d: no room left in option for suboption length", subopt);
+               expert_add_info_format_text(pinfo, v_ti, &ei_bootp_missing_subopt_length,
+                                                                       "Suboption %d: no room left in option for suboption length", subopt);
                return (optend);
        }
 
@@ -3313,7 +3348,8 @@ dissect_vendor_alcatel_suboption(packet_info *pinfo, proto_item *v_ti, proto_tre
        suboptoff++;
 
        if (suboptoff+subopt_len > optend) {
-               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "Suboption %d: no room left in option for suboption value", subopt);
+               expert_add_info_format_text(pinfo, vti, &ei_bootp_missing_subopt_value,
+                                               "Suboption %d: no room left in option for suboption value", subopt);
                return (optend);
        }
 
@@ -3321,7 +3357,7 @@ dissect_vendor_alcatel_suboption(packet_info *pinfo, proto_item *v_ti, proto_tre
        {
        case 58: /* 0x3A - Alcatel-Lucent AVA VLAN Id */
                if (subopt_len != 2) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't 2");
+                       expert_add_info(pinfo, vti, &ei_bootp_bad_length2);
                        return (optend);
                }
 
@@ -3329,7 +3365,7 @@ dissect_vendor_alcatel_suboption(packet_info *pinfo, proto_item *v_ti, proto_tre
                break;
        case 64: /* 0x40 - Alcatel-Lucent TFTP1 */
                if (subopt_len != 4) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't 4");
+                       expert_add_info(pinfo, vti, &ei_bootp_bad_length4);
                        return (optend);
                }
 
@@ -3337,7 +3373,7 @@ dissect_vendor_alcatel_suboption(packet_info *pinfo, proto_item *v_ti, proto_tre
                break;
        case 65: /* 0x41 - Alcatel-Lucent TFTP2 */
                if (subopt_len != 4) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't 4");
+                       expert_add_info(pinfo, vti, &ei_bootp_bad_length4);
                        return (optend);
                }
 
@@ -3345,7 +3381,7 @@ dissect_vendor_alcatel_suboption(packet_info *pinfo, proto_item *v_ti, proto_tre
                break;
        case 66: /* 0x42 - Alcatel-Lucent APPLICATION TYPE */
                if (subopt_len != 1) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "length isn't 1");
+                       expert_add_info(pinfo, vti, &ei_bootp_bad_length1);
                        return (optend);
                }
                proto_tree_add_item(o43alcatel_v_tree, hf_bootp_option43_alcatel_app_type, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
@@ -3354,7 +3390,7 @@ dissect_vendor_alcatel_suboption(packet_info *pinfo, proto_item *v_ti, proto_tre
                proto_tree_add_item(o43alcatel_v_tree, hf_bootp_option43_alcatel_sip_url, tvb, suboptoff, subopt_len, ENC_ASCII|ENC_NA);
                break;
        default:
-               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "ERROR, please report: Unknown subopt type handler %d", subopt);
+               expert_add_info_format_text(pinfo, vti, &hf_bootp_subopt_unknown_type, "ERROR, please report: Unknown subopt type handler %d", subopt);
                return optend;
        }
 
@@ -3419,8 +3455,8 @@ dissect_netware_ip_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v
        suboptoff++;
 
        if (suboptoff >= optend) {
-               expert_add_info_format(pinfo, v_ti, PI_PROTOCOL, PI_ERROR,
-                       "Suboption %d: no room left in option for suboption length", subopt);
+               expert_add_info_format_text(pinfo, v_ti, &ei_bootp_missing_subopt_length,
+                                                                       "Suboption %d: no room left in option for suboption length", subopt);
                return (optend);
        }
 
@@ -3443,8 +3479,7 @@ dissect_netware_ip_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v
                        {
                        case presence:
                                if (subopt_len != 0) {
-                                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR,
-                                               "Suboption %d: length isn't 0", subopt);
+                                       expert_add_info(pinfo, vti, &ei_bootp_bad_length0);
                                }
                                break;
                        default:
@@ -3509,8 +3544,8 @@ dissect_vendor_tr111_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree
        suboptoff++;
 
        if (suboptoff >= optend) {
-               expert_add_info_format(pinfo, v_ti, PI_PROTOCOL, PI_ERROR,
-                       "Suboption %d: no room left in option for suboption length", subopt);
+               expert_add_info_format_text(pinfo, v_ti, &ei_bootp_missing_subopt_length,
+                                                                       "Suboption %d: no room left in option for suboption length", subopt);
                return (optend);
        }
 
@@ -3524,8 +3559,8 @@ dissect_vendor_tr111_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree
        suboptoff++;
 
        if (suboptoff+subopt_len > optend) {
-               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR,
-                       "Suboption %d: no room left in option for suboption value", subopt);
+               expert_add_info_format_text(pinfo, vti, &ei_bootp_missing_subopt_value,
+                                               "Suboption %d: no room left in option for suboption value", subopt);
                return (optend);
        }
 
@@ -3602,8 +3637,8 @@ dissect_vendor_cl_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_
        suboptoff++;
 
        if (suboptoff >= optend) {
-               expert_add_info_format(pinfo, v_ti, PI_PROTOCOL, PI_ERROR,
-                                      "Suboption %d: no room left in option for suboption length", subopt);
+               expert_add_info_format_text(pinfo, v_ti, &ei_bootp_missing_subopt_length,
+                                                                       "Suboption %d: no room left in option for suboption length", subopt);
                return (optend);
        }
 
@@ -3617,8 +3652,8 @@ dissect_vendor_cl_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_
        suboptoff++;
 
        if (suboptoff+subopt_len > optend) {
-               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR,
-                       "Suboption %d: no room left in option for suboption value", subopt);
+               expert_add_info_format_text(pinfo, vti, &ei_bootp_missing_subopt_value,
+                                               "Suboption %d: no room left in option for suboption value", subopt);
                return (optend);
        }
 
@@ -4701,7 +4736,8 @@ dissect_packetcable_i05_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v_
        suboptoff++;
 
        if (suboptoff >= optend) {
-               expert_add_info_format(pinfo, v_ti, PI_PROTOCOL, PI_ERROR, "Suboption %d: no room left in option for suboption length", subopt);
+               expert_add_info_format_text(pinfo, v_ti, &ei_bootp_missing_subopt_length,
+                                                                       "Suboption %d: no room left in option for suboption length", subopt);
                return (optend);
        }
 
@@ -4730,7 +4766,7 @@ dissect_packetcable_i05_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v_
 
        case PKT_CCC_TGT_FLAG:
                if (suboptoff+1 > optend) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "no room left in option for suboption value");
+                       expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
                        return (optend);
                }
                fetch_tgt = tvb_get_guint8(tvb, suboptoff);
@@ -4744,7 +4780,7 @@ dissect_packetcable_i05_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v_
 
        case PKT_CCC_PROV_TIMER:
                if (suboptoff+1 > optend) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "no room left in option for suboption value");
+                       expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
                        return (optend);
                }
                timer_val = tvb_get_guint8(tvb, suboptoff);
@@ -4758,7 +4794,7 @@ dissect_packetcable_i05_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v_
 
        case PKT_CCC_AS_KRB:
                if (suboptoff+12 > optend) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "no room left in option for suboption value");
+                       expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
                        return (optend);
                }
                proto_item_append_text(vti, "(%u byte%s%s)", subopt_len,
@@ -4781,7 +4817,7 @@ dissect_packetcable_i05_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v_
 
        case PKT_CCC_AP_KRB:
                if (suboptoff+12 > optend) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "no room left in option for suboption value");
+                       expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
                        return (optend);
                }
                proto_item_append_text(vti, "(%u byte%s%s)", subopt_len,
@@ -4804,7 +4840,7 @@ dissect_packetcable_i05_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v_
 
        case PKT_CCC_MTA_KRB_CLEAR:
                if (suboptoff+1 > optend) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "no room left in option for suboption value");
+                       expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
                        return (optend);
                }
                ticket_ctl = tvb_get_guint8(tvb, suboptoff);
@@ -4851,8 +4887,8 @@ dissect_packetcable_ietf_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v
        suboptoff++;
 
        if (suboptoff >= optend) {
-               expert_add_info_format(pinfo, v_ti, PI_PROTOCOL, PI_ERROR,
-                       "Suboption %d: no room left in option for suboption length", subopt);
+               expert_add_info_format_text(pinfo, v_ti, &ei_bootp_missing_subopt_length,
+                                                                       "Suboption %d: no room left in option for suboption length", subopt);
                return (optend);
        }
        subopt_len = tvb_get_guint8(tvb, suboptoff);
@@ -4867,7 +4903,7 @@ dissect_packetcable_ietf_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v
        case PKT_CCC_PRI_DHCP:  /* IPv4 values */
        case PKT_CCC_SEC_DHCP:
                if (suboptoff+4 > optend) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "no room left in option for suboption value");
+                       expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
                        return (optend);
                }
                ipv4addr = tvb_get_ipv4(tvb, suboptoff);
@@ -4881,7 +4917,7 @@ dissect_packetcable_ietf_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v
 
        case PKT_CCC_IETF_PROV_SRV:
                if (suboptoff+1 > optend) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "no room left in option for suboption value");
+                       expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
                        return (optend);
                }
                prov_type = tvb_get_guint8(tvb, suboptoff);
@@ -4896,7 +4932,7 @@ dissect_packetcable_ietf_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v
 
                case 1:
                        if (suboptoff+4 > optend) {
-                               expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "no room left in option for suboption value");
+                               expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
                                return (optend);
                        }
                        ipv4addr = tvb_get_ipv4(tvb, suboptoff);
@@ -4919,7 +4955,7 @@ dissect_packetcable_ietf_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v
 
        case PKT_CCC_IETF_AS_KRB:
                if (suboptoff+12 > optend) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "no room left in option for suboption value");
+                       expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
                        return (optend);
                }
                proto_item_append_text(vti, "(%u byte%s%s)", subopt_len,
@@ -4968,7 +5004,7 @@ dissect_packetcable_ietf_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v
 
        case PKT_CCC_TGT_FLAG:
                if (suboptoff+1 > optend) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "no room left in option for suboption value");
+                       expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
                        return (optend);
                }
                fetch_tgt = tvb_get_guint8(tvb, suboptoff);
@@ -4982,7 +5018,7 @@ dissect_packetcable_ietf_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v
 
        case PKT_CCC_PROV_TIMER:
                if (suboptoff+1 > optend) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "no room left in option for suboption value");
+                       expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
                        return (optend);
                }
                if (revision == PACKETCABLE_CCC_DRAFT5)
@@ -4998,7 +5034,7 @@ dissect_packetcable_ietf_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v
 
        case PKT_CCC_IETF_SEC_TKT:
                if (suboptoff+2 > optend) {
-                       expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_ERROR, "no room left in option for suboption value");
+                       expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
                        return (optend);
                }
                sec_tcm = tvb_get_ntohs(tvb, suboptoff);
@@ -5160,8 +5196,7 @@ dissect_bootp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        if (secs > 0 && secs <= 0xff) {
                ti = proto_tree_add_uint_format_value(bp_tree, hf_bootp_secs, tvb,
                            8, 2, secs, "%u", secs);
-               expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_NOTE,
-                           "Seconds elapsed (%u) appears to be encoded as little-endian", secs);
+               expert_add_info_format_text(pinfo, ti, &ei_bootp_secs_le, "Seconds elapsed (%u) appears to be encoded as little-endian", secs);
        } else {
                proto_tree_add_item(bp_tree, hf_bootp_secs, tvb,
                            8, 2, ENC_BIG_ENDIAN);
@@ -5268,7 +5303,7 @@ dissect_bootp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        }
        if ((dhcp_type != NULL) && (!at_end))
        {
-               expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_ERROR, "End option missing");
+               expert_add_info(pinfo, ti, &ei_bootp_end_option_missing);
        }
        if (voff < eoff) {
                /*
@@ -6844,7 +6879,50 @@ proto_register_bootp(void)
                &ett_bootp_fqdn,
        };
 
+       static ei_register_info ei[] = {
+               { &ei_bootp_bad_length0, { "bootp.bad_length0", PI_PROTOCOL, PI_ERROR, "length isn't 0", EXPFILL }},
+               { &ei_bootp_bad_length1, { "bootp.bad_length1", PI_PROTOCOL, PI_ERROR, "length isn't 1", EXPFILL }},
+               { &ei_bootp_bad_length2, { "bootp.bad_length2", PI_PROTOCOL, PI_ERROR, "length isn't 2", EXPFILL }},
+               { &ei_bootp_bad_length4, { "bootp.bad_length4", PI_PROTOCOL, PI_ERROR, "length isn't 4", EXPFILL }},
+               { &ei_bootp_bad_length6, { "bootp.bad_length6", PI_PROTOCOL, PI_ERROR, "length isn't 6", EXPFILL }},
+               { &ei_bootp_bad_length7, { "bootp.bad_length7", PI_PROTOCOL, PI_ERROR, "length isn't 7", EXPFILL }},
+               { &ei_bootp_bad_length3_6, { "bootp.bad_length3or6", PI_PROTOCOL, PI_ERROR, "length isn't 3 or 6", EXPFILL }},
+               { &ei_bootp_bad_length_ge1, { "bootp.bad_length_ge1", PI_PROTOCOL, PI_ERROR, "length isn't >= 1", EXPFILL }},
+               { &ei_bootp_bad_length_ge2, { "bootp.bad_length_ge2", PI_PROTOCOL, PI_ERROR, "length isn't >= 2", EXPFILL }},
+               { &ei_bootp_bad_length_ge3, { "bootp.bad_length_ge3", PI_PROTOCOL, PI_ERROR, "length isn't >= 3", EXPFILL }},
+               { &ei_bootp_bad_length_ge5, { "bootp.bad_length_ge5", PI_PROTOCOL, PI_ERROR, "length isn't >= 5", EXPFILL }},
+               { &ei_bootp_bad_length_ge11, { "bootp.bad_length_ge11", PI_PROTOCOL, PI_ERROR, "length isn't >= 11", EXPFILL }},
+               { &ei_bootp_bad_length_ge31, { "bootp.bad_length_ge31", PI_PROTOCOL, PI_ERROR, "length isn't >= 31", EXPFILL }},
+               { &ei_bootp_bad_length_lt5, { "bootp.bad_length_lt5", PI_PROTOCOL, PI_ERROR, "length < 5", EXPFILL }},
+               { &ei_bootp_opt_length_not_mult2, { "bootp.opt_length_not_mult2", PI_PROTOCOL, PI_ERROR, "Option length isn't a multiple of 2", EXPFILL }},
+               { &ei_bootp_opt_length_not_mult4, { "bootp.opt_length_not_mult4", PI_PROTOCOL, PI_ERROR, "Option length isn't a multiple of 4", EXPFILL }},
+               { &ei_bootp_opt_length_not_mult8, { "bootp.opt_length_not_mult8", PI_PROTOCOL, PI_ERROR, "Option length isn't a multiple of 8", EXPFILL }},
+               { &ei_bootp_opt_length_not_mult4_plus1, { "bootp.opt_length_not_mult4_plus1", PI_PROTOCOL, PI_ERROR, "Option length isn't a multiple of 4 plus 1", EXPFILL }},
+               { &ei_bootp_missing_subopt_length, { "bootp.missing_subopt_length", PI_PROTOCOL, PI_ERROR, "no room left in option for suboption length", EXPFILL }},
+               { &ei_bootp_missing_subopt_value, { "bootp.missing_subopt_value", PI_PROTOCOL, PI_ERROR, "no room left in option for suboption value", EXPFILL }},
+               { &ei_bootp_mal_duid, { "bootp.malformed.duid", PI_PROTOCOL, PI_ERROR, "DUID: malformed option", EXPFILL }},
+               { &hf_bootp_opt_overload_file_end_missing, { "bootp.option.option_overload.file_end_missing", PI_PROTOCOL, PI_ERROR, "file overload end option missing", EXPFILL }},
+               { &hf_bootp_opt_overload_sname_end_missing, { "bootp.option.option_overload.sname_end_missing", PI_PROTOCOL, PI_ERROR, "sname overload end option missing", EXPFILL }},
+               { &hf_bootp_subopt_unknown_type, { "bootp.subopt.unknown_type", PI_PROTOCOL, PI_ERROR, "ERROR, please report: Unknown subopt type handler", EXPFILL }},
+               { &ei_bootp_option77_user_class_len, { "bootp.option.user_class.len", PI_PROTOCOL, PI_ERROR, "UC_Len_X isn't >= 1 (UC_Len_X = 0)", EXPFILL }},
+               { &ei_bootp_option77_user_class_malformed, { "bootp.option.user_class.malformed", PI_PROTOCOL, PI_ERROR, "User Class Information: malformed option", EXPFILL }},
+               { &ei_bootp_option_civic_location_bad_cattype, { "bootp.option.civic_location.bad_cattype", PI_PROTOCOL, PI_ERROR, "Error with CAType", EXPFILL }},
+               { &ei_bootp_bad_length_even, { "bootp.bad_length_even", PI_PROTOCOL, PI_ERROR, "length isn't even number", EXPFILL }},
+               { &ei_bootp_option_dhcp_name_service_invalid, { "bootp.option.dhcp_name_service.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Name Service", EXPFILL }},
+               { &ei_bootp_option_sip_server_address_encoding, { "bootp.option.sip_server_address.encoding", PI_PROTOCOL, PI_ERROR, "RFC 3361 defines only 0 and 1 for Encoding byte", EXPFILL }},
+               { &ei_bootp_option_classless_static_route, { "bootp.option.classless_static.route", PI_PROTOCOL, PI_ERROR, "Mask width > 32", EXPFILL }},
+               { &ei_bootp_option_classless_static_bad_router_length, { "bootp.option.classless_static.bad_router_length", PI_PROTOCOL, PI_ERROR, "Remaining length < bytes", EXPFILL }},
+               { &ei_bootp_invalid_length, { "bootp.option.invalid_length", PI_PROTOCOL, PI_ERROR, "Invalid length of DHCP option!", EXPFILL }},
+               { &ei_bootp_option125_enterprise_malformed, { "bootp.option.enterprise.malformed", PI_PROTOCOL, PI_ERROR, "no room left in option for enterprise data", EXPFILL }},
+               { &ei_bootp_option_6RD_malformed, { "bootp.option.6RD.malformed", PI_PROTOCOL, PI_ERROR, "6RD: malformed option", EXPFILL }},
+               { &ei_bootp_option82_vi_cl_tag_unknown, { "bootp.option.option.vi.cl.tag_unknown", PI_PROTOCOL, PI_ERROR, "Unknown tag", EXPFILL }},
+               { &ei_bootp_suboption_invalid, { "bootp.suboption_invalid", PI_PROTOCOL, PI_ERROR, "Invalid suboption", EXPFILL }},
+               { &ei_bootp_secs_le, { "bootp.secs_le", PI_PROTOCOL, PI_NOTE, "Seconds elapsed appears to be encoded as little-endian", EXPFILL }},
+               { &ei_bootp_end_option_missing, { "bootp.end_option_missing", PI_PROTOCOL, PI_ERROR, "End option missing", EXPFILL }},
+       };
+
        module_t *bootp_module;
+       expert_module_t* expert_bootp;
 
        proto_bootp = proto_register_protocol("Bootstrap Protocol", "BOOTP/DHCP",
                                              "bootp");
@@ -6852,6 +6930,9 @@ proto_register_bootp(void)
        proto_register_subtree_array(ett, array_length(ett));
        bootp_dhcp_tap = register_tap("bootp");
 
+       expert_bootp = expert_register_protocol(proto_bootp);
+       expert_register_field_array(expert_bootp, ei, array_length(ei));
+
        /* register init routine to setup the custom bootp options */
        register_init_routine(&bootp_init_protocol);
 
index bada8b6e73b6349b4087c9446bdf3c6b134e8972..e2411ba6541e1d407ad22f31ea0225ea419f7a86 100644 (file)
@@ -200,6 +200,16 @@ static gint ett_dhcpv6_vendor_option = -1;
 static gint ett_dhcpv6_pkt_option = -1;
 static gint ett_dhcpv6_netserver_option = -1;
 
+static expert_field ei_dhcpv6_bogus_length = EI_INIT;
+static expert_field ei_dhcpv6_malformed_option = EI_INIT;
+static expert_field ei_dhcpv6_no_suboption_len = EI_INIT;
+static expert_field ei_dhcpv6_invalid_byte = EI_INIT;
+static expert_field ei_dhcpv6_invalid_time_value = EI_INIT;
+static expert_field ei_dhcpv6_invalid_type = EI_INIT;
+static expert_field ei_dhcpv6_bad_length3_6 = EI_INIT;
+static expert_field ei_dhcpv6_malformed_dns = EI_INIT;
+
+
 static int hf_dhcpv6_bulk_leasequery_size = -1;
 static int hf_dhcpv6_bulk_leasequery_msgtype = -1;
 static int hf_dhcpv6_bulk_leasequery_reserved = -1;
@@ -208,6 +218,10 @@ static int hf_dhcpv6_bulk_leasequery_trans_id = -1;
 static gint ett_dhcpv6_bulk_leasequery = -1;
 static gint ett_dhcpv6_bulk_leasequery_options = -1;
 
+static expert_field ei_dhcpv6_bulk_leasequery_bad_query_type = EI_INIT;
+static expert_field ei_dhcpv6_bulk_leasequery_no_lq_relay_data = EI_INIT;
+static expert_field ei_dhcpv6_bulk_leasequery_bad_msg_type = EI_INIT;
+
 #define UDP_PORT_DHCPV6_DOWNSTREAM      546
 #define UDP_PORT_DHCPV6_UPSTREAM        547
 
@@ -599,7 +613,7 @@ dissect_packetcable_ccc_option(proto_tree *v_tree, proto_item *v_item, packet_in
 
     /* There must be at least five octets left to be a valid sub element */
     if (optend <= 0) {
-        expert_add_info_format(pinfo, v_item, PI_PROTOCOL, PI_WARN, "Sub element %d: no room left in option for suboption length", subopt);
+        expert_add_info_format_text(pinfo, v_item, &ei_dhcpv6_no_suboption_len, "Sub element %d: no room left in option for suboption length", subopt);
         return (optend);
     }
     /* g_print("dissect packetcable ccc option subopt_len=%d optend=%d\n\n", subopt_len, optend); */
@@ -613,7 +627,7 @@ dissect_packetcable_ccc_option(proto_tree *v_tree, proto_item *v_item, packet_in
             proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_pri_dhcp, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
         }
         else {
-            expert_add_info_format(pinfo, vti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", subopt_len);
+            expert_add_info_format_text(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
         }
 
         suboptoff += subopt_len;
@@ -623,7 +637,7 @@ dissect_packetcable_ccc_option(proto_tree *v_tree, proto_item *v_item, packet_in
             proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_sec_dhcp, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
         }
         else {
-            expert_add_info_format(pinfo, vti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", subopt_len);
+            expert_add_info_format_text(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
         }
 
         suboptoff += subopt_len;
@@ -642,11 +656,11 @@ dissect_packetcable_ccc_option(proto_tree *v_tree, proto_item *v_item, packet_in
                 proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_prov_srv_ipv4, tvb, suboptoff+1, 4, ENC_BIG_ENDIAN);
             }
             else {
-                expert_add_info_format(pinfo, vti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", subopt_len);
+                expert_add_info_format_text(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
             }
         }
         else {
-            expert_add_info_format(pinfo, vti, PI_PROTOCOL, PI_WARN, "Invalid type: %u (%u byte%s)",
+            expert_add_info_format_text(pinfo, vti, &ei_dhcpv6_invalid_type, "Invalid type: %u (%u byte%s)",
                 type, subopt_len, plurality(subopt_len, "", "s"));
         }
         suboptoff += subopt_len;
@@ -659,7 +673,7 @@ dissect_packetcable_ccc_option(proto_tree *v_tree, proto_item *v_item, packet_in
             proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_as_krb_max_retry_count, tvb, suboptoff+8, 4, ENC_BIG_ENDIAN);
         }
         else {
-            expert_add_info_format(pinfo, vti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", subopt_len);
+            expert_add_info_format_text(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
         }
         suboptoff += subopt_len;
         break;
@@ -670,7 +684,7 @@ dissect_packetcable_ccc_option(proto_tree *v_tree, proto_item *v_item, packet_in
             proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_ap_krb_max_retry_count, tvb, suboptoff+8, 4, ENC_BIG_ENDIAN);
         }
         else {
-            expert_add_info_format(pinfo, vti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", subopt_len);
+            expert_add_info_format_text(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
         }
         suboptoff += subopt_len;
         break;
@@ -709,7 +723,7 @@ dissect_packetcable_ccc_option(proto_tree *v_tree, proto_item *v_item, packet_in
 
             ti = proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_krb_realm, tvb, suboptoff, subopt_len, ENC_ASCII|ENC_NA);
             if (kr_fail_flag)
-                expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN, "Invalid at byte=%d", kr_pos);
+                expert_add_info_format_text(pinfo, ti, &ei_dhcpv6_invalid_byte, "Invalid at byte=%d", kr_pos);
         }
         suboptoff += subopt_len;
         break;
@@ -720,7 +734,7 @@ dissect_packetcable_ccc_option(proto_tree *v_tree, proto_item *v_item, packet_in
             proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_tgt_flag_fetch, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
         }
         else {
-            expert_add_info_format(pinfo, vti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", subopt_len);
+            expert_add_info_format_text(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
         }
         suboptoff += subopt_len;
         break;
@@ -729,10 +743,10 @@ dissect_packetcable_ccc_option(proto_tree *v_tree, proto_item *v_item, packet_in
         if (subopt_len == 1) {
             ti = proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_prov_timer, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
             if (tvb_get_guint8(tvb, suboptoff ) > 30)
-                expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN, "Invalid time value");
+                expert_add_info(pinfo, ti, &ei_dhcpv6_invalid_time_value);
         }
         else {
-            expert_add_info_format(pinfo, vti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", subopt_len);
+            expert_add_info_format_text(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
         }
         suboptoff += subopt_len;
         break;
@@ -743,7 +757,7 @@ dissect_packetcable_ccc_option(proto_tree *v_tree, proto_item *v_item, packet_in
             proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_sec_tcm_provisioning_server, tvb, suboptoff, 2, ENC_BIG_ENDIAN);
             proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_sec_tcm_call_manager_server, tvb, suboptoff, 2, ENC_BIG_ENDIAN);
         } else {
-            expert_add_info_format(pinfo, vti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", subopt_len);
+            expert_add_info_format_text(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
         }
         suboptoff += subopt_len;
         break;
@@ -782,7 +796,7 @@ dissect_packetcable_cccV6_option(proto_tree *v_tree, proto_item *v_item, packet_
 
     /* There must be at least five octets left to be a valid sub element */
     if (optend <= 0) {
-        expert_add_info_format(pinfo, v_item, PI_PROTOCOL, PI_WARN, "Sub element %d: no room left in option for suboption length", subopt);
+        expert_add_info_format_text(pinfo, v_item, &ei_dhcpv6_no_suboption_len, "Sub element %d: no room left in option for suboption length", subopt);
         return (optend);
     }
 
@@ -794,7 +808,7 @@ dissect_packetcable_cccV6_option(proto_tree *v_tree, proto_item *v_item, packet_
             if (subopt_len < 35) {
                 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_pri_dss, tvb, suboptoff, subopt_len, ENC_ASCII|ENC_NA);
             } else {
-                expert_add_info_format(pinfo, vti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", subopt_len);
+                expert_add_info_format_text(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
             }
             suboptoff += subopt_len;
             break;
@@ -802,7 +816,7 @@ dissect_packetcable_cccV6_option(proto_tree *v_tree, proto_item *v_item, packet_
             if (subopt_len < 35) {
                 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_sec_dss, tvb, suboptoff, subopt_len, ENC_ASCII|ENC_NA);
             } else {
-                expert_add_info_format(pinfo, vti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", subopt_len);
+                expert_add_info_format_text(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
             }
             suboptoff += subopt_len;
             break;
@@ -871,7 +885,7 @@ dissect_packetcable_cccV6_option(proto_tree *v_tree, proto_item *v_item, packet_
 
                 ti = proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_krb_realm, tvb, suboptoff, subopt_len, ENC_ASCII|ENC_NA);
                 if (kr_fail_flag)
-                    expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN, "Invalid at byte=%d", kr_pos);
+                    expert_add_info_format_text(pinfo, ti, &ei_dhcpv6_invalid_byte, "Invalid at byte=%d", kr_pos);
             }
             suboptoff += subopt_len;
             break;
@@ -882,7 +896,7 @@ dissect_packetcable_cccV6_option(proto_tree *v_tree, proto_item *v_item, packet_
                 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_tgt_flag_fetch, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
             }
             else {
-                expert_add_info_format(pinfo, vti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", subopt_len);
+                expert_add_info_format_text(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
             }
             suboptoff += subopt_len;
             break;
@@ -891,10 +905,10 @@ dissect_packetcable_cccV6_option(proto_tree *v_tree, proto_item *v_item, packet_
             if (subopt_len == 1) {
                 ti = proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_prov_timer, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
                 if (tvb_get_guint8(tvb, suboptoff ) > 30)
-                    expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN, "Invalid time value");
+                    expert_add_info(pinfo, ti, &ei_dhcpv6_invalid_time_value);
             }
             else {
-                expert_add_info_format(pinfo, vti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", subopt_len);
+                expert_add_info_format_text(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
             }
             suboptoff += subopt_len;
             break;
@@ -905,7 +919,7 @@ dissect_packetcable_cccV6_option(proto_tree *v_tree, proto_item *v_item, packet_
                 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_sec_tcm_provisioning_server, tvb, suboptoff, 2, ENC_BIG_ENDIAN);
                 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_sec_tcm_call_manager_server, tvb, suboptoff, 2, ENC_BIG_ENDIAN);
             } else {
-                expert_add_info_format(pinfo, vti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", subopt_len);
+                expert_add_info_format_text(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
             }
             suboptoff += subopt_len;
             break;
@@ -973,7 +987,7 @@ dissect_cablelabs_specific_opts(proto_tree *v_tree, proto_item *v_item, packet_i
                 } else if (tlv_len == 6) {
                     proto_item_append_text(ti, "\"%s\"", tvb_format_stringzpad(tvb, sub_off, tlv_len));
                 } else {
-                    expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR, "Suboption %d: suboption length isn't 3 or 6", type);
+                    expert_add_info_format_text(pinfo, ti, &ei_dhcpv6_bad_length3_6, "Suboption %d: suboption length isn't 3 or 6", type);
                 }
                 break;
 
@@ -1009,7 +1023,7 @@ dissect_cablelabs_specific_opts(proto_tree *v_tree, proto_item *v_item, packet_i
                 opt_len = tlv_len;
                 field_len = tlv_len;
                 if (tlv_len != 6) {
-                    expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", tlv_len);
+                    expert_add_info_format_text(pinfo, ti, &ei_dhcpv6_bogus_length, "Bogus length: %d", tlv_len);
                 }
                 else {
                     proto_item_append_text(ti, "%s",
@@ -1081,7 +1095,7 @@ dissect_cablelabs_specific_opts(proto_tree *v_tree, proto_item *v_item, packet_i
             case CL_CM_MAC_ADDR :
                 opt_len = tlv_len;
                 if (tlv_len != 6) {
-                    expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR, "Bogus length: %d", tlv_len);
+                    expert_add_info_format_text(pinfo, ti, &ei_dhcpv6_bogus_length, "Bogus length: %d", tlv_len);
                 }
                 else {
                     /*proto_item_append_text(ti, "CM MAC Address Option = %s", */
@@ -1142,7 +1156,7 @@ dissect_cablelabs_specific_opts(proto_tree *v_tree, proto_item *v_item, packet_i
         }
     }
     else {
-        expert_add_info_format(pinfo, v_item, PI_PROTOCOL, PI_WARN, "Bogus length: %d", len);
+        expert_add_info_format_text(pinfo, v_item, &ei_dhcpv6_bogus_length, "Bogus length: %d", len);
     }
 }
 
@@ -1170,7 +1184,7 @@ dhcpv6_domain(proto_tree * subtree, proto_item *v_item, packet_info *pinfo, tvbu
          * to allow us to continue after such a malformed record.
          */
         if ( optlen < len ) {
-            expert_add_info_format(pinfo, v_item, PI_PROTOCOL, PI_WARN, "Malformed DNS name record (MS Vista client?)");
+            expert_add_info(pinfo, v_item, &ei_dhcpv6_malformed_dns);
             return;
         }
         offset++;
@@ -1179,7 +1193,7 @@ dhcpv6_domain(proto_tree * subtree, proto_item *v_item, packet_info *pinfo, tvbu
         if(!len){
             if(!pos){
                 /* empty string, this must be an error? */
-                expert_add_info_format(pinfo, v_item, PI_MALFORMED, PI_ERROR, "Malformed option");
+                expert_add_info(pinfo, v_item, &ei_dhcpv6_malformed_option);
                 return;
             } else {
                 proto_tree_add_string(subtree, hf_dhcpv6_domain, tvb, start_offset, offset-start_offset, domain);
@@ -1195,7 +1209,7 @@ dhcpv6_domain(proto_tree * subtree, proto_item *v_item, packet_info *pinfo, tvbu
         }
         if(pos+len>254){
             /* too long string, this must be an error? */
-            expert_add_info_format(pinfo, v_item, PI_MALFORMED, PI_ERROR, "Malformed option");
+            expert_add_info(pinfo, v_item, &ei_dhcpv6_malformed_option);
             return;
         }
         tvb_memcpy(tvb, domain+pos, offset, len);
@@ -1258,7 +1272,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
     case OPTION_SERVERID:
     case OPTION_RELAYID:
         if (optlen < 2) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "DUID: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "DUID: malformed option");
             break;
         }
 
@@ -1271,10 +1285,10 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
             nstime_t llt_time;
 
             if (optlen < 8) {
-                expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "DUID: malformed option");
+                expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "DUID: malformed option");
                 break;
             }
-                       proto_tree_add_item(subtree, hf_duidllt_hwtype, tvb, off + 2, 2, ENC_BIG_ENDIAN);
+            proto_tree_add_item(subtree, hf_duidllt_hwtype, tvb, off + 2, 2, ENC_BIG_ENDIAN);
 
             /* Packet specifies seconds since Jan 1 2000, so add 946684800U (30 years) to get back to epoch */
             llt_time.secs = tvb_get_ntohl(tvb, off + 4)+946684800U;
@@ -1290,7 +1304,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
         case DUID_EN:
             if (optlen < 6) {
-                expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "DUID: malformed option");
+                expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "DUID: malformed option");
                 break;
             }
             proto_tree_add_item(subtree, hf_duiden_enterprise, tvb, off + 2, 4, ENC_BIG_ENDIAN);
@@ -1301,7 +1315,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         case DUID_LL:
         case DUID_LL_OLD:
             if (optlen < 4) {
-                expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "DUID: malformed option");
+                expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "DUID: malformed option");
                 break;
             }
             proto_tree_add_item(subtree, hf_duidll_hwtype, tvb, off + 2, 2, ENC_BIG_ENDIAN);
@@ -1315,7 +1329,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_NTP_SERVER:
         if (optlen < 4) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "NTP Server: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "NTP Server: malformed option");
             break;
         }
         while (optlen > temp_optlen) {
@@ -1347,9 +1361,9 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
     case OPTION_IA_PD:
         if (optlen < 12) {
             if (opttype == OPTION_IA_NA)
-                expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "IA_NA: malformed option");
+                expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "IA_NA: malformed option");
             else
-                expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "IA_PD: malformed option");
+                expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "IA_PD: malformed option");
             break;
         }
         proto_tree_add_string(subtree, hf_iaid, tvb, off,
@@ -1382,7 +1396,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_IA_TA:
         if (optlen < 4) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "IA_TA: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "IA_TA: malformed option");
             break;
         }
         proto_tree_add_string(subtree, hf_iata, tvb, off,
@@ -1402,7 +1416,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         guint32 preferred_lifetime, valid_lifetime;
 
         if (optlen < 24) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "IA_TA: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "IA_TA: malformed option");
             break;
         }
 
@@ -1447,14 +1461,14 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_PREFERENCE:
         if (optlen != 1) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "PREFERENCE: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "PREFERENCE: malformed option");
             break;
         }
         proto_tree_add_item(subtree, hf_option_preference, tvb, off, 1, ENC_BIG_ENDIAN);
         break;
     case OPTION_ELAPSED_TIME:
         if (optlen != 2) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "ELAPSED-TIME: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "ELAPSED-TIME: malformed option");
             break;
         }
 
@@ -1464,7 +1478,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_RELAY_MSG:
         if (optlen == 0) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "RELAY-MSG: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "RELAY-MSG: malformed option");
         } else {
             /* here, we should dissect a full DHCP message */
             dissect_dhcpv6(tvb, pinfo, subtree, downstream, off, off + optlen);
@@ -1472,7 +1486,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_AUTH:
         if (optlen < 11) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "AUTH: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "AUTH: malformed option");
             break;
         }
 
@@ -1485,7 +1499,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_UNICAST:
         if (optlen != 16) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "UNICAST: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "UNICAST: malformed option");
             break;
         }
         proto_tree_add_item(subtree, hf_opt_unicast, tvb, off, 16, ENC_NA);
@@ -1497,7 +1511,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_VENDOR_CLASS:
         if (optlen < 4) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "VENDOR_CLASS: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "VENDOR_CLASS: malformed option");
             break;
         }
         proto_tree_add_item(subtree, hf_vendorclass_enterprise, tvb, off, 4, ENC_BIG_ENDIAN);
@@ -1506,7 +1520,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_VENDOR_OPTS:
         if (optlen < 4) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "VENDOR_OPTS: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "VENDOR_OPTS: malformed option");
             break;
         }
 
@@ -1537,7 +1551,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         gint namelen;
 
         if (optlen == 0) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "INTERFACE_ID: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "INTERFACE_ID: malformed option");
             break;
         }
 
@@ -1556,7 +1570,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
     break;
     case OPTION_RECONF_MSG:
         if (optlen != 1) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "RECONF_MSG: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "RECONF_MSG: malformed option");
             break;
         }
 
@@ -1564,7 +1578,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_RECONF_ACCEPT:
         if (optlen)
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "RECONF_ACCEPT: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "RECONF_ACCEPT: malformed option");
         break;
     case OPTION_SIP_SERVER_D:
         if (optlen > 0) {
@@ -1574,7 +1588,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_SIP_SERVER_A:
         if (optlen % 16) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "SIP servers address: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "SIP servers address: malformed option");
             break;
         }
 
@@ -1583,7 +1597,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_DNS_SERVERS:
         if (optlen % 16) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "DNS servers address: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "DNS servers address: malformed option");
             break;
         }
 
@@ -1598,7 +1612,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_NIS_SERVERS:
         if (optlen % 16) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "NIS servers address: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "NIS servers address: malformed option");
             break;
         }
         for (i = 0; i < optlen; i += 16)
@@ -1606,7 +1620,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_NISP_SERVERS:
         if (optlen % 16) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "NISP servers address: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "NISP servers address: malformed option");
             break;
         }
         for (i = 0; i < optlen; i += 16)
@@ -1626,7 +1640,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_SNTP_SERVERS:
         if (optlen % 16) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "SNTP servers address: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "SNTP servers address: malformed option");
             break;
         }
         for (i = 0; i < optlen; i += 16)
@@ -1634,7 +1648,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_LIFETIME:
         if (optlen != 4) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "LIFETIME: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "LIFETIME: malformed option");
             break;
         }
         proto_tree_add_item(subtree, hf_opt_lifetime, tvb, off, 4, ENC_BIG_ENDIAN);
@@ -1647,7 +1661,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_BCMCS_SERVER_A:
         if (optlen % 16) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "BCMCS servers address: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "BCMCS servers address: malformed option");
             break;
         }
         for (i = 0; i < optlen; i += 16)
@@ -1655,7 +1669,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_REMOTE_ID:
         if (optlen < 4) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "REMOTE_ID: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "REMOTE_ID: malformed option");
             break;
         }
         proto_tree_add_item(subtree, hf_remoteid_enterprise, tvb, off, 4, ENC_BIG_ENDIAN);
@@ -1664,14 +1678,14 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_SUBSCRIBER_ID:
         if (optlen == 0) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "SUBSCRIBER_ID: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "SUBSCRIBER_ID: malformed option");
             break;
         }
         proto_tree_add_item(subtree, hf_subscriber_id, tvb, off, optlen, ENC_ASCII|ENC_NA);
         break;
     case OPTION_CLIENT_FQDN:
         if (optlen < 1) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "FQDN: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "FQDN: malformed option");
         } else {
             /*
              * +-----+-+-+-+
@@ -1688,7 +1702,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_PANA_AGENT:
         if (optlen % 16) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "PANA agent address: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "PANA agent address: malformed option");
             break;
         }
         for (i = 0; i < optlen; i += 16)
@@ -1706,7 +1720,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
     {
         guint8 query_type;
         if (optlen < 17) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "LQ-QUERY: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "LQ-QUERY: malformed option");
             break;
         }
         query_type = tvb_get_guint8(tvb, off);
@@ -1715,8 +1729,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
             ((query_type == LQ_QUERY_RELAYID) ||
              (query_type == LQ_QUERY_LINK_ADDRESS) ||
              (query_type == LQ_QUERY_REMOTEID))) {
-            expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN, 
-                "LQ-QUERY: Query types only supported by Bulk Leasequery");
+            expert_add_info(pinfo, ti, &ei_dhcpv6_bulk_leasequery_bad_query_type);
         }
 
         proto_tree_add_item(subtree, hf_lq_query_link_address, tvb, off+1, 16, ENC_NA);
@@ -1746,7 +1759,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_CLT_TIME:
         if (optlen != 4) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "CLT_TIME: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "CLT_TIME: malformed option");
             break;
         }
 
@@ -1754,12 +1767,12 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_LQ_RELAY_DATA:
         if (optlen < 16) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "LQ_RELAY_DATA: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "LQ_RELAY_DATA: malformed option");
             break;
         }
 
         if (protocol == proto_dhcpv6_bulk_leasequery) {
-            expert_add_info_format(pinfo, option_item, PI_PROTOCOL, PI_WARN, "LQ_RELAY_DATA: Not allowed in Bulk Leasequery");
+            expert_add_info(pinfo, option_item, &ei_dhcpv6_bulk_leasequery_no_lq_relay_data);
         }
 
         proto_tree_add_item(subtree, hf_lq_relay_data_peer_addr, tvb, off, 16, ENC_NA);
@@ -1767,7 +1780,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_LQ_CLIENT_LINK:
         if (optlen % 16) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "LQ client links address: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "LQ client links address: malformed option");
             break;
         }
         for (i = 0; i < optlen; i += 16)
@@ -1775,7 +1788,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_CAPWAP_AC_V6:
         if (optlen % 16) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "CAPWAP Access Controllers address: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "CAPWAP Access Controllers address: malformed option");
             break;
         }
         for (i = 0; i < optlen; i += 16)
@@ -1790,7 +1803,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
     }
     case OPTION_IAPREFIX:
         if (optlen < 25) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "IAPREFIX: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "IAPREFIX: malformed option");
             break;
         }
 
@@ -1822,14 +1835,14 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_MIP6_HA:
         if (optlen != 16) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "MIP6_HA: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "MIP6_HA: malformed option");
             break;
         }
         proto_tree_add_item(subtree, hf_mip6_ha, tvb, off, 16, ENC_NA);
         break;
     case OPTION_MIP6_HOA:
         if (optlen != 16) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "MIP6_HOA: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "MIP6_HOA: malformed option");
             break;
         }
 
@@ -1837,7 +1850,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
         break;
     case OPTION_NAI:
         if (optlen < 4) {
-            expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "NAI: malformed option");
+            expert_add_info_format_text(pinfo, option_item, &ei_dhcpv6_malformed_option, "NAI: malformed option");
             break;
         }
         proto_tree_add_item(subtree, hf_nai, tvb, off, optlen - 2, ENC_ASCII|ENC_NA);
@@ -1941,7 +1954,7 @@ dissect_dhcpv6_bulk_leasequery_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree
         (msg_type != LEASEQUERY_REPLY) &&
         (msg_type != LEASEQUERY_DONE) &&
         (msg_type != LEASEQUERY_DATA))
-        expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN
+        expert_add_info_format_text(pinfo, ti, &ei_dhcpv6_bulk_leasequery_bad_msg_type
             "Message Type %d not allowed by DHCPv6 Bulk Leasequery", msg_type);
 
     offset++;
@@ -2233,6 +2246,17 @@ proto_register_dhcpv6(void)
         &ett_dhcpv6_netserver_option
     };
 
+    static ei_register_info ei[] = {
+        { &ei_dhcpv6_bogus_length, { "dhcpv6.bogus_length", PI_MALFORMED, PI_ERROR, "Bogus length", EXPFILL }},
+        { &ei_dhcpv6_malformed_option, { "dhcpv6.malformed_option", PI_MALFORMED, PI_ERROR, "Malformed option", EXPFILL }},
+        { &ei_dhcpv6_no_suboption_len, { "dhcpv6.no_suboption_len", PI_PROTOCOL, PI_WARN, "no room left in option for suboption length", EXPFILL }},
+        { &ei_dhcpv6_invalid_byte, { "dhcpv6.invalid_byte", PI_PROTOCOL, PI_WARN, "Invalid at byte", EXPFILL }},
+        { &ei_dhcpv6_invalid_time_value, { "dhcpv6.invalid_time_value", PI_PROTOCOL, PI_WARN, "Invalid time value", EXPFILL }},
+        { &ei_dhcpv6_invalid_type, { "dhcpv6.invalid_type", PI_PROTOCOL, PI_WARN, "Invalid type", EXPFILL }},
+        { &ei_dhcpv6_bad_length3_6, { "dhcpv6.bad_length3or6", PI_MALFORMED, PI_ERROR, "suboption length isn't 3 or 6", EXPFILL }},
+        { &ei_dhcpv6_malformed_dns, { "dhcpv6.malformed_dns", PI_PROTOCOL, PI_WARN, "Malformed DNS name record (MS Vista client?)", EXPFILL }},
+    };
+
     static hf_register_info bulk_leasequery_hf[] = {
         { &hf_dhcpv6_bulk_leasequery_size,
           { "Message size", "dhcpv6.bulk_leasequery.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
@@ -2249,14 +2273,29 @@ proto_register_dhcpv6(void)
         &ett_dhcpv6_bulk_leasequery_options
     };
 
+    static ei_register_info ei_bulk_leasequery[] = {
+        { &ei_dhcpv6_bulk_leasequery_bad_query_type, { "dhcpv6.bulk_leasequery.bad_query_type", PI_MALFORMED, PI_WARN, "LQ-QUERY: Query types only supported by Bulk Leasequery", EXPFILL }},
+        { &ei_dhcpv6_bulk_leasequery_no_lq_relay_data, { "dhcpv6.bulk_leasequery.no_lq_relay_data", PI_MALFORMED, PI_WARN, "LQ_RELAY_DATA: Not allowed in Bulk Leasequery", EXPFILL }},
+        { &ei_dhcpv6_bulk_leasequery_bad_msg_type, { "dhcpv6.bulk_leasequery.bad_msg_type", PI_MALFORMED, PI_WARN, "Message Type %d not allowed by DHCPv6 Bulk Leasequery", EXPFILL }},
+    };
+
+    expert_module_t* expert_dhcpv6;
+    expert_module_t* expert_dhcpv6_bulk_leasequery;
+
     proto_dhcpv6 = proto_register_protocol("DHCPv6", "DHCPv6", "dhcpv6");
     proto_register_field_array(proto_dhcpv6, hf, array_length(hf));
     proto_register_subtree_array(ett, array_length(ett));
 
+    expert_dhcpv6 = expert_register_protocol(proto_dhcpv6);
+    expert_register_field_array(expert_dhcpv6, ei, array_length(ei));
+
     proto_dhcpv6_bulk_leasequery = proto_register_protocol("DHCPv6 Bulk Leasequery", "DHCPv6 Bulk Leasequery", "dhcpv6.bulk_leasequery");
     proto_register_field_array(proto_dhcpv6_bulk_leasequery, bulk_leasequery_hf, array_length(bulk_leasequery_hf));
     proto_register_subtree_array(ett_bulk_leasequery, array_length(ett_bulk_leasequery));
 
+    expert_dhcpv6_bulk_leasequery = expert_register_protocol(proto_dhcpv6_bulk_leasequery);
+    expert_register_field_array(expert_dhcpv6_bulk_leasequery, ei_bulk_leasequery, array_length(ei_bulk_leasequery));
+
     /* Allow other dissectors to find this one by name.
        Just choose upstream version for now as they are identical. */
     register_dissector("dhcpv6", dissect_dhcpv6_upstream, proto_dhcpv6);