summaryrefslogtreecommitdiffstats
path: root/sys/netgraph
diff options
context:
space:
mode:
authorarchie <archie@FreeBSD.org>1999-12-01 19:41:15 +0000
committerarchie <archie@FreeBSD.org>1999-12-01 19:41:15 +0000
commitabcc28c7f8416570111b9f237ccac06a980119a1 (patch)
tree058a7b4594e9e2af1af786ebf8ac8f6995986c6b /sys/netgraph
parenta5c64fe8bbf78d360a1400b91af82ca843efc407 (diff)
downloadFreeBSD-src-abcc28c7f8416570111b9f237ccac06a980119a1.zip
FreeBSD-src-abcc28c7f8416570111b9f237ccac06a980119a1.tar.gz
Add more comments describing how to use parse types and how they work.
Diffstat (limited to 'sys/netgraph')
-rw-r--r--sys/netgraph/ng_parse.h211
1 files changed, 165 insertions, 46 deletions
diff --git a/sys/netgraph/ng_parse.h b/sys/netgraph/ng_parse.h
index 1efbdbe..0dbf769 100644
--- a/sys/netgraph/ng_parse.h
+++ b/sys/netgraph/ng_parse.h
@@ -47,10 +47,18 @@
This defines a library of routines for converting between various C
language types in binary form and ASCII strings. Types are user
- definable. Several pre-defined types are supplied, for some
- common C types: structures, variable and fixed length arrays,
- integer types, variable and fixed length strings, IP addresses,
- etc.
+ definable. Several pre-defined types are supplied, for some common
+ C types: structures, variable and fixed length arrays, integer types,
+ variable and fixed length strings, IP addresses, etc.
+
+ A netgraph node type may provide a list of types that correspond to
+ the structures it expects to send and receive in the arguments field
+ of a control message. This allows these messages to be converted
+ between their native binary form and the corresponding ASCII form.
+
+ A future use of the ASCII form may be for inter-machine communication
+ of control messages, because the ASCII form is machine independent
+ whereas the native binary form is not.
Syntax
------
@@ -77,32 +85,106 @@
That is, strings are specified just like C strings. The usual
backslash escapes are accepted.
- Other simple types have their obvious ASCII forms.
+ Other simple types (integers, IP addresses) have their obvious forms.
Example
-------
- Structure Binary (big endian)
- --------- -------------------
-
- struct foo {
- struct in_addr ip; 03 03 03 03
- int bar; 00 00 00 00
- u_char num; 02 00
- short ary[0]; 00 05 00 00 00 0a
- };
-
- ASCII form: "{ ip=3.3.3.3 num=3 ary=[ 5 2=10 ] }"
-
- Note that omitted fields or array elements get their default values
- ("bar" and ary[2]), and that the alignment is handled automatically
- (the extra 00 byte after "num").
+ Suppose we have a netgraph command that takes as an argument
+ a 'struct foo' shown below. Here is an example of a possible
+ value for the structure, and the corresponding ASCII encoding
+ of that value:
+
+ Structure Binary value
+ --------- ------------
+
+ struct foo {
+ struct in_addr ip; 01 02 03 04
+ int bar; 00 00 00 00
+ char label[8]; 61 62 63 0a 00 00 00 00
+ u_char alen; 03 00
+ short ary[0]; 05 00 00 00 0a 00
+ };
+
+ ASCII value
+ -----------
+
+ { ip=1.2.3.4 label="abc\n" alen=3 ary=[ 5 2=10 ] }
+
+ Note that omitted fields and array elements get their default
+ values ("bar" and ary[2]), and that the alignment is handled
+ automatically (the extra 00 byte after "num"). Also, since byte
+ order and alignment are inherently machine dependent, so is this
+ conversion process. The above example shows an x86 (little
+ endian) encoding. Also the above example is tricky because the
+ structure is variable length, depending on 'alen', the number of
+ elements in the array 'ary'.
+
+ Here is how one would define a parse type for the above structure,
+ subclassing the pre-defined types below. We construct the type in
+ a 'bottom up' fashion, defining each field's type first, then the
+ type for the whole structure ('//' comments used to avoid breakage).
+
+ // Super-type info for 'label' field
+ struct ng_parse_fixedsstring_info foo_label_info = { 8 };
+
+ // Parse type for 'label' field
+ struct ng_parse_type foo_label_type = {
+ &ng_parse_fixedstring_type // super-type
+ &foo_label_info // super-type info
+ };
+
+ #define OFFSETOF(s, e) ((char *)&((s *)0)->e - (char *)((s *)0))
+
+ // Function to compute the length of the array 'ary', which
+ // is variable length, depending on the previous field 'alen'.
+ // Upon entry 'buf' will be pointing at &ary[0].
+ int
+ foo_ary_getLength(const struct ng_parse_type *type,
+ const u_char *start, const u_char *buf)
+ {
+ const struct foo *f;
+
+ f = (const struct foo *)(buf - OFFSETOF(struct foo, ary));
+ return f->alen;
+ }
+
+ // Super-type info for 'ary' field
+ struct ng_parse_array_info foo_ary_info = {
+ &ng_parse_int16_type, // element type
+ &foo_ary_getLength // func to get array length
+ }
+
+ // Parse type for 'ary' field
+ struct ng_parse_type foo_ary_type = {
+ &ng_parse_array_type, // super-type
+ &foo_ary_info // super-type info
+ };
+
+ // Super-type info for struct foo
+ struct ng_parse_struct_info foo_fields = {
+ { "ip", &ng_parse_ipaddr_type },
+ { "bar", &ng_parse_int32_type },
+ { "label", &foo_label_type },
+ { "alen", &ng_parse_int8_type },
+ { "ary", &foo_ary_type },
+ { NULL }
+ };
+
+ // Parse type for struct foo
+ struct ng_parse_type foo_type = {
+ &ng_parse_struct_type, // super-type
+ &foo_fields // super-type info
+ };
To define a type, you can define it as a sub-type of a predefined
- type, overriding some of the predefined type's methods and/or its
- alignment, or define your own syntax, with the restriction that
- the ASCII representation must not contain any whitespace or these
- characters: { } [ ] = "
+ type as shown above, possibly overriding some of the predefined
+ type's methods, or define an entirely new syntax, with the restriction
+ that the ASCII representation of your type's value must not contain
+ any whitespace or any of these characters: { } [ ] = "
+
+ See ng_ksocket.c for an example of how to do this for 'struct sockaddr'.
+ See ng_parse.c to see implementations of the pre-defined types below.
*/
@@ -112,7 +194,8 @@
/*
* Three methods are required for a type. These may be given explicitly
- * or, if NULL, inherited from the super-type.
+ * or, if NULL, inherited from the super-type. The 'getDefault' method
+ * is always optional; the others are required if there is no super-type.
*/
struct ng_parse_type;
@@ -182,7 +265,16 @@ typedef int ng_getAlign_t(const struct ng_parse_type *type);
/*
* This structure describes a type, which may be a sub-type of another
- * type by pointing to it with 'supertype' and omitting one or more methods.
+ * type by pointing to it with 'supertype' and possibly omitting methods.
+ * Typically the super-type requires some type-specific info, which is
+ * supplied by the 'info' field.
+ *
+ * The 'private' field is ignored by all of the pre-defined types.
+ * Sub-types may use it as they see fit.
+ *
+ * The 'getDefault' method may always be omitted (even if there is no
+ * super-type), which means the value for any item of this type must
+ * always be explicitly given.
*/
struct ng_parse_type {
const struct ng_parse_type *supertype; /* super-type, if any */
@@ -199,7 +291,11 @@ struct ng_parse_type {
************************************************************************/
/*
- * Structures
+ * STRUCTURE TYPE
+ *
+ * This type supports arbitrary C structures. The normal field alignment
+ * rules for the local machine are applied. Fields are always parsed in
+ * field order, no matter what order they are listed in the ASCII string.
*
* Default value: Determined on a per-field basis
* Additional info: struct ng_parse_struct_info *
@@ -220,23 +316,26 @@ struct ng_parse_struct_info {
};
/*
- * Fixed length arrays
+ * FIXED LENGTH ARRAY TYPE
*
- * Default value: See below
+ * This type supports fixed length arrays, having any element type.
+ *
+ * Default value: As returned by getDefault for each index
* Additional info: struct ng_parse_fixedarray_info *
*/
extern const struct ng_parse_type ng_parse_fixedarray_type;
-typedef int ng_parse_array_getLength_t(const struct ng_parse_type *type,
- const u_char *start, const u_char *buf);
+/*
+ * Get the default value for the element at index 'index'. This method
+ * may be NULL, in which case the default value is computed from the
+ * element type. Otherwise, it should fill in the default value at *buf
+ * (having size *buflen) and update *buflen to the length of the filled-in
+ * value before return. If there is not enough routine return ERANGE.
+ */
typedef int ng_parse_array_getDefault_t(const struct ng_parse_type *type,
int index, const u_char *start,
u_char *buf, int *buflen);
-/* The 'getDefault' method may be NULL, in which case the default value
- is computed from the element type. If not, it should fill in the
- default value at *buf (having size *buflen) and update *buflen to the
- length of the filled-in value before return. */
struct ng_parse_fixedarray_info {
const struct ng_parse_type *elementType;
int length;
@@ -244,13 +343,25 @@ struct ng_parse_fixedarray_info {
};
/*
- * Variable length arrays
+ * VARIABLE LENGTH ARRAY TYPE
+ *
+ * Same as fixed length arrays, except that the length is determined
+ * by a function instead of a constant value.
*
* Default value: Same as with fixed length arrays
* Additional info: struct ng_parse_array_info *
*/
extern const struct ng_parse_type ng_parse_array_type;
+/*
+ * Return the length of the array. If the array is a field in a structure,
+ * all prior fields are guaranteed to be filled in already. Upon entry,
+ * 'start' is equal to the first byte parsed in this run, while 'buf' points
+ * to the first element of the array to be filled in.
+ */
+typedef int ng_parse_array_getLength_t(const struct ng_parse_type *type,
+ const u_char *start, const u_char *buf);
+
struct ng_parse_array_info {
const struct ng_parse_type *elementType;
ng_parse_array_getLength_t *getLength;
@@ -258,7 +369,9 @@ struct ng_parse_array_info {
};
/*
- * Arbitrary length strings
+ * ARBITRARY LENGTH STRING TYPE
+ *
+ * For arbirary length, NUL-terminated strings.
*
* Default value: Empty string
* Additional info: None required
@@ -266,8 +379,10 @@ struct ng_parse_array_info {
extern const struct ng_parse_type ng_parse_string_type;
/*
- * Bounded length strings. These are strings that have a fixed-size
- * buffer, and always include a terminating NUL character.
+ * BOUNDED LENGTH STRING TYPE
+ *
+ * These are strings that have a fixed-size buffer, and always include
+ * a terminating NUL character.
*
* Default value: Empty string
* Additional info: struct ng_parse_fixedsstring_info *
@@ -279,7 +394,7 @@ struct ng_parse_fixedsstring_info {
};
/*
- * Some commonly used bounded length string types
+ * COMMONLY USED BOUNDED LENGTH STRING TYPES
*/
extern const struct ng_parse_type ng_parse_nodebuf_type; /* NG_NODELEN + 1 */
extern const struct ng_parse_type ng_parse_hookbuf_type; /* NG_HOOKLEN + 1 */
@@ -288,7 +403,7 @@ extern const struct ng_parse_type ng_parse_typebuf_type; /* NG_TYPELEN + 1 */
extern const struct ng_parse_type ng_parse_cmdbuf_type; /* NG_CMDSTRLEN + 1 */
/*
- * Integer types
+ * INTEGER TYPES
*
* Default value: 0
* Additional info: None required
@@ -299,7 +414,7 @@ extern const struct ng_parse_type ng_parse_int32_type;
extern const struct ng_parse_type ng_parse_int64_type;
/*
- * IP address type
+ * IP ADDRESS TYPE
*
* Default value: 0.0.0.0
* Additional info: None required
@@ -307,9 +422,11 @@ extern const struct ng_parse_type ng_parse_int64_type;
extern const struct ng_parse_type ng_parse_ipaddr_type;
/*
- * Variable length byte array. The bytes are displayed in hex.
- * ASCII form may be either an array of bytes or a string constant,
- * in which case the array is zero-filled after the string bytes.
+ * VARIABLE LENGTH BYTE ARRAY TYPE
+ *
+ * The bytes are displayed in hex. The ASCII form may be either an
+ * array of bytes or a string constant, in which case the array is
+ * zero-filled after the string bytes.
*
* Default value: All bytes are zero
* Additional info: ng_parse_array_getLength_t *
@@ -317,7 +434,9 @@ extern const struct ng_parse_type ng_parse_ipaddr_type;
extern const struct ng_parse_type ng_parse_bytearray_type;
/*
- * Netgraph control message type
+ * NETGRAPH CONTROL MESSAGE TYPE
+ *
+ * This is the parse type for a struct ng_mesg.
*
* Default value: All fields zero
* Additional info: None required
OpenPOWER on IntegriCloud