Home | History | Annotate | Download | only in src
      1 /* dnsmasq is Copyright (c) 2000-2009 Simon Kelley
      2 
      3    This program is free software; you can redistribute it and/or modify
      4    it under the terms of the GNU General Public License as published by
      5    the Free Software Foundation; version 2 dated June, 1991, or
      6    (at your option) version 3 dated 29 June, 2007.
      7 
      8    This program is distributed in the hope that it will be useful,
      9    but WITHOUT ANY WARRANTY; without even the implied warranty of
     10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11    GNU General Public License for more details.
     12 
     13    You should have received a copy of the GNU General Public License
     14    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15 */
     16 
     17 #include "dnsmasq.h"
     18 
     19 #ifdef HAVE_DHCP
     20 
     21 #define BOOTREQUEST 1
     22 #define BOOTREPLY 2
     23 #define DHCP_COOKIE 0x63825363
     24 
     25 /* The Linux in-kernel DHCP client silently ignores any packet
     26    smaller than this. Sigh...........   */
     27 #define MIN_PACKETSZ 300
     28 
     29 #define OPTION_PAD 0
     30 #define OPTION_NETMASK 1
     31 #define OPTION_ROUTER 3
     32 #define OPTION_DNSSERVER 6
     33 #define OPTION_HOSTNAME 12
     34 #define OPTION_DOMAINNAME 15
     35 #define OPTION_BROADCAST 28
     36 #define OPTION_VENDOR_CLASS_OPT 43
     37 #define OPTION_REQUESTED_IP 50
     38 #define OPTION_LEASE_TIME 51
     39 #define OPTION_OVERLOAD 52
     40 #define OPTION_MESSAGE_TYPE 53
     41 #define OPTION_SERVER_IDENTIFIER 54
     42 #define OPTION_REQUESTED_OPTIONS 55
     43 #define OPTION_MESSAGE 56
     44 #define OPTION_MAXMESSAGE 57
     45 #define OPTION_T1 58
     46 #define OPTION_T2 59
     47 #define OPTION_VENDOR_ID 60
     48 #define OPTION_CLIENT_ID 61
     49 #define OPTION_SNAME 66
     50 #define OPTION_FILENAME 67
     51 #define OPTION_USER_CLASS 77
     52 #define OPTION_CLIENT_FQDN 81
     53 #define OPTION_AGENT_ID 82
     54 #define OPTION_ARCH 93
     55 #define OPTION_PXE_UUID 97
     56 #define OPTION_SUBNET_SELECT 118
     57 #define OPTION_END 255
     58 
     59 #define SUBOPT_CIRCUIT_ID 1
     60 #define SUBOPT_REMOTE_ID 2
     61 #define SUBOPT_SUBNET_SELECT 5 /* RFC 3527 */
     62 #define SUBOPT_SUBSCR_ID 6     /* RFC 3393 */
     63 #define SUBOPT_SERVER_OR 11    /* RFC 5107 */
     64 
     65 #define SUBOPT_PXE_BOOT_ITEM 71 /* PXE standard */
     66 #define SUBOPT_PXE_DISCOVERY 6
     67 #define SUBOPT_PXE_SERVERS 8
     68 #define SUBOPT_PXE_MENU 9
     69 #define SUBOPT_PXE_MENU_PROMPT 10
     70 
     71 #define DHCPDISCOVER 1
     72 #define DHCPOFFER 2
     73 #define DHCPREQUEST 3
     74 #define DHCPDECLINE 4
     75 #define DHCPACK 5
     76 #define DHCPNAK 6
     77 #define DHCPRELEASE 7
     78 #define DHCPINFORM 8
     79 
     80 #define have_config(config, mask) ((config) && ((config)->flags & (mask)))
     81 #define option_len(opt) ((int) (((unsigned char*) (opt))[1]))
     82 #define option_ptr(opt, i) ((void*) &(((unsigned char*) (opt))[2u + (unsigned int) (i)]))
     83 
     84 static int sanitise(unsigned char* opt, char* buf);
     85 static struct in_addr server_id(struct dhcp_context* context, struct in_addr override,
     86                                 struct in_addr fallback);
     87 static unsigned int calc_time(struct dhcp_context* context, struct dhcp_config* config,
     88                               unsigned char* opt);
     89 static void option_put(struct dhcp_packet* mess, unsigned char* end, int opt, int len,
     90                        unsigned int val);
     91 static void option_put_string(struct dhcp_packet* mess, unsigned char* end, int opt, char* string,
     92                               int null_term);
     93 static struct in_addr option_addr(unsigned char* opt);
     94 static struct in_addr option_addr_arr(unsigned char* opt, int offset);
     95 static unsigned int option_uint(unsigned char* opt, int i, int size);
     96 static void log_packet(char* type, void* addr, unsigned char* ext_mac, int mac_len, char* interface,
     97                        char* string, u32 xid);
     98 static unsigned char* option_find(struct dhcp_packet* mess, size_t size, int opt_type, int minsize);
     99 static unsigned char* option_find1(unsigned char* p, unsigned char* end, int opt, int minsize);
    100 static size_t dhcp_packet_size(struct dhcp_packet* mess, struct dhcp_netid* netid,
    101                                unsigned char* agent_id, unsigned char* real_end);
    102 static void clear_packet(struct dhcp_packet* mess, unsigned char* end);
    103 static void do_options(struct dhcp_context* context, struct dhcp_packet* mess,
    104                        unsigned char* real_end, unsigned char* req_options, char* hostname,
    105                        char* domain, char* config_domain, struct dhcp_netid* netid,
    106                        struct in_addr subnet_addr, unsigned char fqdn_flags, int null_term,
    107                        int pxearch, unsigned char* uuid);
    108 
    109 static void match_vendor_opts(unsigned char* opt, struct dhcp_opt* dopt);
    110 static void do_encap_opts(struct dhcp_opt* opts, int encap, int flag, struct dhcp_packet* mess,
    111                           unsigned char* end, int null_term);
    112 static void pxe_misc(struct dhcp_packet* mess, unsigned char* end, unsigned char* uuid);
    113 static int prune_vendor_opts(struct dhcp_netid* netid);
    114 static struct dhcp_opt* pxe_opts(int pxe_arch, struct dhcp_netid* netid);
    115 struct dhcp_boot* find_boot(struct dhcp_netid* netid);
    116 
    117 size_t dhcp_reply(struct dhcp_context* context, char* iface_name, int int_index, size_t sz,
    118                   time_t now, int unicast_dest, int* is_inform) {
    119     unsigned char *opt, *clid = NULL;
    120     struct dhcp_lease *ltmp, *lease = NULL;
    121     struct dhcp_vendor* vendor;
    122     struct dhcp_mac* mac;
    123     struct dhcp_netid_list* id_list;
    124     int clid_len = 0, ignore = 0, do_classes = 0, selecting = 0, pxearch = -1;
    125     struct dhcp_packet* mess = (struct dhcp_packet*) daemon->dhcp_packet.iov_base;
    126     unsigned char* end = (unsigned char*) (mess + 1);
    127     unsigned char* real_end = (unsigned char*) (mess + 1);
    128     char *hostname = NULL, *offer_hostname = NULL, *client_hostname = NULL, *domain = NULL;
    129     int hostname_auth = 0, borken_opt = 0;
    130     unsigned char* req_options = NULL;
    131     char* message = NULL;
    132     unsigned int time;
    133     struct dhcp_config* config;
    134     struct dhcp_netid* netid;
    135     struct in_addr subnet_addr, fallback, override;
    136     unsigned short fuzz = 0;
    137     unsigned int mess_type = 0;
    138     unsigned char fqdn_flags = 0;
    139     unsigned char *agent_id = NULL, *uuid = NULL;
    140     unsigned char* emac = NULL;
    141     int emac_len = 0;
    142     struct dhcp_netid known_id, iface_id;
    143     struct dhcp_opt* o;
    144     unsigned char pxe_uuid[17];
    145 
    146     subnet_addr.s_addr = override.s_addr = 0;
    147 
    148     /* set tag with name == interface */
    149     iface_id.net = iface_name;
    150     iface_id.next = NULL;
    151     netid = &iface_id;
    152 
    153     if (mess->op != BOOTREQUEST || mess->hlen > DHCP_CHADDR_MAX) return 0;
    154 
    155     if (mess->htype == 0 && mess->hlen != 0) return 0;
    156 
    157     /* check for DHCP rather than BOOTP */
    158     if ((opt = option_find(mess, sz, OPTION_MESSAGE_TYPE, 1))) {
    159         mess_type = option_uint(opt, 0, 1);
    160 
    161         /* only insist on a cookie for DHCP. */
    162         if (*((u32*) &mess->options) != htonl(DHCP_COOKIE)) return 0;
    163 
    164         /* two things to note here: expand_buf may move the packet,
    165        so reassign mess from daemon->packet. Also, the size
    166        sent includes the IP and UDP headers, hence the magic "-28" */
    167         if ((opt = option_find(mess, sz, OPTION_MAXMESSAGE, 2))) {
    168             size_t size = (size_t) option_uint(opt, 0, 2) - 28;
    169 
    170             if (size > DHCP_PACKET_MAX)
    171                 size = DHCP_PACKET_MAX;
    172             else if (size < sizeof(struct dhcp_packet))
    173                 size = sizeof(struct dhcp_packet);
    174 
    175             if (expand_buf(&daemon->dhcp_packet, size)) {
    176                 mess = (struct dhcp_packet*) daemon->dhcp_packet.iov_base;
    177                 real_end = end = ((unsigned char*) mess) + size;
    178             }
    179         }
    180 
    181         /* Some buggy clients set ciaddr when they shouldn't, so clear that here since
    182        it can affect the context-determination code. */
    183         if ((option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ) || mess_type == DHCPDISCOVER))
    184             mess->ciaddr.s_addr = 0;
    185 
    186         if ((opt = option_find(mess, sz, OPTION_AGENT_ID, 1))) {
    187             /* Any agent-id needs to be copied back out, verbatim, as the last option
    188                in the packet. Here, we shift it to the very end of the buffer, if it doesn't
    189                get overwritten, then it will be shuffled back at the end of processing.
    190                Note that the incoming options must not be overwritten here, so there has to
    191                be enough free space at the end of the packet to copy the option. */
    192             unsigned char* sopt;
    193             unsigned int total = option_len(opt) + 2;
    194             unsigned char* last_opt = option_find(mess, sz, OPTION_END, 0);
    195             if (last_opt && last_opt < end - total) {
    196                 end -= total;
    197                 agent_id = end;
    198                 memcpy(agent_id, opt, total);
    199             }
    200 
    201             /* look for RFC3527 Link selection sub-option */
    202             if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)),
    203                                      SUBOPT_SUBNET_SELECT, INADDRSZ)))
    204                 subnet_addr = option_addr(sopt);
    205 
    206             /* look for RFC5107 server-identifier-override */
    207             if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)),
    208                                      SUBOPT_SERVER_OR, INADDRSZ)))
    209                 override = option_addr(sopt);
    210 
    211             /* if a circuit-id or remote-is option is provided, exact-match to options. */
    212             for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next) {
    213                 int search;
    214 
    215                 if (vendor->match_type == MATCH_CIRCUIT)
    216                     search = SUBOPT_CIRCUIT_ID;
    217                 else if (vendor->match_type == MATCH_REMOTE)
    218                     search = SUBOPT_REMOTE_ID;
    219                 else if (vendor->match_type == MATCH_SUBSCRIBER)
    220                     search = SUBOPT_SUBSCR_ID;
    221                 else
    222                     continue;
    223 
    224                 if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)),
    225                                          search, 1)) &&
    226                     vendor->len == option_len(sopt) &&
    227                     memcmp(option_ptr(sopt, 0), vendor->data, vendor->len) == 0) {
    228                     vendor->netid.next = netid;
    229                     netid = &vendor->netid;
    230                     break;
    231                 }
    232             }
    233         }
    234 
    235         /* Check for RFC3011 subnet selector - only if RFC3527 one not present */
    236         if (subnet_addr.s_addr == 0 && (opt = option_find(mess, sz, OPTION_SUBNET_SELECT, INADDRSZ)))
    237             subnet_addr = option_addr(opt);
    238 
    239         /* If there is no client identifier option, use the hardware address */
    240         if ((opt = option_find(mess, sz, OPTION_CLIENT_ID, 1))) {
    241             clid_len = option_len(opt);
    242             clid = option_ptr(opt, 0);
    243         }
    244 
    245         /* do we have a lease in store? */
    246         lease = lease_find_by_client(mess->chaddr, mess->hlen, mess->htype, clid, clid_len);
    247 
    248         /* If this request is missing a clid, but we've seen one before,
    249        use it again for option matching etc. */
    250         if (lease && !clid && lease->clid) {
    251             clid_len = lease->clid_len;
    252             clid = lease->clid;
    253         }
    254 
    255         /* find mac to use for logging and hashing */
    256         emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
    257     }
    258 
    259     for (mac = daemon->dhcp_macs; mac; mac = mac->next)
    260         if (mac->hwaddr_len == mess->hlen &&
    261             (mac->hwaddr_type == mess->htype || mac->hwaddr_type == 0) &&
    262             memcmp_masked(mac->hwaddr, mess->chaddr, mess->hlen, mac->mask)) {
    263             mac->netid.next = netid;
    264             netid = &mac->netid;
    265         }
    266 
    267     /* Determine network for this packet. Our caller will have already linked all the
    268        contexts which match the addresses of the receiving interface but if the
    269        machine has an address already, or came via a relay, or we have a subnet selector,
    270        we search again. If we don't have have a giaddr or explicit subnet selector,
    271        use the ciaddr. This is necessary because a  machine which got a lease via a
    272        relay won't use the relay to renew. If matching a ciaddr fails but we have a context
    273        from the physical network, continue using that to allow correct DHCPNAK generation later. */
    274     if (mess->giaddr.s_addr || subnet_addr.s_addr || mess->ciaddr.s_addr) {
    275         struct dhcp_context *context_tmp, *context_new = NULL;
    276         struct in_addr addr;
    277         int force = 0;
    278 
    279         if (subnet_addr.s_addr) {
    280             addr = subnet_addr;
    281             force = 1;
    282         } else if (mess->giaddr.s_addr) {
    283             addr = mess->giaddr;
    284             force = 1;
    285         } else {
    286             /* If ciaddr is in the hardware derived set of contexts, leave that unchanged */
    287             addr = mess->ciaddr;
    288             for (context_tmp = context; context_tmp; context_tmp = context_tmp->current)
    289                 if (context_tmp->netmask.s_addr &&
    290                     is_same_net(addr, context_tmp->start, context_tmp->netmask) &&
    291                     is_same_net(addr, context_tmp->end, context_tmp->netmask)) {
    292                     context_new = context;
    293                     break;
    294                 }
    295         }
    296 
    297         if (!context_new)
    298             for (context_tmp = daemon->dhcp; context_tmp; context_tmp = context_tmp->next)
    299                 if (context_tmp->netmask.s_addr &&
    300                     is_same_net(addr, context_tmp->start, context_tmp->netmask) &&
    301                     is_same_net(addr, context_tmp->end, context_tmp->netmask)) {
    302                     context_tmp->current = context_new;
    303                     context_new = context_tmp;
    304                 }
    305 
    306         if (context_new || force) context = context_new;
    307     }
    308 
    309     if (!context) {
    310         //      my_syslog(MS_DHCP | LOG_WARNING, _("no address range available for DHCP request %s
    311         //      %s"),
    312         //		subnet_addr.s_addr ? _("with subnet selector") : _("via"),
    313         //		subnet_addr.s_addr ? inet_ntoa(subnet_addr) : (mess->giaddr.s_addr ?
    314         //inet_ntoa(mess->giaddr) : iface_name));
    315         return 0;
    316     }
    317 
    318     /* keep _a_ local address available. */
    319     fallback = context->local;
    320 
    321     if (daemon->options & OPT_LOG_OPTS) {
    322         struct dhcp_context* context_tmp;
    323         for (context_tmp = context; context_tmp; context_tmp = context_tmp->current) {
    324             strcpy(daemon->namebuff, inet_ntoa(context_tmp->start));
    325             if (context_tmp->flags & (CONTEXT_STATIC | CONTEXT_PROXY))
    326                 my_syslog(MS_DHCP | LOG_INFO, _("%u Available DHCP subnet: %s/%s"),
    327                           ntohl(mess->xid), daemon->namebuff, inet_ntoa(context_tmp->netmask));
    328             else
    329                 my_syslog(MS_DHCP | LOG_INFO, _("%u Available DHCP range: %s -- %s"),
    330                           ntohl(mess->xid), daemon->namebuff, inet_ntoa(context_tmp->end));
    331         }
    332     }
    333 
    334     mess->op = BOOTREPLY;
    335 
    336     config = find_config(daemon->dhcp_conf, context, clid, clid_len, mess->chaddr, mess->hlen,
    337                          mess->htype, NULL);
    338 
    339     /* set "known" tag for known hosts */
    340     if (config) {
    341         known_id.net = "known";
    342         known_id.next = netid;
    343         netid = &known_id;
    344     }
    345 
    346     if (mess_type == 0) {
    347         /* BOOTP request */
    348         struct dhcp_netid id, bootp_id;
    349         struct in_addr* logaddr = NULL;
    350 
    351         /* must have a MAC addr for bootp */
    352         if (mess->htype == 0 || mess->hlen == 0 || (context->flags & CONTEXT_PROXY)) return 0;
    353 
    354         if (have_config(config, CONFIG_DISABLE)) message = _("disabled");
    355 
    356         end = mess->options + 64; /* BOOTP vend area is only 64 bytes */
    357 
    358         if (have_config(config, CONFIG_NAME)) {
    359             hostname = config->hostname;
    360             domain = config->domain;
    361         }
    362 
    363         if (have_config(config, CONFIG_NETID)) {
    364             config->netid.next = netid;
    365             netid = &config->netid;
    366         }
    367 
    368         /* Match incoming filename field as a netid. */
    369         if (mess->file[0]) {
    370             memcpy(daemon->dhcp_buff2, mess->file, sizeof(mess->file));
    371             daemon->dhcp_buff2[sizeof(mess->file) + 1] = 0; /* ensure zero term. */
    372             id.net = (char*) daemon->dhcp_buff2;
    373             id.next = netid;
    374             netid = &id;
    375         }
    376 
    377         /* Add "bootp" as a tag to allow different options, address ranges etc
    378        for BOOTP clients */
    379         bootp_id.net = "bootp";
    380         bootp_id.next = netid;
    381         netid = &bootp_id;
    382 
    383         for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
    384             if (match_netid(id_list->list, netid, 0)) message = _("ignored");
    385 
    386         if (!message) {
    387             int nailed = 0;
    388 
    389             if (have_config(config, CONFIG_ADDR)) {
    390                 nailed = 1;
    391                 logaddr = &config->addr;
    392                 mess->yiaddr = config->addr;
    393                 if ((lease = lease_find_by_addr(config->addr)) &&
    394                     (lease->hwaddr_len != mess->hlen || lease->hwaddr_type != mess->htype ||
    395                      memcmp(lease->hwaddr, mess->chaddr, lease->hwaddr_len) != 0))
    396                     message = _("address in use");
    397             } else {
    398                 if (!(lease = lease_find_by_client(mess->chaddr, mess->hlen, mess->htype, NULL, 0)) ||
    399                     !address_available(context, lease->addr, netid)) {
    400                     if (lease) {
    401                         /* lease exists, wrong network. */
    402                         lease_prune(lease, now);
    403                         lease = NULL;
    404                     }
    405                     if (!address_allocate(context, &mess->yiaddr, mess->chaddr, mess->hlen, netid,
    406                                           now))
    407                         message = _("no address available");
    408                 } else
    409                     mess->yiaddr = lease->addr;
    410             }
    411 
    412             if (!message && !(context = narrow_context(context, mess->yiaddr, netid)))
    413                 message = _("wrong network");
    414             else if (context->netid.net) {
    415                 context->netid.next = netid;
    416                 netid = &context->netid;
    417             }
    418 
    419             if (!message && !nailed) {
    420                 for (id_list = daemon->bootp_dynamic; id_list; id_list = id_list->next)
    421                     if ((!id_list->list) || match_netid(id_list->list, netid, 0)) break;
    422                 if (!id_list) message = _("no address configured");
    423             }
    424 
    425             if (!message && !lease && (!(lease = lease_allocate(mess->yiaddr))))
    426                 message = _("no leases left");
    427 
    428             if (!message) {
    429                 logaddr = &mess->yiaddr;
    430 
    431                 lease_set_hwaddr(lease, mess->chaddr, NULL, mess->hlen, mess->htype, 0);
    432                 if (hostname) lease_set_hostname(lease, hostname, 1);
    433                 /* infinite lease unless nailed in dhcp-host line. */
    434                 lease_set_expires(
    435                     lease, have_config(config, CONFIG_TIME) ? config->lease_time : 0xffffffff, now);
    436                 lease_set_interface(lease, int_index);
    437 
    438                 clear_packet(mess, end);
    439                 do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr), domain,
    440                            netid, subnet_addr, 0, 0, 0, NULL);
    441             }
    442         }
    443 
    444         log_packet("BOOTP", logaddr, mess->chaddr, mess->hlen, iface_name, message, mess->xid);
    445 
    446         return message ? 0 : dhcp_packet_size(mess, netid, agent_id, real_end);
    447     }
    448 
    449     if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 4))) {
    450         /* http://tools.ietf.org/wg/dhc/draft-ietf-dhc-fqdn-option/draft-ietf-dhc-fqdn-option-10.txt */
    451         int len = option_len(opt);
    452         char* pq = daemon->dhcp_buff;
    453         unsigned char *pp, *op = option_ptr(opt, 0);
    454 
    455         fqdn_flags = *op;
    456         len -= 3;
    457         op += 3;
    458         pp = op;
    459 
    460         /* Always force update, since the client has no way to do it itself. */
    461         if (!(fqdn_flags & 0x01)) fqdn_flags |= 0x02;
    462 
    463         fqdn_flags &= ~0x08;
    464         fqdn_flags |= 0x01;
    465 
    466         if (fqdn_flags & 0x04)
    467             while (*op != 0 && ((op + (*op) + 1) - pp) < len) {
    468                 memcpy(pq, op + 1, *op);
    469                 pq += *op;
    470                 op += (*op) + 1;
    471                 *(pq++) = '.';
    472             }
    473         else {
    474             memcpy(pq, op, len);
    475             if (len > 0 && op[len - 1] == 0) borken_opt = 1;
    476             pq += len + 1;
    477         }
    478 
    479         if (pq != daemon->dhcp_buff) pq--;
    480 
    481         *pq = 0;
    482 
    483         if (legal_hostname(daemon->dhcp_buff)) offer_hostname = client_hostname = daemon->dhcp_buff;
    484     } else if ((opt = option_find(mess, sz, OPTION_HOSTNAME, 1))) {
    485         int len = option_len(opt);
    486         memcpy(daemon->dhcp_buff, option_ptr(opt, 0), len);
    487         /* Microsoft clients are broken, and need zero-terminated strings
    488        in options. We detect this state here, and do the same in
    489        any options we send */
    490         if (len > 0 && daemon->dhcp_buff[len - 1] == 0)
    491             borken_opt = 1;
    492         else
    493             daemon->dhcp_buff[len] = 0;
    494         if (legal_hostname(daemon->dhcp_buff)) client_hostname = daemon->dhcp_buff;
    495     }
    496 
    497     if (client_hostname && daemon->options & OPT_LOG_OPTS)
    498         my_syslog(MS_DHCP | LOG_INFO, _("%u client provides name: %s"), ntohl(mess->xid),
    499                   client_hostname);
    500 
    501     if (have_config(config, CONFIG_NAME)) {
    502         hostname = config->hostname;
    503         domain = config->domain;
    504         hostname_auth = 1;
    505         /* be careful not to send an OFFER with a hostname not matching the DISCOVER. */
    506         if (fqdn_flags != 0 || !client_hostname || hostname_isequal(hostname, client_hostname))
    507             offer_hostname = hostname;
    508     } else if (client_hostname) {
    509         domain = strip_hostname(client_hostname);
    510 
    511         if (strlen(client_hostname) != 0) {
    512             hostname = client_hostname;
    513             if (!config) {
    514                 /* Search again now we have a hostname.
    515                Only accept configs without CLID and HWADDR here, (they won't match)
    516                to avoid impersonation by name. */
    517                 struct dhcp_config* new =
    518                     find_config(daemon->dhcp_conf, context, NULL, 0, mess->chaddr, mess->hlen,
    519                                 mess->htype, hostname);
    520                 if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr) {
    521                     config = new;
    522                     /* set "known" tag for known hosts */
    523                     known_id.net = "known";
    524                     known_id.next = netid;
    525                     netid = &known_id;
    526                 }
    527             }
    528         }
    529     }
    530 
    531     if (have_config(config, CONFIG_NETID)) {
    532         config->netid.next = netid;
    533         netid = &config->netid;
    534     }
    535 
    536     /* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match.
    537        Otherwise assume the option is an array, and look for a matching element.
    538        If no data given, existance of the option is enough. */
    539     for (o = daemon->dhcp_match; o; o = o->next) {
    540         int i, matched = 0;
    541 
    542         if (!(opt = option_find(mess, sz, o->opt, 1)) || o->len > option_len(opt)) continue;
    543 
    544         if (o->len == 0)
    545             matched = 1;
    546         else if (o->flags & DHOPT_HEX) {
    547             if (memcmp_masked(o->val, option_ptr(opt, 0), o->len, o->u.wildcard_mask)) matched = 1;
    548         } else
    549             for (i = 0; i <= (option_len(opt) - o->len);) {
    550                 if (memcmp(o->val, option_ptr(opt, i), o->len) == 0) {
    551                     matched = 1;
    552                     break;
    553                 }
    554 
    555                 if (o->flags & DHOPT_STRING)
    556                     i++;
    557                 else
    558                     i += o->len;
    559             }
    560 
    561         if (matched) {
    562             o->netid->next = netid;
    563             netid = o->netid;
    564         }
    565     }
    566 
    567     /* user-class options are, according to RFC3004, supposed to contain
    568        a set of counted strings. Here we check that this is so (by seeing
    569        if the counts are consistent with the overall option length) and if
    570        so zero the counts so that we don't get spurious matches between
    571        the vendor string and the counts. If the lengths don't add up, we
    572        assume that the option is a single string and non RFC3004 compliant
    573        and just do the substring match. dhclient provides these broken options.
    574        The code, later, which sends user-class data to the lease-change script
    575        relies on the transformation done here.
    576     */
    577 
    578     if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1))) {
    579         unsigned char* ucp = option_ptr(opt, 0);
    580         int tmp, j;
    581         for (j = 0; j < option_len(opt); j += ucp[j] + 1)
    582             ;
    583         if (j == option_len(opt))
    584             for (j = 0; j < option_len(opt); j = tmp) {
    585                 tmp = j + ucp[j] + 1;
    586                 ucp[j] = 0;
    587             }
    588     }
    589 
    590     for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next) {
    591         int mopt;
    592 
    593         if (vendor->match_type == MATCH_VENDOR)
    594             mopt = OPTION_VENDOR_ID;
    595         else if (vendor->match_type == MATCH_USER)
    596             mopt = OPTION_USER_CLASS;
    597         else
    598             continue;
    599 
    600         if ((opt = option_find(mess, sz, mopt, 1))) {
    601             int i;
    602             for (i = 0; i <= (option_len(opt) - vendor->len); i++)
    603                 if (memcmp(vendor->data, option_ptr(opt, i), vendor->len) == 0) {
    604                     vendor->netid.next = netid;
    605                     netid = &vendor->netid;
    606                     break;
    607                 }
    608         }
    609     }
    610 
    611     /* mark vendor-encapsulated options which match the client-supplied vendor class */
    612     match_vendor_opts(option_find(mess, sz, OPTION_VENDOR_ID, 1), daemon->dhcp_opts);
    613 
    614     if (daemon->options & OPT_LOG_OPTS) {
    615         if (sanitise(option_find(mess, sz, OPTION_VENDOR_ID, 1), daemon->namebuff))
    616             my_syslog(MS_DHCP | LOG_INFO, _("%u Vendor class: %s"), ntohl(mess->xid),
    617                       daemon->namebuff);
    618         if (sanitise(option_find(mess, sz, OPTION_USER_CLASS, 1), daemon->namebuff))
    619             my_syslog(MS_DHCP | LOG_INFO, _("%u User class: %s"), ntohl(mess->xid),
    620                       daemon->namebuff);
    621     }
    622 
    623     /* if all the netids in the ignore list are present, ignore this client */
    624     for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
    625         if (match_netid(id_list->list, netid, 0)) ignore = 1;
    626 
    627     /* Can have setting to ignore the client ID for a particular MAC address or hostname */
    628     if (have_config(config, CONFIG_NOCLID)) clid = NULL;
    629 
    630     /* Check if client is PXE client. */
    631     if (daemon->enable_pxe && (opt = option_find(mess, sz, OPTION_VENDOR_ID, 9)) &&
    632         strncmp(option_ptr(opt, 0), "PXEClient", 9) == 0) {
    633         if ((opt = option_find(mess, sz, OPTION_PXE_UUID, 17))) {
    634             memcpy(pxe_uuid, option_ptr(opt, 0), 17);
    635             uuid = pxe_uuid;
    636         }
    637 
    638         /* Check if this is really a PXE bootserver request, and handle specially if so. */
    639         if ((mess_type == DHCPREQUEST || mess_type == DHCPINFORM) &&
    640             (opt = option_find(mess, sz, OPTION_VENDOR_CLASS_OPT, 1)) &&
    641             (opt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)),
    642                                 SUBOPT_PXE_BOOT_ITEM, 4))) {
    643             struct pxe_service* service;
    644             int type = option_uint(opt, 0, 2);
    645             int layer = option_uint(opt, 2, 2);
    646             unsigned char save71[4];
    647             struct dhcp_opt opt71;
    648 
    649             if (ignore) return 0;
    650 
    651             if (layer & 0x8000) {
    652                 my_syslog(MS_DHCP | LOG_ERR, _("PXE BIS not supported"));
    653                 return 0;
    654             }
    655 
    656             memcpy(save71, option_ptr(opt, 0), 4);
    657 
    658             for (service = daemon->pxe_services; service; service = service->next)
    659                 if (service->type == type) break;
    660 
    661             if (!service || !service->basename) return 0;
    662 
    663             clear_packet(mess, end);
    664 
    665             mess->yiaddr = mess->ciaddr;
    666             mess->ciaddr.s_addr = 0;
    667             if (service->server.s_addr != 0)
    668                 mess->siaddr = service->server;
    669             else
    670                 mess->siaddr = context->local;
    671 
    672             snprintf((char*) mess->file, sizeof(mess->file), "%s.%d", service->basename, layer);
    673             option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
    674             option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context->local.s_addr));
    675             pxe_misc(mess, end, uuid);
    676 
    677             prune_vendor_opts(netid);
    678             opt71.val = save71;
    679             opt71.opt = SUBOPT_PXE_BOOT_ITEM;
    680             opt71.len = 4;
    681             opt71.flags = DHOPT_VENDOR_MATCH;
    682             opt71.netid = NULL;
    683             opt71.next = daemon->dhcp_opts;
    684             do_encap_opts(&opt71, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
    685 
    686             log_packet("PXE", &mess->yiaddr, emac, emac_len, iface_name, (char*) mess->file,
    687                        mess->xid);
    688             return dhcp_packet_size(mess, netid, agent_id, real_end);
    689         }
    690 
    691         if ((opt = option_find(mess, sz, OPTION_ARCH, 2))) {
    692             pxearch = option_uint(opt, 0, 2);
    693 
    694             /* proxy DHCP here. The DHCPREQUEST stuff is for gPXE */
    695             if ((mess_type == DHCPDISCOVER || mess_type == DHCPREQUEST) &&
    696                 (context->flags & CONTEXT_PROXY)) {
    697                 struct dhcp_boot* boot = find_boot(netid);
    698 
    699                 mess->yiaddr.s_addr = 0;
    700                 if (mess_type == DHCPDISCOVER || mess->ciaddr.s_addr == 0) {
    701                     mess->ciaddr.s_addr = 0;
    702                     mess->flags |= htons(0x8000); /* broadcast */
    703                 }
    704 
    705                 clear_packet(mess, end);
    706 
    707                 /* Provide the bootfile here, for gPXE, and in case we have no menu items
    708                and set discovery_control = 8 */
    709                 if (boot) {
    710                     if (boot->next_server.s_addr) mess->siaddr = boot->next_server;
    711 
    712                     if (boot->file) strncpy((char*) mess->file, boot->file, sizeof(mess->file) - 1);
    713                 }
    714 
    715                 option_put(mess, end, OPTION_MESSAGE_TYPE, 1,
    716                            mess_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK);
    717                 option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ,
    718                            htonl(context->local.s_addr));
    719                 pxe_misc(mess, end, uuid);
    720                 prune_vendor_opts(netid);
    721                 do_encap_opts(pxe_opts(pxearch, netid), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH,
    722                               mess, end, 0);
    723 
    724                 log_packet("PXE", NULL, emac, emac_len, iface_name,
    725                            ignore ? "proxy" : "proxy-ignored", mess->xid);
    726                 return ignore ? 0 : dhcp_packet_size(mess, netid, agent_id, real_end);
    727             }
    728         }
    729     }
    730 
    731     /* if we're just a proxy server, go no further */
    732     if (context->flags & CONTEXT_PROXY) return 0;
    733 
    734     if ((opt = option_find(mess, sz, OPTION_REQUESTED_OPTIONS, 0))) {
    735         req_options = (unsigned char*) daemon->dhcp_buff2;
    736         memcpy(req_options, option_ptr(opt, 0), option_len(opt));
    737         req_options[option_len(opt)] = OPTION_END;
    738     }
    739 
    740     switch (mess_type) {
    741         case DHCPDECLINE:
    742             if (!(opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ)) ||
    743                 option_addr(opt).s_addr != server_id(context, override, fallback).s_addr)
    744                 return 0;
    745 
    746             /* sanitise any message. Paranoid? Moi? */
    747             sanitise(option_find(mess, sz, OPTION_MESSAGE, 1), daemon->dhcp_buff);
    748 
    749             if (!(opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ))) return 0;
    750 
    751             log_packet("DHCPDECLINE", option_ptr(opt, 0), emac, emac_len, iface_name,
    752                        daemon->dhcp_buff, mess->xid);
    753 
    754             if (lease && lease->addr.s_addr == option_addr(opt).s_addr) lease_prune(lease, now);
    755 
    756             if (have_config(config, CONFIG_ADDR) && config->addr.s_addr == option_addr(opt).s_addr) {
    757                 prettyprint_time(daemon->dhcp_buff, DECLINE_BACKOFF);
    758                 my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"),
    759                           inet_ntoa(config->addr), daemon->dhcp_buff);
    760                 config->flags |= CONFIG_DECLINED;
    761                 config->decline_time = now;
    762             } else
    763                 /* make sure this host gets a different address next time. */
    764                 for (; context; context = context->current) context->addr_epoch++;
    765 
    766             return 0;
    767 
    768         case DHCPRELEASE:
    769             if (!(context = narrow_context(context, mess->ciaddr, netid)) ||
    770                 !(opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ)) ||
    771                 option_addr(opt).s_addr != server_id(context, override, fallback).s_addr)
    772                 return 0;
    773 
    774             if (lease && lease->addr.s_addr == mess->ciaddr.s_addr)
    775                 lease_prune(lease, now);
    776             else
    777                 message = _("unknown lease");
    778 
    779             log_packet("DHCPRELEASE", &mess->ciaddr, emac, emac_len, iface_name, message, mess->xid);
    780 
    781             return 0;
    782 
    783         case DHCPDISCOVER:
    784             if (ignore || have_config(config, CONFIG_DISABLE)) {
    785                 message = _("ignored");
    786                 opt = NULL;
    787             } else {
    788                 struct in_addr addr, conf;
    789 
    790                 addr.s_addr = conf.s_addr = 0;
    791 
    792                 if ((opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
    793                     addr = option_addr(opt);
    794 
    795                 if (have_config(config, CONFIG_ADDR)) {
    796                     char* addrs = inet_ntoa(config->addr);
    797 
    798                     if ((ltmp = lease_find_by_addr(config->addr)) && ltmp != lease &&
    799                         !config_has_mac(config, ltmp->hwaddr, ltmp->hwaddr_len, ltmp->hwaddr_type)) {
    800                         int len;
    801                         unsigned char* mac =
    802                             extended_hwaddr(ltmp->hwaddr_type, ltmp->hwaddr_len, ltmp->hwaddr,
    803                                             ltmp->clid_len, ltmp->clid, &len);
    804                         my_syslog(MS_DHCP | LOG_WARNING,
    805                                   _("not using configured address %s because it is leased to %s"),
    806                                   addrs, print_mac(daemon->namebuff, mac, len));
    807                     } else {
    808                         struct dhcp_context* tmp;
    809                         for (tmp = context; tmp; tmp = tmp->current)
    810                             if (context->router.s_addr == config->addr.s_addr) break;
    811                         if (tmp)
    812                             my_syslog(MS_DHCP | LOG_WARNING,
    813                                       _("not using configured address %s because it is in use by "
    814                                         "the server or relay"),
    815                                       addrs);
    816                         else if (have_config(config, CONFIG_DECLINED) &&
    817                                  difftime(now, config->decline_time) < (float) DECLINE_BACKOFF)
    818                             my_syslog(MS_DHCP | LOG_WARNING,
    819                                       _("not using configured address %s because it was previously "
    820                                         "declined"),
    821                                       addrs);
    822                         else
    823                             conf = config->addr;
    824                     }
    825                 }
    826 
    827                 if (conf.s_addr)
    828                     mess->yiaddr = conf;
    829                 else if (lease && address_available(context, lease->addr, netid) &&
    830                          !config_find_by_address(daemon->dhcp_conf, lease->addr))
    831                     mess->yiaddr = lease->addr;
    832                 else if (opt && address_available(context, addr, netid) &&
    833                          !lease_find_by_addr(addr) &&
    834                          !config_find_by_address(daemon->dhcp_conf, addr))
    835                     mess->yiaddr = addr;
    836                 else if (emac_len == 0)
    837                     message = _("no unique-id");
    838                 else if (!address_allocate(context, &mess->yiaddr, emac, emac_len, netid, now))
    839                     message = _("no address available");
    840             }
    841 
    842             log_packet("DHCPDISCOVER", opt ? option_ptr(opt, 0) : NULL, emac, emac_len, iface_name,
    843                        message, mess->xid);
    844 
    845             if (message || !(context = narrow_context(context, mess->yiaddr, netid))) return 0;
    846 
    847             log_packet("DHCPOFFER", &mess->yiaddr, emac, emac_len, iface_name, NULL, mess->xid);
    848 
    849             if (context->netid.net) {
    850                 context->netid.next = netid;
    851                 netid = &context->netid;
    852             }
    853 
    854             time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
    855             clear_packet(mess, end);
    856             option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPOFFER);
    857             option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ,
    858                        ntohl(server_id(context, override, fallback).s_addr));
    859             option_put(mess, end, OPTION_LEASE_TIME, 4, time);
    860             /* T1 and T2 are required in DHCPOFFER by HP's wacky Jetdirect client. */
    861             if (time != 0xffffffff) {
    862                 option_put(mess, end, OPTION_T1, 4, (time / 2));
    863                 option_put(mess, end, OPTION_T2, 4, (time * 7) / 8);
    864             }
    865             do_options(context, mess, end, req_options, offer_hostname, get_domain(mess->yiaddr),
    866                        domain, netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid);
    867 
    868             return dhcp_packet_size(mess, netid, agent_id, real_end);
    869 
    870         case DHCPREQUEST:
    871             if (ignore || have_config(config, CONFIG_DISABLE)) return 0;
    872             if ((opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ))) {
    873                 /* SELECTING  or INIT_REBOOT */
    874                 mess->yiaddr = option_addr(opt);
    875 
    876                 /* send vendor and user class info for new or recreated lease */
    877                 do_classes = 1;
    878 
    879                 if ((opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ))) {
    880                     /* SELECTING */
    881                     selecting = 1;
    882 
    883                     if (override.s_addr != 0) {
    884                         if (option_addr(opt).s_addr != override.s_addr) return 0;
    885                     } else {
    886                         for (; context; context = context->current)
    887                             if (context->local.s_addr == option_addr(opt).s_addr) break;
    888 
    889                         if (!context) {
    890                             /* In auth mode, a REQUEST sent to the wrong server
    891                            should be faulted, so that the client establishes
    892                            communication with us, otherwise, silently ignore. */
    893                             if (!(daemon->options & OPT_AUTHORITATIVE)) return 0;
    894                             message = _("wrong server-ID");
    895                         }
    896                     }
    897 
    898                     /* If a lease exists for this host and another address, squash it. */
    899                     if (lease && lease->addr.s_addr != mess->yiaddr.s_addr) {
    900                         lease_prune(lease, now);
    901                         lease = NULL;
    902                     }
    903                 } else {
    904                     /* INIT-REBOOT */
    905                     if (!lease && !(daemon->options & OPT_AUTHORITATIVE)) return 0;
    906 
    907                     if (lease && lease->addr.s_addr != mess->yiaddr.s_addr) {
    908                         message = _("wrong address");
    909                         /* avoid loops when client brain-dead */
    910                         lease_prune(lease, now);
    911                         lease = NULL;
    912                     }
    913                 }
    914             } else {
    915                 /* RENEWING or REBINDING */
    916                 /* Check existing lease for this address.
    917                    We allow it to be missing if dhcp-authoritative mode
    918                    as long as we can allocate the lease now - checked below.
    919                    This makes for a smooth recovery from a lost lease DB */
    920                 if ((lease && mess->ciaddr.s_addr != lease->addr.s_addr) ||
    921                     (!lease && !(daemon->options & OPT_AUTHORITATIVE))) {
    922                     message = _("lease not found");
    923                     /* ensure we broadcast NAK */
    924                     unicast_dest = 0;
    925                 }
    926                 /* desynchronise renewals */
    927                 fuzz = rand16();
    928                 mess->yiaddr = mess->ciaddr;
    929             }
    930 
    931             log_packet("DHCPREQUEST", &mess->yiaddr, emac, emac_len, iface_name, NULL, mess->xid);
    932 
    933             if (!message) {
    934                 struct dhcp_config* addr_config;
    935                 struct dhcp_context* tmp = NULL;
    936 
    937                 if (have_config(config, CONFIG_ADDR))
    938                     for (tmp = context; tmp; tmp = tmp->current)
    939                         if (context->router.s_addr == config->addr.s_addr) break;
    940 
    941                 if (!(context = narrow_context(context, mess->yiaddr, netid))) {
    942                     /* If a machine moves networks whilst it has a lease, we catch that here. */
    943                     message = _("wrong network");
    944                     /* ensure we broadcast NAK */
    945                     unicast_dest = 0;
    946                 }
    947 
    948                 /* Check for renewal of a lease which is outside the allowed range. */
    949                 else if (!address_available(context, mess->yiaddr, netid) &&
    950                          (!have_config(config, CONFIG_ADDR) ||
    951                           config->addr.s_addr != mess->yiaddr.s_addr))
    952                     message = _("address not available");
    953 
    954                 /* Check if a new static address has been configured. Be very sure that
    955                    when the client does DISCOVER, it will get the static address, otherwise
    956                    an endless protocol loop will ensue. */
    957                 else if (!tmp && !selecting && have_config(config, CONFIG_ADDR) &&
    958                          (!have_config(config, CONFIG_DECLINED) ||
    959                           difftime(now, config->decline_time) > (float) DECLINE_BACKOFF) &&
    960                          config->addr.s_addr != mess->yiaddr.s_addr &&
    961                          (!(ltmp = lease_find_by_addr(config->addr)) || ltmp == lease))
    962                     message = _("static lease available");
    963 
    964                 /* Check to see if the address is reserved as a static address for another host */
    965                 else if ((addr_config = config_find_by_address(daemon->dhcp_conf, mess->yiaddr)) &&
    966                          addr_config != config)
    967                     message = _("address reserved");
    968 
    969                 else if (!lease && (ltmp = lease_find_by_addr(mess->yiaddr))) {
    970                     /* If a host is configured with more than one MAC address, it's OK to 'nix
    971                    a lease from one of it's MACs to give the address to another. */
    972                     if (config &&
    973                         config_has_mac(config, ltmp->hwaddr, ltmp->hwaddr_len, ltmp->hwaddr_type)) {
    974                         my_syslog(MS_DHCP | LOG_INFO, _("abandoning lease to %s of %s"),
    975                                   print_mac(daemon->namebuff, ltmp->hwaddr, ltmp->hwaddr_len),
    976                                   inet_ntoa(ltmp->addr));
    977                         lease = ltmp;
    978                     } else
    979                         message = _("address in use");
    980                 }
    981 
    982                 if (!message) {
    983                     if (emac_len == 0)
    984                         message = _("no unique-id");
    985 
    986                     else if (!lease) {
    987                         if ((lease = lease_allocate(mess->yiaddr)))
    988                             do_classes = 1;
    989                         else
    990                             message = _("no leases left");
    991                     }
    992                 }
    993             }
    994 
    995             if (message) {
    996                 log_packet("DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, message, mess->xid);
    997 
    998                 mess->yiaddr.s_addr = 0;
    999                 clear_packet(mess, end);
   1000                 option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPNAK);
   1001                 option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ,
   1002                            ntohl(server_id(context, override, fallback).s_addr));
   1003                 option_put_string(mess, end, OPTION_MESSAGE, message, borken_opt);
   1004                 /* This fixes a problem with the DHCP spec, broadcasting a NAK to a host on
   1005                    a distant subnet which unicast a REQ to us won't work. */
   1006                 if (!unicast_dest || mess->giaddr.s_addr != 0 || mess->ciaddr.s_addr == 0 ||
   1007                     is_same_net(context->local, mess->ciaddr, context->netmask)) {
   1008                     mess->flags |= htons(0x8000); /* broadcast */
   1009                     mess->ciaddr.s_addr = 0;
   1010                 }
   1011             } else {
   1012                 if (do_classes) {
   1013                     if (mess->giaddr.s_addr) lease->giaddr = mess->giaddr;
   1014 
   1015                     lease->changed = 1;
   1016                     /* copy user-class and vendor class into new lease, for the script */
   1017                     if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1))) {
   1018                         int len = option_len(opt);
   1019                         unsigned char* ucp = option_ptr(opt, 0);
   1020                         /* If the user-class option started as counted strings, the first byte will
   1021                          * be zero. */
   1022                         if (len != 0 && ucp[0] == 0) ucp++, len--;
   1023                         free(lease->userclass);
   1024                         if ((lease->userclass = whine_malloc(len + 1))) {
   1025                             memcpy(lease->userclass, ucp, len);
   1026                             lease->userclass[len] = 0;
   1027                             lease->userclass_len = len + 1;
   1028                         }
   1029                     }
   1030                     if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 1))) {
   1031                         int len = option_len(opt);
   1032                         unsigned char* ucp = option_ptr(opt, 0);
   1033                         free(lease->vendorclass);
   1034                         if ((lease->vendorclass = whine_malloc(len + 1))) {
   1035                             memcpy(lease->vendorclass, ucp, len);
   1036                             lease->vendorclass[len] = 0;
   1037                             lease->vendorclass_len = len + 1;
   1038                         }
   1039                     }
   1040                     if ((opt = option_find(mess, sz, OPTION_HOSTNAME, 1))) {
   1041                         int len = option_len(opt);
   1042                         unsigned char* ucp = option_ptr(opt, 0);
   1043                         free(lease->supplied_hostname);
   1044                         if ((lease->supplied_hostname = whine_malloc(len + 1))) {
   1045                             memcpy(lease->supplied_hostname, ucp, len);
   1046                             lease->supplied_hostname[len] = 0;
   1047                             lease->supplied_hostname_len = len + 1;
   1048                         }
   1049                     }
   1050                 }
   1051 
   1052                 if (!hostname_auth && (client_hostname = host_from_dns(mess->yiaddr))) {
   1053                     hostname = client_hostname;
   1054                     hostname_auth = 1;
   1055                 }
   1056 
   1057                 if (context->netid.net) {
   1058                     context->netid.next = netid;
   1059                     netid = &context->netid;
   1060                 }
   1061 
   1062                 time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
   1063                 lease_set_hwaddr(lease, mess->chaddr, clid, mess->hlen, mess->htype, clid_len);
   1064 
   1065                 /* if all the netids in the ignore_name list are present, ignore client-supplied name */
   1066                 if (!hostname_auth) {
   1067                     for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
   1068                         if ((!id_list->list) || match_netid(id_list->list, netid, 0)) break;
   1069                     if (id_list) hostname = NULL;
   1070                 }
   1071                 if (hostname) lease_set_hostname(lease, hostname, hostname_auth);
   1072 
   1073                 lease_set_expires(lease, time, now);
   1074                 lease_set_interface(lease, int_index);
   1075 
   1076                 if (override.s_addr != 0)
   1077                     lease->override = override;
   1078                 else
   1079                     override = lease->override;
   1080 
   1081                 log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostname,
   1082                            mess->xid);
   1083 
   1084                 clear_packet(mess, end);
   1085                 option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
   1086                 option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ,
   1087                            ntohl(server_id(context, override, fallback).s_addr));
   1088                 option_put(mess, end, OPTION_LEASE_TIME, 4, time);
   1089                 if (time != 0xffffffff) {
   1090                     while (fuzz > (time / 16)) fuzz = fuzz / 2;
   1091                     option_put(mess, end, OPTION_T1, 4, (time / 2) - fuzz);
   1092                     option_put(mess, end, OPTION_T2, 4, ((time / 8) * 7) - fuzz);
   1093                 }
   1094                 do_options(context, mess, end, req_options, hostname, get_domain(mess->yiaddr),
   1095                            domain, netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid);
   1096             }
   1097 
   1098             return dhcp_packet_size(mess, netid, agent_id, real_end);
   1099 
   1100         case DHCPINFORM:
   1101             if (ignore || have_config(config, CONFIG_DISABLE)) message = _("ignored");
   1102 
   1103             log_packet("DHCPINFORM", &mess->ciaddr, emac, emac_len, iface_name, message, mess->xid);
   1104 
   1105             if (message || mess->ciaddr.s_addr == 0) return 0;
   1106 
   1107             /* For DHCPINFORM only, cope without a valid context */
   1108             context = narrow_context(context, mess->ciaddr, netid);
   1109 
   1110             /* Find a least based on IP address if we didn't
   1111            get one from MAC address/client-d */
   1112             if (!lease && (lease = lease_find_by_addr(mess->ciaddr)) && lease->hostname)
   1113                 hostname = lease->hostname;
   1114 
   1115             if (!hostname) hostname = host_from_dns(mess->ciaddr);
   1116 
   1117             log_packet("DHCPACK", &mess->ciaddr, emac, emac_len, iface_name, hostname, mess->xid);
   1118 
   1119             if (context && context->netid.net) {
   1120                 context->netid.next = netid;
   1121                 netid = &context->netid;
   1122             }
   1123 
   1124             if (lease) {
   1125                 if (override.s_addr != 0)
   1126                     lease->override = override;
   1127                 else
   1128                     override = lease->override;
   1129             }
   1130 
   1131             clear_packet(mess, end);
   1132             option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
   1133             option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ,
   1134                        ntohl(server_id(context, override, fallback).s_addr));
   1135 
   1136             if (lease) {
   1137                 if (lease->expires == 0)
   1138                     time = 0xffffffff;
   1139                 else
   1140                     time = (unsigned int) difftime(lease->expires, now);
   1141                 option_put(mess, end, OPTION_LEASE_TIME, 4, time);
   1142                 lease_set_interface(lease, int_index);
   1143             }
   1144 
   1145             do_options(context, mess, end, req_options, hostname, get_domain(mess->ciaddr), domain,
   1146                        netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid);
   1147 
   1148             *is_inform = 1; /* handle reply differently */
   1149             return dhcp_packet_size(mess, netid, agent_id, real_end);
   1150     }
   1151 
   1152     return 0;
   1153 }
   1154 
   1155 /* find a good value to use as MAC address for logging and address-allocation hashing.
   1156    This is normally just the chaddr field from the DHCP packet,
   1157    but eg Firewire will have hlen == 0 and use the client-id instead.
   1158    This could be anything, but will normally be EUI64 for Firewire.
   1159    We assume that if the first byte of the client-id equals the htype byte
   1160    then the client-id is using the usual encoding and use the rest of the
   1161    client-id: if not we can use the whole client-id. This should give
   1162    sane MAC address logs. */
   1163 unsigned char* extended_hwaddr(int hwtype, int hwlen, unsigned char* hwaddr, int clid_len,
   1164                                unsigned char* clid, int* len_out) {
   1165     if (hwlen == 0 && clid && clid_len > 3) {
   1166         if (clid[0] == hwtype) {
   1167             *len_out = clid_len - 1;
   1168             return clid + 1;
   1169         }
   1170 
   1171 #if defined(ARPHRD_EUI64) && defined(ARPHRD_IEEE1394)
   1172         if (clid[0] == ARPHRD_EUI64 && hwtype == ARPHRD_IEEE1394) {
   1173             *len_out = clid_len - 1;
   1174             return clid + 1;
   1175         }
   1176 #endif
   1177 
   1178         *len_out = clid_len;
   1179         return clid;
   1180     }
   1181 
   1182     *len_out = hwlen;
   1183     return hwaddr;
   1184 }
   1185 
   1186 static unsigned int calc_time(struct dhcp_context* context, struct dhcp_config* config,
   1187                               unsigned char* opt) {
   1188     unsigned int time = have_config(config, CONFIG_TIME) ? config->lease_time : context->lease_time;
   1189 
   1190     if (opt) {
   1191         unsigned int req_time = option_uint(opt, 0, 4);
   1192         if (req_time < 120) req_time = 120; /* sanity */
   1193         if (time == 0xffffffff || (req_time != 0xffffffff && req_time < time)) time = req_time;
   1194     }
   1195 
   1196     return time;
   1197 }
   1198 
   1199 static struct in_addr server_id(struct dhcp_context* context, struct in_addr override,
   1200                                 struct in_addr fallback) {
   1201     if (override.s_addr != 0)
   1202         return override;
   1203     else if (context)
   1204         return context->local;
   1205     else
   1206         return fallback;
   1207 }
   1208 
   1209 static int sanitise(unsigned char* opt, char* buf) {
   1210     char* p;
   1211     int i;
   1212 
   1213     *buf = 0;
   1214 
   1215     if (!opt) return 0;
   1216 
   1217     p = option_ptr(opt, 0);
   1218 
   1219     for (i = option_len(opt); i > 0; i--) {
   1220         char c = *p++;
   1221         if (isprint((int) c)) *buf++ = c;
   1222     }
   1223     *buf = 0; /* add terminator */
   1224 
   1225     return 1;
   1226 }
   1227 
   1228 static void log_packet(char* type, void* addr, unsigned char* ext_mac, int mac_len, char* interface,
   1229                        char* string, u32 xid) {
   1230     struct in_addr a;
   1231 
   1232     /* addr may be misaligned */
   1233     if (addr) memcpy(&a, addr, sizeof(a));
   1234 
   1235     print_mac(daemon->namebuff, ext_mac, mac_len);
   1236 
   1237     if (daemon->options & OPT_LOG_OPTS)
   1238         my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s%s %s", ntohl(xid), type, interface,
   1239                   addr ? inet_ntoa(a) : "", addr ? " " : "", daemon->namebuff, string ? string : "");
   1240     else
   1241         my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s%s %s", type, interface, addr ? inet_ntoa(a) : "",
   1242                   addr ? " " : "", daemon->namebuff, string ? string : "");
   1243 }
   1244 
   1245 static void log_options(unsigned char* start, u32 xid) {
   1246     while (*start != OPTION_END) {
   1247         int is_ip, is_name, i;
   1248         char* text = option_string(start[0], &is_ip, &is_name);
   1249         unsigned char trunc = option_len(start);
   1250 
   1251         if (is_ip)
   1252             for (daemon->namebuff[0] = 0, i = 0; i <= trunc - INADDRSZ; i += INADDRSZ) {
   1253                 if (i != 0) strncat(daemon->namebuff, ", ", 256 - strlen(daemon->namebuff));
   1254                 strncat(daemon->namebuff, inet_ntoa(option_addr_arr(start, i)),
   1255                         256 - strlen(daemon->namebuff));
   1256             }
   1257         else if (!is_name || !sanitise(start, daemon->namebuff)) {
   1258             if (trunc > 13) trunc = 13;
   1259             print_mac(daemon->namebuff, option_ptr(start, 0), trunc);
   1260         }
   1261 
   1262         my_syslog(MS_DHCP | LOG_INFO, "%u sent size:%3d option:%3d%s%s%s%s%s", ntohl(xid),
   1263                   option_len(start), start[0], text ? ":" : "", text ? text : "",
   1264                   trunc == 0 ? "" : "  ", trunc == 0 ? "" : daemon->namebuff,
   1265                   trunc == option_len(start) ? "" : "...");
   1266         start += start[1] + 2;
   1267     }
   1268 }
   1269 
   1270 static unsigned char* option_find1(unsigned char* p, unsigned char* end, int opt, int minsize) {
   1271     while (1) {
   1272         if (p > end)
   1273             return NULL;
   1274         else if (*p == OPTION_END)
   1275             return opt == OPTION_END ? p : NULL;
   1276         else if (*p == OPTION_PAD)
   1277             p++;
   1278         else {
   1279             int opt_len;
   1280             if (p > end - 2) return NULL; /* malformed packet */
   1281             opt_len = option_len(p);
   1282             if (p > end - (2 + opt_len)) return NULL; /* malformed packet */
   1283             if (*p == opt && opt_len >= minsize) return p;
   1284             p += opt_len + 2;
   1285         }
   1286     }
   1287 }
   1288 
   1289 static unsigned char* option_find(struct dhcp_packet* mess, size_t size, int opt_type, int minsize) {
   1290     unsigned char *ret, *overload;
   1291 
   1292     /* skip over DHCP cookie; */
   1293     if ((ret = option_find1(&mess->options[0] + sizeof(u32), ((unsigned char*) mess) + size,
   1294                             opt_type, minsize)))
   1295         return ret;
   1296 
   1297     /* look for overload option. */
   1298     if (!(overload = option_find1(&mess->options[0] + sizeof(u32), ((unsigned char*) mess) + size,
   1299                                   OPTION_OVERLOAD, 1)))
   1300         return NULL;
   1301 
   1302     /* Can we look in filename area ? */
   1303     if ((overload[2] & 1) &&
   1304         (ret = option_find1(&mess->file[0], &mess->file[128], opt_type, minsize)))
   1305         return ret;
   1306 
   1307     /* finally try sname area */
   1308     if ((overload[2] & 2) &&
   1309         (ret = option_find1(&mess->sname[0], &mess->sname[64], opt_type, minsize)))
   1310         return ret;
   1311 
   1312     return NULL;
   1313 }
   1314 
   1315 static struct in_addr option_addr_arr(unsigned char* opt, int offset) {
   1316     /* this worries about unaligned data in the option. */
   1317     /* struct in_addr is network byte order */
   1318     struct in_addr ret;
   1319 
   1320     memcpy(&ret, option_ptr(opt, offset), INADDRSZ);
   1321 
   1322     return ret;
   1323 }
   1324 
   1325 static struct in_addr option_addr(unsigned char* opt) {
   1326     return option_addr_arr(opt, 0);
   1327 }
   1328 
   1329 static unsigned int option_uint(unsigned char* opt, int offset, int size) {
   1330     /* this worries about unaligned data and byte order */
   1331     unsigned int ret = 0;
   1332     int i;
   1333     unsigned char* p = option_ptr(opt, offset);
   1334 
   1335     for (i = 0; i < size; i++) ret = (ret << 8) | *p++;
   1336 
   1337     return ret;
   1338 }
   1339 
   1340 static unsigned char* dhcp_skip_opts(unsigned char* start) {
   1341     while (*start != 0) start += start[1] + 2;
   1342     return start;
   1343 }
   1344 
   1345 /* only for use when building packet: doesn't check for bad data. */
   1346 static unsigned char* find_overload(struct dhcp_packet* mess) {
   1347     unsigned char* p = &mess->options[0] + sizeof(u32);
   1348 
   1349     while (*p != 0) {
   1350         if (*p == OPTION_OVERLOAD) return p;
   1351         p += p[1] + 2;
   1352     }
   1353     return NULL;
   1354 }
   1355 
   1356 static size_t dhcp_packet_size(struct dhcp_packet* mess, struct dhcp_netid* netid,
   1357                                unsigned char* agent_id, unsigned char* real_end) {
   1358     unsigned char* p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
   1359     unsigned char* overload;
   1360     size_t ret;
   1361     struct dhcp_netid_list* id_list;
   1362     struct dhcp_netid* n;
   1363 
   1364     /* move agent_id back down to the end of the packet */
   1365     if (agent_id) {
   1366         memmove(p, agent_id, real_end - agent_id);
   1367         p += real_end - agent_id;
   1368         memset(p, 0, real_end - p); /* in case of overlap */
   1369     }
   1370 
   1371     /* We do logging too */
   1372     if (netid && (daemon->options & OPT_LOG_OPTS)) {
   1373         char* s = daemon->namebuff;
   1374         for (*s = 0; netid; netid = netid->next) {
   1375             /* kill dupes. */
   1376             for (n = netid->next; n; n = n->next)
   1377                 if (strcmp(netid->net, n->net) == 0) break;
   1378 
   1379             if (!n) {
   1380                 strncat(s, netid->net, (MAXDNAME - 1) - strlen(s));
   1381                 if (netid->next) strncat(s, ", ", (MAXDNAME - 1) - strlen(s));
   1382             }
   1383         }
   1384         my_syslog(MS_DHCP | LOG_INFO, _("%u tags: %s"), ntohl(mess->xid), s);
   1385     }
   1386 
   1387     /* add END options to the regions. */
   1388     overload = find_overload(mess);
   1389 
   1390     if (overload && (option_uint(overload, 0, 1) & 1)) {
   1391         *dhcp_skip_opts(mess->file) = OPTION_END;
   1392         if (daemon->options & OPT_LOG_OPTS) log_options(mess->file, mess->xid);
   1393     } else if ((daemon->options & OPT_LOG_OPTS) && strlen((char*) mess->file) != 0)
   1394         my_syslog(MS_DHCP | LOG_INFO, _("%u bootfile name: %s"), ntohl(mess->xid),
   1395                   (char*) mess->file);
   1396 
   1397     if (overload && (option_uint(overload, 0, 1) & 2)) {
   1398         *dhcp_skip_opts(mess->sname) = OPTION_END;
   1399         if (daemon->options & OPT_LOG_OPTS) log_options(mess->sname, mess->xid);
   1400     } else if ((daemon->options & OPT_LOG_OPTS) && strlen((char*) mess->sname) != 0)
   1401         my_syslog(MS_DHCP | LOG_INFO, _("%u server name: %s"), ntohl(mess->xid),
   1402                   (char*) mess->sname);
   1403 
   1404     *p++ = OPTION_END;
   1405 
   1406     if (daemon->options & OPT_LOG_OPTS) {
   1407         if (mess->siaddr.s_addr != 0)
   1408             my_syslog(MS_DHCP | LOG_INFO, _("%u next server: %s"), ntohl(mess->xid),
   1409                       inet_ntoa(mess->siaddr));
   1410 
   1411         log_options(&mess->options[0] + sizeof(u32), mess->xid);
   1412     }
   1413 
   1414     for (id_list = daemon->force_broadcast; id_list; id_list = id_list->next)
   1415         if (match_netid(id_list->list, netid, 0))
   1416             mess->flags |= htons(0x8000); /* force broadcast */
   1417 
   1418     ret = (size_t)(p - (unsigned char*) mess);
   1419 
   1420     if (ret < MIN_PACKETSZ) ret = MIN_PACKETSZ;
   1421 
   1422     return ret;
   1423 }
   1424 
   1425 static unsigned char* free_space(struct dhcp_packet* mess, unsigned char* end, int opt, int len) {
   1426     unsigned char* p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
   1427 
   1428     if (p + len + 3 >= end)
   1429     /* not enough space in options area, try and use overload, if poss */
   1430     {
   1431         unsigned char* overload;
   1432 
   1433         if (!(overload = find_overload(mess)) && (mess->file[0] == 0 || mess->sname[0] == 0)) {
   1434             /* attempt to overload fname and sname areas, we've reserved space for the
   1435                overflow option previuously. */
   1436             overload = p;
   1437             *(p++) = OPTION_OVERLOAD;
   1438             *(p++) = 1;
   1439         }
   1440 
   1441         p = NULL;
   1442 
   1443         /* using filename field ? */
   1444         if (overload) {
   1445             if (mess->file[0] == 0) overload[2] |= 1;
   1446 
   1447             if (overload[2] & 1) {
   1448                 p = dhcp_skip_opts(mess->file);
   1449                 if (p + len + 3 >= mess->file + sizeof(mess->file)) p = NULL;
   1450             }
   1451 
   1452             if (!p) {
   1453                 /* try to bring sname into play (it may be already) */
   1454                 if (mess->sname[0] == 0) overload[2] |= 2;
   1455 
   1456                 if (overload[2] & 2) {
   1457                     p = dhcp_skip_opts(mess->sname);
   1458                     if (p + len + 3 >= mess->sname + sizeof(mess->file)) p = NULL;
   1459                 }
   1460             }
   1461         }
   1462 
   1463         if (!p)
   1464             my_syslog(MS_DHCP | LOG_WARNING,
   1465                       _("cannot send DHCP/BOOTP option %d: no space left in packet"), opt);
   1466     }
   1467 
   1468     if (p) {
   1469         *(p++) = opt;
   1470         *(p++) = len;
   1471     }
   1472 
   1473     return p;
   1474 }
   1475 
   1476 static void option_put(struct dhcp_packet* mess, unsigned char* end, int opt, int len,
   1477                        unsigned int val) {
   1478     int i;
   1479     unsigned char* p = free_space(mess, end, opt, len);
   1480 
   1481     if (p)
   1482         for (i = 0; i < len; i++) *(p++) = val >> (8 * (len - (i + 1)));
   1483 }
   1484 
   1485 static void option_put_string(struct dhcp_packet* mess, unsigned char* end, int opt, char* string,
   1486                               int null_term) {
   1487     unsigned char* p;
   1488     size_t len = strlen(string);
   1489 
   1490     if (null_term && len != 255) len++;
   1491 
   1492     if ((p = free_space(mess, end, opt, len))) memcpy(p, string, len);
   1493 }
   1494 
   1495 /* return length, note this only does the data part */
   1496 static int do_opt(struct dhcp_opt* opt, unsigned char* p, struct dhcp_context* context,
   1497                   int null_term) {
   1498     int len = opt->len;
   1499 
   1500     if ((opt->flags & DHOPT_STRING) && null_term && len != 255) len++;
   1501 
   1502     if (p && len != 0) {
   1503         if (context && (opt->flags & DHOPT_ADDR)) {
   1504             int j;
   1505             struct in_addr* a = (struct in_addr*) opt->val;
   1506             for (j = 0; j < opt->len; j += INADDRSZ, a++) {
   1507                 /* zero means "self" (but not in vendorclass options.) */
   1508                 if (a->s_addr == 0)
   1509                     memcpy(p, &context->local, INADDRSZ);
   1510                 else
   1511                     memcpy(p, a, INADDRSZ);
   1512                 p += INADDRSZ;
   1513             }
   1514         } else
   1515             memcpy(p, opt->val, len);
   1516     }
   1517     return len;
   1518 }
   1519 
   1520 static int in_list(unsigned char* list, int opt) {
   1521     int i;
   1522 
   1523     /* If no requested options, send everything, not nothing. */
   1524     if (!list) return 1;
   1525 
   1526     for (i = 0; list[i] != OPTION_END; i++)
   1527         if (opt == list[i]) return 1;
   1528 
   1529     return 0;
   1530 }
   1531 
   1532 static struct dhcp_opt* option_find2(struct dhcp_netid* netid, struct dhcp_opt* opts, int opt) {
   1533     struct dhcp_opt* tmp;
   1534     for (tmp = opts; tmp; tmp = tmp->next)
   1535         if (tmp->opt == opt && !(tmp->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR)))
   1536             if (match_netid(tmp->netid, netid, netid ? 0 : 1)) return tmp;
   1537 
   1538     return netid ? option_find2(NULL, opts, opt) : NULL;
   1539 }
   1540 
   1541 /* mark vendor-encapsulated options which match the client-supplied  or
   1542    config-supplied vendor class */
   1543 static void match_vendor_opts(unsigned char* opt, struct dhcp_opt* dopt) {
   1544     for (; dopt; dopt = dopt->next) {
   1545         dopt->flags &= ~DHOPT_VENDOR_MATCH;
   1546         if (opt && (dopt->flags & DHOPT_VENDOR)) {
   1547             int i, len = 0;
   1548             if (dopt->u.vendor_class) len = strlen((char*) dopt->u.vendor_class);
   1549             for (i = 0; i <= (option_len(opt) - len); i++)
   1550                 if (len == 0 || memcmp(dopt->u.vendor_class, option_ptr(opt, i), len) == 0) {
   1551                     dopt->flags |= DHOPT_VENDOR_MATCH;
   1552                     break;
   1553                 }
   1554         }
   1555     }
   1556 }
   1557 
   1558 static void do_encap_opts(struct dhcp_opt* opt, int encap, int flag, struct dhcp_packet* mess,
   1559                           unsigned char* end, int null_term) {
   1560     int len, enc_len;
   1561     struct dhcp_opt* start;
   1562     unsigned char* p;
   1563 
   1564     /* find size in advance */
   1565     for (enc_len = 0, start = opt; opt; opt = opt->next)
   1566         if (opt->flags & flag) {
   1567             int new = do_opt(opt, NULL, NULL, null_term) + 2;
   1568             if (enc_len + new <= 255)
   1569                 enc_len += new;
   1570             else {
   1571                 p = free_space(mess, end, encap, enc_len);
   1572                 for (; start && start != opt; start = start->next)
   1573                     if (p && (start->flags & flag)) {
   1574                         len = do_opt(start, p + 2, NULL, null_term);
   1575                         *(p++) = start->opt;
   1576                         *(p++) = len;
   1577                         p += len;
   1578                     }
   1579                 enc_len = new;
   1580                 start = opt;
   1581             }
   1582         }
   1583 
   1584     if (enc_len != 0 && (p = free_space(mess, end, encap, enc_len + 1))) {
   1585         for (; start; start = start->next)
   1586             if (start->flags & flag) {
   1587                 len = do_opt(start, p + 2, NULL, null_term);
   1588                 *(p++) = start->opt;
   1589                 *(p++) = len;
   1590                 p += len;
   1591             }
   1592         *p = OPTION_END;
   1593     }
   1594 }
   1595 
   1596 static void pxe_misc(struct dhcp_packet* mess, unsigned char* end, unsigned char* uuid) {
   1597     unsigned char* p;
   1598 
   1599     option_put_string(mess, end, OPTION_VENDOR_ID, "PXEClient", 0);
   1600     if (uuid && (p = free_space(mess, end, OPTION_PXE_UUID, 17))) memcpy(p, uuid, 17);
   1601 }
   1602 
   1603 static int prune_vendor_opts(struct dhcp_netid* netid) {
   1604     int force = 0;
   1605     struct dhcp_opt* opt;
   1606 
   1607     /* prune vendor-encapsulated options based on netid, and look if we're forcing them to be sent */
   1608     for (opt = daemon->dhcp_opts; opt; opt = opt->next)
   1609         if (opt->flags & DHOPT_VENDOR_MATCH) {
   1610             if (!match_netid(opt->netid, netid, 1))
   1611                 opt->flags &= ~DHOPT_VENDOR_MATCH;
   1612             else if (opt->flags & DHOPT_FORCE)
   1613                 force = 1;
   1614         }
   1615     return force;
   1616 }
   1617 
   1618 static struct dhcp_opt* pxe_opts(int pxe_arch, struct dhcp_netid* netid) {
   1619 #define NUM_OPTS 4
   1620 
   1621     unsigned char *p, *q;
   1622     struct pxe_service* service;
   1623     static struct dhcp_opt *o, *ret;
   1624     int i, j = NUM_OPTS - 1;
   1625 
   1626     /* We pass back references to these, hence they are declared static */
   1627     static unsigned char discovery_control;
   1628     static unsigned char fake_prompt[] = {0, 'P', 'X', 'E'};
   1629     static struct dhcp_opt* fake_opts = NULL;
   1630 
   1631     /* We are found by broadcast, so disable multicast. It gets switched on again
   1632        if we point to other servers and don't give a unicast address. Note that
   1633        we don't provide our own address for services we are the boot server for because unicast
   1634        discovery is to port 4011 and we don't listen there. If you are using proxy DHCP
   1635        and DHCP relays, the relay will need to forward to the proxy too. */
   1636     discovery_control = 2;
   1637 
   1638     ret = daemon->dhcp_opts;
   1639 
   1640     if (!fake_opts && !(fake_opts = whine_malloc(NUM_OPTS * sizeof(struct dhcp_opt)))) return ret;
   1641 
   1642     for (i = 0; i < NUM_OPTS; i++) {
   1643         fake_opts[i].flags = DHOPT_VENDOR_MATCH;
   1644         fake_opts[i].netid = NULL;
   1645         fake_opts[i].next = i == (NUM_OPTS - 1) ? ret : &fake_opts[i + 1];
   1646     }
   1647 
   1648     /* create the data for the PXE_MENU and PXE_SERVERS options. */
   1649     p = (unsigned char*) daemon->dhcp_buff;
   1650     q = (unsigned char*) daemon->dhcp_buff2;
   1651 
   1652     for (i = 0, service = daemon->pxe_services; service; service = service->next)
   1653         if (pxe_arch == service->CSA && match_netid(service->netid, netid, 1)) {
   1654             size_t len = strlen(service->menu);
   1655             /* opt 43 max size is 255. encapsulated option has type and length
   1656                bytes, so its max size is 253. */
   1657             if (p - (unsigned char*) daemon->dhcp_buff + len + 3 < 253) {
   1658                 *(p++) = service->type >> 8;
   1659                 *(p++) = service->type;
   1660                 *(p++) = len;
   1661                 memcpy(p, service->menu, len);
   1662                 p += len;
   1663                 i++;
   1664             } else {
   1665             toobig:
   1666                 my_syslog(MS_DHCP | LOG_ERR, _("PXE menu too large"));
   1667                 return daemon->dhcp_opts;
   1668             }
   1669 
   1670             if (!service->basename) {
   1671                 if (service->server.s_addr != 0) {
   1672                     if (q - (unsigned char*) daemon->dhcp_buff2 + 3 + INADDRSZ >= 253) goto toobig;
   1673 
   1674                     /* Boot service with known address - give it */
   1675                     *(q++) = service->type >> 8;
   1676                     *(q++) = service->type;
   1677                     *(q++) = 1;
   1678                     /* dest misaligned */
   1679                     memcpy(q, &service->server.s_addr, INADDRSZ);
   1680                     q += INADDRSZ;
   1681                 } else if (service->type != 0)
   1682                     /* We're not supplying a server, so let the client multicast.
   1683                    type zero is "local boot" so no need for M/C on that. */
   1684                     discovery_control = 0;
   1685             }
   1686         }
   1687 
   1688     /* if no prompt, wait forever if there's a choice */
   1689     fake_prompt[0] = (i > 1) ? 255 : 0;
   1690 
   1691     if (i == 0)
   1692         discovery_control = 8; /* no menu - just use use mess->filename */
   1693     else {
   1694         ret = &fake_opts[j--];
   1695         ret->len = p - (unsigned char*) daemon->dhcp_buff;
   1696         ret->val = (unsigned char*) daemon->dhcp_buff;
   1697         ret->opt = SUBOPT_PXE_MENU;
   1698 
   1699         if (q - (unsigned char*) daemon->dhcp_buff2 != 0) {
   1700             ret = &fake_opts[j--];
   1701             ret->len = q - (unsigned char*) daemon->dhcp_buff2;
   1702             ret->val = (unsigned char*) daemon->dhcp_buff2;
   1703             ret->opt = SUBOPT_PXE_SERVERS;
   1704         }
   1705     }
   1706 
   1707     for (o = daemon->dhcp_opts; o; o = o->next)
   1708         if ((o->flags & DHOPT_VENDOR_MATCH) && o->opt == SUBOPT_PXE_MENU_PROMPT) break;
   1709 
   1710     if (!o) {
   1711         ret = &fake_opts[j--];
   1712         ret->len = sizeof(fake_prompt);
   1713         ret->val = fake_prompt;
   1714         ret->opt = SUBOPT_PXE_MENU_PROMPT;
   1715     }
   1716 
   1717     if (discovery_control != 0) {
   1718         ret = &fake_opts[j--];
   1719         ret->len = 1;
   1720         ret->opt = SUBOPT_PXE_DISCOVERY;
   1721         ret->val = &discovery_control;
   1722     }
   1723 
   1724     return ret;
   1725 }
   1726 
   1727 static void clear_packet(struct dhcp_packet* mess, unsigned char* end) {
   1728     memset(mess->sname, 0, sizeof(mess->sname));
   1729     memset(mess->file, 0, sizeof(mess->file));
   1730     memset(&mess->options[0] + sizeof(u32), 0, end - (&mess->options[0] + sizeof(u32)));
   1731     mess->siaddr.s_addr = 0;
   1732 }
   1733 
   1734 struct dhcp_boot* find_boot(struct dhcp_netid* netid) {
   1735     struct dhcp_boot* boot;
   1736 
   1737     /* decide which dhcp-boot option we're using */
   1738     for (boot = daemon->boot_config; boot; boot = boot->next)
   1739         if (match_netid(boot->netid, netid, 0)) break;
   1740     if (!boot) /* No match, look for one without a netid */
   1741         for (boot = daemon->boot_config; boot; boot = boot->next)
   1742             if (match_netid(boot->netid, netid, 1)) break;
   1743 
   1744     return boot;
   1745 }
   1746 
   1747 static void do_options(struct dhcp_context* context, struct dhcp_packet* mess, unsigned char* end,
   1748                        unsigned char* req_options, char* hostname, char* domain,
   1749                        char* config_domain, struct dhcp_netid* netid, struct in_addr subnet_addr,
   1750                        unsigned char fqdn_flags, int null_term, int pxe_arch, unsigned char* uuid) {
   1751     struct dhcp_opt *opt, *config_opts = daemon->dhcp_opts;
   1752     struct dhcp_boot* boot;
   1753     unsigned char* p;
   1754     int i, len, force_encap = 0;
   1755     unsigned char f0 = 0, s0 = 0;
   1756     int done_file = 0, done_server = 0;
   1757 
   1758     if (config_domain && (!domain || !hostname_isequal(domain, config_domain)))
   1759         my_syslog(MS_DHCP | LOG_WARNING, _("Ignoring domain %s for DHCP host name %s"),
   1760                   config_domain, hostname);
   1761 
   1762     /* logging */
   1763     if ((daemon->options & OPT_LOG_OPTS) && req_options) {
   1764         char* q = daemon->namebuff;
   1765         for (i = 0; req_options[i] != OPTION_END; i++) {
   1766             char* s = option_string(req_options[i], NULL, NULL);
   1767             q += snprintf(q, MAXDNAME - (q - daemon->namebuff), "%d%s%s%s", req_options[i],
   1768                           s ? ":" : "", s ? s : "", req_options[i + 1] == OPTION_END ? "" : ", ");
   1769             if (req_options[i + 1] == OPTION_END || (q - daemon->namebuff) > 40) {
   1770                 q = daemon->namebuff;
   1771                 my_syslog(MS_DHCP | LOG_INFO, _("%u requested options: %s"), ntohl(mess->xid),
   1772                           daemon->namebuff);
   1773             }
   1774         }
   1775     }
   1776 
   1777     if (context) mess->siaddr = context->local;
   1778 
   1779     /* See if we can send the boot stuff as options.
   1780        To do this we need a requested option list, BOOTP
   1781        and very old DHCP clients won't have this, we also
   1782        provide an manual option to disable it.
   1783        Some PXE ROMs have bugs (surprise!) and need zero-terminated
   1784        names, so we always send those.  */
   1785     if ((boot = find_boot(netid))) {
   1786         if (boot->sname) {
   1787             if (!(daemon->options & OPT_NO_OVERRIDE) && req_options &&
   1788                 in_list(req_options, OPTION_SNAME))
   1789                 option_put_string(mess, end, OPTION_SNAME, boot->sname, 1);
   1790             else
   1791                 strncpy((char*) mess->sname, boot->sname, sizeof(mess->sname) - 1);
   1792         }
   1793 
   1794         if (boot->file) {
   1795             if (!(daemon->options & OPT_NO_OVERRIDE) && req_options &&
   1796                 in_list(req_options, OPTION_FILENAME))
   1797                 option_put_string(mess, end, OPTION_FILENAME, boot->file, 1);
   1798             else
   1799                 strncpy((char*) mess->file, boot->file, sizeof(mess->file) - 1);
   1800         }
   1801 
   1802         if (boot->next_server.s_addr) mess->siaddr = boot->next_server;
   1803     } else
   1804     /* Use the values of the relevant options if no dhcp-boot given and
   1805        they're not explicitly asked for as options. OPTION_END is used
   1806        as an internal way to specify siaddr without using dhcp-boot, for use in
   1807        dhcp-optsfile. */
   1808     {
   1809         if ((!req_options || !in_list(req_options, OPTION_FILENAME)) && mess->file[0] == 0 &&
   1810             (opt = option_find2(netid, config_opts, OPTION_FILENAME)) &&
   1811             !(opt->flags & DHOPT_FORCE)) {
   1812             strncpy((char*) mess->file, (char*) opt->val, sizeof(mess->file) - 1);
   1813             done_file = 1;
   1814         }
   1815 
   1816         if ((!req_options || !in_list(req_options, OPTION_SNAME)) &&
   1817             (opt = option_find2(netid, config_opts, OPTION_SNAME)) && !(opt->flags & DHOPT_FORCE)) {
   1818             strncpy((char*) mess->sname, (char*) opt->val, sizeof(mess->sname) - 1);
   1819             done_server = 1;
   1820         }
   1821 
   1822         if ((opt = option_find2(netid, config_opts, OPTION_END)))
   1823             mess->siaddr.s_addr = ((struct in_addr*) opt->val)->s_addr;
   1824     }
   1825 
   1826     /* We don't want to do option-overload for BOOTP, so make the file and sname
   1827        fields look like they are in use, even when they aren't. This gets restored
   1828        at the end of this function. */
   1829 
   1830     if (!req_options || (daemon->options & OPT_NO_OVERRIDE)) {
   1831         f0 = mess->file[0];
   1832         mess->file[0] = 1;
   1833         s0 = mess->sname[0];
   1834         mess->sname[0] = 1;
   1835     }
   1836 
   1837     /* At this point, if mess->sname or mess->file are zeroed, they are available
   1838        for option overload, reserve space for the overload option. */
   1839     if (mess->file[0] == 0 || mess->sname[0] == 0) end -= 3;
   1840 
   1841     /* rfc3011 says this doesn't need to be in the requested options list. */
   1842     if (subnet_addr.s_addr)
   1843         option_put(mess, end, OPTION_SUBNET_SELECT, INADDRSZ, ntohl(subnet_addr.s_addr));
   1844 
   1845     /* replies to DHCPINFORM may not have a valid context */
   1846     if (context) {
   1847         if (!option_find2(netid, config_opts, OPTION_NETMASK))
   1848             option_put(mess, end, OPTION_NETMASK, INADDRSZ, ntohl(context->netmask.s_addr));
   1849 
   1850         /* May not have a "guessed" broadcast address if we got no packets via a relay
   1851        from this net yet (ie just unicast renewals after a restart */
   1852         if (context->broadcast.s_addr && !option_find2(netid, config_opts, OPTION_BROADCAST))
   1853             option_put(mess, end, OPTION_BROADCAST, INADDRSZ, ntohl(context->broadcast.s_addr));
   1854 
   1855         /* Same comments as broadcast apply, and also may not be able to get a sensible
   1856        default when using subnet select.  User must configure by steam in that case. */
   1857         if (context->router.s_addr && in_list(req_options, OPTION_ROUTER) &&
   1858             !option_find2(netid, config_opts, OPTION_ROUTER))
   1859             option_put(mess, end, OPTION_ROUTER, INADDRSZ, ntohl(context->router.s_addr));
   1860 
   1861         if (in_list(req_options, OPTION_DNSSERVER) &&
   1862             !option_find2(netid, config_opts, OPTION_DNSSERVER))
   1863             option_put(mess, end, OPTION_DNSSERVER, INADDRSZ, ntohl(context->local.s_addr));
   1864     }
   1865 
   1866     if (domain && in_list(req_options, OPTION_DOMAINNAME) &&
   1867         !option_find2(netid, config_opts, OPTION_DOMAINNAME))
   1868         option_put_string(mess, end, OPTION_DOMAINNAME, domain, null_term);
   1869 
   1870     /* Note that we ignore attempts to set the fqdn using --dhc-option=81,<name> */
   1871     if (hostname) {
   1872         if (in_list(req_options, OPTION_HOSTNAME) &&
   1873             !option_find2(netid, config_opts, OPTION_HOSTNAME))
   1874             option_put_string(mess, end, OPTION_HOSTNAME, hostname, null_term);
   1875 
   1876         if (fqdn_flags != 0) {
   1877             len = strlen(hostname) + 3;
   1878 
   1879             if (fqdn_flags & 0x04)
   1880                 len += 2;
   1881             else if (null_term)
   1882                 len++;
   1883 
   1884             if (domain) len += strlen(domain) + 1;
   1885 
   1886             if ((p = free_space(mess, end, OPTION_CLIENT_FQDN, len))) {
   1887                 *(p++) = fqdn_flags;
   1888                 *(p++) = 255;
   1889                 *(p++) = 255;
   1890 
   1891                 if (fqdn_flags & 0x04) {
   1892                     p = do_rfc1035_name(p, hostname);
   1893                     if (domain) p = do_rfc1035_name(p, domain);
   1894                     *p++ = 0;
   1895                 } else {
   1896                     memcpy(p, hostname, strlen(hostname));
   1897                     p += strlen(hostname);
   1898                     if (domain) {
   1899                         *(p++) = '.';
   1900                         memcpy(p, domain, strlen(domain));
   1901                         p += strlen(domain);
   1902                     }
   1903                     if (null_term) *(p++) = 0;
   1904                 }
   1905             }
   1906         }
   1907     }
   1908 
   1909     for (opt = config_opts; opt; opt = opt->next) {
   1910         int optno = opt->opt;
   1911 
   1912         /* was it asked for, or are we sending it anyway? */
   1913         if (!(opt->flags & DHOPT_FORCE) && !in_list(req_options, optno)) continue;
   1914 
   1915         /* prohibit some used-internally options */
   1916         if (optno == OPTION_CLIENT_FQDN || optno == OPTION_MAXMESSAGE || optno == OPTION_OVERLOAD ||
   1917             optno == OPTION_PAD || optno == OPTION_END)
   1918             continue;
   1919 
   1920         if (optno == OPTION_SNAME && done_server) continue;
   1921 
   1922         if (optno == OPTION_FILENAME && done_file) continue;
   1923 
   1924         /* netids match and not encapsulated? */
   1925         if (opt != option_find2(netid, config_opts, optno)) continue;
   1926 
   1927         /* For the options we have default values on
   1928        dhc-option=<optionno> means "don't include this option"
   1929        not "include a zero-length option" */
   1930         if (opt->len == 0 &&
   1931             (optno == OPTION_NETMASK || optno == OPTION_BROADCAST || optno == OPTION_ROUTER ||
   1932              optno == OPTION_DNSSERVER || optno == OPTION_DOMAINNAME || optno == OPTION_HOSTNAME))
   1933             continue;
   1934 
   1935         /* vendor-class comes from elsewhere for PXE */
   1936         if (pxe_arch != -1 && optno == OPTION_VENDOR_ID) continue;
   1937 
   1938         /* always force null-term for filename and servername - buggy PXE again. */
   1939         len = do_opt(opt, NULL, context,
   1940                      (optno == OPTION_SNAME || optno == OPTION_FILENAME) ? 1 : null_term);
   1941 
   1942         if ((p = free_space(mess, end, optno, len))) {
   1943             do_opt(opt, p, context,
   1944                    (optno == OPTION_SNAME || optno == OPTION_FILENAME) ? 1 : null_term);
   1945 
   1946             /* If we send a vendor-id, revisit which vendor-ops we consider
   1947                it appropriate to send. */
   1948             if (optno == OPTION_VENDOR_ID) match_vendor_opts(p - 2, config_opts);
   1949         }
   1950     }
   1951 
   1952     /* Now send options to be encapsulated in arbitrary options,
   1953        eg dhcp-option=encap:172,17,.......
   1954        The may be more that one "outer" to do, so group
   1955        all the options which match each outer in turn. */
   1956     for (opt = config_opts; opt; opt = opt->next) opt->flags &= ~DHOPT_ENCAP_DONE;
   1957 
   1958     for (opt = config_opts; opt; opt = opt->next)
   1959         if ((opt->flags & (DHOPT_ENCAPSULATE | DHOPT_ENCAP_DONE)) == DHOPT_ENCAPSULATE) {
   1960             struct dhcp_opt* o;
   1961             int found = 0;
   1962 
   1963             for (o = config_opts; o; o = o->next) {
   1964                 o->flags &= ~DHOPT_ENCAP_MATCH;
   1965                 if ((o->flags & DHOPT_ENCAPSULATE) && opt->u.encap == o->u.encap) {
   1966                     o->flags |= DHOPT_ENCAP_DONE;
   1967                     if (match_netid(o->netid, netid, 1) &&
   1968                         (o->flags & DHOPT_FORCE || in_list(req_options, o->u.encap))) {
   1969                         o->flags |= DHOPT_ENCAP_MATCH;
   1970                         found = 1;
   1971                     }
   1972                 }
   1973             }
   1974 
   1975             if (found)
   1976                 do_encap_opts(config_opts, opt->u.encap, DHOPT_ENCAP_MATCH, mess, end, null_term);
   1977         }
   1978 
   1979     /* Must precede pxe_opts, since it overwrites req_options */
   1980     force_encap = prune_vendor_opts(netid);
   1981     if (in_list(req_options, OPTION_VENDOR_CLASS_OPT)) force_encap = 1;
   1982 
   1983     if (pxe_arch != -1) {
   1984         pxe_misc(mess, end, uuid);
   1985         config_opts = pxe_opts(pxe_arch, netid);
   1986     }
   1987 
   1988     if (force_encap)
   1989         do_encap_opts(config_opts, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end,
   1990                       null_term);
   1991 
   1992     /* restore BOOTP anti-overload hack */
   1993     if (!req_options || (daemon->options & OPT_NO_OVERRIDE)) {
   1994         mess->file[0] = f0;
   1995         mess->sname[0] = s0;
   1996     }
   1997 }
   1998 
   1999 #endif
   2000