1/*
2 * ng_parse.h
3 */
4
5/*-
6 * Copyright (c) 1999 Whistle Communications, Inc.
7 * All rights reserved.
8 *
9 * Subject to the following obligations and disclaimer of warranty, use and
10 * redistribution of this software, in source or object code forms, with or
11 * without modifications are expressly permitted by Whistle Communications;
12 * provided, however, that:
13 * 1. Any and all reproductions of the source or object code must include the
14 *    copyright notice above and the following disclaimer of warranties; and
15 * 2. No rights are granted, in any manner or form, to use Whistle
16 *    Communications, Inc. trademarks, including the mark "WHISTLE
17 *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
18 *    such appears in the above copyright notice or in the software.
19 *
20 * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
21 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
22 * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
23 * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
25 * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
26 * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
27 * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
28 * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
29 * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
30 * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
31 * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
32 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
36 * OF SUCH DAMAGE.
37 *
38 * Author: Archie Cobbs <archie@freebsd.org>
39 *
40 * $Whistle: ng_parse.h,v 1.2 1999/11/29 01:43:48 archie Exp $
41 * $FreeBSD$
42 */
43
44#ifndef _NETGRAPH_NG_PARSE_H_
45#define _NETGRAPH_NG_PARSE_H_
46
47/*
48
49  This defines a library of routines for converting between various C
50  language types in binary form and ASCII strings.  Types are user
51  definable.  Several pre-defined types are supplied, for some common
52  C types: structures, variable and fixed length arrays, integer types,
53  variable and fixed length strings, IP addresses, etc.
54
55  A netgraph node type may provide a list of types that correspond to
56  the structures it expects to send and receive in the arguments field
57  of a control message.  This allows these messages to be converted
58  between their native binary form and the corresponding ASCII form.
59
60  A future use of the ASCII form may be for inter-machine communication
61  of control messages, because the ASCII form is machine independent
62  whereas the native binary form is not.
63
64  Syntax
65  ------
66
67    Structures:
68
69      '{' [ <name>=<value> ... ] '}'
70
71      Omitted fields have their default values by implication.
72      The order in which the fields are specified does not matter.
73
74    Arrays:
75
76      '[' [ [index=]<value> ... ] ']'
77
78      Element value may be specified with or without the "<index>=" prefix;
79      If omitted, the index after the previous element is used.
80      Omitted fields have their default values by implication.
81
82    Strings:
83
84      "foo bar blah\r\n"
85
86      That is, strings are specified just like C strings. The usual
87      backslash escapes are accepted.
88
89    Other simple types (integers, IP addresses) have their obvious forms.
90
91  Example
92  -------
93
94    Suppose we have a netgraph command that takes as an argument
95    a 'struct foo' shown below.  Here is an example of a possible
96    value for the structure, and the corresponding ASCII encoding
97    of that value:
98
99	Structure			Binary value
100	---------			------------
101
102	struct foo {
103	    struct in_addr ip;  	01 02 03 04
104	    int bar;			00 00 00 00
105	    char label[8];		61 62 63 0a 00 00 00 00
106	    u_char alen;		03 00
107	    short ary[];	  	05 00 00 00 0a 00
108	};
109
110	ASCII value
111	-----------
112
113	{ ip=1.2.3.4 label="abc\n" alen=3 ary=[ 5 2=10 ] }
114
115    Note that omitted fields and array elements get their default
116    values ("bar" and ary[2]), and that the alignment is handled
117    automatically (the extra 00 byte after "alen").  Also, since byte
118    order and alignment are inherently machine dependent, so is this
119    conversion process.  The above example shows an x86 (little
120    endian) encoding.  Also the above example is tricky because the
121    structure is variable length, depending on 'alen', the number of
122    elements in the array 'ary'.
123
124    Here is how one would define a parse type for the above structure,
125    subclassing the pre-defined types below.  We construct the type in
126    a 'bottom up' fashion, defining each field's type first, then the
127    type for the whole structure ('//' comments used to avoid breakage).
128
129    // Super-type info for 'label' field
130    struct ng_parse_fixedstring_info foo_label_info = { 8 };
131
132    // Parse type for 'label' field
133    struct ng_parse_type foo_label_type = {
134	    &ng_parse_fixedstring_type		// super-type
135	    &foo_label_info			// super-type info
136    };
137
138    #define OFFSETOF(s, e) ((char *)&((s *)0)->e - (char *)((s *)0))
139
140    // Function to compute the length of the array 'ary', which
141    // is variable length, depending on the previous field 'alen'.
142    // Upon entry 'buf' will be pointing at &ary[0].
143    int
144    foo_ary_getLength(const struct ng_parse_type *type,
145	    const u_char *start, const u_char *buf)
146    {
147	    const struct foo *f;
148
149	    f = (const struct foo *)(buf - OFFSETOF(struct foo, ary));
150	    return f->alen;
151    }
152
153    // Super-type info for 'ary' field
154    struct ng_parse_array_info foo_ary_info = {
155	    &ng_parse_int16_type,		// element type
156	    &foo_ary_getLength			// func to get array length
157    }
158
159    // Parse type for 'ary' field
160    struct ng_parse_type foo_ary_type = {
161	    &ng_parse_array_type,		// super-type
162	    &foo_ary_info			// super-type info
163    };
164
165    // Super-type info for struct foo
166    struct ng_parse_struct_field foo_fields[] = {
167	    { "ip",	&ng_parse_ipaddr_type	},
168	    { "bar",	&ng_parse_int32_type	},
169	    { "label",	&foo_label_type		},
170	    { "alen",	&ng_parse_uint8_type	},
171	    { "ary",	&foo_ary_type		},
172	    { NULL }
173    };
174
175    // Parse type for struct foo
176    struct ng_parse_type foo_type = {
177	    &ng_parse_struct_type,		// super-type
178	    &foo_fields				// super-type info
179    };
180
181  To define a type, you can define it as a sub-type of a predefined
182  type as shown above, possibly overriding some of the predefined
183  type's methods, or define an entirely new syntax, with the restriction
184  that the ASCII representation of your type's value must not contain
185  any whitespace or any of these characters: { } [ ] = "
186
187  See ng_ksocket.c for an example of how to do this for 'struct sockaddr'.
188  See ng_parse.c to see implementations of the pre-defined types below.
189
190*/
191
192/************************************************************************
193			METHODS REQUIRED BY A TYPE
194 ************************************************************************/
195
196/*
197 * Three methods are required for a type. These may be given explicitly
198 * or, if NULL, inherited from the super-type.  The 'getDefault' method
199 * is always optional; the others are required if there is no super-type.
200 */
201
202struct ng_parse_type;
203
204/*
205 * Convert ASCII to binary according to the supplied type.
206 *
207 * The ASCII characters begin at offset *off in 'string'.  The binary
208 * representation is put into 'buf', which has at least *buflen bytes.
209 * 'start' points to the first byte output by ng_parse() (ie, start <= buf).
210 *
211 * Upon return, *buflen contains the length of the new binary data, and
212 * *off is updated to point just past the end of the parsed range of
213 * characters, or, in the case of an error, to the offending character(s).
214 *
215 * Return values:
216 *	0		Success; *buflen holds the length of the data
217 *			and *off points just past the last char parsed.
218 *	EALREADY	Field specified twice
219 *	ENOENT		Unknown field
220 *	E2BIG		Array or character string overflow
221 *	ERANGE		Output was longer than *buflen bytes
222 *	EINVAL		Parse failure or other invalid content
223 *	ENOMEM		Out of memory
224 *	EOPNOTSUPP	Mandatory array/structure element missing
225 */
226typedef	int	ng_parse_t(const struct ng_parse_type *type, const char *string,
227			int *off, const u_char *start,
228			u_char *buf, int *buflen);
229
230/*
231 * Convert binary to ASCII according to the supplied type.
232 *
233 * The results are put into 'buf', which is at least buflen bytes long.
234 * *off points to the current byte in 'data' and should be updated
235 * before return to point just past the last byte unparsed.
236 *
237 * Returns:
238 *	0		Success
239 *	ERANGE		Output was longer than buflen bytes
240 */
241typedef	int	ng_unparse_t(const struct ng_parse_type *type,
242			const u_char *data, int *off, char *buf, int buflen);
243
244/*
245 * Compute the default value according to the supplied type.
246 *
247 * Store the result in 'buf', which is at least *buflen bytes long.
248 * Upon return *buflen contains the length of the output.
249 *
250 * Returns:
251 *	0		Success
252 *	ERANGE		Output was longer than *buflen bytes
253 *	EOPNOTSUPP	Default value is not specified for this type
254 */
255typedef	int	ng_getDefault_t(const struct ng_parse_type *type,
256			const u_char *start, u_char *buf, int *buflen);
257
258/*
259 * Return the alignment requirement of this type.  Zero is same as one.
260 */
261typedef	int	ng_getAlign_t(const struct ng_parse_type *type);
262
263/************************************************************************
264			TYPE DEFINITION
265 ************************************************************************/
266
267/*
268 * This structure describes a type, which may be a sub-type of another
269 * type by pointing to it with 'supertype' and possibly omitting methods.
270 * Typically the super-type requires some type-specific info, which is
271 * supplied by the 'info' field.
272 *
273 * The 'private' field is ignored by all of the pre-defined types.
274 * Sub-types may use it as they see fit.
275 *
276 * The 'getDefault' method may always be omitted (even if there is no
277 * super-type), which means the value for any item of this type must
278 * always be explicitly given.
279 */
280struct ng_parse_type {
281	const struct ng_parse_type *supertype;	/* super-type, if any */
282	const void		*info;		/* type-specific info */
283	void			*private;	/* client private info */
284	ng_parse_t		*parse;		/* parse method */
285	ng_unparse_t		*unparse;	/* unparse method */
286	ng_getDefault_t		*getDefault;	/* get default value method */
287	ng_getAlign_t		*getAlign;	/* get alignment */
288};
289
290/************************************************************************
291			PRE-DEFINED TYPES
292 ************************************************************************/
293
294/*
295 * STRUCTURE TYPE
296 *
297 * This type supports arbitrary C structures.  The normal field alignment
298 * rules for the local machine are applied.  Fields are always parsed in
299 * field order, no matter what order they are listed in the ASCII string.
300 *
301 *   Default value:		Determined on a per-field basis
302 *   Additional info:		struct ng_parse_struct_field *
303 */
304extern const struct ng_parse_type ng_parse_struct_type;
305
306/* Each field has a name, type, and optional alignment override. If the
307   override is non-zero, the alignment is determined from the field type.
308   Note: add an extra struct ng_parse_struct_field with name == NULL
309   to indicate the end of the list. */
310struct ng_parse_struct_field {
311	const char			*name;		/* field name */
312	const struct ng_parse_type	*type;		/* field type */
313	int				alignment;	/* override alignment */
314};
315
316/*
317 * FIXED LENGTH ARRAY TYPE
318 *
319 * This type supports fixed length arrays, having any element type.
320 *
321 *   Default value:		As returned by getDefault for each index
322 *   Additional info:		struct ng_parse_fixedarray_info *
323 */
324extern const struct ng_parse_type ng_parse_fixedarray_type;
325
326/*
327 * Get the default value for the element at index 'index'.  This method
328 * may be NULL, in which case the default value is computed from the
329 * element type.  Otherwise, it should fill in the default value at *buf
330 * (having size *buflen) and update *buflen to the length of the filled-in
331 * value before return.  If there is not enough routine return ERANGE.
332 */
333typedef	int	ng_parse_array_getDefault_t(const struct ng_parse_type *type,
334				int index, const u_char *start,
335				u_char *buf, int *buflen);
336
337struct ng_parse_fixedarray_info {
338	const struct ng_parse_type	*elementType;
339	int				length;
340	ng_parse_array_getDefault_t	*getDefault;
341};
342
343/*
344 * VARIABLE LENGTH ARRAY TYPE
345 *
346 * Same as fixed length arrays, except that the length is determined
347 * by a function instead of a constant value.
348 *
349 *   Default value:		Same as with fixed length arrays
350 *   Additional info:		struct ng_parse_array_info *
351 */
352extern const struct ng_parse_type ng_parse_array_type;
353
354/*
355 * Return the length of the array.  If the array is a field in a structure,
356 * all prior fields are guaranteed to be filled in already.  Upon entry,
357 * 'start' is equal to the first byte parsed in this run, while 'buf' points
358 * to the first element of the array to be filled in.
359 */
360typedef int	ng_parse_array_getLength_t(const struct ng_parse_type *type,
361				const u_char *start, const u_char *buf);
362
363struct ng_parse_array_info {
364	const struct ng_parse_type	*elementType;
365	ng_parse_array_getLength_t	*getLength;
366	ng_parse_array_getDefault_t	*getDefault;
367};
368
369/*
370 * ARBITRARY LENGTH STRING TYPE
371 *
372 * For arbirary length, NUL-terminated strings.
373 *
374 *   Default value:		Empty string
375 *   Additional info:		None required
376 */
377extern const struct ng_parse_type ng_parse_string_type;
378
379/*
380 * BOUNDED LENGTH STRING TYPE
381 *
382 * These are strings that have a fixed-size buffer, and always include
383 * a terminating NUL character.
384 *
385 *   Default value:		Empty string
386 *   Additional info:		struct ng_parse_fixedstring_info *
387 */
388extern const struct ng_parse_type ng_parse_fixedstring_type;
389
390struct ng_parse_fixedstring_info {
391	int	bufSize;	/* size of buffer (including NUL) */
392};
393
394/*
395 * EXPLICITLY SIZED STRING TYPE
396 *
397 * These are strings that have a two byte length field preceding them.
398 * Parsed strings are NOT NUL-terminated.
399 *
400 *   Default value:		Empty string
401 *   Additional info:		None
402 */
403extern const struct ng_parse_type ng_parse_sizedstring_type;
404
405/*
406 * COMMONLY USED BOUNDED LENGTH STRING TYPES
407 */
408extern const struct ng_parse_type ng_parse_nodebuf_type;  /* NG_NODESIZ */
409extern const struct ng_parse_type ng_parse_hookbuf_type;  /* NG_HOOKSIZ */
410extern const struct ng_parse_type ng_parse_pathbuf_type;  /* NG_PATHSIZ */
411extern const struct ng_parse_type ng_parse_typebuf_type;  /* NG_TYPESIZ */
412extern const struct ng_parse_type ng_parse_cmdbuf_type;   /* NG_CMDSTRSIZ */
413
414/*
415 * INTEGER TYPES
416 *
417 *   Default value:		0
418 *   Additional info:		None required
419 */
420extern const struct ng_parse_type ng_parse_int8_type;
421extern const struct ng_parse_type ng_parse_int16_type;
422extern const struct ng_parse_type ng_parse_int32_type;
423extern const struct ng_parse_type ng_parse_int64_type;
424
425/* Same thing but unparse as unsigned quantities */
426extern const struct ng_parse_type ng_parse_uint8_type;
427extern const struct ng_parse_type ng_parse_uint16_type;
428extern const struct ng_parse_type ng_parse_uint32_type;
429extern const struct ng_parse_type ng_parse_uint64_type;
430
431/* Same thing but unparse as hex quantities, e.g., "0xe7" */
432extern const struct ng_parse_type ng_parse_hint8_type;
433extern const struct ng_parse_type ng_parse_hint16_type;
434extern const struct ng_parse_type ng_parse_hint32_type;
435extern const struct ng_parse_type ng_parse_hint64_type;
436
437/*
438 * IP ADDRESS TYPE
439 *
440 *   Default value:		0.0.0.0
441 *   Additional info:		None required
442 */
443extern const struct ng_parse_type ng_parse_ipaddr_type;
444
445/*
446 * ETHERNET ADDRESS TYPE
447 *
448 *   Default value:		None
449 *   Additional info:		None required
450 */
451extern const struct ng_parse_type ng_parse_enaddr_type;
452
453/*
454 * VARIABLE LENGTH BYTE ARRAY TYPE
455 *
456 * The bytes are displayed in hex.  The ASCII form may be either an
457 * array of bytes or a string constant, in which case the array is
458 * zero-filled after the string bytes.
459 *
460 *   Default value:		All bytes are zero
461 *   Additional info:		ng_parse_array_getLength_t *
462 */
463extern const struct ng_parse_type ng_parse_bytearray_type;
464
465/*
466 * NETGRAPH CONTROL MESSAGE TYPE
467 *
468 * This is the parse type for a struct ng_mesg.
469 *
470 *   Default value:		All fields zero
471 *   Additional info:		None required
472 */
473extern const struct ng_parse_type ng_parse_ng_mesg_type;
474
475/************************************************************************
476		CONVERSTION AND PARSING ROUTINES
477 ************************************************************************/
478
479/* Tokens for parsing structs and arrays */
480enum ng_parse_token {
481	T_LBRACE,		/* '{' */
482	T_RBRACE,		/* '}' */
483	T_LBRACKET,		/* '[' */
484	T_RBRACKET,		/* ']' */
485	T_EQUALS,		/* '=' */
486	T_STRING,		/* string in double quotes */
487	T_ERROR,		/* error parsing string in double quotes */
488	T_WORD,			/* anything else containing no whitespace */
489	T_EOF,			/* end of string reached */
490};
491
492/*
493 * See typedef ng_parse_t for definition
494 */
495extern int	ng_parse(const struct ng_parse_type *type, const char *string,
496			int *off, u_char *buf, int *buflen);
497
498/*
499 * See typedef ng_unparse_t for definition (*off assumed to be zero).
500 */
501extern int	ng_unparse(const struct ng_parse_type *type,
502			const u_char *data, char *buf, int buflen);
503
504/*
505 * See typedef ng_getDefault_t for definition
506 */
507extern int	ng_parse_getDefault(const struct ng_parse_type *type,
508			u_char *buf, int *buflen);
509
510/*
511 * Parse a token: '*startp' is the offset to start looking.  Upon
512 * successful return, '*startp' equals the beginning of the token
513 * and '*lenp' the length.  If error, '*startp' points at the
514 * offending character(s).
515 */
516extern enum	ng_parse_token ng_parse_get_token(const char *s,
517			int *startp, int *lenp);
518
519/*
520 * Like above, but specifically for getting a string token and returning
521 * the string value.  The string token must be enclosed in double quotes
522 * and the normal C backslash escapes are recognized.  The caller must
523 * eventually free() the returned result.  Returns NULL if token is
524 * not a string token, or parse or other error. Otherwise, *lenp contains
525 * the number of characters parsed, and *slenp (if not NULL) contains
526 * the actual number of characters in the parsed string.
527 */
528extern char	*ng_get_string_token(const char *s, int *startp,
529			int *lenp, int *slenp);
530
531/*
532 * Convert a raw string into a doubly-quoted string including any
533 * necessary backslash escapes.  Caller must free the result.
534 * Returns NULL if ENOMEM. Normally "slen" should equal strlen(s)
535 * unless you want to encode NUL bytes.
536 */
537extern char	*ng_encode_string(const char *s, int slen);
538
539#endif /* _NETGRAPH_NG_PARSE_H_ */
540
541