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