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));
304 assoc_ip_cnt = get_associated_ips(tmp_lease,
313 log_info(
"%s: hardware length too long, " 314 "no reply sent", msgbuf);
334 assoc_ip_cnt = get_associated_ips(tmp_lease,
342 lease_dereference(&tmp_lease,
MDL);
354 if (want_associated_ip && (assoc_ip_cnt > nassoc_ips)) {
355 log_info(
"%d IP addresses associated with %s, " 356 "only %d sent in reply.",
357 assoc_ip_cnt, dbg_info, nassoc_ips);
365 snprintf(msgbuf,
sizeof(msgbuf),
366 "DHCPLEASEQUERY from %s for %s",
367 inet_ntoa(packet->
raw->
giaddr), dbg_info);
374 dhcp_msg_type_name =
"DHCPLEASEUNKNOWN";
378 dhcp_msg_type_name =
"DHCPLEASEACTIVE";
381 dhcp_msg_type_name =
"DHCPLEASEUNASSIGNED";
411 log_error(
"%s: out of memory, no reply sent", msgbuf);
412 lease_dereference(&lease,
MDL);
435 lease_dereference(&lease,
MDL);
436 log_info(
"%s: out of memory, no reply sent",
452 time_renewal = lease->
starts +
453 (lease_duration / 2);
454 time_rebinding = lease->
starts +
455 (lease_duration / 2) +
456 (lease_duration / 4) +
457 (lease_duration / 8);
460 time_renewal = htonl(time_renewal -
cur_time);
465 sizeof(time_renewal))) {
467 lease_dereference(&lease,
MDL);
468 log_info(
"%s: out of memory, no reply sent",
475 time_rebinding = htonl(time_rebinding -
cur_time);
480 sizeof(time_rebinding))) {
482 lease_dereference(&lease,
MDL);
483 log_info(
"%s: out of memory, no reply sent",
495 sizeof(time_expiry))) {
497 lease_dereference(&lease,
MDL);
498 log_info(
"%s: out of memory, no reply sent",
505 if (lease->
scope != NULL) {
508 memset(&vendor_class, 0,
sizeof(vendor_class));
511 "vendor-class-identifier")) {
514 (
void *)vendor_class.
data,
518 lease_dereference(&lease,
MDL);
520 "class identifier, no reply " 560 client_last_transaction_time =
563 client_last_transaction_time = htonl(0);
567 &client_last_transaction_time,
568 sizeof(client_last_transaction_time))) {
570 lease_dereference(&lease,
MDL);
571 log_info(
"%s: out of memory, no reply sent",
580 if (want_associated_ip && (assoc_ip_cnt > 0)) {
584 assoc_ip_cnt *
sizeof(assoc_ips[0]))) {
586 lease_dereference(&lease,
MDL);
587 log_info(
"%s: out of memory, no reply sent",
606 sizeof(dhcpMsgType))) {
608 lease_dereference(&lease,
MDL);
609 log_info(
"%s: error adding option, no reply sent", msgbuf);
627 memset(&prl, 0,
sizeof(prl));
663 lease_dereference(&lease,
MDL);
665 to.sin_family = AF_INET;
667 to.sin_len =
sizeof(to);
669 memset(to.sin_zero, 0,
sizeof(to.sin_zero));
675 if (packet->
raw->
giaddr.s_addr != htonl(INADDR_LOOPBACK)) {
688 interface = packet->interface;
694 log_info(
"%s to %s for %s (%d associated IPs)",
696 inet_ntoa(to.sin_addr), dbg_info, assoc_ip_cnt);
735 struct in6_addr link_addr;
741 unsigned char data[65536];
749 static const int required_opts_lq[] = {
758 static const int required_opt_CLIENT_DATA[] = {
770 get_lq_query(
struct lq6_state *lq)
779 if ((lq_query->
data != NULL) || (lq_query->
len != 0)) {
785 return ISC_R_NOTFOUND;
791 return ISC_R_FAILURE;
794 return ISC_R_SUCCESS;
802 valid_query_msg(
struct lq6_state *lq) {
814 "client identifier missing",
819 log_error(
"Error processing %s from %s; " 820 "unable to evaluate Client Identifier",
832 "server identifier found " 833 "(CLIENTID %s, SERVERID %s)",
837 lq->client_id.data, 60),
839 lq->server_id.data, 60));
842 "server identifier found " 846 lq->client_id.data, 60),
852 switch (get_lq_query(lq)) {
856 log_debug(
"Discarding %s from %s; lq-query missing",
861 log_error(
"Error processing %s from %s; " 862 "unable to evaluate LQ-Query",
873 if (lq->client_id.len > 0) {
876 if (lq->server_id.len > 0) {
879 if (lq->lq_query.len > 0) {
890 set_error(
struct lq6_state *lq, u_int16_t code,
const char *message) {
894 memset(&d, 0,
sizeof(d));
895 d.
len =
sizeof(code) + strlen(message);
897 log_fatal(
"set_error: no memory for status code.");
901 memcpy(d.
buffer->
data +
sizeof(code), message, d.
len -
sizeof(code));
905 log_error(
"set_error: error saving status code.");
918 process_lq_by_address(
struct lq6_state *lq) {
923 struct in6_addr addr;
936 "No OPTION_IAADDR.")) {
937 log_error(
"process_lq_by_address: unable " 938 "to set MalformedQuery status code.");
943 memset(&data, 0,
sizeof(data));
946 lq->query_opts, NULL,
949 log_error(
"process_lq_by_address: error evaluating IAADDR.");
952 memcpy(&addr, data.
data,
sizeof(addr));
963 "Address not in a pool.")) {
964 log_error(
"process_lq_by_address: unable " 965 "to set NotConfigured status code.");
971 if (iasubopt_hash_lookup(&iaaddr, pool->
leases, &addr,
972 sizeof(addr),
MDL) == 0) {
987 "no memory for option state.");
995 NULL, (
unsigned char *)data.
data, data.
len,
997 log_error(
"process_lq_by_address: error saving client ID.");
1004 log_error(
"process_lq_by_address: no memory for ia-addr.");
1009 lifetime = iaaddr->
prefer;
1011 lifetime = iaaddr->
valid;
1014 NULL, (
unsigned char *)data.
data, data.
len,
1016 log_error(
"process_lq_by_address: error saving ia-addr.");
1021 lifetime = htonl(iaaddr->
ia->
cltt);
1023 NULL, (
unsigned char *)&lifetime, 4,
1025 log_error(
"process_lq_by_address: error saving clt time.");
1032 opt_cursor = lq->cursor;
1039 sizeof(lq->buf) - lq->cursor,
1040 opt_state, lq->packet,
1041 required_opt_CLIENT_DATA, NULL);
1043 putUShort(lq->buf.data + opt_cursor + 2,
1044 lq->cursor - (opt_cursor + 4));
1050 if (data.
data != NULL)
1056 if (opt_state != NULL)
1067 static struct lq6_state lq;
1075 memset(&lq.client_id, 0,
sizeof(lq.client_id));
1076 memset(&lq.server_id, 0,
sizeof(lq.server_id));
1077 memset(&lq.lq_query, 0,
sizeof(lq.lq_query));
1078 lq.query_opts = NULL;
1079 lq.reply_opts = NULL;
1085 if (!valid_query_msg(&lq)) {
1093 log_error(
"dhcpv6_leasequery: no memory for option state.");
1097 lq.packet->options, lq.reply_opts,
1102 memcpy(lq.buf.reply.transaction_id,
1103 lq.packet->dhcpv6_transaction_id,
1104 sizeof(lq.buf.reply.transaction_id));
1126 log_info(
"dhcpv6_leasequery: not allowed, query ignored.");
1139 if (lq.server_id.data == NULL)
1144 (
unsigned char *)lq.server_id.data,
1149 "error saving server identifier.");
1156 lq.client_id.buffer,
1157 (
unsigned char *)lq.client_id.data,
1162 "error saving client identifier.");
1174 "OPTION_LQ_QUERY too short.")) {
1176 "to set MalformedQuery status code.");
1182 lq.query_type = lq.lq_query.data [0];
1183 memcpy(&lq.link_addr, lq.lq_query.data + 1,
sizeof(lq.link_addr));
1184 switch (lq.query_type) {
1189 "QUERY_BY_CLIENTID not supported.")) {
1190 log_error(
"dhcpv6_leasequery: unable to " 1191 "set UnknownQueryType status code.");
1197 "Unknown query-type.")) {
1198 log_error(
"dhcpv6_leasequery: unable to " 1199 "set UnknownQueryType status code.");
1206 log_error(
"dhcpv6_leasequery: no memory for option state.");
1213 log_error(
"dhcpv6_leasequery: error parsing query-options.");
1215 "Bad query-options.")) {
1217 "to set MalformedQuery status code.");
1224 if (!process_lq_by_address(&lq))
1230 sizeof(lq.buf) - lq.cursor,
1237 reply_ret->
len = lq.cursor;
1238 reply_ret->
buffer = NULL;
1240 log_fatal(
"dhcpv6_leasequery: no memory to store Reply.");
1242 memcpy(reply_ret->
buffer->
data, lq.buf.data, lq.cursor);
1247 if (lq.packet != NULL)
1249 if (lq.client_id.data != NULL)
1251 if (lq.server_id.data != NULL)
1253 if (lq.lq_query.data != NULL)
1255 if (lq.query_opts != NULL)
1257 if (lq.reply_opts != NULL)
#define D6O_LQ_CLIENT_LINK
struct binding_scope * global_scope
const char * piaddr(const struct iaddr addr)
#define DHO_PXE_CLIENT_ID
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