Diff for /embedaddon/dnsmasq/src/rfc3315.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2014/06/15 16:31:38 version 1.1.1.3, 2016/11/02 09:57:01
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
   
    This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
Line 130  static int dhcp6_maybe_relay(struct state *state, void Line 130  static int dhcp6_maybe_relay(struct state *state, void
       MAC address from the local ND cache. */        MAC address from the local ND cache. */
               
       if (!state->link_address)        if (!state->link_address)
        get_client_mac(client_addr, state->interface, state->mac, &state->mac_len, &state->mac_type);        get_client_mac(client_addr, state->interface, state->mac, &state->mac_len, &state->mac_type, now);
       else        else
         {          {
           struct dhcp_context *c;            struct dhcp_context *c;
Line 313  static int dhcp6_no_relay(struct state *state, int msg Line 313  static int dhcp6_no_relay(struct state *state, int msg
   else if (msg_type != DHCP6IREQ)    else if (msg_type != DHCP6IREQ)
     return 0;      return 0;
   
  /* server-id must match except for SOLICIT and CONFIRM messages */  /* server-id must match except for SOLICIT, CONFIRM and REBIND messages */
  if (msg_type != DHCP6SOLICIT && msg_type != DHCP6CONFIRM && msg_type != DHCP6IREQ &&  if (msg_type != DHCP6SOLICIT && msg_type != DHCP6CONFIRM && msg_type != DHCP6IREQ && msg_type != DHCP6REBIND &&
       (!(opt = opt6_find(state->packet_options, state->end, OPTION6_SERVER_ID, 1)) ||        (!(opt = opt6_find(state->packet_options, state->end, OPTION6_SERVER_ID, 1)) ||
        opt6_len(opt) != daemon->duid_len ||         opt6_len(opt) != daemon->duid_len ||
        memcmp(opt6_ptr(opt, 0), daemon->duid, daemon->duid_len) != 0))         memcmp(opt6_ptr(opt, 0), daemon->duid, daemon->duid_len) != 0))
Line 328  static int dhcp6_no_relay(struct state *state, int msg Line 328  static int dhcp6_no_relay(struct state *state, int msg
       (msg_type == DHCP6REQUEST || msg_type == DHCP6RENEW || msg_type == DHCP6RELEASE || msg_type == DHCP6DECLINE))        (msg_type == DHCP6REQUEST || msg_type == DHCP6RENEW || msg_type == DHCP6RELEASE || msg_type == DHCP6DECLINE))
           
     {        {  
         *outmsgtypep = DHCP6REPLY;
       o1 = new_opt6(OPTION6_STATUS_CODE);        o1 = new_opt6(OPTION6_STATUS_CODE);
       put_opt6_short(DHCP6USEMULTI);        put_opt6_short(DHCP6USEMULTI);
       put_opt6_string("Use multicast");        put_opt6_string("Use multicast");
Line 690  static int dhcp6_no_relay(struct state *state, int msg Line 691  static int dhcp6_no_relay(struct state *state, int msg
 #endif  #endif
   
             o = build_ia(state, &t1cntr);              o = build_ia(state, &t1cntr);
               if (address_assigned)
                   address_assigned = 2;
   
             for (ia_counter = 0; ia_option; ia_counter++, ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))              for (ia_counter = 0; ia_option; ia_counter++, ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
               {                {
Line 780  static int dhcp6_no_relay(struct state *state, int msg Line 783  static int dhcp6_no_relay(struct state *state, int msg
                 address_assigned = 1;                  address_assigned = 1;
               }                }
                           
               if (address_assigned != 1)
                 {
                   /* If the server will not assign any addresses to any IAs in a
                      subsequent Request from the client, the server MUST send an Advertise
                      message to the client that doesn't include any IA options. */
                   if (!state->lease_allocate)
                     {
                       save_counter(o);
                       continue;
                     }
                   
                   /* If the server cannot assign any addresses to an IA in the message
                      from the client, the server MUST include the IA in the Reply message
                      with no addresses in the IA and a Status Code option in the IA
                      containing status code NoAddrsAvail. */
                   o1 = new_opt6(OPTION6_STATUS_CODE);
                   put_opt6_short(DHCP6NOADDRS);
                   put_opt6_string(_("address unavailable"));
                   end_opt6(o1);
                 }
               
             end_ia(t1cntr, min_time, 0);              end_ia(t1cntr, min_time, 0);
             end_opt6(o);                      end_opt6(o);        
           }            }
Line 805  static int dhcp6_no_relay(struct state *state, int msg Line 829  static int dhcp6_no_relay(struct state *state, int msg
             put_opt6_short(DHCP6NOADDRS);              put_opt6_short(DHCP6NOADDRS);
             put_opt6_string(_("no addresses available"));              put_opt6_string(_("no addresses available"));
             end_opt6(o1);              end_opt6(o1);
            log6_packet(state, "DHCPADVERTISE", NULL, _("no addresses available"));
             /* Some clients will ask repeatedly when we're not giving
                out addresses because we're in stateless mode. Avoid spamming
                the log in that case. */
             for (c = state->context; c; c = c->current)
               if (!(c->flags & CONTEXT_RA_STATELESS))
                 {
                   log6_packet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", NULL, _("no addresses available"));
                   break;
                 }
           }            }
   
         break;          break;
Line 861  static int dhcp6_no_relay(struct state *state, int msg Line 894  static int dhcp6_no_relay(struct state *state, int msg
                       {                        {
                         /* Static range, not configured. */                          /* Static range, not configured. */
                         o1 = new_opt6(OPTION6_STATUS_CODE);                          o1 = new_opt6(OPTION6_STATUS_CODE);
                        put_opt6_short(DHCP6UNSPEC);                        put_opt6_short(DHCP6NOADDRS);
                         put_opt6_string(_("address unavailable"));                          put_opt6_string(_("address unavailable"));
                         end_opt6(o1);                          end_opt6(o1);
                       }                        }
Line 1014  static int dhcp6_no_relay(struct state *state, int msg Line 1047  static int dhcp6_no_relay(struct state *state, int msg
                   {                    {
                     preferred_time = valid_time = 0;                      preferred_time = valid_time = 0;
                     message = _("address invalid");                      message = _("address invalid");
                  }                  } 
   
                if (message)                if (message && (message != state->hostname))
                   log6_packet(state, "DHCPREPLY", req_addr, message);                       log6_packet(state, "DHCPREPLY", req_addr, message);   
                 else                  else
                   log6_quiet(state, "DHCPREPLY", req_addr, message);                    log6_quiet(state, "DHCPREPLY", req_addr, message);
Line 1039  static int dhcp6_no_relay(struct state *state, int msg Line 1072  static int dhcp6_no_relay(struct state *state, int msg
               
     case DHCP6CONFIRM:      case DHCP6CONFIRM:
       {        {
           int good_addr = 0;
   
         /* set reply message type */          /* set reply message type */
         *outmsgtypep = DHCP6REPLY;          *outmsgtypep = DHCP6REPLY;
                   
Line 1054  static int dhcp6_no_relay(struct state *state, int msg Line 1089  static int dhcp6_no_relay(struct state *state, int msg
               {                {
                 struct in6_addr *req_addr = opt6_ptr(ia_option, 0);                  struct in6_addr *req_addr = opt6_ptr(ia_option, 0);
                                   
                if (!address6_available(state->context, req_addr, tagif, 1))                if (!address6_valid(state->context, req_addr, tagif, 1))
                   {                    {
                     o1 = new_opt6(OPTION6_STATUS_CODE);                      o1 = new_opt6(OPTION6_STATUS_CODE);
                     put_opt6_short(DHCP6NOTONLINK);                      put_opt6_short(DHCP6NOTONLINK);
Line 1063  static int dhcp6_no_relay(struct state *state, int msg Line 1098  static int dhcp6_no_relay(struct state *state, int msg
                     return 1;                      return 1;
                   }                    }
   
                   good_addr = 1;
                 log6_quiet(state, "DHCPREPLY", req_addr, state->hostname);                  log6_quiet(state, "DHCPREPLY", req_addr, state->hostname);
               }                }
           }                  }      
           
           /* No addresses, no reply: RFC 3315 18.2.2 */
           if (!good_addr)
             return 0;
   
         o1 = new_opt6(OPTION6_STATUS_CODE);          o1 = new_opt6(OPTION6_STATUS_CODE);
         put_opt6_short(DHCP6SUCCESS );          put_opt6_short(DHCP6SUCCESS );
Line 1232  static int dhcp6_no_relay(struct state *state, int msg Line 1272  static int dhcp6_no_relay(struct state *state, int msg
               }                }
                           
           }            }
   
           /* We must anwser with 'success' in global section anyway */
           o1 = new_opt6(OPTION6_STATUS_CODE);
           put_opt6_short(DHCP6SUCCESS);
           put_opt6_string(_("success"));
           end_opt6(o1);
         break;          break;
       }        }
   
Line 1274  static struct dhcp_netid *add_options(struct state *st Line 1320  static struct dhcp_netid *add_options(struct state *st
               
       if (opt_cfg->opt == OPTION6_REFRESH_TIME)        if (opt_cfg->opt == OPTION6_REFRESH_TIME)
         done_refresh = 1;          done_refresh = 1;
          
         if (opt_cfg->opt == OPTION6_DNS_SERVER)
           done_dns = 1;
               
       if (opt_cfg->flags & DHOPT_ADDR6)        if (opt_cfg->flags & DHOPT_ADDR6)
         {          {
           int len, j;            int len, j;
           struct in6_addr *a;            struct in6_addr *a;
                       
           if (opt_cfg->opt == OPTION6_DNS_SERVER)  
             done_dns = 1;  
             
           for (a = (struct in6_addr *)opt_cfg->val, len = opt_cfg->len, j = 0;             for (a = (struct in6_addr *)opt_cfg->val, len = opt_cfg->len, j = 0; 
                j < opt_cfg->len; j += IN6ADDRSZ, a++)                 j < opt_cfg->len; j += IN6ADDRSZ, a++)
             if ((IN6_IS_ADDR_ULA_ZERO(a) && IN6_IS_ADDR_UNSPECIFIED(state->ula_addr)) ||              if ((IN6_IS_ADDR_ULA_ZERO(a) && IN6_IS_ADDR_UNSPECIFIED(state->ula_addr)) ||
Line 2008  static unsigned int opt6_uint(unsigned char *opt, int  Line 2054  static unsigned int opt6_uint(unsigned char *opt, int 
   return ret;    return ret;
 }   } 
   
void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, struct in6_addr *peer_address, u32 scope_id)void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, 
                      struct in6_addr *peer_address, u32 scope_id, time_t now)
 {  {
   /* ->local is same value for all relays on ->current chain */    /* ->local is same value for all relays on ->current chain */
       
Line 2022  void relay_upstream6(struct dhcp_relay *relay, ssize_t Line 2069  void relay_upstream6(struct dhcp_relay *relay, ssize_t
   unsigned char mac[DHCP_CHADDR_MAX];    unsigned char mac[DHCP_CHADDR_MAX];
   
   inet_pton(AF_INET6, ALL_SERVERS, &multicast);    inet_pton(AF_INET6, ALL_SERVERS, &multicast);
  get_client_mac(peer_address, scope_id, mac, &maclen, &mactype);  get_client_mac(peer_address, scope_id, mac, &maclen, &mactype, now);
   
   /* source address == relay address */    /* source address == relay address */
   from.addr.addr6 = relay->local.addr.addr6;    from.addr.addr6 = relay->local.addr.addr6;

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>