wpabuf.c
Go to the documentation of this file.00001
00016 #include "includes.h"
00017
00018 #include "common.h"
00019 #include "wpabuf.h"
00020
00021 static void wpabuf_overflow(const struct wpabuf *buf, size_t len)
00022 {
00023 wpa_printf(MSG_ERROR, "wpabuf %p (size=%lu used=%lu) overflow len=%lu",
00024 buf, (unsigned long) buf->size, (unsigned long) buf->used,
00025 (unsigned long) len);
00026 abort();
00027 }
00028
00029
00030 int wpabuf_resize(struct wpabuf **_buf, size_t add_len)
00031 {
00032 struct wpabuf *buf = *_buf;
00033 if (buf->used + add_len > buf->size) {
00034 unsigned char *nbuf;
00035 if (buf->ext_data) {
00036 nbuf = os_realloc(buf->ext_data, buf->used + add_len);
00037 if (nbuf == NULL)
00038 return -1;
00039 os_memset(nbuf + buf->used, 0, add_len);
00040 buf->ext_data = nbuf;
00041 } else {
00042 nbuf = os_realloc(buf, sizeof(struct wpabuf) +
00043 buf->used + add_len);
00044 if (nbuf == NULL)
00045 return -1;
00046 buf = (struct wpabuf *) nbuf;
00047 os_memset(nbuf + sizeof(struct wpabuf) + buf->used, 0,
00048 add_len);
00049 *_buf = buf;
00050 }
00051 buf->size = buf->used + add_len;
00052 }
00053
00054 return 0;
00055 }
00056
00057
00064 struct wpabuf * wpabuf_alloc(size_t len)
00065 {
00066 struct wpabuf *buf = os_zalloc(sizeof(struct wpabuf) + len);
00067 if (buf == NULL)
00068 return NULL;
00069 buf->size = len;
00070 return buf;
00071 }
00072
00073
00074 struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len)
00075 {
00076 struct wpabuf *buf = os_zalloc(sizeof(struct wpabuf));
00077 if (buf == NULL)
00078 return NULL;
00079
00080 buf->size = len;
00081 buf->used = len;
00082 buf->ext_data = data;
00083
00084 return buf;
00085 }
00086
00087
00088 struct wpabuf * wpabuf_alloc_copy(const void *data, size_t len)
00089 {
00090 struct wpabuf *buf = wpabuf_alloc(len);
00091 if (buf)
00092 wpabuf_put_data(buf, data, len);
00093 return buf;
00094 }
00095
00096
00097 struct wpabuf * wpabuf_dup(const struct wpabuf *src)
00098 {
00099 struct wpabuf *buf = wpabuf_alloc(wpabuf_len(src));
00100 if (buf)
00101 wpabuf_put_data(buf, wpabuf_head(src), wpabuf_len(src));
00102 return buf;
00103 }
00104
00105
00111 void wpabuf_free(struct wpabuf *buf)
00112 {
00113 if (buf == NULL)
00114 return;
00115 os_free(buf->ext_data);
00116 os_free(buf);
00117 }
00118
00119
00120 void * wpabuf_put(struct wpabuf *buf, size_t len)
00121 {
00122 void *tmp = wpabuf_mhead_u8(buf) + wpabuf_len(buf);
00123 buf->used += len;
00124 if (buf->used > buf->size) {
00125 wpabuf_overflow(buf, len);
00126 }
00127 return tmp;
00128 }
00129
00130
00141 struct wpabuf * wpabuf_concat(struct wpabuf *a, struct wpabuf *b)
00142 {
00143 struct wpabuf *n = NULL;
00144 size_t len = 0;
00145
00146 if (b == NULL)
00147 return a;
00148
00149 if (a)
00150 len += wpabuf_len(a);
00151 if (b)
00152 len += wpabuf_len(b);
00153
00154 n = wpabuf_alloc(len);
00155 if (n) {
00156 if (a)
00157 wpabuf_put_buf(n, a);
00158 if (b)
00159 wpabuf_put_buf(n, b);
00160 }
00161
00162 wpabuf_free(a);
00163 wpabuf_free(b);
00164
00165 return n;
00166 }
00167
00168
00182 struct wpabuf * wpabuf_zeropad(struct wpabuf *buf, size_t len)
00183 {
00184 struct wpabuf *ret;
00185 size_t blen;
00186
00187 if (buf == NULL)
00188 return NULL;
00189
00190 blen = wpabuf_len(buf);
00191 if (blen >= len)
00192 return buf;
00193
00194 ret = wpabuf_alloc(len);
00195 if (ret) {
00196 os_memset(wpabuf_put(ret, len - blen), 0, len - blen);
00197 wpabuf_put_buf(ret, buf);
00198 }
00199 wpabuf_free(buf);
00200
00201 return ret;
00202 }
00203
00204
00205 void wpabuf_printf(struct wpabuf *buf, char *fmt, ...)
00206 {
00207 va_list ap;
00208 void *tmp = wpabuf_mhead_u8(buf) + wpabuf_len(buf);
00209 int res;
00210
00211 va_start(ap, fmt);
00212 res = vsnprintf(tmp, buf->size - buf->used, fmt, ap);
00213 va_end(ap);
00214 if (res < 0 || (size_t) res >= buf->size - buf->used)
00215 wpabuf_overflow(buf, res);
00216 buf->used += res;
00217 }
00218