Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / network / stacks / AROSTCP / dhcp / doc / api+protocol
blob48569f21b74412de9b84b791c6d5f0a417707610
1 This file documents the protocol that the ISC DHCP server and ISC
2 Object Management clients (clients that use the ISC Object Management
3 API) speak between one another.
5 Protocol:
7 All multi-byte numbers are represented in network byte order.
9 On startup, each side sends a status message indicating what version
10 of the protocol they are speaking.   The status message looks like
11 this:
13 +---------+---------+
14 | version | hlength |
15 +---------+---------+
17 version - a 32-bit fixed-point number with the decimal point between
18           the third and second decimal digits from the left,
19           representing the version of the protocol.   The current
20           protocol version is 1.00.   If the field were considered as
21           a 32-bit integer, this would correspond to a value of 100
22           decimal, or 0x64.
24 hlength - a 32-bit integer representing the length of the fixed-length
25           header in subsequent messages.   This is normally 56, but
26           can be changed to a value larger than 56 by either side
27           without upgrading the revision number.
30 The startup message is not authenticated.   Either side may reject the
31 other side's startup message as invalid by simply closing the
32 connection.   The only fixed part of the startup message is the
33 version number - future versions may delete hlength, or add further
34 startup information.
36 Following the startup message, all messages have the same format.
37 Currently, the format includes a fixed-length header (the length in
38 hlength, above)
40 +--------+----+--------+----+-----+---------+------------+------------+-----+
41 | authid | op | handle | id | rid | authlen | msg values | obj values | sig |
42 +--------+----+--------+----+-----+---------+------------+------------+-----+
44 The fixed-length header consists of:
46 authid = a 32-bit authenticator handle.
47         For an original message (one not in response to some other
48         message), this will be chosen by the originator.   For a
49         message in response to another message, the authenticator for
50         that message is used, except if the response is an error
51         message indicating that the authenticator used was unknown,
52         in which case the null authenticator is used.   Messages that
53         are generated as the result of a notify registration use the
54         authenticator used in the original notify registration.
55         The authenticator itself is generated by having one side of
56         the connection send an object of type "authenticator" to the
57         other side with values that indicate what kind of
58         authentication mechanism to use and what key to use.   The two
59         most likely things here are a Kerberos V principal name or the
60         name of a shared secret that can be used to calculate an MD5
61         hash.   The mechanism for doing this has yet to be finalized.
62         If authid is zero, the message is not authenticated.
64 op = 32-bit opcode, one of:
65         open = 1
66         refresh = 2
67         update = 3
68         notify = 4
69         error = 5
70         delete = 6
71 handle = 32-bit object handle
72         A handle on the object being opened, created, refreshed or
73         updated.   If no handle is yet available (e.g., with open and
74         new), then the value zero is sent.
75 id = 32-bit transaction id of the message - a monotonically increasing
76      number that starts with some randomly chosen number at the
77      beginning of the life of the connection.   The value should never
78      be zero.
79 rid = 32-bit transaction ID of the message to which this message is a
80       response, or zero if this message is not in response to a
81       message from the other side.
83 authlen = a 32-bit number representing the length of the authenticator
85 msg values = a series of name+value pairs, specific to this message.
86          Each name+value pair starts with a 16-bit name length,
87          followed by that many bytes of name, followed by a 32-bit
88          value length, followed by that many bytes of value.   If the
89          length is zero, this is a value of the blank string.   If the
90          length is all ones (2^32-1), then there is no value - for an
91          update, this means the value for this name and the name
92          itself should be deleted from the object, which may or may
93          not be possible.   The list of name/value pairs ends with a
94          zero-length name, which is not followed by a value
95          length/value pair.
97 obj values = a series of name+value pairs, as above, specific to the
98         object being created, updated or refreshed.
100 signature = authlen bytes of data signing the message.   The signature
101             algorithm is a property of the authenticator handle.
103 Message types:
105 1: open
106    relevant input values:
107         object-type = the name of the type of object
108         open:create = boolean - create the object if it doesn't yet exist
109         open:exclusive = boolean - don't open the object if it does exist
110         open:update = boolean - update the object with included values
111                       if it matches.
112         the handle should always be the null handle
114    The input value must also contain key information for the type of
115    object being searched that uniquely identifies an object, or search
116    information that matches only one object.  Each object has a key
117    specification (a key is something that uniquely identifies an
118    object), so see the key specification for that object to see
119    what to send here.   An open message with the create flag set must
120    specify a key, and not merely matching criteria.   Some objects may
121    allow more than one key, and it may be that the union of those keys
122    is required to uniquely identify the object, or it may be that any
123    one such key will uniquely identify the object.   The documentation
124    for the type of object will specify this.
126    An open message will result in an immediate response message whose
127    opcode will either be "error" or "update".   The error message may
128    include an error:reason value containing a text string explaining
129    the error, and will always include an error:code value which will
130    be the numeric error code for what went wrong.   Possible error
131    codes are:
133         not found - no such object exists
134         already exists - object already exists, and exclusive flag was
135                          set.
136         not unique - more than one object matching the specification
137                      exists.
138         permission denied - the authenticator ID specified does not
139                             have authorization to access this object,
140                             or if the update flag was specified, to
141                             update the object.
143    If the response is an update message, the update message will
144    include the object handle and all of the name/value pairs
145    associated with that object.
147 2: refresh
149    no input values except the handle need be specified.   The null
150    handle may not be specified.   If the handle is valid, and the
151    authenticator ID specified has permission to examine the object,
152    then an update message will be sent for that object.   Otherwise,
153    one of the following errors will be sent:
155         invalid handle - the handle does not refer to a known object
156         permisson denied - the handle refers to an object that the
157                            requestor does not have permission to
158                            examine. 
160 3: update
162    Requests that the contents of the specified object be updated with
163    the values included.   Values that are not specified are not
164    updated.   The response will be either an error message or an
165    update-ok message.   If rid is nonzero, no response will be
166    generated, even if there was an error.   Possible errors include:
168         invalid handle - no such object was found
169         permission denied - the handle refers to an object that the
170                             requestor does not have permission to
171                             modify.
172         not confirmed - the update could not be committed due to some
173                         kind of resource problem, for example
174                         insufficient memory or a disk failure.
176 4: notify
178    Requests that whenever the object with the specified handle is
179    modified, an update be sent.   If there is something wrong with the
180    request, an error message will be returned immediately.
181    Otherwise, whenever a change is made to the object, an update
182    message will be sent containing whatever changes were made (or
183    possibly all the values associated with the object, depending on
184    the implementation).   Possible errors:
186         invalid handle
187         permission denied - the handle refers to an object that the
188                             requestor does not have permission to
189                             examine.
190         not supported - the object implementation does not support
191                         notifications
193 5: status
195    Sends a status code in response to a message.  Always sent in
196    response to a message sent by the other side.  There should never
197    be a response to this message.
199 6: delete
201    Deletes the specified object.   Response will be either request-ok,
202    or error.   Possible errors include:
204         invalid handle - no such object was found
205         permission denied - the handle refers to an object that the
206                             requestor does not have permission to
207                             modify.
208         not confirmed - the deletion could not be committed due to
209                         some kind of resource problem, for example
210                         insufficient memory or a disk failure.
212 7: notify-cancel
214    Like notify, but requests that an existing notification be cancelled.
216 8: notify-cancelled
218    Indicates that because of a local change, a notification that had
219    been registered can no longer be performed.   This could be as a
220    result of the permissions on a object changing, or an object being
221    deleted.   There should never be a response to this message.
223 internals:
225 Both client and server use same protocol and infrastructure.   There
226 are many object types, each of which is stored in a registry.
227 Objects whose type is not recognized can either be handled by the
228 generic object type, which is registered with the type "*".   If no
229 generic object type is registered, then objects with unknown types are
230 simply not supported.   On the client, there are probably no special
231 object handlers (although this is by no means forbidden).   On the
232 server, probably everything is a special object.
234 Each object type has the following methods:
239 dhcpctl_status dhcpctl_connect (dhcpctl_handle *connection,
240                                 char *server_name, int port,
241                                 dhcpctl_handle *authinfo)
242         synchronous
243         returns nonzero status code if it didn't connect, zero otherwise
244         stores connection handle through connection, which can be used
245         for subsequent access to the specified server. 
246         server_name is the name of the server, and port is the TCP
247         port on which it is listening.
248         authinfo is the handle to an object containing authentication
249         information.
251 dhcpctl_status dhcpctl_open_object (dhcpctl_handle h,
252                                     dhcpctl_handle connection,
253                                     int flags)
254         asynchronous - just queues the request
255         returns nonzero status code if open couldn't be queued
256         returns zero if open was queued
257         h is a handle to an object created by dhcpctl_new_object
258         connection is a connection to a DHCP server
259         flags include:
260            DHCPCTL_CREATE - if the object doesn't exist, create it
261            DHCPCTL_UPDATE - update the object on the server using the
262                             attached parameters 
263            DHCPCTL_EXCL - error if the object exists and DHCPCTL_CREATE
264                           was also specified
266 dhcpctl_status dhcpctl_new_object (dhcpctl_handle *h,
267                                    dhcpctl_handle connection,
268                                    char *object_type)
269         synchronous - creates a local handle for a host entry.
270         returns nonzero status code if the local host entry couldn't
271         be created
272         stores handle to host through h if successful, and returns zero.
273         object_type is a pointer to a NUL-terminated string containing
274         the ascii name of the type of object being accessed - e.g., "host"
276 dhcpctl_status dhcpctl_set_callback (dhcpctl_handle h, void *data,
277                                      void (*callback) (dhcpctl_handle,
278                                                        dhcpctl_status, void *))
279         synchronous, with asynchronous aftereffect
280         handle is some object upon which some kind of process has been
281         started - e.g., an open, an update or a refresh.
282         data is an anonymous pointer containing some information that
283         the callback will use to figure out what event completed.
284         return value of 0 means callback was successfully set, a nonzero
285         status code is returned otherwise.
286         Upon completion of whatever task is in process, the callback
287         will be passed the handle to the object, a status code
288         indicating what happened, and the anonymous pointer passed to 
290 dhcpctl_status dhcpctl_wait_for_completion (dhcpctl_handle h,
291                                             dhcpctl_status *s)
292         synchronous
293         returns zero if the callback completes, a nonzero status if
294         there was some problem relating to the wait operation.   The
295         status of the queued request will be stored through s, and
296         will also be either zero for success or nonzero for some kind
297         of failure.    Never returns until completion or until the
298         connection to the server is lost.   This performs the same
299         function as dhcpctl_set_callback and the subsequent callback,
300         for programs that want to do inline execution instead of using
301         callbacks.
303 dhcpctl_status dhcpctl_get_value (data_string *result,
304                                   dhcpctl_handle h, char *value_name)
305         synchronous
306         returns zero if the call succeeded, a nonzero status code if
307         it didn't. 
308         result is the address of an empty data string (initialized
309         with bzero or cleared with data_string_forget).   On
310         successful completion, the addressed data string will contain
311         the value that was fetched.
312         dhcpctl_handle refers to some dhcpctl item
313         value_name refers to some value related to that item - e.g.,
314         for a handle associated with a completed host lookup, value
315         could be one of "hardware-address", "dhcp-client-identifier",
316         "known" or "client-hostname".
318 dhcpctl_status dhcpctl_get_boolean (int *result,
319                                     dhcpctl_handle h, char *value_name)
320         like dhcpctl_get_value, but more convenient for boolean
321         values, since no data_string needs to be dealt with.
323 dhcpctl_status dhcpctl_set_value (dhcpctl_handle h, data_string value,
324                                   char *value_name)
325         Sets a value on an object referred to by a dhcpctl_handle.
326         The opposite of dhcpctl_get_value.   Does not update the
327         server - just sets the value on the handle.
329 dhcpctl_status dhcpctl_set_string_value (dhcpctl_handle h, char *value,
330                                          char *value_name)
331         Sets a NUL-terminated ASCII value on an object referred to by
332         a dhcpctl_handle.   like dhcpctl_set_value, but saves the
333         trouble of creating a data_string for a NUL-terminated string.
334         Does not update the server - just sets the value on the handle.
336 dhcpctl_status dhcpctl_set_boolean (dhcpctl_handle h, int value,
337                                     char *value_name)
338         Sets a boolean value on an object - like dhcpctl_set_value,
339         only more convenient for booleans.
341 dhcpctl_status dhcpctl_object_update (dhcpctl_handle h)
342         Queues an update on the object referenced by the handle (there
343         can't be any other work in progress on the handle).   An
344         update means local parameters will be sent to the server.
346 dhcpctl_status dhcpctl_object_refresh (dhcpctl_handle h)
347         Queues an update on the object referenced by the handle (there
348         can't be any other work in progress on the handle).   An
349         update means local parameters will be sent to the server.
351 dhcpctl_status dhcpctl_object_delete (dhcpctl_handle h)
352         Queues a delete of the object referenced by the handle (there
353         can't be any other work in progress on the handle).   A
354         delete means that the object will be permanently deleted on
355         the remote end, assuming the remote end supports object
356         persistence.
358 So a sample program that would update a host declaration would look
359 something like this:
361         /* Create a local object into which to store authentication
362            information. */
363         if ((status = dhcpctl_new_object (&auth, dhcpctl_null_handle,
364                                           "authentication-information")))
365                 dhcpctl_error ("Can't create authentication information: %m");
367         /* Set up the authenticator with an algorithm type, user name and
368            password. */
369         if ((status = dhcpctl_set_string_value (&auth, "mellon", "username")))
370                 dhcpctl_error ("Can't set username: %m", status);
371         if ((status = dhcpctl_set_string_value (&auth, "three blind mice",
372                                                 "password")))
373                 dhcpctl_error ("Can't set password: %m", status);
374         if ((status = dhcpctl_set_string_value (&auth, "md5-hash",
375                                                 "algorithm")))
376                 dhcpctl_error ("Can't set authentication algorithm: %m.",
377                                status);
379         /* Connect to the server. */
380         if ((status = dhcpctl_connect (&c, "dhcp.server.com", 612, &auth)))
382                 dhcpctl_error ("Can't connect to dhcp.server.com: %m",
383                                status);
385         /* Create a host object. */
386         if ((status = dhcpctl_new_object (&hp, c, "host")))
387                 dhcpctl_error ("Host create failed: %m", status);
389         /* Create a data_string to contain the host's client
390            identifier, and set it. */
391         if ((status =
392              data_string_create_from_hex (&client_id,
393                                           "1:08:00:2b:34:1a:c3")))
394                 dhcpctl_error ("Can't create client identifier: %m");
395         if ((status = dhcpctl_set_value (hp, client_id,
396                                          "dhcp-client-identifier")))
397                 dhcpctl_error ("Host client identifier set failed.");
398         /* Set the known flag to 1. */
399         if ((status = dhcpctl_set_boolean (hp, 1, "known")))
400                 dhcpctl_error ("Host known set failed.");
402         /* Open an existing host object that matches the client identifier,
403            and update it from the local context, or if no host entry
404            yet exists matching the identifier, create one and
405            initialize it. */
406         if ((status = dhcpctl_open_object (&hp, c,
407                                            DHCPCTL_CREATE | DHCPCTL_UPDATE)))
408                 dhcpctl_error ("Can't open host: %m", status);
410         /* Wait for the process to complete, check status. */
411         if ((status = dhcpctl_wait_for_completion (hp, &wait_status)))
412                 dhcpctl_error ("Host create/lookup wait failed: %m", status);
413         if (waitstatus)
414                 dhcpctl_error ("Host create/lookup failed: %m", status);
416 The API is a bit complicated, for a couple of reasons.   I want to
417 make it general, so that there aren't a bazillion functions to call,
418 one for each data type.   I want it to be thread-safe, which is why
419 each function returns a status and the error printer requires a status
420 code for input.   I want it to be possible to make it asynchronous, so
421 that it can work in tandem with, for example, an X toolkit.   If
422 you're just writing a simple update cgi program, you probably won't
423 want to bother to use the asynchronous callbacks, and indeed the above
424 example doesn't.
426 I glossed over data strings above - basically, they're objects with a
427 pointer to a reference-counted buffer structure, an offset into that
428 buffer, and a length.   These are used within the DHCP server, so you
429 can get an idea of how they work - basically, they're a convenient and
430 efficient way to store a string with a length such that substrings can
431 easily be taken and such that more than one user at a time can have a
432 pointer to the string.
434 I will also probably add locking primitives, so that you can get the
435 value of something and be sure that some other updator process won't
436 modify it while you have the lock.