dcerpc: remove use-after-free (found by clang).
[metze/wireshark/wip.git] / epan / xdlc.c
index cb3c5af42ff2d5173bf791f06c54c7c027aede51..06af5ec3f021ea22455bbdff55452f6066d3ea6c 100644 (file)
@@ -2,10 +2,8 @@
  * Routines for use by various SDLC-derived protocols, such as HDLC
  * and its derivatives LAPB, IEEE 802.2 LLC, etc..
  *
- * $Id$
- *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
 
 #include <stdio.h>
 #include <string.h>
@@ -33,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" },
@@ -136,7 +132,7 @@ const value_string modifier_vals_resp[] = {
 };
 
 int
-get_xdlc_control(const guchar *pd, int offset, int is_extended)
+get_xdlc_control(const guchar *pd, int offset, gboolean is_extended)
 {
     guint16 control;
 
@@ -145,27 +141,27 @@ get_xdlc_control(const guchar *pd, int offset, int 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;
+        /*
+         * 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;
 }
@@ -175,8 +171,8 @@ dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
   proto_tree *xdlc_tree, int hf_xdlc_control, gint ett_xdlc_control,
   const xdlc_cf_items *cf_items_nonext, const xdlc_cf_items *cf_items_ext,
   const value_string *u_modifier_short_vals_cmd,
-  const value_string *u_modifier_short_vals_resp, int is_response,
-  int is_extended, int append_info)
+  const value_string *u_modifier_short_vals_resp, gboolean is_response,
+  gboolean is_extended, gboolean append_info)
 {
     guint16 control;
     int control_len;
@@ -188,193 +184,203 @@ dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
     const gchar *frame_type = NULL;
     const gchar *modifier;
 
-    info=ep_alloc(80);
+    info=(char *)wmem_alloc(wmem_packet_scope(), 80);
     switch (tvb_get_guint8(tvb, offset) & 0x03) {
 
     case XDLC_S:
-       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)";
-       }
         /*
-        * Supervisory frame.
-        */
-       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:
+ */