#ifndef lint
static char copyright[] =
-"$Id: conflex.c,v 1.49 1999/07/16 21:33:58 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: conflex.c,v 1.50 1999/07/19 01:15:10 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
return DDNS_FWD_NAME;
if (!strcasecmp (atom + 1, "dns-rev-name"))
return DDNS_REV_NAME;
+ if (!strcasecmp (atom + 1, "ns-update"))
+ return DNS_UPDATE;
if (!strcasecmp (atom + 1, "omain"))
return DOMAIN;
if (!strcasecmp (atom + 1, "eny"))
return LEASE;
if (!strcasecmp (atom + 1, "eased-address"))
return LEASED_ADDRESS;
+ if (!strcasecmp (atom + 1, "lease-time"))
+ return LEASE_TIME;
if (!strcasecmp (atom + 1, "imit"))
return LIMIT;
break;
#ifndef lint
static char copyright[] =
-"$Id: nsupdate.c,v 1.5 1999/07/18 19:37:23 mellon Exp $ Copyright (c) 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: nsupdate.c,v 1.6 1999/07/19 01:15:11 mellon Exp $ Copyright (c) 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
necessary which can be any combination and number of remove A, add A,
remove PTR, add PTR */
-/* Return the forward name of a lease. */
+#if 0
+/* Return the reverse name of a lease. */
char *ddns_rev_name(lease, state, packet)
struct lease *lease;
struct lease_state *state;
#endif
return hostname;
}
+#endif
-int nsupdateA(hostname, ip_addr, ttl, opcode)
+static int nsupdateA(hostname, ip_addr, ttl, opcode)
char *hostname;
char *ip_addr;
u_int32_t ttl;
return z;
}
-int nsupdatePTR(hostname, revname, ttl, opcode)
+static int nsupdatePTR(revname, hostname, ttl, opcode)
char *hostname;
char *revname;
u_int32_t ttl;
return z;
}
+#if 0
void nsupdate(lease, state, packet, opcode)
struct lease *lease;
struct lease_state *state;
char *hostname, *revname;
u_int32_t ttl = 0;
+return;
if (!(opcode == ADD || opcode == DELETE))
return;
if (lease -> ddns_rev_name &&
(strcmp(hostname, lease -> ddns_fwd_name) ||
strcmp(revname, lease -> ddns_rev_name)) &&
- nsupdatePTR(lease -> ddns_fwd_name, revname,
+ nsupdatePTR(revname, lease -> ddns_fwd_name,
ttl, DELETE)) {
/* clear the forward DNS name pointer */
if (lease -> ddns_rev_name)
if (!lease -> ddns_rev_name) {
/* add a PTR RR */
- if (nsupdatePTR(hostname, revname, ttl, ADD)) {
+ if (nsupdatePTR(revname, hostname, ttl, ADD)) {
/* remember in the lease struct for a release */
lease -> ddns_rev_name =
dmalloc(strlen(revname) + 1, "nsupdate");
piaddr(lease->ip_addr), ttl, DELETE);
if (lease -> ddns_rev_name &&
- nsupdatePTR(lease -> ddns_fwd_name,
- lease -> ddns_rev_name, ttl, opcode)) {
+ nsupdatePTR(lease -> ddns_rev_name,
+ lease -> ddns_fwd_name,
+ ttl, opcode)) {
/* clear the reverse DNS name pointer */
if (lease -> ddns_rev_name)
dfree(lease -> ddns_rev_name,
return;
}
+#endif
+
+/* public function to update an A record if needed */
+int updateA(struct data_string *lhs, struct data_string *rhs, unsigned int ttl,
+ struct lease *lease)
+{
+
+ static char hostname[MAXDNAME];
+ static char ipaddr[MAXDNAME];
+
+ hostname[0] = '\0';
+ strncat(hostname, lhs->data, lhs->len);
+ hostname[lhs->len] = '\0';
+
+ ipaddr[0] = '\0';
+ strncat(ipaddr, rhs->data, rhs->len);
+ ipaddr[rhs->len] = '\0';
+
+ /* delete an existing A if the one to be added is different */
+ if (lease -> ddns_fwd_name &&
+ strcmp(hostname, lease -> ddns_fwd_name)) {
+ int y;
+ y=nsupdateA(lease -> ddns_fwd_name, ipaddr, 0, DELETE);
+
+ if (y) {
+ /* clear the forward DNS name pointer */
+ if (lease -> ddns_fwd_name)
+ dfree(lease -> ddns_fwd_name, "nsupdate");
+ lease -> ddns_fwd_name = 0;
+ }
+ }
+ /* only update if there is no A record there already */
+ if (!lease -> ddns_fwd_name) {
+ int y;
+ y=nsupdateA(hostname, ipaddr, ttl, ADD);
+ if (y < 1)
+ return 0;
+
+ /* remember this in the lease structure for release */
+ lease -> ddns_fwd_name = dmalloc(strlen(hostname) + 1,
+ "nsupdate");
+ strcpy (lease -> ddns_fwd_name, hostname);
+ }
+
+ return 1;
+}
+
+/* public function to update an A record if needed */
+int updatePTR(struct data_string *lhs, struct data_string *rhs,
+ unsigned int ttl, struct lease *lease)
+{
+
+ static char hostname[MAXDNAME];
+ static char revname[MAXDNAME];
+
+ revname[0] = '\0';
+ strncat(revname, lhs->data, lhs->len);
+ revname[lhs->len] = '\0';
+
+ hostname[0] = '\0';
+ strncat(hostname, rhs->data, rhs->len);
+ hostname[rhs->len] = '\0';
+
+ /* delete an existing PTR if the one to be added is different */
+ if (lease -> ddns_rev_name &&
+ strcmp(revname, lease -> ddns_rev_name)) {
+ int y;
+ y=nsupdatePTR(revname, hostname, 0, DELETE);
+
+ if (y) {
+ /* clear the reverse DNS name pointer */
+ if (lease -> ddns_rev_name)
+ dfree(lease -> ddns_rev_name, "nsupdate");
+ lease -> ddns_rev_name = 0;
+ }
+ }
+ /* only update if there is no PTR record there already */
+ if (!lease -> ddns_rev_name) {
+ int y;
+ y=nsupdatePTR(revname, hostname, ttl, ADD);
+ if (y < 1)
+ return 0;
+
+ /* remember this in the lease structure for release */
+ lease -> ddns_rev_name = dmalloc(strlen(revname) + 1,
+ "nsupdate");
+ strcpy (lease -> ddns_rev_name, revname);
+ }
+
+ return 1;
+}
#endif /* defined (NSUPDATE) */
#ifndef lint
static char copyright[] =
-"$Id: parse.c,v 1.29 1999/07/16 21:33:59 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: parse.c,v 1.30 1999/07/19 01:15:11 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
goto norparen;
break;
+ case DNS_UPDATE:
+#if !defined (NSUPDATE)
+ parse_warn ("you are using dns-update() but have not compiled with the NSUPDATE switch.");
+ skip_to_semi (cfile);
+ *lose = 1;
+ return 0;
+#endif
+ token = next_token (&val, cfile);
+ if (!expression_allocate (expr, "parse_expression: DNS_UPDATE"))
+ log_fatal ("can't allocate expression");
+ (*expr) -> op = expr_dns_update;
+
+ token = next_token (&val, cfile);
+ if (token != LPAREN)
+ goto nolparen;
+
+ if (!(parse_data_expression
+ (&(*expr) -> data.dns_update.type, cfile, lose))) {
+ expression_dereference (expr,
+ "parse_expression: noRRtype");
+ parse_warn ("expecting DNS RR type.");
+ skip_to_semi (cfile);
+ *lose = 1;
+ return 0;
+ }
+
+ token = next_token (&val, cfile);
+ if (token != COMMA)
+ goto nocomma;
+
+ if (!(parse_data_expression
+ (&(*expr) -> data.dns_update.expr1, cfile, lose)))
+ goto nodata;
+
+ token = next_token (&val, cfile);
+ if (token != COMMA)
+ goto nocomma;
+
+ if (!(parse_data_expression
+ (&(*expr) -> data.dns_update.expr2, cfile, lose)))
+ goto nodata;
+
+ token = next_token (&val, cfile);
+ if (token != COMMA)
+ goto nocomma;
+
+ if (!(parse_data_expression
+ (&(*expr) -> data.dns_update.ttl, cfile, lose))) {
+ expression_dereference (expr,
+ "parse_expression: nottl");
+ parse_warn ("expecting data expression.");
+ skip_to_semi (cfile);
+ *lose = 1;
+ return 0;
+ }
+
+ token = next_token (&val, cfile);
+ if (token != RPAREN)
+ goto norparen;
+ break;
+
case OPTION:
case CONFIG_OPTION:
if (!expression_allocate (expr, "parse_expression: OPTION"))
(*expr) -> op = expr_leased_address;
break;
+ case LEASE_TIME:
+ token = next_token (&val, cfile);
+ if (!expression_allocate (expr,
+ "parse_expression: LEASED_LEASE_TIME"))
+ log_fatal ("can't allocate expression");
+ (*expr) -> op = expr_lease_time;
+ break;
+
case HOST_DECL_NAME:
token = next_token (&val, cfile);
if (!expression_allocate (expr,
#ifndef lint
static char copyright[] =
-"$Id: tree.c,v 1.33 1999/07/16 21:33:59 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
+"$Id: tree.c,v 1.34 1999/07/19 01:15:11 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
struct expression *expr;
{
struct data_string left, right;
+ struct data_string rrtype, expr1, expr2, ttl;
+ int s0, s1, s2, s3;
int bleft, bright;
int sleft, sright;
*result = packet -> known;
return 1;
+ case expr_dns_update:
+#if defined (NSUPDATE)
+ /* we only want to do this on a DHCPREQUEST */
+ if (packet -> packet_type != DHCPREQUEST)
+ return 0;
+ memset (&rrtype, 0, sizeof expr1);
+ s0 = evaluate_data_expression (&rrtype, packet, options, lease,
+ expr -> data.dns_update.type);
+ memset (&expr1, 0, sizeof expr1);
+ s1 = evaluate_data_expression (&expr1, packet, options, lease,
+ expr -> data.dns_update.expr1);
+ memset (&expr2, 0, sizeof expr2);
+ s2 = evaluate_data_expression (&expr2, packet, options, lease,
+ expr -> data.dns_update.expr2);
+ memset (&ttl, 0, sizeof ttl);
+ s3 = evaluate_data_expression (&ttl, packet, options, lease,
+ expr -> data.dns_update.ttl);
+
+ *result = 0; /* assume failure */
+ if (s0 && s1 && s2 && s3) {
+ if (rrtype.len == 1 &&
+ strncmp(rrtype.data, "a", 1) == 0) {
+log_info("calling updateA(expr1, expr2, %d, lease)", atol(ttl.data));
+ updateA(expr1, expr2, atol(ttl.data), lease);
+ } else if (rrtype.len == 3 &&
+ strncmp(rrtype.data, "ptr", 3) == 0) {
+log_info("calling updatePTR(expr1, expr2, %d, lease)", atol(ttl.data));
+ updatePTR(expr1, expr2, atol(ttl.data), lease);
+ }
+ *result = 1;
+ }
+#if defined (DEBUG_EXPRESSIONS)
+ log_info ("dns-update(%s, %s, %s):",
+ print_hex_1(rrtype.len, rrtype.data, 60),
+ print_hex_2(expr1.len, expr1.data, 60),
+ print_hex_3(expr2.len, expr2.data, 60));
+#endif
+ return 1;
+#else
+ return 0;
+#endif
+
case expr_substring:
case expr_suffix:
case expr_option:
case expr_host_decl_name:
case expr_config_option:
case expr_leased_address:
+ case expr_lease_time:
log_error ("Data opcode in evaluate_boolean_expression: %d",
expr -> op);
return 0;
struct expression *expr;
{
struct data_string data, other;
- unsigned long offset, len;
+ unsigned long offset, len, i;
int s0, s1, s2, s3;
int status;
#endif
return 1;
+ case expr_lease_time:
+ if (!lease) {
+ log_error ("data: leased_lease_time: not available");
+ return 0;
+ }
+ i = lease -> ends - lease -> starts;
+ if (buffer_allocate (&result -> buffer, 11, "lease-time")) {
+ result -> data = &result -> buffer -> data [0];
+#if defined (NO_SNPRINTF)
+ snprintf(result -> data, 11, "%lu", i);
+#else
+ snprintf(result -> data, 11, "%lu", i);
+#endif
+ result -> len = strlen(result -> data);
+ result -> terminated = 0;
+ } else {
+ log_error ("data: leased-lease-time: no memory.");
+ return 0;
+ }
+#if defined (DEBUG_EXPRESSIONS)
+ log_info ("data: leased-lease-time = %s",
+ print_hex_1 (result -> len, result -> data, 60));
+#endif
+ return 1;
+
case expr_check:
case expr_equal:
case expr_and:
case expr_const_int:
*result = expr -> data.const_int;
return 1;
+
}
log_error ("evaluate_numeric_expression: bogus opcode %d", expr -> op);
/* No subexpressions. */
case expr_leased_address:
+ case expr_lease_time:
case expr_const_int:
case expr_check:
case expr_option:
expr -> op == expr_equal ||
expr -> op == expr_and ||
expr -> op == expr_or ||
+ expr -> op == expr_dns_update ||
expr -> op == expr_not);
}
expr -> op == expr_host_lookup ||
expr -> op == expr_binary_to_ascii ||
expr -> op == expr_reverse ||
- expr -> op == expr_leased_address);
+ expr -> op == expr_leased_address ||
+ expr -> op == expr_lease_time);
}
int is_numeric_expression (expr)
struct lease *mockup_lease PROTO ((struct packet *,
struct shared_network *,
struct host_decl *));
-void static_lease_dereference PROTO ((struct lease *));
+void static_lease_dereference PROTO ((struct lease *, char *));
struct lease *allocate_lease PROTO ((struct packet *, struct pool *, int));
int permitted PROTO ((struct packet *, struct permit *));
EXPIRY = 409,
RELEASE = 410,
COMMIT = 411,
+ DNS_UPDATE = 412,
+ LEASE_TIME = 413,
};
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
expr_config_option,
expr_host_decl_name,
expr_pick_first_value,
+ expr_lease_time,
+ expr_dns_update,
};
struct expression {
struct expression *car;
struct expression *cdr;
} pick_first_value;
+ struct {
+ struct expression *type;
+ struct expression *expr1;
+ struct expression *expr2;
+ struct expression *ttl;
+ } dns_update;
} data;
int flags;
# define EXPR_EPHEMERAL 1
#ifndef lint
static char copyright[] =
-"$Id: bootp.c,v 1.52 1999/07/18 19:38:33 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: bootp.c,v 1.53 1999/07/19 01:15:22 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
/* Execute the commit statements, if there are any. */
execute_statements (packet, lease, packet -> options,
- state -> options, lease -> on_commit);
+ options, lease -> on_commit);
/* We're done with the option state. */
option_state_dereference (&options, "bootrequest");
#ifndef lint
static char copyright[] =
-"$Id: dhcp.c,v 1.102 1999/07/18 19:39:14 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dhcp.c,v 1.103 1999/07/19 01:15:22 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
/* If we found a lease, release it. */
if (lease) {
-#if defined (NSUPDATE)
+#if defined (NSUPDATE) && 0
nsupdate (lease, lease -> state, packet, DELETE);
#endif
/* If there are statements to execute when the lease is
committed, execute them. */
if (lease -> on_release) {
execute_statements (packet, lease, packet -> options,
- state -> options,
+ (struct option_state *)0, /* XXX */
lease -> on_release);
executable_statement_dereference (&lease -> on_release,
"dhcprelease");
hanging off the lease. */
/* why not update for static leases too? */
/* Because static leases aren't currently recorded? */
+/* XXX
#if defined (NSUPDATE)
if (!(lease -> flags & STATIC_LEASE) && offer == DHCPACK)
nsupdate (lease, state, packet, ADD);
#endif
+*/
/* If there are statements to execute when the lease is
committed, execute them. */