wpabuf.c revision c5ec7f57ead87efa365800228aa0b09a12d9e6c4
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Dynamic data buffer 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "trace.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpabuf.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPA_TRACE 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define WPABUF_MAGIC 0x51a974e3 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf_trace { 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int magic; 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf_trace * wpabuf_get_trace(const struct wpabuf *buf) 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return (struct wpabuf_trace *) 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((const u8 *) buf - sizeof(struct wpabuf_trace)); 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_TRACE */ 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpabuf_overflow(const struct wpabuf *buf, size_t len) 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPA_TRACE 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf_trace *trace = wpabuf_get_trace(buf); 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (trace->magic != WPABUF_MAGIC) { 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "wpabuf: invalid magic %x", 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt trace->magic); 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_TRACE */ 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "wpabuf %p (size=%lu used=%lu) overflow len=%lu", 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, (unsigned long) buf->size, (unsigned long) buf->used, 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_show("wpabuf overflow"); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abort(); 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpabuf_resize(struct wpabuf **_buf, size_t add_len) 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf = *_buf; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPA_TRACE 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf_trace *trace; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_TRACE */ 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *_buf = wpabuf_alloc(add_len); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return *_buf == NULL ? -1 : 0; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPA_TRACE 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt trace = wpabuf_get_trace(buf); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (trace->magic != WPABUF_MAGIC) { 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "wpabuf: invalid magic %x", 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt trace->magic); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_show("wpabuf_resize invalid magic"); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abort(); 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_TRACE */ 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf->used + add_len > buf->size) { 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *nbuf; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf->ext_data) { 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nbuf = os_realloc(buf->ext_data, buf->used + add_len); 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nbuf == NULL) 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(nbuf + buf->used, 0, add_len); 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf->ext_data = nbuf; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPA_TRACE 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nbuf = os_realloc(trace, sizeof(struct wpabuf_trace) + 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct wpabuf) + 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf->used + add_len); 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nbuf == NULL) 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt trace = (struct wpabuf_trace *) nbuf; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = (struct wpabuf *) (trace + 1); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(nbuf + sizeof(struct wpabuf_trace) + 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct wpabuf) + buf->used, 0, 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt add_len); 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPA_TRACE */ 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nbuf = os_realloc(buf, sizeof(struct wpabuf) + 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf->used + add_len); 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nbuf == NULL) 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = (struct wpabuf *) nbuf; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(nbuf + sizeof(struct wpabuf) + buf->used, 0, 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt add_len); 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_TRACE */ 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *_buf = buf; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf->size = buf->used + add_len; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpabuf_alloc - Allocate a wpabuf of the given size 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length for the allocated buffer 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Buffer to the allocated wpabuf or %NULL on failure 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * wpabuf_alloc(size_t len) 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPA_TRACE 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf_trace *trace = os_zalloc(sizeof(struct wpabuf_trace) + 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct wpabuf) + len); 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (trace == NULL) 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt trace->magic = WPABUF_MAGIC; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = (struct wpabuf *) (trace + 1); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPA_TRACE */ 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf = os_zalloc(sizeof(struct wpabuf) + len); 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_TRACE */ 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf->size = len; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len) 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPA_TRACE 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf_trace *trace = os_zalloc(sizeof(struct wpabuf_trace) + 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct wpabuf)); 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (trace == NULL) 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt trace->magic = WPABUF_MAGIC; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = (struct wpabuf *) (trace + 1); 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPA_TRACE */ 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf = os_zalloc(sizeof(struct wpabuf)); 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_TRACE */ 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf->size = len; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf->used = len; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf->ext_data = data; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * wpabuf_alloc_copy(const void *data, size_t len) 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf = wpabuf_alloc(len); 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf) 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, data, len); 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * wpabuf_dup(const struct wpabuf *src) 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf = wpabuf_alloc(wpabuf_len(src)); 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf) 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, wpabuf_head(src), wpabuf_len(src)); 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpabuf_free - Free a wpabuf 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: wpabuf buffer 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpabuf_free(struct wpabuf *buf) 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPA_TRACE 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf_trace *trace; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt trace = wpabuf_get_trace(buf); 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (trace->magic != WPABUF_MAGIC) { 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "wpabuf_free: invalid magic %x", 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt trace->magic); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_trace_show("wpabuf_free magic mismatch"); 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt abort(); 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf->ext_data); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(trace); 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPA_TRACE */ 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf->ext_data); 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPA_TRACE */ 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * wpabuf_put(struct wpabuf *buf, size_t len) 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *tmp = wpabuf_mhead_u8(buf) + wpabuf_len(buf); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf->used += len; 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf->used > buf->size) { 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_overflow(buf, len); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tmp; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpabuf_concat - Concatenate two buffers into a newly allocated one 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @a: First buffer 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @b: Second buffer 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: wpabuf with concatenated a + b data or %NULL on failure 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Both buffers a and b will be freed regardless of the return value. Input 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * buffers can be %NULL which is interpreted as an empty buffer. 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * wpabuf_concat(struct wpabuf *a, struct wpabuf *b) 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *n = NULL; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len = 0; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b == NULL) 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return a; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a) 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += wpabuf_len(a); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b) 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += wpabuf_len(b); 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt n = wpabuf_alloc(len); 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (n) { 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a) 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(n, a); 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b) 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(n, b); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(a); 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(b); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return n; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpabuf_zeropad - Pad buffer with 0x00 octets (prefix) to specified length 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer to be padded 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length for the padded buffer 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: wpabuf padded to len octets or %NULL on failure 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If buf is longer than len octets or of same size, it will be returned as-is. 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Otherwise a new buffer is allocated and prefixed with 0x00 octets followed 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * by the source data. The source buffer will be freed on error, i.e., caller 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will only be responsible on freeing the returned buffer. If buf is %NULL, 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * %NULL will be returned. 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * wpabuf_zeropad(struct wpabuf *buf, size_t len) 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ret; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t blen; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt blen = wpabuf_len(buf); 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (blen >= len) 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = wpabuf_alloc(len); 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpabuf_put(ret, len - blen), 0, len - blen); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(ret, buf); 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpabuf_printf(struct wpabuf *buf, char *fmt, ...) 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt va_list ap; 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *tmp = wpabuf_mhead_u8(buf) + wpabuf_len(buf); 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt va_start(ap, fmt); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = vsnprintf(tmp, buf->size - buf->used, fmt, ap); 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt va_end(ap); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 || (size_t) res >= buf->size - buf->used) 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_overflow(buf, res); 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf->used += res; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 299