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