Annotation of embedaddon/libpdel/structs/type/structs_type_data.c, revision 1.1.1.1
1.1 misho 1:
2: /*
3: * Copyright (c) 2001-2002 Packet Design, LLC.
4: * All rights reserved.
5: *
6: * Subject to the following obligations and disclaimer of warranty,
7: * use and redistribution of this software, in source or object code
8: * forms, with or without modifications are expressly permitted by
9: * Packet Design; provided, however, that:
10: *
11: * (i) Any and all reproductions of the source or object code
12: * must include the copyright notice above and the following
13: * disclaimer of warranties; and
14: * (ii) No rights are granted, in any manner or form, to use
15: * Packet Design trademarks, including the mark "PACKET DESIGN"
16: * on advertising, endorsements, or otherwise except as such
17: * appears in the above copyright notice or in the software.
18: *
19: * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
20: * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
21: * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
22: * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
23: * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
24: * OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
25: * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
26: * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
27: * RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE
28: * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
29: * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
30: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
31: * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
32: * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
33: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
35: * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
36: * THE POSSIBILITY OF SUCH DAMAGE.
37: *
38: * Author: Archie Cobbs <archie@freebsd.org>
39: */
40:
41: #include <sys/types.h>
42: #include <sys/socket.h>
43: #include <netinet/in.h>
44: #include <arpa/inet.h>
45: #include <net/ethernet.h>
46:
47: #include <stdlib.h>
48: #include <stdio.h>
49: #include <stdarg.h>
50: #include <string.h>
51: #include <limits.h>
52: #include <assert.h>
53: #include <ctype.h>
54: #include <errno.h>
55: #include <time.h>
56:
57: #include "structs/structs.h"
58: #include "structs/type/array.h"
59: #include "structs/type/data.h"
60: #include "io/filter.h"
61: #include "io/base64.h"
62: #include "util/typed_mem.h"
63:
64: #define HEXVAL(c) (isdigit(c) ? (c) - '0' : tolower(c) - 'a' + 10)
65:
66: static const char hexchars[] = "0123456789abcdef";
67:
68: /*********************************************************************
69: BINARY DATA TYPE
70: *********************************************************************/
71:
72: int
73: structs_data_copy(const struct structs_type *type, const void *from, void *to)
74: {
75: const char *const mtype = type->args[1].v;
76: const struct structs_data *const fdata = from;
77: struct structs_data *const tdata = to;
78: u_char *copy;
79:
80: if (fdata->length == 0) {
81: memset(tdata, 0, sizeof(*tdata));
82: return (0);
83: }
84: if ((copy = MALLOC(mtype, fdata->length)) == NULL)
85: return (-1);
86: memcpy(copy, fdata->data, fdata->length);
87: tdata->data = copy;
88: tdata->length = fdata->length;
89: return (0);
90: }
91:
92: int
93: structs_data_equal(const struct structs_type *type,
94: const void *v1, const void *v2)
95: {
96: const struct structs_data *const d1 = v1;
97: const struct structs_data *const d2 = v2;
98:
99: return (d1->length == d2->length
100: && memcmp(d1->data, d2->data, d1->length) == 0);
101: }
102:
103: char *
104: structs_data_ascify(const struct structs_type *type,
105: const char *mtype, const void *data)
106: {
107: const char *const charmap = type->args[0].v;
108: const struct structs_data *const d = data;
109: struct filter *encoder;
110: char *edata;
111: int elen;
112: int i;
113:
114: /* Handle hex encoding */
115: if (charmap != NULL && *charmap == '\0') {
116: if ((edata = MALLOC(mtype, d->length * 2 + 1)) == NULL)
117: return (NULL);
118: for (i = 0; i < d->length; i++) {
119: edata[i * 2] = hexchars[(d->data[i] >> 4) & 0x0f];
120: edata[i * 2 + 1] = hexchars[d->data[i] & 0x0f];
121: }
122: edata[i * 2] = '\0';
123: return (edata);
124: }
125:
126: /* Get encoding filter */
127: if ((encoder = b64_encoder_create(charmap)) == NULL)
128: return (NULL);
129:
130: /* Encode data */
131: elen = filter_process(encoder, d->data,
132: d->length, 1, (u_char **)&edata, mtype);
133: filter_destroy(&encoder);
134: if (elen == -1)
135: return (NULL);
136:
137: /* Return encoded data as a string */
138: edata[elen] = '\0';
139: return (edata);
140: }
141:
142: int
143: structs_data_binify(const struct structs_type *type,
144: const char *ascii, void *data, char *ebuf, size_t emax)
145: {
146: const char *const charmap = type->args[0].v;
147: const char *const mtype = type->args[1].v;
148: struct structs_data *const d = data;
149: struct filter *decoder;
150: u_char *bdata;
151: int blen;
152: int i;
153:
154: /* Handle hex encoding */
155: if (charmap != NULL && *charmap == '\0') {
156: if ((bdata = MALLOC(mtype, (strlen(ascii) + 1) / 2)) == NULL)
157: return (-1);
158: for (blen = 0; *ascii != '\0'; blen++) {
159: while (isspace(*ascii))
160: ascii++;
161: if (*ascii == '\0')
162: break;
163: bdata[blen] = 0;
164: for (i = 4; i >= 0; i -= 4) {
165: if (!isxdigit(*ascii)) {
166: strlcpy(ebuf, *ascii == '\0' ?
167: "odd length hex sequence" :
168: "non-hex character seen", emax);
169: FREE(mtype, bdata);
170: return (-1);
171: }
172: bdata[blen] |= HEXVAL(*ascii) << i;
173: ascii++;
174: }
175: }
176: goto done;
177: }
178:
179: /* Get decoding filter */
180: if ((decoder = b64_decoder_create(charmap, 1)) == NULL)
181: return (-1);
182:
183: /* Decode data */
184: blen = filter_process(decoder, ascii, strlen(ascii), 1, &bdata, mtype);
185: filter_destroy(&decoder);
186: if (blen == -1) {
187: strlcpy(ebuf, "invalid encoded binary data", emax);
188: return (-1);
189: }
190:
191: done:
192: /* Fill in structure */
193: d->length = blen;
194: d->data = bdata;
195: return (0);
196: }
197:
198: void
199: structs_data_free(const struct structs_type *type, void *data)
200: {
201: const char *const mtype = type->args[1].v;
202: struct structs_data *const d = data;
203:
204: FREE(mtype, d->data);
205: memset(d, 0, sizeof(*d));
206: }
207:
208: int
209: structs_data_encode(const struct structs_type *type, const char *mtype,
210: struct structs_data *code, const void *data)
211: {
212: const struct structs_data *const d = data;
213: u_int32_t elength;
214:
215: if ((code->data = MALLOC(mtype, 4 + d->length)) == NULL)
216: return (-1);
217: elength = htonl(d->length);
218: memcpy(code->data, &elength, 4);
219: memcpy(code->data + 4, d->data, d->length);
220: code->length = 4 + d->length;
221: return (0);
222: }
223:
224: int
225: structs_data_decode(const struct structs_type *type, const u_char *code,
226: size_t cmax, void *data, char *ebuf, size_t emax)
227: {
228: const char *const mtype = type->args[1].v;
229: struct structs_data *const d = data;
230: u_int32_t elength;
231:
232: if (cmax < 4)
233: goto bogus;
234: memcpy(&elength, code, 4);
235: d->length = ntohl(elength);
236: if (cmax < d->length) {
237: bogus: strlcpy(ebuf, "encoded data is corrupted", emax);
238: errno = EINVAL;
239: return (-1);
240: }
241: if ((d->data = MALLOC(mtype, d->length)) == NULL)
242: return (-1);
243: memcpy(d->data, code + 4, d->length);
244: return (4 + d->length);
245: }
246:
247: const struct structs_type structs_type_data =
248: STRUCTS_DATA_TYPE(NULL, STRUCTS_DATA_MEMTYPE);
249:
250: const struct structs_type structs_type_hexdata =
251: STRUCTS_DATA_TYPE("", STRUCTS_DATA_MEMTYPE);
252:
253: /*********************************************************************
254: FIXED LENGTH BINARY DATA TYPE
255: *********************************************************************/
256:
257: char *
258: structs_fixeddata_ascify(const struct structs_type *type,
259: const char *mtype, const void *data)
260: {
261: const u_char *bytes = data;
262: char *s;
263: int i;
264:
265: if ((s = MALLOC(mtype, type->size * 2 + 1)) == NULL)
266: return (NULL);
267: for (i = 0; i < type->size; i++) {
268: s[i * 2] = hexchars[(bytes[i] >> 4) & 0x0f];
269: s[i * 2 + 1] = hexchars[bytes[i] & 0x0f];
270: }
271: s[i * 2] = '\0';
272: return (s);
273: }
274:
275: int
276: structs_fixeddata_binify(const struct structs_type *type,
277: const char *ascii, void *data, char *ebuf, size_t emax)
278: {
279: u_char *bytes = data;
280: int i;
281: int j;
282:
283: for (i = 0; i < type->size; i++) {
284: bytes[i] = 0;
285: for (j = 4; j >= 0; j -= 4) {
286: while (isspace(*ascii))
287: ascii++;
288: if (!isxdigit(*ascii)) {
289: strlcpy(ebuf, *ascii == '\0' ?
290: "hex string is too short" :
291: "non-hex character seen", emax);
292: goto fail;
293: }
294: bytes[i] |= HEXVAL(*ascii) << j;
295: ascii++;
296: }
297: }
298: while (isspace(*ascii))
299: ascii++;
300: if (*ascii != '\0') {
301: strlcpy(ebuf, "hex string is too long", emax);
302: fail: errno = EINVAL;
303: return (-1);
304: }
305: return (0);
306: }
307:
308: int
309: structs_fixeddata_encode(const struct structs_type *type, const char *mtype,
310: struct structs_data *code, const void *data)
311: {
312: if ((code->data = MALLOC(mtype, type->size)) == NULL)
313: return (-1);
314: memcpy(code->data, data, type->size);
315: code->length = type->size;
316: return (0);
317: }
318:
319: int
320: structs_fixeddata_decode(const struct structs_type *type, const u_char *code,
321: size_t cmax, void *data, char *ebuf, size_t emax)
322: {
323: if (cmax < type->size) {
324: strlcpy(ebuf, "encoded data is truncated", emax);
325: errno = EINVAL;
326: return (-1);
327: }
328: memcpy(data, code, type->size);
329: return (type->size);
330: }
331:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>