]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Brian Murrel's latest dns update implementation - more programmability.
authorTed Lemon <source@isc.org>
Mon, 19 Jul 1999 01:15:22 +0000 (01:15 +0000)
committerTed Lemon <source@isc.org>
Mon, 19 Jul 1999 01:15:22 +0000 (01:15 +0000)
common/conflex.c
common/nsupdate.c
common/parse.c
common/tree.c
includes/dhcpd.h
includes/dhctoken.h
includes/tree.h
server/bootp.c
server/dhcp.c

index 1d88882a7c3774b53005c54f6064d42e1a585ba7..08f89b873eae3f6d8ef9f22c74ee001522ab5412 100644 (file)
@@ -22,7 +22,7 @@
 
 #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"
@@ -414,6 +414,8 @@ static enum dhcp_token intern (atom, dfv)
                        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"))
@@ -513,6 +515,8 @@ static enum dhcp_token intern (atom, dfv)
                        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;
index daf3ee6a91496d0fdbb523ee472d126f0c68a6f0..b6463d97c0e8ede0436aec241db2fc1aa8fc8dbc 100644 (file)
@@ -25,7 +25,7 @@
 
 #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"
@@ -38,7 +38,8 @@ static char copyright[] =
    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;
@@ -176,8 +177,9 @@ char *ddns_fwd_name(lease, state, packet)
 #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;
@@ -237,7 +239,7 @@ int nsupdateA(hostname, ip_addr, ttl, opcode)
        return z;
 }
 
-int nsupdatePTR(hostname, revname, ttl, opcode)
+static int nsupdatePTR(revname, hostname, ttl, opcode)
        char *hostname;
        char *revname;
        u_int32_t ttl;
@@ -262,6 +264,7 @@ int nsupdatePTR(hostname, revname, ttl, opcode)
        return z;
 }
 
+#if 0
 void nsupdate(lease, state, packet, opcode)
        struct lease *lease;
        struct lease_state *state;
@@ -271,6 +274,7 @@ void nsupdate(lease, state, packet, opcode)
        char    *hostname, *revname;
        u_int32_t       ttl = 0;
 
+return;
        if (!(opcode == ADD || opcode == DELETE))
                return;
 
@@ -325,7 +329,7 @@ void nsupdate(lease, state, packet, opcode)
                        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)
@@ -366,7 +370,7 @@ void nsupdate(lease, state, packet, opcode)
 
                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");
@@ -382,8 +386,9 @@ void nsupdate(lease, state, packet, opcode)
                                      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,
@@ -404,4 +409,95 @@ void nsupdate(lease, state, packet, opcode)
        
        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) */
index fed33e1342939654a9bb1d8e0625757ee1eb276c..871d679d058ee3046af801224c9abd5a2c997019 100644 (file)
@@ -22,7 +22,7 @@
 
 #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"
@@ -1883,6 +1883,67 @@ int parse_non_binary (expr, cfile, lose, context)
                        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"))
@@ -1915,6 +1976,14 @@ int parse_non_binary (expr, cfile, lose, context)
                (*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,
index 466e4cbdfdbb26f24c294270012ddbb7dfe71ef7..3f61436f47e47eb5259824ac5fdd9703b12133bf 100644 (file)
@@ -22,7 +22,7 @@
 
 #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"
@@ -386,6 +386,8 @@ int evaluate_boolean_expression (result, packet, options, lease, expr)
        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;
 
@@ -524,6 +526,48 @@ int evaluate_boolean_expression (result, packet, options, lease, expr)
                *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:
@@ -542,6 +586,7 @@ int evaluate_boolean_expression (result, packet, options, lease, expr)
              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;
@@ -568,7 +613,7 @@ int evaluate_data_expression (result, packet, options, lease, expr)
        struct expression *expr;
 {
        struct data_string data, other;
-       unsigned long offset, len;
+       unsigned long offset, len, i;
        int s0, s1, s2, s3;
        int status;
 
@@ -1150,6 +1195,31 @@ int evaluate_data_expression (result, packet, options, lease, expr)
 #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:
@@ -1271,6 +1341,7 @@ int evaluate_numeric_expression (result, packet, options, lease, expr)
              case expr_const_int:
                *result = expr -> data.const_int;
                return 1;
+
        }
 
        log_error ("evaluate_numeric_expression: bogus opcode %d", expr -> op);
@@ -1484,6 +1555,7 @@ void expression_dereference (eptr, name)
 
                /* No subexpressions. */
              case expr_leased_address:
+             case expr_lease_time:
              case expr_const_int:
              case expr_check:
              case expr_option:
@@ -1547,6 +1619,7 @@ int is_boolean_expression (expr)
                expr -> op == expr_equal ||
                expr -> op == expr_and ||
                expr -> op == expr_or ||
+               expr -> op == expr_dns_update ||
                expr -> op == expr_not);
 }
 
@@ -1567,7 +1640,8 @@ int is_data_expression (expr)
                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)
index 72d227f60be2edb763147ddf8de932fa07e97ca5..a8f61e0d628c96be149170f07ee24c26f9595dfb 100644 (file)
@@ -996,7 +996,7 @@ struct lease *find_lease PROTO ((struct packet *,
 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 *));
index 203526cd5308a30a548ebd1a9de50a7f0945b29a..73626ba5a521a58211612b85aebf8fa0886f8386 100644 (file)
@@ -191,6 +191,8 @@ enum dhcp_token {
        EXPIRY = 409,
        RELEASE = 410,
        COMMIT = 411,
+       DNS_UPDATE = 412,
+       LEASE_TIME = 413,
 };
 
 #define is_identifier(x)       ((x) >= FIRST_TOKEN &&  \
index b80066b4cb9974c316fd8ede291105c17023f19d..065f8d939ac5400299e9480cb459543ea2ebde13 100644 (file)
@@ -89,6 +89,8 @@ enum expr_op {
        expr_config_option,
        expr_host_decl_name,
        expr_pick_first_value,
+       expr_lease_time,
+       expr_dns_update,
 };
 
 struct expression {
@@ -137,6 +139,12 @@ 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
index eed80eb50df16875eeda7755218b4b95ebc38577..577890c3e233411a5535c97986a4cdf76205d4bd 100644 (file)
@@ -22,7 +22,7 @@
 
 #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"
@@ -268,7 +268,7 @@ void bootp (packet)
 
        /* 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");
index b7f95121ad28cf0921707dd0146f4b39fccdce4b..dfe82bbe21ecde38996c22d5768e724d2350f5b3 100644 (file)
@@ -22,7 +22,7 @@
 
 #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"
@@ -294,14 +294,14 @@ void dhcprelease (packet)
 
        /* 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");
@@ -1254,10 +1254,12 @@ void ack_lease (packet, lease, offer, when, msg)
           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. */