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