3 * Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
22 #define WPABUF_MAGIC 0x51a974e3
28 static struct wpabuf_trace
* wpabuf_get_trace(const struct wpabuf
*buf
)
30 return (struct wpabuf_trace
*)
31 ((const u8
*) buf
- sizeof(struct wpabuf_trace
));
33 #endif /* WPA_TRACE */
36 static void wpabuf_overflow(const struct wpabuf
*buf
, size_t len
)
39 struct wpabuf_trace
*trace
= wpabuf_get_trace(buf
);
40 if (trace
->magic
!= WPABUF_MAGIC
) {
41 wpa_printf(MSG_ERROR
, "wpabuf: invalid magic %x",
44 #endif /* WPA_TRACE */
45 wpa_printf(MSG_ERROR
, "wpabuf %p (size=%lu used=%lu) overflow len=%lu",
46 buf
, (unsigned long) buf
->size
, (unsigned long) buf
->used
,
48 wpa_trace_show("wpabuf overflow");
53 int wpabuf_resize(struct wpabuf
**_buf
, size_t add_len
)
55 struct wpabuf
*buf
= *_buf
;
57 struct wpabuf_trace
*trace
;
58 #endif /* WPA_TRACE */
61 *_buf
= wpabuf_alloc(add_len
);
62 return *_buf
== NULL
? -1 : 0;
66 trace
= wpabuf_get_trace(buf
);
67 if (trace
->magic
!= WPABUF_MAGIC
) {
68 wpa_printf(MSG_ERROR
, "wpabuf: invalid magic %x",
70 wpa_trace_show("wpabuf_resize invalid magic");
73 #endif /* WPA_TRACE */
75 if (buf
->used
+ add_len
> buf
->size
) {
78 nbuf
= os_realloc(buf
->ext_data
, buf
->used
+ add_len
);
81 os_memset(nbuf
+ buf
->used
, 0, add_len
);
85 nbuf
= os_realloc(trace
, sizeof(struct wpabuf_trace
) +
86 sizeof(struct wpabuf
) +
90 trace
= (struct wpabuf_trace
*) nbuf
;
91 buf
= (struct wpabuf
*) (trace
+ 1);
92 os_memset(nbuf
+ sizeof(struct wpabuf_trace
) +
93 sizeof(struct wpabuf
) + buf
->used
, 0,
96 nbuf
= os_realloc(buf
, sizeof(struct wpabuf
) +
100 buf
= (struct wpabuf
*) nbuf
;
101 os_memset(nbuf
+ sizeof(struct wpabuf
) + buf
->used
, 0,
103 #endif /* WPA_TRACE */
106 buf
->size
= buf
->used
+ add_len
;
114 * wpabuf_alloc - Allocate a wpabuf of the given size
115 * @len: Length for the allocated buffer
116 * Returns: Buffer to the allocated wpabuf or %NULL on failure
118 struct wpabuf
* wpabuf_alloc(size_t len
)
121 struct wpabuf_trace
*trace
= os_zalloc(sizeof(struct wpabuf_trace
) +
122 sizeof(struct wpabuf
) + len
);
126 trace
->magic
= WPABUF_MAGIC
;
127 buf
= (struct wpabuf
*) (trace
+ 1);
128 #else /* WPA_TRACE */
129 struct wpabuf
*buf
= os_zalloc(sizeof(struct wpabuf
) + len
);
132 #endif /* WPA_TRACE */
139 struct wpabuf
* wpabuf_alloc_ext_data(u8
*data
, size_t len
)
142 struct wpabuf_trace
*trace
= os_zalloc(sizeof(struct wpabuf_trace
) +
143 sizeof(struct wpabuf
));
147 trace
->magic
= WPABUF_MAGIC
;
148 buf
= (struct wpabuf
*) (trace
+ 1);
149 #else /* WPA_TRACE */
150 struct wpabuf
*buf
= os_zalloc(sizeof(struct wpabuf
));
153 #endif /* WPA_TRACE */
157 buf
->ext_data
= data
;
163 struct wpabuf
* wpabuf_alloc_copy(const void *data
, size_t len
)
165 struct wpabuf
*buf
= wpabuf_alloc(len
);
167 wpabuf_put_data(buf
, data
, len
);
172 struct wpabuf
* wpabuf_dup(const struct wpabuf
*src
)
174 struct wpabuf
*buf
= wpabuf_alloc(wpabuf_len(src
));
176 wpabuf_put_data(buf
, wpabuf_head(src
), wpabuf_len(src
));
182 * wpabuf_free - Free a wpabuf
183 * @buf: wpabuf buffer
185 void wpabuf_free(struct wpabuf
*buf
)
188 struct wpabuf_trace
*trace
;
191 trace
= wpabuf_get_trace(buf
);
192 if (trace
->magic
!= WPABUF_MAGIC
) {
193 wpa_printf(MSG_ERROR
, "wpabuf_free: invalid magic %x",
195 wpa_trace_show("wpabuf_free magic mismatch");
198 os_free(buf
->ext_data
);
200 #else /* WPA_TRACE */
203 os_free(buf
->ext_data
);
205 #endif /* WPA_TRACE */
209 void * wpabuf_put(struct wpabuf
*buf
, size_t len
)
211 void *tmp
= wpabuf_mhead_u8(buf
) + wpabuf_len(buf
);
213 if (buf
->used
> buf
->size
) {
214 wpabuf_overflow(buf
, len
);
221 * wpabuf_concat - Concatenate two buffers into a newly allocated one
224 * Returns: wpabuf with concatenated a + b data or %NULL on failure
226 * Both buffers a and b will be freed regardless of the return value. Input
227 * buffers can be %NULL which is interpreted as an empty buffer.
229 struct wpabuf
* wpabuf_concat(struct wpabuf
*a
, struct wpabuf
*b
)
231 struct wpabuf
*n
= NULL
;
238 len
+= wpabuf_len(a
);
240 len
+= wpabuf_len(b
);
242 n
= wpabuf_alloc(len
);
245 wpabuf_put_buf(n
, a
);
247 wpabuf_put_buf(n
, b
);
258 * wpabuf_zeropad - Pad buffer with 0x00 octets (prefix) to specified length
259 * @buf: Buffer to be padded
260 * @len: Length for the padded buffer
261 * Returns: wpabuf padded to len octets or %NULL on failure
263 * If buf is longer than len octets or of same size, it will be returned as-is.
264 * Otherwise a new buffer is allocated and prefixed with 0x00 octets followed
265 * by the source data. The source buffer will be freed on error, i.e., caller
266 * will only be responsible on freeing the returned buffer. If buf is %NULL,
267 * %NULL will be returned.
269 struct wpabuf
* wpabuf_zeropad(struct wpabuf
*buf
, size_t len
)
277 blen
= wpabuf_len(buf
);
281 ret
= wpabuf_alloc(len
);
283 os_memset(wpabuf_put(ret
, len
- blen
), 0, len
- blen
);
284 wpabuf_put_buf(ret
, buf
);
292 void wpabuf_printf(struct wpabuf
*buf
, char *fmt
, ...)
295 void *tmp
= wpabuf_mhead_u8(buf
) + wpabuf_len(buf
);
299 res
= vsnprintf(tmp
, buf
->size
- buf
->used
, fmt
, ap
);
301 if (res
< 0 || (size_t) res
>= buf
->size
- buf
->used
)
302 wpabuf_overflow(buf
, res
);