Merged the hostap_2.6 updates, and the Leap of Faith work, from the hostap_update...
[mech_eap.git] / libeap / src / utils / wpabuf.c
index eda779e..96cb25c 100644 (file)
@@ -1,15 +1,9 @@
 /*
  * Dynamic data buffer
- * Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2007-2012, Jouni Malinen <j@w1.fi>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
  */
 
 #include "includes.h"
@@ -23,7 +17,7 @@
 
 struct wpabuf_trace {
        unsigned int magic;
-};
+} __attribute__((aligned(8)));
 
 static struct wpabuf_trace * wpabuf_get_trace(const struct wpabuf *buf)
 {
@@ -74,12 +68,12 @@ int wpabuf_resize(struct wpabuf **_buf, size_t add_len)
 
        if (buf->used + add_len > buf->size) {
                unsigned char *nbuf;
-               if (buf->ext_data) {
-                       nbuf = os_realloc(buf->ext_data, buf->used + add_len);
+               if (buf->flags & WPABUF_FLAG_EXT_DATA) {
+                       nbuf = os_realloc(buf->buf, buf->used + add_len);
                        if (nbuf == NULL)
                                return -1;
                        os_memset(nbuf + buf->used, 0, add_len);
-                       buf->ext_data = nbuf;
+                       buf->buf = nbuf;
                } else {
 #ifdef WPA_TRACE
                        nbuf = os_realloc(trace, sizeof(struct wpabuf_trace) +
@@ -101,6 +95,7 @@ int wpabuf_resize(struct wpabuf **_buf, size_t add_len)
                        os_memset(nbuf + sizeof(struct wpabuf) + buf->used, 0,
                                  add_len);
 #endif /* WPA_TRACE */
+                       buf->buf = (u8 *) (buf + 1);
                        *_buf = buf;
                }
                buf->size = buf->used + add_len;
@@ -132,6 +127,7 @@ struct wpabuf * wpabuf_alloc(size_t len)
 #endif /* WPA_TRACE */
 
        buf->size = len;
+       buf->buf = (u8 *) (buf + 1);
        return buf;
 }
 
@@ -154,7 +150,8 @@ struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len)
 
        buf->size = len;
        buf->used = len;
-       buf->ext_data = data;
+       buf->buf = data;
+       buf->flags |= WPABUF_FLAG_EXT_DATA;
 
        return buf;
 }
@@ -195,17 +192,28 @@ void wpabuf_free(struct wpabuf *buf)
                wpa_trace_show("wpabuf_free magic mismatch");
                abort();
        }
-       os_free(buf->ext_data);
+       if (buf->flags & WPABUF_FLAG_EXT_DATA)
+               os_free(buf->buf);
        os_free(trace);
 #else /* WPA_TRACE */
        if (buf == NULL)
                return;
-       os_free(buf->ext_data);
+       if (buf->flags & WPABUF_FLAG_EXT_DATA)
+               os_free(buf->buf);
        os_free(buf);
 #endif /* WPA_TRACE */
 }
 
 
+void wpabuf_clear_free(struct wpabuf *buf)
+{
+       if (buf) {
+               os_memset(wpabuf_mhead(buf), 0, wpabuf_len(buf));
+               wpabuf_free(buf);
+       }
+}
+
+
 void * wpabuf_put(struct wpabuf *buf, size_t len)
 {
        void *tmp = wpabuf_mhead_u8(buf) + wpabuf_len(buf);
@@ -302,3 +310,33 @@ void wpabuf_printf(struct wpabuf *buf, char *fmt, ...)
                wpabuf_overflow(buf, res);
        buf->used += res;
 }
+
+
+/**
+ * wpabuf_parse_bin - Parse a null terminated string of binary data to a wpabuf
+ * @buf: Buffer with null terminated string (hexdump) of binary data
+ * Returns: wpabuf or %NULL on failure
+ *
+ * The string len must be a multiple of two and contain only hexadecimal digits.
+ */
+struct wpabuf * wpabuf_parse_bin(const char *buf)
+{
+       size_t len;
+       struct wpabuf *ret;
+
+       len = os_strlen(buf);
+       if (len & 0x01)
+               return NULL;
+       len /= 2;
+
+       ret = wpabuf_alloc(len);
+       if (ret == NULL)
+               return NULL;
+
+       if (hexstr2bin(buf, wpabuf_put(ret, len), len)) {
+               wpabuf_free(ret);
+               return NULL;
+       }
+
+       return ret;
+}