2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-30 13:57:50 +00:00

Brian Murrel's latest dns update implementation - more programmability.

This commit is contained in:
Ted Lemon
1999-07-19 01:15:22 +00:00
parent 0f7099d754
commit 069e9f4c15
9 changed files with 274 additions and 19 deletions

View File

@@ -22,7 +22,7 @@
#ifndef lint #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@@ -414,6 +414,8 @@ static enum dhcp_token intern (atom, dfv)
return DDNS_FWD_NAME; return DDNS_FWD_NAME;
if (!strcasecmp (atom + 1, "dns-rev-name")) if (!strcasecmp (atom + 1, "dns-rev-name"))
return DDNS_REV_NAME; return DDNS_REV_NAME;
if (!strcasecmp (atom + 1, "ns-update"))
return DNS_UPDATE;
if (!strcasecmp (atom + 1, "omain")) if (!strcasecmp (atom + 1, "omain"))
return DOMAIN; return DOMAIN;
if (!strcasecmp (atom + 1, "eny")) if (!strcasecmp (atom + 1, "eny"))
@@ -513,6 +515,8 @@ static enum dhcp_token intern (atom, dfv)
return LEASE; return LEASE;
if (!strcasecmp (atom + 1, "eased-address")) if (!strcasecmp (atom + 1, "eased-address"))
return LEASED_ADDRESS; return LEASED_ADDRESS;
if (!strcasecmp (atom + 1, "lease-time"))
return LEASE_TIME;
if (!strcasecmp (atom + 1, "imit")) if (!strcasecmp (atom + 1, "imit"))
return LIMIT; return LIMIT;
break; break;

View File

@@ -25,7 +25,7 @@
#ifndef lint #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@@ -38,7 +38,8 @@ static char copyright[] =
necessary which can be any combination and number of remove A, add A, necessary which can be any combination and number of remove A, add A,
remove PTR, add PTR */ 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) char *ddns_rev_name(lease, state, packet)
struct lease *lease; struct lease *lease;
struct lease_state *state; struct lease_state *state;
@@ -176,8 +177,9 @@ char *ddns_fwd_name(lease, state, packet)
#endif #endif
return hostname; return hostname;
} }
#endif
int nsupdateA(hostname, ip_addr, ttl, opcode) static int nsupdateA(hostname, ip_addr, ttl, opcode)
char *hostname; char *hostname;
char *ip_addr; char *ip_addr;
u_int32_t ttl; u_int32_t ttl;
@@ -237,7 +239,7 @@ int nsupdateA(hostname, ip_addr, ttl, opcode)
return z; return z;
} }
int nsupdatePTR(hostname, revname, ttl, opcode) static int nsupdatePTR(revname, hostname, ttl, opcode)
char *hostname; char *hostname;
char *revname; char *revname;
u_int32_t ttl; u_int32_t ttl;
@@ -262,6 +264,7 @@ int nsupdatePTR(hostname, revname, ttl, opcode)
return z; return z;
} }
#if 0
void nsupdate(lease, state, packet, opcode) void nsupdate(lease, state, packet, opcode)
struct lease *lease; struct lease *lease;
struct lease_state *state; struct lease_state *state;
@@ -271,6 +274,7 @@ void nsupdate(lease, state, packet, opcode)
char *hostname, *revname; char *hostname, *revname;
u_int32_t ttl = 0; u_int32_t ttl = 0;
return;
if (!(opcode == ADD || opcode == DELETE)) if (!(opcode == ADD || opcode == DELETE))
return; return;
@@ -325,7 +329,7 @@ void nsupdate(lease, state, packet, opcode)
if (lease -> ddns_rev_name && if (lease -> ddns_rev_name &&
(strcmp(hostname, lease -> ddns_fwd_name) || (strcmp(hostname, lease -> ddns_fwd_name) ||
strcmp(revname, lease -> ddns_rev_name)) && strcmp(revname, lease -> ddns_rev_name)) &&
nsupdatePTR(lease -> ddns_fwd_name, revname, nsupdatePTR(revname, lease -> ddns_fwd_name,
ttl, DELETE)) { ttl, DELETE)) {
/* clear the forward DNS name pointer */ /* clear the forward DNS name pointer */
if (lease -> ddns_rev_name) if (lease -> ddns_rev_name)
@@ -366,7 +370,7 @@ void nsupdate(lease, state, packet, opcode)
if (!lease -> ddns_rev_name) { if (!lease -> ddns_rev_name) {
/* add a PTR RR */ /* add a PTR RR */
if (nsupdatePTR(hostname, revname, ttl, ADD)) { if (nsupdatePTR(revname, hostname, ttl, ADD)) {
/* remember in the lease struct for a release */ /* remember in the lease struct for a release */
lease -> ddns_rev_name = lease -> ddns_rev_name =
dmalloc(strlen(revname) + 1, "nsupdate"); dmalloc(strlen(revname) + 1, "nsupdate");
@@ -382,8 +386,9 @@ void nsupdate(lease, state, packet, opcode)
piaddr(lease->ip_addr), ttl, DELETE); piaddr(lease->ip_addr), ttl, DELETE);
if (lease -> ddns_rev_name && if (lease -> ddns_rev_name &&
nsupdatePTR(lease -> ddns_fwd_name, nsupdatePTR(lease -> ddns_rev_name,
lease -> ddns_rev_name, ttl, opcode)) { lease -> ddns_fwd_name,
ttl, opcode)) {
/* clear the reverse DNS name pointer */ /* clear the reverse DNS name pointer */
if (lease -> ddns_rev_name) if (lease -> ddns_rev_name)
dfree(lease -> ddns_rev_name, dfree(lease -> ddns_rev_name,
@@ -404,4 +409,95 @@ void nsupdate(lease, state, packet, opcode)
return; 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) */ #endif /* defined (NSUPDATE) */

View File

@@ -22,7 +22,7 @@
#ifndef lint #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@@ -1883,6 +1883,67 @@ int parse_non_binary (expr, cfile, lose, context)
goto norparen; goto norparen;
break; 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 OPTION:
case CONFIG_OPTION: case CONFIG_OPTION:
if (!expression_allocate (expr, "parse_expression: OPTION")) if (!expression_allocate (expr, "parse_expression: OPTION"))
@@ -1915,6 +1976,14 @@ int parse_non_binary (expr, cfile, lose, context)
(*expr) -> op = expr_leased_address; (*expr) -> op = expr_leased_address;
break; 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: case HOST_DECL_NAME:
token = next_token (&val, cfile); token = next_token (&val, cfile);
if (!expression_allocate (expr, if (!expression_allocate (expr,

View File

@@ -22,7 +22,7 @@
#ifndef lint #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@@ -386,6 +386,8 @@ int evaluate_boolean_expression (result, packet, options, lease, expr)
struct expression *expr; struct expression *expr;
{ {
struct data_string left, right; struct data_string left, right;
struct data_string rrtype, expr1, expr2, ttl;
int s0, s1, s2, s3;
int bleft, bright; int bleft, bright;
int sleft, sright; int sleft, sright;
@@ -524,6 +526,48 @@ int evaluate_boolean_expression (result, packet, options, lease, expr)
*result = packet -> known; *result = packet -> known;
return 1; 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_substring:
case expr_suffix: case expr_suffix:
case expr_option: case expr_option:
@@ -542,6 +586,7 @@ int evaluate_boolean_expression (result, packet, options, lease, expr)
case expr_host_decl_name: case expr_host_decl_name:
case expr_config_option: case expr_config_option:
case expr_leased_address: case expr_leased_address:
case expr_lease_time:
log_error ("Data opcode in evaluate_boolean_expression: %d", log_error ("Data opcode in evaluate_boolean_expression: %d",
expr -> op); expr -> op);
return 0; return 0;
@@ -568,7 +613,7 @@ int evaluate_data_expression (result, packet, options, lease, expr)
struct expression *expr; struct expression *expr;
{ {
struct data_string data, other; struct data_string data, other;
unsigned long offset, len; unsigned long offset, len, i;
int s0, s1, s2, s3; int s0, s1, s2, s3;
int status; int status;
@@ -1150,6 +1195,31 @@ int evaluate_data_expression (result, packet, options, lease, expr)
#endif #endif
return 1; 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_check:
case expr_equal: case expr_equal:
case expr_and: case expr_and:
@@ -1271,6 +1341,7 @@ int evaluate_numeric_expression (result, packet, options, lease, expr)
case expr_const_int: case expr_const_int:
*result = expr -> data.const_int; *result = expr -> data.const_int;
return 1; return 1;
} }
log_error ("evaluate_numeric_expression: bogus opcode %d", expr -> op); log_error ("evaluate_numeric_expression: bogus opcode %d", expr -> op);
@@ -1484,6 +1555,7 @@ void expression_dereference (eptr, name)
/* No subexpressions. */ /* No subexpressions. */
case expr_leased_address: case expr_leased_address:
case expr_lease_time:
case expr_const_int: case expr_const_int:
case expr_check: case expr_check:
case expr_option: case expr_option:
@@ -1547,6 +1619,7 @@ int is_boolean_expression (expr)
expr -> op == expr_equal || expr -> op == expr_equal ||
expr -> op == expr_and || expr -> op == expr_and ||
expr -> op == expr_or || expr -> op == expr_or ||
expr -> op == expr_dns_update ||
expr -> op == expr_not); expr -> op == expr_not);
} }
@@ -1567,7 +1640,8 @@ int is_data_expression (expr)
expr -> op == expr_host_lookup || expr -> op == expr_host_lookup ||
expr -> op == expr_binary_to_ascii || expr -> op == expr_binary_to_ascii ||
expr -> op == expr_reverse || expr -> op == expr_reverse ||
expr -> op == expr_leased_address); expr -> op == expr_leased_address ||
expr -> op == expr_lease_time);
} }
int is_numeric_expression (expr) int is_numeric_expression (expr)

View File

@@ -996,7 +996,7 @@ struct lease *find_lease PROTO ((struct packet *,
struct lease *mockup_lease PROTO ((struct packet *, struct lease *mockup_lease PROTO ((struct packet *,
struct shared_network *, struct shared_network *,
struct host_decl *)); 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)); struct lease *allocate_lease PROTO ((struct packet *, struct pool *, int));
int permitted PROTO ((struct packet *, struct permit *)); int permitted PROTO ((struct packet *, struct permit *));

View File

@@ -191,6 +191,8 @@ enum dhcp_token {
EXPIRY = 409, EXPIRY = 409,
RELEASE = 410, RELEASE = 410,
COMMIT = 411, COMMIT = 411,
DNS_UPDATE = 412,
LEASE_TIME = 413,
}; };
#define is_identifier(x) ((x) >= FIRST_TOKEN && \ #define is_identifier(x) ((x) >= FIRST_TOKEN && \

View File

@@ -89,6 +89,8 @@ enum expr_op {
expr_config_option, expr_config_option,
expr_host_decl_name, expr_host_decl_name,
expr_pick_first_value, expr_pick_first_value,
expr_lease_time,
expr_dns_update,
}; };
struct expression { struct expression {
@@ -137,6 +139,12 @@ struct expression {
struct expression *car; struct expression *car;
struct expression *cdr; struct expression *cdr;
} pick_first_value; } pick_first_value;
struct {
struct expression *type;
struct expression *expr1;
struct expression *expr2;
struct expression *ttl;
} dns_update;
} data; } data;
int flags; int flags;
# define EXPR_EPHEMERAL 1 # define EXPR_EPHEMERAL 1

View File

@@ -22,7 +22,7 @@
#ifndef lint #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@@ -268,7 +268,7 @@ void bootp (packet)
/* Execute the commit statements, if there are any. */ /* Execute the commit statements, if there are any. */
execute_statements (packet, lease, packet -> options, execute_statements (packet, lease, packet -> options,
state -> options, lease -> on_commit); options, lease -> on_commit);
/* We're done with the option state. */ /* We're done with the option state. */
option_state_dereference (&options, "bootrequest"); option_state_dereference (&options, "bootrequest");

View File

@@ -22,7 +22,7 @@
#ifndef lint #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@@ -294,14 +294,14 @@ void dhcprelease (packet)
/* If we found a lease, release it. */ /* If we found a lease, release it. */
if (lease) { if (lease) {
#if defined (NSUPDATE) #if defined (NSUPDATE) && 0
nsupdate (lease, lease -> state, packet, DELETE); nsupdate (lease, lease -> state, packet, DELETE);
#endif #endif
/* If there are statements to execute when the lease is /* If there are statements to execute when the lease is
committed, execute them. */ committed, execute them. */
if (lease -> on_release) { if (lease -> on_release) {
execute_statements (packet, lease, packet -> options, execute_statements (packet, lease, packet -> options,
state -> options, (struct option_state *)0, /* XXX */
lease -> on_release); lease -> on_release);
executable_statement_dereference (&lease -> on_release, executable_statement_dereference (&lease -> on_release,
"dhcprelease"); "dhcprelease");
@@ -1254,10 +1254,12 @@ void ack_lease (packet, lease, offer, when, msg)
hanging off the lease. */ hanging off the lease. */
/* why not update for static leases too? */ /* why not update for static leases too? */
/* Because static leases aren't currently recorded? */ /* Because static leases aren't currently recorded? */
/* XXX
#if defined (NSUPDATE) #if defined (NSUPDATE)
if (!(lease -> flags & STATIC_LEASE) && offer == DHCPACK) if (!(lease -> flags & STATIC_LEASE) && offer == DHCPACK)
nsupdate (lease, state, packet, ADD); nsupdate (lease, state, packet, ADD);
#endif #endif
*/
/* If there are statements to execute when the lease is /* If there are statements to execute when the lease is
committed, execute them. */ committed, execute them. */