dcerpc: remove use-after-free (found by clang).
[metze/wireshark/wip.git] / epan / xdlc.c
index f1a6e0f2de86f2628f3f2d211775cb28b19dd6f2..06af5ec3f021ea22455bbdff55452f6066d3ea6c 100644 (file)
@@ -2,8 +2,6 @@
  * Routines for use by various SDLC-derived protocols, such as HDLC
  * and its derivatives LAPB, IEEE 802.2 LLC, etc..
  *
- * $Id$
- *
  * Wireshark - Network traffic analyzer
  * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
@@ -31,7 +29,7 @@
 #include <glib.h>
 #include <epan/packet.h>
 #include <epan/xdlc.h>
-#include <epan/emem.h>
+#include <wsutil/pint.h>
 
 const value_string ftype_vals[] = {
     { XDLC_I, "Information frame" },
@@ -143,87 +141,29 @@ get_xdlc_control(const guchar *pd, int offset, gboolean is_extended)
     case XDLC_S:
     default:
         /*
-        * Supervisory or Information frame.
-        */
-       if (is_extended)
-               control = pletohs(&pd[offset]);
-       else
-               control = pd[offset];
-       break;
+         * Supervisory or Information frame.
+         */
+        if (is_extended)
+                control = pletoh16(&pd[offset]);
+        else
+                control = pd[offset];
+        break;
 
     case XDLC_U:
-       /*
-        * Unnumbered frame.
-        *
-        * XXX - is this two octets, with a P/F bit, in HDLC extended
-        * operation?  It's one octet in LLC, even though the control
-        * field of I and S frames is a 2-byte extended-operation field
-        * in LLC.  Given that there are no sequence numbers in the
-        * control field of a U frame, there doesn't appear to be any
-        * need for it to be 2 bytes in extended operation.
-        */
-       control = pd[offset];
-       break;
-    }
-    return control;
-}
-
-/*
- * Check whether the control field of the packet looks valid.
- */
-gboolean
-check_xdlc_control(tvbuff_t *tvb, int offset,
-  const value_string *u_modifier_short_vals_cmd,
-  const value_string *u_modifier_short_vals_resp, gboolean is_response,
-  gboolean is_extended _U_)
-{
-    guint16 control;
-
-    if (!tvb_bytes_exist(tvb, offset, 1))
-       return FALSE;   /* not enough data to check */
-    switch (tvb_get_guint8(tvb, offset) & 0x03) {
-
-    case XDLC_S:
         /*
-        * Supervisory frame.
-        * No fields to check for validity here.
-        */
-       return TRUE;
-
-    case XDLC_U:
-       /*
-        * Unnumbered frame.
-        *
-        * XXX - is this two octets, with a P/F bit, in HDLC extended
-        * operation?  It's one octet in LLC, even though the control
-        * field of I and S frames is a 2-byte extended-operation field
-        * in LLC.  Given that there are no sequence numbers in the
-        * control field of a U frame, there doesn't appear to be any
-        * need for it to be 2 bytes in extended operation.
-        */
-       if (u_modifier_short_vals_cmd == NULL)
-               u_modifier_short_vals_cmd = modifier_short_vals_cmd;
-       if (u_modifier_short_vals_resp == NULL)
-               u_modifier_short_vals_resp = modifier_short_vals_resp;
-       control = tvb_get_guint8(tvb, offset);
-       if (is_response) {
-               if (match_strval(control & XDLC_U_MODIFIER_MASK,
-                   u_modifier_short_vals_resp) == NULL)
-                       return FALSE;   /* unknown modifier */
-       } else {
-               if (match_strval(control & XDLC_U_MODIFIER_MASK,
-                   u_modifier_short_vals_cmd) == NULL)
-                       return FALSE;   /* unknown modifier */
-       }
-       return TRUE;
-
-    default:
-       /*
-        * Information frame.
-        * No fields to check for validity here.
-        */
-       return TRUE;
+         * Unnumbered frame.
+         *
+         * XXX - is this two octets, with a P/F bit, in HDLC extended
+         * operation?  It's one octet in LLC, even though the control
+         * field of I and S frames is a 2-byte extended-operation field
+         * in LLC.  Given that there are no sequence numbers in the
+         * control field of a U frame, there doesn't appear to be any
+         * need for it to be 2 bytes in extended operation.
+         */
+        control = pd[offset];
+        break;
     }
+    return control;
 }
 
 int
@@ -244,193 +184,203 @@ dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
     const gchar *frame_type = NULL;
     const gchar *modifier;
 
-    info=(char *)ep_alloc(80);
+    info=(char *)wmem_alloc(wmem_packet_scope(), 80);
     switch (tvb_get_guint8(tvb, offset) & 0x03) {
 
     case XDLC_S:
         /*
-        * Supervisory frame.
-        */
-       if (is_extended) {
-           control = tvb_get_letohs(tvb, offset);
-           control_len = 2;
-           cf_items = cf_items_ext;
-           control_format = "Control field: %s (0x%04X)";
-       } else {
-           control = tvb_get_guint8(tvb, offset);
-           control_len = 1;
-           cf_items = cf_items_nonext;
-           control_format = "Control field: %s (0x%02X)";
-       }
-       switch (control & XDLC_S_FTYPE_MASK) {
-       case XDLC_RR:
-           frame_type = "RR";
-           break;
+         * Supervisory frame.
+         */
+        if (is_extended) {
+            control = tvb_get_letohs(tvb, offset);
+            control_len = 2;
+            cf_items = cf_items_ext;
+            control_format = "Control field: %s (0x%04X)";
+        } else {
+            control = tvb_get_guint8(tvb, offset);
+            control_len = 1;
+            cf_items = cf_items_nonext;
+            control_format = "Control field: %s (0x%02X)";
+        }
+        switch (control & XDLC_S_FTYPE_MASK) {
+        case XDLC_RR:
+            frame_type = "RR";
+            break;
 
-       case XDLC_RNR:
-           frame_type = "RNR";
-           break;
+        case XDLC_RNR:
+            frame_type = "RNR";
+            break;
 
-       case XDLC_REJ:
-           frame_type = "REJ";
-           break;
+        case XDLC_REJ:
+            frame_type = "REJ";
+            break;
 
-       case XDLC_SREJ:
-           frame_type = "SREJ";
-           break;
-       }
-       if (is_extended) {
-           poll_final = (control & XDLC_P_F_EXT);
-           g_snprintf(info, 80, "S%s, func=%s, N(R)=%u",
-                       (poll_final ?
-                           (is_response ? " F" : " P") :
-                           ""),
-                       frame_type,
-                       (control & XDLC_N_R_EXT_MASK) >> XDLC_N_R_EXT_SHIFT);
-       } else {
-           poll_final = (control & XDLC_P_F);
-           g_snprintf(info, 80, "S%s, func=%s, N(R)=%u",
-                       (poll_final ?
-                           (is_response ? " F" : " P") :
-                           ""),
-                       frame_type,
-                       (control & XDLC_N_R_MASK) >> XDLC_N_R_SHIFT);
-       }
-       if (check_col(pinfo->cinfo, COL_INFO)) {
-           if (append_info) {
-               col_append_str(pinfo->cinfo, COL_INFO, ", ");
-               col_append_str(pinfo->cinfo, COL_INFO, info);
-           } else
-               col_add_str(pinfo->cinfo, COL_INFO, info);
-       }
-       if (xdlc_tree) {
-           tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
-               offset, control_len, control, control_format, info, control);
-           control_tree = proto_item_add_subtree(tc, ett_xdlc_control);
-           proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_n_r,
-               tvb, offset, control_len, control);
-           if (poll_final) {
-               proto_tree_add_boolean(control_tree,
-                       (is_response ? *cf_items->hf_xdlc_f :
-                                      *cf_items->hf_xdlc_p),
-                       tvb, offset, control_len, control);
-           }
-           proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_s_ftype,
-               tvb, offset, control_len, control);
-           /* This will always say it's a supervisory frame */
-           proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_ftype_s_u,
-               tvb, offset, control_len, control);
-       }
-       break;
+        case XDLC_SREJ:
+            frame_type = "SREJ";
+            break;
+        }
+        if (is_extended) {
+            poll_final = (control & XDLC_P_F_EXT);
+            g_snprintf(info, 80, "S%s, func=%s, N(R)=%u",
+                        (poll_final ?
+                            (is_response ? " F" : " P") :
+                            ""),
+                        frame_type,
+                        (control & XDLC_N_R_EXT_MASK) >> XDLC_N_R_EXT_SHIFT);
+        } else {
+            poll_final = (control & XDLC_P_F);
+            g_snprintf(info, 80, "S%s, func=%s, N(R)=%u",
+                        (poll_final ?
+                            (is_response ? " F" : " P") :
+                            ""),
+                        frame_type,
+                        (control & XDLC_N_R_MASK) >> XDLC_N_R_SHIFT);
+        }
+        if (append_info) {
+            col_append_str(pinfo->cinfo, COL_INFO, ", ");
+            col_append_str(pinfo->cinfo, COL_INFO, info);
+        } else {
+            col_add_str(pinfo->cinfo, COL_INFO, info);
+        }
+        if (xdlc_tree) {
+            tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
+                offset, control_len, control, control_format, info, control);
+            control_tree = proto_item_add_subtree(tc, ett_xdlc_control);
+            proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_n_r,
+                tvb, offset, control_len, control);
+            if (poll_final) {
+                proto_tree_add_boolean(control_tree,
+                        (is_response ? *cf_items->hf_xdlc_f :
+                                       *cf_items->hf_xdlc_p),
+                        tvb, offset, control_len, control);
+            }
+            proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_s_ftype,
+                tvb, offset, control_len, control);
+            /* This will always say it's a supervisory frame */
+            proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_ftype_s_u,
+                tvb, offset, control_len, control);
+        }
+        break;
 
     case XDLC_U:
-       /*
-        * Unnumbered frame.
-        *
-        * XXX - is this two octets, with a P/F bit, in HDLC extended
-        * operation?  It's one octet in LLC, even though the control
-        * field of I and S frames is a 2-byte extended-operation field
-        * in LLC.  Given that there are no sequence numbers in the
-        * control field of a U frame, there doesn't appear to be any
-        * need for it to be 2 bytes in extended operation.
-        */
-       if (u_modifier_short_vals_cmd == NULL)
-               u_modifier_short_vals_cmd = modifier_short_vals_cmd;
-       if (u_modifier_short_vals_resp == NULL)
-               u_modifier_short_vals_resp = modifier_short_vals_resp;
-       control = tvb_get_guint8(tvb, offset);
-       control_len = 1;
-       cf_items = cf_items_nonext;
-       control_format = "Control field: %s (0x%02X)";
-       if (is_response) {
-               modifier = val_to_str(control & XDLC_U_MODIFIER_MASK,
-                       u_modifier_short_vals_resp, "Unknown");
-       } else {
-               modifier = val_to_str(control & XDLC_U_MODIFIER_MASK,
-                       u_modifier_short_vals_cmd, "Unknown");
-       }
-       poll_final = (control & XDLC_P_F);
-       g_snprintf(info, 80, "U%s, func=%s",
-               (poll_final ?
-                   (is_response ? " F" : " P") :
-                   ""),
-               modifier);
-       if (check_col(pinfo->cinfo, COL_INFO)) {
-           if (append_info) {
-               col_append_str(pinfo->cinfo, COL_INFO, ", ");
-               col_append_str(pinfo->cinfo, COL_INFO, info);
-           } else
-               col_add_str(pinfo->cinfo, COL_INFO, info);
-       }
-       if (xdlc_tree) {
-           tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
-               offset, control_len, control, control_format, info, control);
-           control_tree = proto_item_add_subtree(tc, ett_xdlc_control);
-           if (poll_final) {
-               proto_tree_add_boolean(control_tree,
-                       (is_response ? *cf_items->hf_xdlc_f:
-                                      *cf_items->hf_xdlc_p),
-                       tvb, offset, control_len, control);
-           }
-           proto_tree_add_uint(control_tree,
-               (is_response ? *cf_items->hf_xdlc_u_modifier_resp :
-                              *cf_items->hf_xdlc_u_modifier_cmd),
-               tvb, offset, control_len, control);
-           /* This will always say it's an unnumbered frame */
-           proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_ftype_s_u,
-               tvb, offset, control_len, control);
-       }
-       break;
+        /*
+         * Unnumbered frame.
+         *
+         * XXX - is this two octets, with a P/F bit, in HDLC extended
+         * operation?  It's one octet in LLC, even though the control
+         * field of I and S frames is a 2-byte extended-operation field
+         * in LLC.  Given that there are no sequence numbers in the
+         * control field of a U frame, there doesn't appear to be any
+         * need for it to be 2 bytes in extended operation.
+         */
+        if (u_modifier_short_vals_cmd == NULL)
+                u_modifier_short_vals_cmd = modifier_short_vals_cmd;
+        if (u_modifier_short_vals_resp == NULL)
+                u_modifier_short_vals_resp = modifier_short_vals_resp;
+        control = tvb_get_guint8(tvb, offset);
+        control_len = 1;
+        cf_items = cf_items_nonext;
+        control_format = "Control field: %s (0x%02X)";
+        if (is_response) {
+                modifier = val_to_str(control & XDLC_U_MODIFIER_MASK,
+                        u_modifier_short_vals_resp, "Unknown");
+        } else {
+                modifier = val_to_str(control & XDLC_U_MODIFIER_MASK,
+                        u_modifier_short_vals_cmd, "Unknown");
+        }
+        poll_final = (control & XDLC_P_F);
+        g_snprintf(info, 80, "U%s, func=%s",
+                (poll_final ?
+                    (is_response ? " F" : " P") :
+                    ""),
+                modifier);
+        if (append_info) {
+            col_append_str(pinfo->cinfo, COL_INFO, ", ");
+        col_append_str(pinfo->cinfo, COL_INFO, info);
+        } else {
+            col_add_str(pinfo->cinfo, COL_INFO, info);
+        }
+        if (xdlc_tree) {
+            tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
+                offset, control_len, control, control_format, info, control);
+            control_tree = proto_item_add_subtree(tc, ett_xdlc_control);
+            if (poll_final) {
+                proto_tree_add_boolean(control_tree,
+                        (is_response ? *cf_items->hf_xdlc_f:
+                                       *cf_items->hf_xdlc_p),
+                        tvb, offset, control_len, control);
+            }
+            proto_tree_add_uint(control_tree,
+                (is_response ? *cf_items->hf_xdlc_u_modifier_resp :
+                               *cf_items->hf_xdlc_u_modifier_cmd),
+                tvb, offset, control_len, control);
+            /* This will always say it's an unnumbered frame */
+            proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_ftype_s_u,
+                tvb, offset, control_len, control);
+        }
+        break;
 
     default:
-       /*
-        * Information frame.
-        */
-       if (is_extended) {
-           control = tvb_get_letohs(tvb, offset);
-           control_len = 2;
-           cf_items = cf_items_ext;
-           control_format = "Control field: %s (0x%04X)";
-           poll_final = (control & XDLC_P_F_EXT);
-           g_snprintf(info, 80, "I%s, N(R)=%u, N(S)=%u",
-                       ((control & XDLC_P_F_EXT) ? " P" : ""),
-                       (control & XDLC_N_R_EXT_MASK) >> XDLC_N_R_EXT_SHIFT,
-                       (control & XDLC_N_S_EXT_MASK) >> XDLC_N_S_EXT_SHIFT);
-       } else {
-           control = tvb_get_guint8(tvb, offset);
-           control_len = 1;
-           cf_items = cf_items_nonext;
-           control_format = "Control field: %s (0x%02X)";
-           poll_final = (control & XDLC_P_F);
-           g_snprintf(info, 80, "I%s, N(R)=%u, N(S)=%u",
-                       ((control & XDLC_P_F) ? " P" : ""),
-                       (control & XDLC_N_R_MASK) >> XDLC_N_R_SHIFT,
-                       (control & XDLC_N_S_MASK) >> XDLC_N_S_SHIFT);
-       }
-       if (check_col(pinfo->cinfo, COL_INFO)) {
-           if (append_info) {
-               col_append_str(pinfo->cinfo, COL_INFO, ", ");
-               col_append_str(pinfo->cinfo, COL_INFO, info);
-           } else
-               col_add_str(pinfo->cinfo, COL_INFO, info);
-       }
-       if (xdlc_tree) {
-           tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
-               offset, control_len, control, control_format, info, control);
-           control_tree = proto_item_add_subtree(tc, ett_xdlc_control);
-           proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_n_r,
-               tvb, offset, control_len, control);
-           proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_n_s,
-               tvb, offset, control_len, control);
-           if (poll_final) {
-               proto_tree_add_boolean(control_tree, *cf_items->hf_xdlc_p,
-                       tvb, offset, control_len, control);
-           }
-           /* This will always say it's an information frame */
-           proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_ftype_i,
-               tvb, offset, control_len, control);
-       }
-       break;
+        /*
+         * Information frame.
+         */
+        if (is_extended) {
+            control = tvb_get_letohs(tvb, offset);
+            control_len = 2;
+            cf_items = cf_items_ext;
+            control_format = "Control field: %s (0x%04X)";
+            poll_final = (control & XDLC_P_F_EXT);
+            g_snprintf(info, 80, "I%s, N(R)=%u, N(S)=%u",
+                        ((control & XDLC_P_F_EXT) ? " P" : ""),
+                        (control & XDLC_N_R_EXT_MASK) >> XDLC_N_R_EXT_SHIFT,
+                        (control & XDLC_N_S_EXT_MASK) >> XDLC_N_S_EXT_SHIFT);
+        } else {
+            control = tvb_get_guint8(tvb, offset);
+            control_len = 1;
+            cf_items = cf_items_nonext;
+            control_format = "Control field: %s (0x%02X)";
+            poll_final = (control & XDLC_P_F);
+            g_snprintf(info, 80, "I%s, N(R)=%u, N(S)=%u",
+                        ((control & XDLC_P_F) ? " P" : ""),
+                        (control & XDLC_N_R_MASK) >> XDLC_N_R_SHIFT,
+                        (control & XDLC_N_S_MASK) >> XDLC_N_S_SHIFT);
+        }
+        if (append_info) {
+            col_append_str(pinfo->cinfo, COL_INFO, ", ");
+        col_append_str(pinfo->cinfo, COL_INFO, info);
+        } else {
+            col_add_str(pinfo->cinfo, COL_INFO, info);
+        }
+        if (xdlc_tree) {
+            tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
+                offset, control_len, control, control_format, info, control);
+            control_tree = proto_item_add_subtree(tc, ett_xdlc_control);
+            proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_n_r,
+                tvb, offset, control_len, control);
+            proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_n_s,
+                tvb, offset, control_len, control);
+            if (poll_final) {
+                proto_tree_add_boolean(control_tree, *cf_items->hf_xdlc_p,
+                        tvb, offset, control_len, control);
+            }
+            /* This will always say it's an information frame */
+            proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_ftype_i,
+                tvb, offset, control_len, control);
+        }
+        break;
     }
     return control;
 }
+
+/*
+ * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */