65 struct lease *(*
next)(
const struct lease *)) {
80 for (p=
next(lease); p != NULL; p=
next(p)) {
93 lease_reference(retval, newest,
MDL);
97 get_associated_ips(
const struct lease *lease,
98 struct lease *(*
next)(
const struct lease *),
99 const struct lease *newest,
100 u_int32_t *associated_ips,
101 unsigned int associated_ips_size) {
103 const struct lease *p;
114 for (p=lease; p != NULL; p=
next(p)) {
116 if (cnt < associated_ips_size) {
117 memcpy(&associated_ips[cnt],
119 sizeof(associated_ips[cnt]));
136 struct lease *tmp_lease;
138 int want_associated_ip;
140 u_int32_t assoc_ips[40];
141 const int nassoc_ips =
sizeof(assoc_ips) /
sizeof(assoc_ips[0]);
143 unsigned char dhcpMsgType;
144 const char *dhcp_msg_type_name;
146 struct group *relay_group;
149 int allow_leasequery;
151 u_int32_t lease_duration;
152 u_int32_t time_renewal;
153 u_int32_t time_rebinding;
154 u_int32_t time_expiry;
155 u_int32_t client_last_transaction_time;
156 struct sockaddr_in to;
157 struct in_addr siaddr;
169 snprintf(msgbuf,
sizeof(msgbuf),
170 "DHCPLEASEQUERY from %s", inet_ntoa(packet->
raw->
giaddr));
176 log_info(
"%s: missing giaddr, ciaddr is %s, no reply sent",
194 relay_group = subnet->
group;
198 subnet_dereference(&subnet,
MDL);
202 log_error(
"No memory for option state.");
203 log_info(
"%s: out of memory, no reply sent", msgbuf);
222 allow_leasequery = 0;
230 packet, NULL, NULL, packet->
options,
234 if (!allow_leasequery) {
235 log_info(
"%s: LEASEQUERY not allowed, query ignored", msgbuf);
252 lease = tmp_lease = NULL;
253 if (memcmp(cip.
iabuf,
"\0\0\0", 4)) {
255 want_associated_ip = 0;
257 snprintf(dbg_info,
sizeof(dbg_info),
"IP %s",
piaddr(cip));
263 want_associated_ip = 1;
271 memset(&uid, 0,
sizeof(uid));
292 assoc_ip_cnt = get_associated_ips(tmp_lease,
301 log_info(
"%s: hardware length too long, "
302 "no reply sent", msgbuf);
322 assoc_ip_cnt = get_associated_ips(tmp_lease,
330 lease_dereference(&tmp_lease,
MDL);
342 if (want_associated_ip && (assoc_ip_cnt > nassoc_ips)) {
343 log_info(
"%d IP addresses associated with %s, "
344 "only %d sent in reply.",
345 assoc_ip_cnt, dbg_info, nassoc_ips);
353 snprintf(msgbuf,
sizeof(msgbuf),
354 "DHCPLEASEQUERY from %s for %s",
355 inet_ntoa(packet->
raw->
giaddr), dbg_info);
362 dhcp_msg_type_name =
"DHCPLEASEUNKNOWN";
366 dhcp_msg_type_name =
"DHCPLEASEACTIVE";
369 dhcp_msg_type_name =
"DHCPLEASEUNASSIGNED";
399 log_error(
"%s: out of memory, no reply sent", msgbuf);
400 lease_dereference(&lease,
MDL);
423 lease_dereference(&lease,
MDL);
424 log_info(
"%s: out of memory, no reply sent",
440 time_renewal = lease->
starts +
441 (lease_duration / 2);
442 time_rebinding = lease->
starts +
443 (lease_duration / 2) +
444 (lease_duration / 4) +
445 (lease_duration / 8);
448 time_renewal = htonl(time_renewal -
cur_time);
453 sizeof(time_renewal))) {
455 lease_dereference(&lease,
MDL);
456 log_info(
"%s: out of memory, no reply sent",
463 time_rebinding = htonl(time_rebinding -
cur_time);
468 sizeof(time_rebinding))) {
470 lease_dereference(&lease,
MDL);
471 log_info(
"%s: out of memory, no reply sent",
483 sizeof(time_expiry))) {
485 lease_dereference(&lease,
MDL);
486 log_info(
"%s: out of memory, no reply sent",
493 if (lease->
scope != NULL) {
496 memset(&vendor_class, 0,
sizeof(vendor_class));
499 "vendor-class-identifier")) {
502 (
void *)vendor_class.
data,
506 lease_dereference(&lease,
MDL);
508 "class identifier, no reply "
548 client_last_transaction_time =
551 client_last_transaction_time = htonl(0);
555 &client_last_transaction_time,
556 sizeof(client_last_transaction_time))) {
558 lease_dereference(&lease,
MDL);
559 log_info(
"%s: out of memory, no reply sent",
568 if (want_associated_ip && (assoc_ip_cnt > 0)) {
572 assoc_ip_cnt *
sizeof(assoc_ips[0]))) {
574 lease_dereference(&lease,
MDL);
575 log_info(
"%s: out of memory, no reply sent",
594 sizeof(dhcpMsgType))) {
596 lease_dereference(&lease,
MDL);
597 log_info(
"%s: error adding option, no reply sent", msgbuf);
615 memset(&prl, 0,
sizeof(prl));
651 lease_dereference(&lease,
MDL);
653 to.sin_family = AF_INET;
655 to.sin_len =
sizeof(to);
657 memset(to.sin_zero, 0,
sizeof(to.sin_zero));
663 if (packet->
raw->
giaddr.s_addr != htonl(INADDR_LOOPBACK)) {
676 interface = packet->interface;
682 log_info(
"%s to %s for %s (%d associated IPs)",
684 inet_ntoa(to.sin_addr), dbg_info, assoc_ip_cnt);
723 struct in6_addr link_addr;
729 unsigned char data[65536];
737 static const int required_opts_lq[] = {
746 static const int required_opt_CLIENT_DATA[] = {
758 get_lq_query(
struct lq6_state *lq)
767 if ((lq_query->
data != NULL) || (lq_query->
len != 0)) {
773 return ISC_R_NOTFOUND;
779 return ISC_R_FAILURE;
782 return ISC_R_SUCCESS;
790 valid_query_msg(
struct lq6_state *lq) {
791 struct packet *packet = lq->packet;
802 "client identifier missing",
807 log_error(
"Error processing %s from %s; "
808 "unable to evaluate Client Identifier",
820 "server identifier found "
821 "(CLIENTID %s, SERVERID %s)",
825 lq->client_id.data, 60),
827 lq->server_id.data, 60));
830 "server identifier found "
834 lq->client_id.data, 60),
840 switch (get_lq_query(lq)) {
844 log_debug(
"Discarding %s from %s; lq-query missing",
849 log_error(
"Error processing %s from %s; "
850 "unable to evaluate LQ-Query",
861 if (lq->client_id.len > 0) {
864 if (lq->server_id.len > 0) {
867 if (lq->lq_query.len > 0) {
878 set_error(
struct lq6_state *lq, u_int16_t code,
const char *message) {
882 memset(&d, 0,
sizeof(d));
883 d.len =
sizeof(code) + strlen(message);
885 log_fatal(
"set_error: no memory for status code.");
887 d.data = d.buffer->data;
889 memcpy(d.buffer->data +
sizeof(code), message, d.len -
sizeof(code));
891 d.buffer, (
unsigned char *)d.data, d.len,
893 log_error(
"set_error: error saving status code.");
906 process_lq_by_address(
struct lq6_state *lq) {
907 struct packet *packet = lq->packet;
911 struct in6_addr addr;
924 "No OPTION_IAADDR.")) {
925 log_error(
"process_lq_by_address: unable "
926 "to set MalformedQuery status code.");
931 memset(&data, 0,
sizeof(data));
934 lq->query_opts, NULL,
937 log_error(
"process_lq_by_address: error evaluating IAADDR.");
940 memcpy(&addr, data.data,
sizeof(addr));
951 "Address not in a pool.")) {
952 log_error(
"process_lq_by_address: unable "
953 "to set NotConfigured status code.");
959 if (iasubopt_hash_lookup(&iaaddr, pool->
leases, &addr,
960 sizeof(addr),
MDL) == 0) {
975 "no memory for option state.");
983 NULL, (
unsigned char *)data.data, data.len,
985 log_error(
"process_lq_by_address: error saving client ID.");
992 log_error(
"process_lq_by_address: no memory for ia-addr.");
995 data.data = data.buffer->data;
996 memcpy(data.buffer->data, &iaaddr->
addr, 16);
997 lifetime = iaaddr->
prefer;
998 putULong(data.buffer->data + 16, lifetime);
999 lifetime = iaaddr->
valid;
1000 putULong(data.buffer->data + 20, lifetime);
1002 NULL, (
unsigned char *)data.data, data.len,
1004 log_error(
"process_lq_by_address: error saving ia-addr.");
1009 lifetime = htonl(iaaddr->
ia->
cltt);
1011 NULL, (
unsigned char *)&lifetime, 4,
1013 log_error(
"process_lq_by_address: error saving clt time.");
1020 opt_cursor = lq->cursor;
1027 sizeof(lq->buf) - lq->cursor,
1028 opt_state, lq->packet,
1029 required_opt_CLIENT_DATA, NULL);
1031 putUShort(lq->buf.data + opt_cursor + 2,
1032 lq->cursor - (opt_cursor + 4));
1038 if (data.data != NULL)
1044 if (opt_state != NULL)
1055 static struct lq6_state lq;
1063 memset(&lq.client_id, 0,
sizeof(lq.client_id));
1064 memset(&lq.server_id, 0,
sizeof(lq.server_id));
1065 memset(&lq.lq_query, 0,
sizeof(lq.lq_query));
1066 lq.query_opts = NULL;
1067 lq.reply_opts = NULL;
1073 if (!valid_query_msg(&lq)) {
1081 log_error(
"dhcpv6_leasequery: no memory for option state.");
1085 lq.packet->options, lq.reply_opts,
1090 memcpy(lq.buf.reply.transaction_id,
1091 lq.packet->dhcpv6_transaction_id,
1092 sizeof(lq.buf.reply.transaction_id));
1114 log_info(
"dhcpv6_leasequery: not allowed, query ignored.");
1127 if (lq.server_id.data == NULL)
1132 (
unsigned char *)lq.server_id.data,
1137 "error saving server identifier.");
1144 lq.client_id.buffer,
1145 (
unsigned char *)lq.client_id.data,
1150 "error saving client identifier.");
1162 "OPTION_LQ_QUERY too short.")) {
1164 "to set MalformedQuery status code.");
1170 lq.query_type = lq.lq_query.data [0];
1171 memcpy(&lq.link_addr, lq.lq_query.data + 1,
sizeof(lq.link_addr));
1172 switch (lq.query_type) {
1177 "QUERY_BY_CLIENTID not supported.")) {
1178 log_error(
"dhcpv6_leasequery: unable to "
1179 "set UnknownQueryType status code.");
1185 "Unknown query-type.")) {
1186 log_error(
"dhcpv6_leasequery: unable to "
1187 "set UnknownQueryType status code.");
1194 log_error(
"dhcpv6_leasequery: no memory for option state.");
1201 log_error(
"dhcpv6_leasequery: error parsing query-options.");
1203 "Bad query-options.")) {
1205 "to set MalformedQuery status code.");
1212 if (!process_lq_by_address(&lq))
1218 sizeof(lq.buf) - lq.cursor,
1225 reply_ret->
len = lq.cursor;
1226 reply_ret->
buffer = NULL;
1228 log_fatal(
"dhcpv6_leasequery: no memory to store Reply.");
1230 memcpy(reply_ret->
buffer->
data, lq.buf.data, lq.cursor);
1235 if (lq.packet != NULL)
1237 if (lq.client_id.data != NULL)
1239 if (lq.server_id.data != NULL)
1241 if (lq.lq_query.data != NULL)
1243 if (lq.query_opts != NULL)
1245 if (lq.reply_opts != NULL)
#define D6O_LQ_CLIENT_LINK
struct binding_scope * global_scope
const char * piaddr(const struct iaddr addr)
void dhcpv6_leasequery(struct data_string *, struct packet *)
struct universe server_universe
char * print_hw_addr(int htype, const int hlen, const unsigned char *data) const
#define print_hex_1(len, data, limit)
#define DHO_DHCP_PARAMETER_REQUEST_LIST
#define DHCP_R_INVALIDARG
const char * dhcpv6_type_names[]
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
#define DHO_DHCP_LEASE_TIME
int find_bound_string(struct data_string *value, struct binding_scope *scope, const char *name)
struct universe dhcp_universe
void data_string_forget(struct data_string *data, const char *file, int line)
struct group * root_group
void dhcpleasequery(struct packet *packet, int ms_nulltp)
int log_error(const char *,...) __attribute__((__format__(__printf__
void copy_server_duid(struct data_string *ds, const char *file, int line)
#define DHO_DHCP_REBINDING_TIME
#define DHO_ASSOCIATED_IP
struct option_state * options
unsigned char dhcpv6_msg_type
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int parse_option_buffer(struct option_state *options, const unsigned char *buffer, unsigned length, struct universe *universe)
void get_server_source_address(struct in_addr *from, struct option_state *options, struct option_state *out_options, struct packet *packet)
#define DHO_CLIENT_LAST_TRANSACTION_TIME
struct hardware hardware_addr
int find_subnet(struct subnet **sp, struct iaddr addr, const char *file, int line)
void execute_statements_in_scope(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct group *group, struct group *limiting_group, struct on_star *on_star)
struct interface_info * fallback_interface
#define STATUS_NotConfigured
int option_state_allocate(struct option_state **ptr, const char *file, int line)
int evaluate_option_cache(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
int packet_reference(struct packet **ptr, struct packet *bp, const char *file, int line)
binding_state_t binding_state
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
struct class * classes[PACKET_MAX_CLASSES]
void putULong(unsigned char *, u_int32_t)
int find_lease_by_hw_addr(struct lease **, const unsigned char *, unsigned, const char *, int)
struct data_string iaid_duid
ssize_t send_packet(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
int cons_options(struct packet *inpacket, struct dhcp_packet *outpacket, struct lease *lease, struct client_state *client_state, int mms, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, int overload_avail, int terminate, int bootpp, struct data_string *prl, const char *vuname)
int save_option_buffer(struct universe *universe, struct option_state *options, struct buffer *bp, unsigned char *buffer, unsigned length, unsigned code, int terminatep)
int add_option(struct option_state *options, unsigned int option_num, void *data, unsigned int data_len)
int option_chain_head_reference(struct option_chain_head **ptr, struct option_chain_head *bp, const char *file, int line)
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
int int log_info(const char *,...) __attribute__((__format__(__printf__
isc_result_t ipv6_pool_dereference(struct ipv6_pool **pool, const char *file, int line)
de-reference an IPv6 pool structure.
isc_result_t find_ipv6_pool(struct ipv6_pool **pool, u_int16_t type, const struct in6_addr *addr)
void get_newest_lease(struct lease **retval, struct lease *lease, struct lease *(*next)(const struct lease *))
int get_option(struct data_string *result, struct universe *universe, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct option_state *options, struct binding_scope **scope, unsigned code, const char *file, int line)
#define DHCPV6_LEASEQUERY_REPLY
isc_result_t get_client_id(struct packet *, struct data_string *)
int store_options6(char *buf, int buflen, struct option_state *opt_state, struct packet *packet, const int *required_opts, struct data_string *oro)
int option_state_dereference(struct option_state **ptr, const char *file, int line)
#define STATUS_UnknownQueryType
struct universe dhcpv6_universe
int evaluate_boolean_option_cache(int *ignorep, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
#define print_hex_2(len, data, limit)
#define LQ6QT_BY_CLIENTID
int packet_dereference(struct packet **ptr, const char *file, int line)
#define STATUS_MalformedQuery
#define DHCPLEASEUNASSIGNED
isc_result_t iasubopt_dereference(struct iasubopt **iasubopt, const char *file, int line)
int find_lease_by_uid(struct lease **, const unsigned char *, unsigned, const char *, int)
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
#define DHO_VENDOR_CLASS_IDENTIFIER
struct universe agent_universe
#define DHO_DHCP_RENEWAL_TIME
#define DHO_DHCP_CLIENT_IDENTIFIER
void putUShort(unsigned char *, u_int32_t)
const unsigned char * data
#define DHO_DHCP_MESSAGE_TYPE
struct binding_scope * scope
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
#define D6O_LQ_RELAY_DATA
int find_lease_by_ip_addr(struct lease **, struct iaddr, const char *, int)
struct option_chain_head * agent_options