5 * Copyright (c) 1999 Whistle Communications, Inc.
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.
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
37 * Author: Archie Cobbs <archie@freebsd.org>
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.2 2003/06/17 04:28:51 dillon Exp $
44 #ifndef _NETGRAPH_PARSE_H_
45 #define _NETGRAPH_PARSE_H_
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.
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.
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.
69 '{' [ <name>=<value> ... ] '}'
71 Omitted fields have their default values by implication.
72 The order in which the fields are specified does not matter.
76 '[' [ [index=]<value> ... ] ']'
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.
86 That is, strings are specified just like C strings. The usual
87 backslash escapes are accepted.
89 Other simple types (integers, IP addresses) have their obvious forms.
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
99 Structure Binary value
100 --------- ------------
103 struct in_addr ip; 01 02 03 04
105 char label[8]; 61 62 63 0a 00 00 00 00
107 short ary[0]; 05 00 00 00 0a 00
113 { ip=1.2.3.4 label="abc\n" alen=3 ary=[ 5 2=10 ] }
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 "num"). 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'.
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).
129 // Super-type info for 'label' field
130 struct ng_parse_fixedstring_info foo_label_info = { 8 };
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
138 #define OFFSETOF(s, e) ((char *)&((s *)0)->e - (char *)((s *)0))
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].
144 foo_ary_getLength(const struct ng_parse_type *type,
145 const u_char *start, const u_char *buf)
149 f = (const struct foo *)(buf - OFFSETOF(struct foo, ary));
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
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
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 },
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
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: { } [ ] = "
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.
192 /************************************************************************
193 METHODS REQUIRED BY A TYPE
194 ************************************************************************/
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.
202 struct ng_parse_type;
205 * Convert ASCII to binary according to the supplied type.
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).
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).
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
226 typedef 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);
231 * Convert binary to ASCII according to the supplied type.
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.
239 * ERANGE Output was longer than buflen bytes
241 typedef int ng_unparse_t(const struct ng_parse_type *type,
242 const u_char *data, int *off, char *buf, int buflen);
245 * Compute the default value according to the supplied type.
247 * Store the result in 'buf', which is at least *buflen bytes long.
248 * Upon return *buflen contains the length of the output.
252 * ERANGE Output was longer than *buflen bytes
253 * EOPNOTSUPP Default value is not specified for this type
255 typedef int ng_getDefault_t(const struct ng_parse_type *type,
256 const u_char *start, u_char *buf, int *buflen);
259 * Return the alignment requirement of this type. Zero is same as one.
261 typedef int ng_getAlign_t(const struct ng_parse_type *type);
263 /************************************************************************
265 ************************************************************************/
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.
273 * The 'private' field is ignored by all of the pre-defined types.
274 * Sub-types may use it as they see fit.
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.
280 struct 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 */
290 /************************************************************************
292 ************************************************************************/
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.
301 * Default value: Determined on a per-field basis
302 * Additional info: struct ng_parse_struct_field *
304 extern const struct ng_parse_type ng_parse_struct_type;
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. */
310 struct ng_parse_struct_field {
311 const char *name; /* field name */
312 const struct ng_parse_type *type; /* field type */
313 int alignment; /* override alignment */
317 * FIXED LENGTH ARRAY TYPE
319 * This type supports fixed length arrays, having any element type.
321 * Default value: As returned by getDefault for each index
322 * Additional info: struct ng_parse_fixedarray_info *
324 extern const struct ng_parse_type ng_parse_fixedarray_type;
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.
333 typedef 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);
337 struct ng_parse_fixedarray_info {
338 const struct ng_parse_type *elementType;
340 ng_parse_array_getDefault_t *getDefault;
344 * VARIABLE LENGTH ARRAY TYPE
346 * Same as fixed length arrays, except that the length is determined
347 * by a function instead of a constant value.
349 * Default value: Same as with fixed length arrays
350 * Additional info: struct ng_parse_array_info *
352 extern const struct ng_parse_type ng_parse_array_type;
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.
360 typedef int ng_parse_array_getLength_t(const struct ng_parse_type *type,
361 const u_char *start, const u_char *buf);
363 struct 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;
370 * ARBITRARY LENGTH STRING TYPE
372 * For arbirary length, NUL-terminated strings.
374 * Default value: Empty string
375 * Additional info: None required
377 extern const struct ng_parse_type ng_parse_string_type;
380 * BOUNDED LENGTH STRING TYPE
382 * These are strings that have a fixed-size buffer, and always include
383 * a terminating NUL character.
385 * Default value: Empty string
386 * Additional info: struct ng_parse_fixedstring_info *
388 extern const struct ng_parse_type ng_parse_fixedstring_type;
390 struct ng_parse_fixedstring_info {
391 int bufSize; /* size of buffer (including NUL) */
395 * COMMONLY USED BOUNDED LENGTH STRING TYPES
397 extern const struct ng_parse_type ng_parse_nodebuf_type; /* NG_NODELEN + 1 */
398 extern const struct ng_parse_type ng_parse_hookbuf_type; /* NG_HOOKLEN + 1 */
399 extern const struct ng_parse_type ng_parse_pathbuf_type; /* NG_PATHLEN + 1 */
400 extern const struct ng_parse_type ng_parse_typebuf_type; /* NG_TYPELEN + 1 */
401 extern const struct ng_parse_type ng_parse_cmdbuf_type; /* NG_CMDSTRLEN + 1 */
407 * Additional info: None required
409 extern const struct ng_parse_type ng_parse_int8_type;
410 extern const struct ng_parse_type ng_parse_int16_type;
411 extern const struct ng_parse_type ng_parse_int32_type;
412 extern const struct ng_parse_type ng_parse_int64_type;
414 /* Same thing but unparse as unsigned quantities */
415 extern const struct ng_parse_type ng_parse_uint8_type;
416 extern const struct ng_parse_type ng_parse_uint16_type;
417 extern const struct ng_parse_type ng_parse_uint32_type;
418 extern const struct ng_parse_type ng_parse_uint64_type;
420 /* Same thing but unparse as hex quantities, e.g., "0xe7" */
421 extern const struct ng_parse_type ng_parse_hint8_type;
422 extern const struct ng_parse_type ng_parse_hint16_type;
423 extern const struct ng_parse_type ng_parse_hint32_type;
424 extern const struct ng_parse_type ng_parse_hint64_type;
429 * Default value: 0.0.0.0
430 * Additional info: None required
432 extern const struct ng_parse_type ng_parse_ipaddr_type;
435 * VARIABLE LENGTH BYTE ARRAY TYPE
437 * The bytes are displayed in hex. The ASCII form may be either an
438 * array of bytes or a string constant, in which case the array is
439 * zero-filled after the string bytes.
441 * Default value: All bytes are zero
442 * Additional info: ng_parse_array_getLength_t *
444 extern const struct ng_parse_type ng_parse_bytearray_type;
447 * NETGRAPH CONTROL MESSAGE TYPE
449 * This is the parse type for a struct ng_mesg.
451 * Default value: All fields zero
452 * Additional info: None required
454 extern const struct ng_parse_type ng_parse_ng_mesg_type;
456 /************************************************************************
457 CONVERSTION AND PARSING ROUTINES
458 ************************************************************************/
460 /* Tokens for parsing structs and arrays */
461 enum ng_parse_token {
464 T_LBRACKET, /* '[' */
465 T_RBRACKET, /* ']' */
467 T_STRING, /* string in double quotes */
468 T_ERROR, /* error parsing string in double quotes */
469 T_WORD, /* anything else containing no whitespace */
470 T_EOF, /* end of string reached */
474 * See typedef ng_parse_t for definition
476 extern int ng_parse(const struct ng_parse_type *type, const char *string,
477 int *off, u_char *buf, int *buflen);
480 * See typedef ng_unparse_t for definition (*off assumed to be zero).
482 extern int ng_unparse(const struct ng_parse_type *type,
483 const u_char *data, char *buf, int buflen);
486 * See typedef ng_getDefault_t for definition
488 extern int ng_parse_getDefault(const struct ng_parse_type *type,
489 u_char *buf, int *buflen);
492 * Parse a token: '*startp' is the offset to start looking. Upon
493 * successful return, '*startp' equals the beginning of the token
494 * and '*lenp' the length. If error, '*startp' points at the
495 * offending character(s).
497 extern enum ng_parse_token ng_parse_get_token(const char *s,
498 int *startp, int *lenp);
501 * Like above, but specifically for getting a string token and returning
502 * the string value. The string token must be enclosed in double quotes
503 * and the normal C backslash escapes are recognized. The caller must
504 * eventually free() the returned result. Returns NULL if token is
505 * not a string token, or parse or other error.
507 extern char *ng_get_string_token(const char *s, int *startp, int *lenp);
510 * Convert a raw string into a doubly-quoted string including any
511 * necessary backslash escapes. Caller must free the result.
512 * Returns NULL if ENOMEM.
514 extern char *ng_encode_string(const char *s);
516 #endif /* _NETGRAPH_PARSE_H_ */