64 struct lease *(*
next)(
const struct lease *)) {
79 for (p=
next(lease); p != NULL; p=
next(p)) {
92 lease_reference(retval, newest,
MDL);
96 get_associated_ips(
const struct lease *lease,
97 struct lease *(*
next)(
const struct lease *),
98 const struct lease *newest,
99 u_int32_t *associated_ips,
100 unsigned int associated_ips_size) {
102 const struct lease *p;
113 for (p=lease; p != NULL; p=
next(p)) {
115 if (cnt < associated_ips_size) {
116 memcpy(&associated_ips[cnt],
118 sizeof(associated_ips[cnt]));
135 struct lease *tmp_lease;
137 int want_associated_ip;
139 u_int32_t assoc_ips[40];
140 const int nassoc_ips =
sizeof(assoc_ips) /
sizeof(assoc_ips[0]);
142 unsigned char dhcpMsgType;
143 const char *dhcp_msg_type_name;
145 struct group *relay_group;
148 int allow_leasequery;
150 u_int32_t lease_duration;
151 u_int32_t time_renewal;
152 u_int32_t time_rebinding;
153 u_int32_t time_expiry;
154 u_int32_t client_last_transaction_time;
155 struct sockaddr_in to;
156 struct in_addr siaddr;
168 snprintf(msgbuf,
sizeof(msgbuf),
169 "DHCPLEASEQUERY from %s", inet_ntoa(packet->
raw->
giaddr));
180 log_info(
"%s: missing giaddr, ciaddr is %s, no reply sent",
198 relay_group = subnet->
group;
202 subnet_dereference(&subnet,
MDL);
206 log_error(
"No memory for option state.");
207 log_info(
"%s: out of memory, no reply sent", msgbuf);
226 allow_leasequery = 0;
234 packet, NULL, NULL, packet->
options,
238 if (!allow_leasequery) {
239 log_info(
"%s: LEASEQUERY not allowed, query ignored", msgbuf);
256 lease = tmp_lease = NULL;
257 if (memcmp(cip.
iabuf,
"\0\0\0", 4)) {
259 want_associated_ip = 0;
261 snprintf(dbg_info,
sizeof(dbg_info),
"IP %s",
piaddr(cip));
267 want_associated_ip = 1;
275 memset(&uid, 0,
sizeof(uid));
308 assoc_ip_cnt = get_associated_ips(tmp_lease,
317 log_info(
"%s: hardware length too long, " 318 "no reply sent", msgbuf);
338 assoc_ip_cnt = get_associated_ips(tmp_lease,
346 lease_dereference(&tmp_lease,
MDL);
358 if (want_associated_ip && (assoc_ip_cnt > nassoc_ips)) {
359 log_info(
"%d IP addresses associated with %s, " 360 "only %d sent in reply.",
361 assoc_ip_cnt, dbg_info, nassoc_ips);
369 snprintf(msgbuf,
sizeof(msgbuf),
370 "DHCPLEASEQUERY from %s for %s",
371 inet_ntoa(packet->
raw->
giaddr), dbg_info);
378 dhcp_msg_type_name =
"DHCPLEASEUNKNOWN";
382 dhcp_msg_type_name =
"DHCPLEASEACTIVE";
385 dhcp_msg_type_name =
"DHCPLEASEUNASSIGNED";
415 log_error(
"%s: out of memory, no reply sent", msgbuf);
416 lease_dereference(&lease,
MDL);
439 lease_dereference(&lease,
MDL);
440 log_info(
"%s: out of memory, no reply sent",
456 time_renewal = lease->
starts +
457 (lease_duration / 2);
458 time_rebinding = lease->
starts +
459 (lease_duration / 2) +
460 (lease_duration / 4) +
461 (lease_duration / 8);
464 time_renewal = htonl(time_renewal -
cur_time);
469 sizeof(time_renewal))) {
471 lease_dereference(&lease,
MDL);
472 log_info(
"%s: out of memory, no reply sent",
479 time_rebinding = htonl(time_rebinding -
cur_time);
484 sizeof(time_rebinding))) {
486 lease_dereference(&lease,
MDL);
487 log_info(
"%s: out of memory, no reply sent",
499 sizeof(time_expiry))) {
501 lease_dereference(&lease,
MDL);
502 log_info(
"%s: out of memory, no reply sent",
509 if (lease->
scope != NULL) {
512 memset(&vendor_class, 0,
sizeof(vendor_class));
515 "vendor-class-identifier")) {
518 (
void *)vendor_class.
data,
522 lease_dereference(&lease,
MDL);
524 "class identifier, no reply " 564 client_last_transaction_time =
567 client_last_transaction_time = htonl(0);
571 &client_last_transaction_time,
572 sizeof(client_last_transaction_time))) {
574 lease_dereference(&lease,
MDL);
575 log_info(
"%s: out of memory, no reply sent",
584 if (want_associated_ip && (assoc_ip_cnt > 0)) {
588 assoc_ip_cnt *
sizeof(assoc_ips[0]))) {
590 lease_dereference(&lease,
MDL);
591 log_info(
"%s: out of memory, no reply sent",
610 sizeof(dhcpMsgType))) {
612 lease_dereference(&lease,
MDL);
613 log_info(
"%s: error adding option, no reply sent", msgbuf);
631 memset(&prl, 0,
sizeof(prl));
667 lease_dereference(&lease,
MDL);
669 to.sin_family = AF_INET;
671 to.sin_len =
sizeof(to);
673 memset(to.sin_zero, 0,
sizeof(to.sin_zero));
679 if (packet->
raw->
giaddr.s_addr != htonl(INADDR_LOOPBACK)) {
692 interface = packet->interface;
698 log_info(
"%s to %s for %s (%d associated IPs)",
700 inet_ntoa(to.sin_addr), dbg_info, assoc_ip_cnt);
739 struct in6_addr link_addr;
745 unsigned char data[65536];
753 static const int required_opts_lq[] = {
762 static const int required_opt_CLIENT_DATA[] = {
774 get_lq_query(
struct lq6_state *lq)
783 if ((lq_query->
data != NULL) || (lq_query->
len != 0)) {
789 return ISC_R_NOTFOUND;
795 return ISC_R_FAILURE;
798 return ISC_R_SUCCESS;
806 valid_query_msg(
struct lq6_state *lq) {
818 "client identifier missing",
823 log_error(
"Error processing %s from %s; " 824 "unable to evaluate Client Identifier",
836 "server identifier found " 837 "(CLIENTID %s, SERVERID %s)",
841 lq->client_id.data, 60),
843 lq->server_id.data, 60));
846 "server identifier found " 850 lq->client_id.data, 60),
856 switch (get_lq_query(lq)) {
860 log_debug(
"Discarding %s from %s; lq-query missing",
865 log_error(
"Error processing %s from %s; " 866 "unable to evaluate LQ-Query",
877 if (lq->client_id.len > 0) {
880 if (lq->server_id.len > 0) {
883 if (lq->lq_query.len > 0) {
894 set_error(
struct lq6_state *lq, u_int16_t code,
const char *message) {
898 memset(&d, 0,
sizeof(d));
899 d.
len =
sizeof(code) + strlen(message);
901 log_fatal(
"set_error: no memory for status code.");
905 memcpy(d.
buffer->
data +
sizeof(code), message, d.
len -
sizeof(code));
909 log_error(
"set_error: error saving status code.");
922 process_lq_by_address(
struct lq6_state *lq) {
927 struct in6_addr addr;
940 "No OPTION_IAADDR.")) {
941 log_error(
"process_lq_by_address: unable " 942 "to set MalformedQuery status code.");
947 memset(&data, 0,
sizeof(data));
950 lq->query_opts, NULL,
953 log_error(
"process_lq_by_address: error evaluating IAADDR.");
956 memcpy(&addr, data.
data,
sizeof(addr));
967 "Address not in a pool.")) {
968 log_error(
"process_lq_by_address: unable " 969 "to set NotConfigured status code.");
975 if (iasubopt_hash_lookup(&iaaddr, pool->
leases, &addr,
976 sizeof(addr),
MDL) == 0) {
991 "no memory for option state.");
999 NULL, (
unsigned char *)data.
data, data.
len,
1001 log_error(
"process_lq_by_address: error saving client ID.");
1008 log_error(
"process_lq_by_address: no memory for ia-addr.");
1013 lifetime = iaaddr->
prefer;
1015 lifetime = iaaddr->
valid;
1018 NULL, (
unsigned char *)data.
data, data.
len,
1020 log_error(
"process_lq_by_address: error saving ia-addr.");
1025 lifetime = htonl(iaaddr->
ia->
cltt);
1027 NULL, (
unsigned char *)&lifetime, 4,
1029 log_error(
"process_lq_by_address: error saving clt time.");
1036 opt_cursor = lq->cursor;
1043 sizeof(lq->buf) - lq->cursor,
1044 opt_state, lq->packet,
1045 required_opt_CLIENT_DATA, NULL);
1047 putUShort(lq->buf.data + opt_cursor + 2,
1048 lq->cursor - (opt_cursor + 4));
1054 if (data.
data != NULL)
1060 if (opt_state != NULL)
1071 static struct lq6_state lq;
1079 memset(&lq.client_id, 0,
sizeof(lq.client_id));
1080 memset(&lq.server_id, 0,
sizeof(lq.server_id));
1081 memset(&lq.lq_query, 0,
sizeof(lq.lq_query));
1082 lq.query_opts = NULL;
1083 lq.reply_opts = NULL;
1089 if (!valid_query_msg(&lq)) {
1097 log_error(
"dhcpv6_leasequery: no memory for option state.");
1101 lq.packet->options, lq.reply_opts,
1106 memcpy(lq.buf.reply.transaction_id,
1107 lq.packet->dhcpv6_transaction_id,
1108 sizeof(lq.buf.reply.transaction_id));
1130 log_info(
"dhcpv6_leasequery: not allowed, query ignored.");
1143 if (lq.server_id.data == NULL)
1148 (
unsigned char *)lq.server_id.data,
1153 "error saving server identifier.");
1160 lq.client_id.buffer,
1161 (
unsigned char *)lq.client_id.data,
1166 "error saving client identifier.");
1178 "OPTION_LQ_QUERY too short.")) {
1180 "to set MalformedQuery status code.");
1186 lq.query_type = lq.lq_query.data [0];
1187 memcpy(&lq.link_addr, lq.lq_query.data + 1,
sizeof(lq.link_addr));
1188 switch (lq.query_type) {
1193 "QUERY_BY_CLIENTID not supported.")) {
1194 log_error(
"dhcpv6_leasequery: unable to " 1195 "set UnknownQueryType status code.");
1201 "Unknown query-type.")) {
1202 log_error(
"dhcpv6_leasequery: unable to " 1203 "set UnknownQueryType status code.");
1210 log_error(
"dhcpv6_leasequery: no memory for option state.");
1217 log_error(
"dhcpv6_leasequery: error parsing query-options.");
1219 "Bad query-options.")) {
1221 "to set MalformedQuery status code.");
1228 if (!process_lq_by_address(&lq))
1234 sizeof(lq.buf) - lq.cursor,
1241 reply_ret->
len = lq.cursor;
1242 reply_ret->
buffer = NULL;
1244 log_fatal(
"dhcpv6_leasequery: no memory to store Reply.");
1246 memcpy(reply_ret->
buffer->
data, lq.buf.data, lq.cursor);
1251 if (lq.packet != NULL)
1253 if (lq.client_id.data != NULL)
1255 if (lq.server_id.data != NULL)
1257 if (lq.lq_query.data != NULL)
1259 if (lq.query_opts != NULL)
1261 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