Parsing options
Kelly Yancey
kelly at nttmcl.com
Thu Jun 16 18:17:11 UTC 2005
On Thu, 16 Jun 2005, [ISO-8859-1] Erik Alapää wrote:
> Hello! I am using the ISC relay code as a basis for developing a
> special-purpose DHCP relay that, in addition to normal relay
> functionality also will sniff some info from the DHCP packets and pass
> that info to an LDAP server. Now my question: Can anyone offer me some
> advice on how to get the lease time, circuit and remote id:s from the
> options part of a packet? I have looked at the functions used by the
> ISC DHCP client and server, but these seem to be EXTREMELY complicated
> for some reason, and they require strange input parameters that the
> relay does not have access to. They use client states, dhcp universe
> structs, option caches and whatnot :| What I need is a routine that
> simply takes a raw dhcp_packet or a dhcp packet struct as defined in
> includes/dhcpd.h and gets me lease time, circuit and remote id. Looks
> like I will have to build one from scratch :(
>
> Regards,
>
> --
> Erik Alapää
> Software Engineer M. Sc., Lic. Ind. Math.
>
I did something similar a couple of years back to record lease
information into a database. Attached is a code snippet with the
important bits of parsing the options and extracting the lease times.
Good luck,
Kelly
--
Kelly Yancey - kbyanc@{posi.net,FreeBSD.org} - kelly at nttmcl.com
-- Attached file included as plaintext by Ecartis --
-- File: dhcrelay-example.c
void
nttmcl_sqllog_dhcp(const struct dhcp_packet *packet, int length)
{
struct option_state *options = NULL;
struct option_cache *op;
char *serverid_str = NULL;
u_int32_t lease_time = 0;
u_int32_t renewal_time = 0;
u_int32_t rebind_time = 0;
u_int8_t message_type = 0;
PGresult *result;
int status;
/* Sanity check to make sure we have a database connection. */
if (sql_conn == NULL)
return;
/* Sanity check the options cookie to ensure this is a DHCP packet. */
if (memcmp(packet->options, DHCP_OPTIONS_COOKIE,
sizeof(DHCP_OPTIONS_COOKIE) - 1) != 0)
return; /* XXX Log bootp data??? */
if (!option_state_allocate(&options, MDL))
return;
if (!parse_option_buffer(options,
packet->options + sizeof(DHCP_OPTIONS_COOKIE) - 1,
length - DHCP_FIXED_NON_UDP - sizeof(DHCP_OPTIONS_COOKIE) + 1,
&dhcp_universe)) {
option_state_dereference(&options, MDL);
return; /* XXX Error should already be logged. */
}
if ((op = lookup_option(&dhcp_universe, options,
DHO_DHCP_MESSAGE_TYPE)) != NULL) {
message_type = *op->data.data;
}
if (message_type != DHCPACK) {
/* Only interested in ACKs. */
option_state_dereference(&options, MDL);
return;
}
if ((op = lookup_option(&dhcp_universe, options,
DHO_DHCP_LEASE_TIME)) != NULL) {
assert(op->data.len == 4 && sizeof(lease_time) == 4);
memcpy(&lease_time, op->data.data, op->data.len);
/* XXX Should be ntoh32. */
lease_time = ntohl(lease_time);
}
if ((op = lookup_option(&dhcp_universe, options,
DHO_DHCP_RENEWAL_TIME)) != NULL) {
assert(op->data.len == 4 && sizeof(renewal_time) == 4);
memcpy(&renewal_time, op->data.data, op->data.len);
renewal_time = ntohl(renewal_time);
}
if ((op = lookup_option(&dhcp_universe, options,
DHO_DHCP_REBINDING_TIME)) != NULL) {
assert(op->data.len == 4 && sizeof(rebind_time) == 4);
memcpy(&rebind_time, op->data.data, op->data.len);
rebind_time = ntohl(rebind_time);
}
if ((op = lookup_option(&dhcp_universe, options,
DHO_DHCP_SERVER_IDENTIFIER)) != NULL) {
struct in_addr ip;
assert(op->data.len == 4 && sizeof(ip) == 4);
memcpy(&ip, op->data.data, sizeof(ip));
serverid_str = nttmcl_sql_strquote(inet_ntoa(&ip), NULL);
}
if (lease_time == 0)
lease_time = default_lease_time;
if (renewal_time == 0)
renewal_time = lease_time / 2;
if (rebind_time == 0)
rebind_time = lease_time * 7 / 8;
... do stuff with the option values ...
option_state_dereference(&options, MDL);
free(serverid_str);
}
More information about the dhcp-hackers
mailing list