wpabuf.c
Go to the documentation of this file.
00001 /*
00002  * Dynamic data buffer
00003  * Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "includes.h"
00016 
00017 #include "common.h"
00018 #include "trace.h"
00019 #include "wpabuf.h"
00020 
00021 #ifdef WPA_TRACE
00022 #define WPABUF_MAGIC 0x51a974e3
00023 
00024 struct wpabuf_trace {
00025         unsigned int magic;
00026 };
00027 
00028 static struct wpabuf_trace * wpabuf_get_trace(const struct wpabuf *buf)
00029 {
00030         return (struct wpabuf_trace *)
00031                 ((const u8 *) buf - sizeof(struct wpabuf_trace));
00032 }
00033 #endif /* WPA_TRACE */
00034 
00035 
00036 static void wpabuf_overflow(const struct wpabuf *buf, size_t len)
00037 {
00038 #ifdef WPA_TRACE
00039         struct wpabuf_trace *trace = wpabuf_get_trace(buf);
00040         if (trace->magic != WPABUF_MAGIC) {
00041                 wpa_printf(MSG_ERROR, "wpabuf: invalid magic %x",
00042                            trace->magic);
00043         }
00044 #endif /* WPA_TRACE */
00045         wpa_printf(MSG_ERROR, "wpabuf %p (size=%lu used=%lu) overflow len=%lu",
00046                    buf, (unsigned long) buf->size, (unsigned long) buf->used,
00047                    (unsigned long) len);
00048         wpa_trace_show("wpabuf overflow");
00049         abort();
00050 }
00051 
00052 
00053 int wpabuf_resize(struct wpabuf **_buf, size_t add_len)
00054 {
00055         struct wpabuf *buf = *_buf;
00056 #ifdef WPA_TRACE
00057         struct wpabuf_trace *trace;
00058 #endif /* WPA_TRACE */
00059 
00060         if (buf == NULL) {
00061                 *_buf = wpabuf_alloc(add_len);
00062                 return *_buf == NULL ? -1 : 0;
00063         }
00064 
00065 #ifdef WPA_TRACE
00066         trace = wpabuf_get_trace(buf);
00067         if (trace->magic != WPABUF_MAGIC) {
00068                 wpa_printf(MSG_ERROR, "wpabuf: invalid magic %x",
00069                            trace->magic);
00070                 wpa_trace_show("wpabuf_resize invalid magic");
00071                 abort();
00072         }
00073 #endif /* WPA_TRACE */
00074 
00075         if (buf->used + add_len > buf->size) {
00076                 unsigned char *nbuf;
00077                 if (buf->ext_data) {
00078                         nbuf = os_realloc(buf->ext_data, buf->used + add_len);
00079                         if (nbuf == NULL)
00080                                 return -1;
00081                         os_memset(nbuf + buf->used, 0, add_len);
00082                         buf->ext_data = nbuf;
00083                 } else {
00084 #ifdef WPA_TRACE
00085                         nbuf = os_realloc(trace, sizeof(struct wpabuf_trace) +
00086                                           sizeof(struct wpabuf) +
00087                                           buf->used + add_len);
00088                         if (nbuf == NULL)
00089                                 return -1;
00090                         trace = (struct wpabuf_trace *) nbuf;
00091                         buf = (struct wpabuf *) (trace + 1);
00092                         os_memset(nbuf + sizeof(struct wpabuf_trace) +
00093                                   sizeof(struct wpabuf) + buf->used, 0,
00094                                   add_len);
00095 #else /* WPA_TRACE */
00096                         nbuf = os_realloc(buf, sizeof(struct wpabuf) +
00097                                           buf->used + add_len);
00098                         if (nbuf == NULL)
00099                                 return -1;
00100                         buf = (struct wpabuf *) nbuf;
00101                         os_memset(nbuf + sizeof(struct wpabuf) + buf->used, 0,
00102                                   add_len);
00103 #endif /* WPA_TRACE */
00104                         *_buf = buf;
00105                 }
00106                 buf->size = buf->used + add_len;
00107         }
00108 
00109         return 0;
00110 }
00111 
00112 
00118 struct wpabuf * wpabuf_alloc(size_t len)
00119 {
00120 #ifdef WPA_TRACE
00121         struct wpabuf_trace *trace = os_zalloc(sizeof(struct wpabuf_trace) +
00122                                                sizeof(struct wpabuf) + len);
00123         struct wpabuf *buf;
00124         if (trace == NULL)
00125                 return NULL;
00126         trace->magic = WPABUF_MAGIC;
00127         buf = (struct wpabuf *) (trace + 1);
00128 #else /* WPA_TRACE */
00129         struct wpabuf *buf = os_zalloc(sizeof(struct wpabuf) + len);
00130         if (buf == NULL)
00131                 return NULL;
00132 #endif /* WPA_TRACE */
00133 
00134         buf->size = len;
00135         return buf;
00136 }
00137 
00138 
00139 struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len)
00140 {
00141 #ifdef WPA_TRACE
00142         struct wpabuf_trace *trace = os_zalloc(sizeof(struct wpabuf_trace) +
00143                                                sizeof(struct wpabuf));
00144         struct wpabuf *buf;
00145         if (trace == NULL)
00146                 return NULL;
00147         trace->magic = WPABUF_MAGIC;
00148         buf = (struct wpabuf *) (trace + 1);
00149 #else /* WPA_TRACE */
00150         struct wpabuf *buf = os_zalloc(sizeof(struct wpabuf));
00151         if (buf == NULL)
00152                 return NULL;
00153 #endif /* WPA_TRACE */
00154 
00155         buf->size = len;
00156         buf->used = len;
00157         buf->ext_data = data;
00158 
00159         return buf;
00160 }
00161 
00162 
00163 struct wpabuf * wpabuf_alloc_copy(const void *data, size_t len)
00164 {
00165         struct wpabuf *buf = wpabuf_alloc(len);
00166         if (buf)
00167                 wpabuf_put_data(buf, data, len);
00168         return buf;
00169 }
00170 
00171 
00172 struct wpabuf * wpabuf_dup(const struct wpabuf *src)
00173 {
00174         struct wpabuf *buf = wpabuf_alloc(wpabuf_len(src));
00175         if (buf)
00176                 wpabuf_put_data(buf, wpabuf_head(src), wpabuf_len(src));
00177         return buf;
00178 }
00179 
00180 
00185 void wpabuf_free(struct wpabuf *buf)
00186 {
00187 #ifdef WPA_TRACE
00188         struct wpabuf_trace *trace;
00189         if (buf == NULL)
00190                 return;
00191         trace = wpabuf_get_trace(buf);
00192         if (trace->magic != WPABUF_MAGIC) {
00193                 wpa_printf(MSG_ERROR, "wpabuf_free: invalid magic %x",
00194                            trace->magic);
00195                 wpa_trace_show("wpabuf_free magic mismatch");
00196                 abort();
00197         }
00198         os_free(buf->ext_data);
00199         os_free(trace);
00200 #else /* WPA_TRACE */
00201         if (buf == NULL)
00202                 return;
00203         os_free(buf->ext_data);
00204         os_free(buf);
00205 #endif /* WPA_TRACE */
00206 }
00207 
00208 
00209 void * wpabuf_put(struct wpabuf *buf, size_t len)
00210 {
00211         void *tmp = wpabuf_mhead_u8(buf) + wpabuf_len(buf);
00212         buf->used += len;
00213         if (buf->used > buf->size) {
00214                 wpabuf_overflow(buf, len);
00215         }
00216         return tmp;
00217 }
00218 
00219 
00229 struct wpabuf * wpabuf_concat(struct wpabuf *a, struct wpabuf *b)
00230 {
00231         struct wpabuf *n = NULL;
00232         size_t len = 0;
00233 
00234         if (b == NULL)
00235                 return a;
00236 
00237         if (a)
00238                 len += wpabuf_len(a);
00239         if (b)
00240                 len += wpabuf_len(b);
00241 
00242         n = wpabuf_alloc(len);
00243         if (n) {
00244                 if (a)
00245                         wpabuf_put_buf(n, a);
00246                 if (b)
00247                         wpabuf_put_buf(n, b);
00248         }
00249 
00250         wpabuf_free(a);
00251         wpabuf_free(b);
00252 
00253         return n;
00254 }
00255 
00256 
00269 struct wpabuf * wpabuf_zeropad(struct wpabuf *buf, size_t len)
00270 {
00271         struct wpabuf *ret;
00272         size_t blen;
00273 
00274         if (buf == NULL)
00275                 return NULL;
00276 
00277         blen = wpabuf_len(buf);
00278         if (blen >= len)
00279                 return buf;
00280 
00281         ret = wpabuf_alloc(len);
00282         if (ret) {
00283                 os_memset(wpabuf_put(ret, len - blen), 0, len - blen);
00284                 wpabuf_put_buf(ret, buf);
00285         }
00286         wpabuf_free(buf);
00287 
00288         return ret;
00289 }
00290 
00291 
00292 void wpabuf_printf(struct wpabuf *buf, char *fmt, ...)
00293 {
00294         va_list ap;
00295         void *tmp = wpabuf_mhead_u8(buf) + wpabuf_len(buf);
00296         int res;
00297 
00298         va_start(ap, fmt);
00299         res = vsnprintf(tmp, buf->size - buf->used, fmt, ap);
00300         va_end(ap);
00301         if (res < 0 || (size_t) res >= buf->size - buf->used)
00302                 wpabuf_overflow(buf, res);
00303         buf->used += res;
00304 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:36