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