xref: /minix/external/bsd/dhcp/dist/doc/api+protocol (revision 83ee113e)
1This file documents the protocol that the ISC DHCP server and ISC
2Object Management clients (clients that use the ISC Object Management
3API) speak between one another.
4
5Protocol:
6
7All multi-byte numbers are represented in network byte order.
8
9On startup, each side sends a status message indicating what version
10of the protocol they are speaking.   The status message looks like
11this:
12
13+---------+---------+
14| version | hlength |
15+---------+---------+
16
17version - 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.
23
24hlength - 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.
28
29
30The startup message is not authenticated.   Either side may reject the
31other side's startup message as invalid by simply closing the
32connection.   The only fixed part of the startup message is the
33version number - future versions may delete hlength, or add further
34startup information.
35
36Following the startup message, all messages have the same format.
37Currently, the format includes a fixed-length header (the length in
38hlength, above)
39
40+--------+----+--------+----+-----+---------+------------+------------+-----+
41| authid | op | handle | id | rid | authlen | msg values | obj values | sig |
42+--------+----+--------+----+-----+---------+------------+------------+-----+
43
44The fixed-length header consists of:
45
46authid = 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.
63
64op = 32-bit opcode, one of:
65	open = 1
66	refresh = 2
67	update = 3
68	notify = 4
69	error = 5
70	delete = 6
71handle = 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.
75id = 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.
79rid = 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.
82
83authlen = a 32-bit number representing the length of the authenticator
84
85msg 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.
96
97obj values = a series of name+value pairs, as above, specific to the
98	object being created, updated or refreshed.
99
100signature = authlen bytes of data signing the message.   The signature
101	    algorithm is a property of the authenticator handle.
102
103Message types:
104
1051: 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
113
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.
125
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:
132
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.
142
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.
146
1472: refresh
148
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:
154
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.
159
1603: update
161
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:
167
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.
175
1764: notify
177
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:
185
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
192
1935: status
194
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.
198
1996: delete
200
201   Deletes the specified object.   Response will be either request-ok,
202   or error.   Possible errors include:
203
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.
211
2127: notify-cancel
213
214   Like notify, but requests that an existing notification be cancelled.
215
2168: notify-cancelled
217
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.
222
223internals:
224
225Both client and server use same protocol and infrastructure.   There
226are many object types, each of which is stored in a registry.
227Objects whose type is not recognized can either be handled by the
228generic object type, which is registered with the type "*".   If no
229generic object type is registered, then objects with unknown types are
230simply not supported.   On the client, there are probably no special
231object handlers (although this is by no means forbidden).   On the
232server, probably everything is a special object.
233
234Each object type has the following methods:
235
236
237
238
239dhcpctl_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.
250
251dhcpctl_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
265
266dhcpctl_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"
275
276dhcpctl_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
289
290dhcpctl_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.
302
303dhcpctl_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".
317
318dhcpctl_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.
322
323dhcpctl_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.
328
329dhcpctl_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.
335
336dhcpctl_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.
340
341dhcpctl_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.
345
346dhcpctl_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.
350
351dhcpctl_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.
357
358So a sample program that would update a host declaration would look
359something like this:
360
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");
366
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);
378
379	/* Connect to the server. */
380	if ((status = dhcpctl_connect (&c, "dhcp.server.com", 612, &auth)))
381
382		dhcpctl_error ("Can't connect to dhcp.server.com: %m",
383			       status);
384
385	/* Create a host object. */
386	if ((status = dhcpctl_new_object (&hp, c, "host")))
387		dhcpctl_error ("Host create failed: %m", status);
388
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.");
401
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);
409
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);
415
416The API is a bit complicated, for a couple of reasons.   I want to
417make it general, so that there aren't a bazillion functions to call,
418one for each data type.   I want it to be thread-safe, which is why
419each function returns a status and the error printer requires a status
420code for input.   I want it to be possible to make it asynchronous, so
421that it can work in tandem with, for example, an X toolkit.   If
422you're just writing a simple update cgi program, you probably won't
423want to bother to use the asynchronous callbacks, and indeed the above
424example doesn't.
425
426I glossed over data strings above - basically, they're objects with a
427pointer to a reference-counted buffer structure, an offset into that
428buffer, and a length.   These are used within the DHCP server, so you
429can get an idea of how they work - basically, they're a convenient and
430efficient way to store a string with a length such that substrings can
431easily be taken and such that more than one user at a time can have a
432pointer to the string.
433
434I will also probably add locking primitives, so that you can get the
435value of something and be sure that some other updator process won't
436modify it while you have the lock.
437