193 lines
6.2 KiB
Groff
193 lines
6.2 KiB
Groff
NAME
|
|
OMAPI - Object Management Application Programming Interface
|
|
|
|
DESCRIPTION
|
|
|
|
Overview
|
|
|
|
OMAPI is an programming layer designed for controlling remote
|
|
applications, and for querying them for their state. It is currently
|
|
used by the ISC DHCP server and this outline addresses the parts of
|
|
OMAPI appropriate to the clients of DHCP server. It does this by also
|
|
describing the use of a thin API layered on top of OMAPI called
|
|
'dhcpctl'
|
|
|
|
OMAPI uses TCP/IP as the transport for server communication, and
|
|
security can be imposed by having the client and server
|
|
cryptographically sign messages using a shared secret.
|
|
|
|
dhcpctl works by presenting the client with handles to objects that
|
|
act as surrogates for the real objects in the server. For example a
|
|
client will create a handle for a lease object, and will request the
|
|
server to fill the lease handle's state. The client application can
|
|
then pull details such as the lease expiration time from the lease
|
|
handle.
|
|
|
|
Modifications can be made to the server state by creating handles to
|
|
new objects, or by modifying attributes of handles to existing
|
|
objects, and then instructing the server to update itself according to
|
|
the changes made.
|
|
|
|
Usage
|
|
|
|
The client application must always call dhcpctl_initialize() before
|
|
making calls to any other dhcpctl functions. This initializes
|
|
various internal data structures.
|
|
|
|
To create the connection to the server the client must use
|
|
dhcpctl_connect() function. As well as making the physical connection
|
|
it will also set up the connection data structures to do
|
|
authentication on each message, if that is required.
|
|
|
|
All the dhcpctl functions return an integer value of type
|
|
isc_result_t. A successful call will yield a result of
|
|
ISC_R_SUCCESS. If the call fails for a reason local to the client
|
|
(e.g. insufficient local memory, or invalid arguments to the call)
|
|
then the return value of the dhcpctl function will show that. If the
|
|
call succeeds but the server couldn't process the request the error
|
|
value from the server is returned through another way, shown below.
|
|
|
|
The easiest way to understand dhcpctl is to see it in action. The
|
|
following program is fully functional, but almost all error checking
|
|
has been removed to make is shorter and easier to understand. This
|
|
program will query the server running on the localhost for the details
|
|
of the lease for IP address 10.0.0.101. It will then print out the time
|
|
the lease ends.
|
|
|
|
#include <stdarg.h>
|
|
#include <sys/time.h>
|
|
#include <sys/socket.h>
|
|
#include <stdio.h>
|
|
#include <netinet/in.h>
|
|
|
|
#include <isc/result.h>
|
|
#include <dhcpctl/dhcpctl.h>
|
|
|
|
int main (int argc, char **argv) {
|
|
dhcpctl_data_string ipaddrstring = NULL;
|
|
dhcpctl_data_string value = NULL;
|
|
|
|
All modifications of handles and all accesses of handle data happen
|
|
via dhcpctl_data_string objects.
|
|
|
|
dhcpctl_handle connection = NULL;
|
|
dhcpctl_handle lease = NULL;
|
|
isc_result_t waitstatus;
|
|
struct in_addr convaddr;
|
|
time_t thetime;
|
|
|
|
dhcpctl_initialize ();
|
|
|
|
Required fist step.
|
|
|
|
dhcpctl_connect (&connection, "127.0.0.1",
|
|
7911, 0);
|
|
|
|
Sets up the connection to the server. The server normally listens on
|
|
port 7911 unless configured to do otherwise.
|
|
|
|
dhcpctl_new_object (&lease, connection,
|
|
"lease");
|
|
|
|
Here we create a handle to a lease. This call just sets up local data
|
|
structure. The server hasn't yet made any association between the
|
|
client's data structure and any lease it has.
|
|
|
|
memset (&ipaddrstring, 0, sizeof
|
|
ipaddrstring);
|
|
|
|
inet_pton(AF_INET, "10.0.0.101",
|
|
&convaddr);
|
|
|
|
omapi_data_string_new (&ipaddrstring,
|
|
4, MDL);
|
|
|
|
Create a new data string to storing in the handle.
|
|
|
|
memcpy(ipaddrstring->value, &convaddr.s_addr, 4);
|
|
|
|
dhcpctl_set_value (lease, ipaddrstring,
|
|
"ip-address");
|
|
|
|
We're setting the ip-address attribute of the lease handle to the
|
|
given address. We've not set any other attributes so when the server
|
|
makes the association the ip address will be all it uses to look up
|
|
the lease in its tables.
|
|
|
|
dhcpctl_open_object (lease, connection, 0);
|
|
|
|
Here we prime the connection with the request to look up the lease in
|
|
the server and fill up the local handle with the attributes the server
|
|
will send over in its answer.
|
|
|
|
dhcpctl_wait_for_completion (lease,
|
|
&waitstatus);
|
|
|
|
This call causes the message to get sent to the server (the message to
|
|
look up the lease and send back the attribute values in the
|
|
answer). The value in the variable waitstatus when the function
|
|
returns will be the result from the server. If the message could
|
|
not be processed properly by the server then the error will be
|
|
reflected here.
|
|
|
|
if (waitstatus != ISC_R_SUCCESS) {
|
|
/* server not authoritative */
|
|
exit (0);
|
|
}
|
|
|
|
dhcpctl_data_string_dereference(&ipaddrstring,
|
|
MDL);
|
|
|
|
Clean-up memory we no longer need.
|
|
|
|
dhcpctl_get_value (&value, lease, "ends");
|
|
|
|
Get the attribute named ``ends'' from the lease handle. This is a
|
|
4-byte integer of the time (in unix epoch seconds) that the lease
|
|
will expire.
|
|
|
|
memcpy(&thetime, value->value, value->len);
|
|
dhcpctl_data_string_dereference(&value, MDL);
|
|
|
|
fprintf (stdout, "ending time is %s",
|
|
ctime(&thetime));
|
|
}
|
|
|
|
|
|
Authentication
|
|
|
|
If the server demands authenticated connections then before opening
|
|
the connection the user must call dhcpctl_new_authenticator.
|
|
|
|
dhcpctl_handle authenticator = NULL;
|
|
const char *keyname = "a-key-name";
|
|
const char *algorithm = "hmac-md5";
|
|
const char *secret = "a-shared-secret";
|
|
|
|
dhcpctl_new_authenticator (&authenticator,
|
|
keyname,
|
|
algorithm,
|
|
secret,
|
|
strlen(secret) + 1);
|
|
|
|
The keyname, algorithm and secret must all match what is specified in
|
|
the server's dhcpd.conf file:
|
|
|
|
key "a-key-name" {
|
|
algorithm hmac-md5;
|
|
secret "a-shared-secret";
|
|
};
|
|
|
|
# Set the omapi-key value to use
|
|
# authenticated connections
|
|
omapi-key "a-key-name";
|
|
|
|
The authenticator handle that is created by the call to
|
|
dhcpctl_new_authenticator must be given as the last (the 4th) argument
|
|
to the call to dhcpctl_connect(). All messages will then be signed
|
|
with the given secret string using the specified algorithm.
|
|
|
|
SEE ALSO
|
|
|
|
dhcpctl(3)
|