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