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