]> git.ipfire.org Git - people/ms/dnsmasq.git/commitdiff
Allow the TFP server or boot server in --pxe-service, to
authorSimon Kelley <simon@thekelleys.org.uk>
Fri, 10 Feb 2012 15:24:51 +0000 (15:24 +0000)
committerSimon Kelley <simon@thekelleys.org.uk>
Fri, 10 Feb 2012 15:24:51 +0000 (15:24 +0000)
 be a domain name instead of an IP address. This allows for
 round-robin to multiple servers, in the same way as
 --dhcp-boot.

CHANGELOG
man/dnsmasq.8
src/dnsmasq.h
src/option.c
src/rfc2131.c

index 532d52931de7ddcf5b20584975cba4272362fc58..f4d7a8b43edcd0342574003c87f4bf96fe35c68d 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -40,6 +40,11 @@ version 2.60
            Fix shell-scripting bug in bld/pkg-wrapper. Thanks to 
            Mark Mitchell for the patch.
 
+           Allow the TFP server or boot server in --pxe-service, to
+           be a domain name instead of an IP address. This allows for
+           round-robin to multiple servers, in the same way as
+           --dhcp-boot. A good suggestion from Cristiano Cumer.
+
            
 version 2.59
             Fix regression in 2.58 which caused failure to start up
index 7dc78425b5777394fea3a09178b78ee6fc4f3de3..474b9f697d35f45e20ae9bcf915719b978e0a950 100644 (file)
@@ -888,7 +888,7 @@ address, and setting this flag enables this mode. Note that in the
 sequential mode, clients which allow a lease to expire are much more
 likely to move IP address; for this reason it should not be generally used.
 .TP
-.B --pxe-service=[tag:<tag>,]<CSA>,<menu text>[,<basename>|<bootservicetype>][,<server address>]
+.B --pxe-service=[tag:<tag>,]<CSA>,<menu text>[,<basename>|<bootservicetype>][,<server address>|<server_name>]
 Most uses of PXE boot-ROMS simply allow the PXE
 system to obtain an IP address and then download the file specified by
 .B dhcp-boot
@@ -904,17 +904,19 @@ parameter after the menu text may be a file name, in which case dnsmasq acts as
 boot server and directs the PXE client to download the file by TFTP,
 either from itself (
 .B enable-tftp 
-must be set for this to work) or another TFTP server if the final IP
-address is given.
+must be set for this to work) or another TFTP server if the final server
+address/name is given.
 Note that the "layer"
 suffix (normally ".0") is supplied by PXE, and should not be added to
 the basename. If an integer boot service type, rather than a basename
 is given, then the PXE client will search for a
 suitable boot service for that type on the network. This search may be done
-by broadcast, or direct to a server if its IP address is provided.  
+by broadcast, or direct to a server if its IP address/name is provided.  
 If no boot service type or filename is provided (or a boot service type of 0 is specified)
 then the menu entry will abort the net boot procedure and
-continue booting from local media.
+continue booting from local media. The server address can be given as a domain
+name which is looked up in /etc/hosts. This name can be associated in
+/etc/hosts with multiple IP addresses, which are used round-robin.
 .TP
 .B --pxe-prompt=[tag:<tag>,]<prompt>[,<timeout>]
 Setting this provides a prompt to be displayed after PXE boot. If the
index bd18296dded30771cbaead3abc95b9b47b5eae1a..ec71e935792d308ea548a7dfebb23108d8fcd661 100644 (file)
@@ -547,7 +547,7 @@ struct dhcp_boot {
 
 struct pxe_service {
   unsigned short CSA, type; 
-  char *menu, *basename;
+  char *menu, *basename, *sname;
   struct in_addr server;
   struct dhcp_netid *netid;
   struct pxe_service *next;
index b0ae1e817a7c23769d34bf15299680d5df0200e3..5ac8d3cc22d7a8e6f7510bb0fca33c20060b2eda 100644 (file)
@@ -2384,6 +2384,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
         static int boottype = 32768;
         
         new->netid = NULL;
+        new->sname = NULL;
         new->server.s_addr = 0;
 
         while (is_tag_prefix(arg))
@@ -2430,10 +2431,17 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
                         new->basename = opt_string_alloc(arg);
                       }
                     
-                    if (comma && (new->server.s_addr = inet_addr(comma)) == (in_addr_t)-1)
-                      option = '?';
+                    if (comma)
+                      {
+                        if (!inet_pton(AF_INET, comma, &new->server))
+                          {
+                            new->server.s_addr = 0;
+                            new->sname = opt_string_alloc(comma);
+                          }
+                      
+                      }
                   }
-
+                
                 /* Order matters */
                 new->next = NULL;
                 if (!daemon->pxe_services)
index 0e075f9ec51b8a704650aac4ef1247a6d11ca487..673ca3618cc202323ba84546378b700162863887 100644 (file)
@@ -63,7 +63,7 @@ static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt);
 static int do_encap_opts(struct dhcp_opt *opts, int encap, int flag, struct dhcp_packet *mess, unsigned char *end, int null_term);
 static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char *uuid);
 static int prune_vendor_opts(struct dhcp_netid *netid);
-static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local);
+static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local, time_t now);
 struct dhcp_boot *find_boot(struct dhcp_netid *netid);
 
   
@@ -799,7 +799,9 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
          
          mess->yiaddr = mess->ciaddr;
          mess->ciaddr.s_addr = 0;
-         if (service->server.s_addr != 0)
+         if (service->sname)
+           mess->siaddr = a_record_from_hosts(service->sname, now);
+         else if (service->server.s_addr != 0)
            mess->siaddr = service->server; 
          else
            mess->siaddr = context->local; 
@@ -868,7 +870,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
                  option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context->local.s_addr));
                  pxe_misc(mess, end, uuid);
                  prune_vendor_opts(tagif_netid);
-                 do_encap_opts(pxe_opts(pxearch, tagif_netid, context->local), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
+                 do_encap_opts(pxe_opts(pxearch, tagif_netid, context->local, now), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
                  
                  log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "proxy-ignored" : "proxy", mess->xid);
                  log_tags(tagif_netid, mess);
@@ -2048,7 +2050,7 @@ static int prune_vendor_opts(struct dhcp_netid *netid)
   return force;
 }
 
-static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local)
+static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local, time_t now)
 {
 #define NUM_OPTS 4  
 
@@ -2105,8 +2107,9 @@ static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct
            return daemon->dhcp_opts;
          }
        
-       boot_server = service->basename ? local : service->server;
-
+       boot_server = service->basename ? local : 
+         (service->sname ? a_record_from_hosts(service->sname, now) : service->server);
+       
        if (boot_server.s_addr != 0)
          {
            if (q - (unsigned char *)daemon->dhcp_buff3 + 3 + INADDRSZ >= 253)
@@ -2579,7 +2582,7 @@ static void do_options(struct dhcp_context *context,
   if (context && pxe_arch != -1)
     {
       pxe_misc(mess, end, uuid);
-      config_opts = pxe_opts(pxe_arch, tagif, context->local);
+      config_opts = pxe_opts(pxe_arch, tagif, context->local, now);
     }
 
   if ((force_encap || in_list(req_options, OPTION_VENDOR_CLASS_OPT)) &&