components/isc-dhcp/patches/002-dhcp_broadcast_offer_bug.patch
changeset 5709 42ebc732084b
parent 5461 5241debe1312
equal deleted inserted replaced
5708:49b43e37ce26 5709:42ebc732084b
       
     1 This patch file was developed in-house to fix a Solaris specific bug. We are
       
     2 working with upstream, but it is unclear at this point whether or not they are
       
     3 going to accept it. This is a highly visible bug which many customers have
       
     4 encountered.
       
     5 
       
     6 --- old/common/socket.c	Tue Mar  1 19:45:19 2016
       
     7 +++ new/common/socket.c	Tue Mar  1 19:45:18 2016
       
     8 @@ -39,6 +39,9 @@
       
     9  #include <sys/ioctl.h>
       
    10  #include <sys/uio.h>
       
    11  #include <sys/uio.h>
       
    12 +#if defined (sun)
       
    13 +#include <sys/ethernet.h>
       
    14 +#endif
       
    15  
       
    16  #if defined(sun) && defined(USE_V4_PKTINFO)
       
    17  #include <sys/sysmacros.h>
       
    18 @@ -87,6 +90,33 @@
       
    19  static int once = 0;
       
    20  #endif /* !defined(SO_BINDTODEVICE) && !defined(USE_FALLBACK) */
       
    21  
       
    22 +#if defined (sun)
       
    23 +int
       
    24 +setup_arp(struct interface_info *interface, struct in_addr ip_addr,
       
    25 +	unsigned char *macaddr)
       
    26 +{
       
    27 +        struct xarpreq ar;
       
    28 +        struct sockaddr_in *sin;
       
    29 +
       
    30 +	(void) memset(&ar, 0, sizeof (ar));
       
    31 +        sin = (struct sockaddr_in *)&ar.xarp_pa;
       
    32 +        sin->sin_family = AF_INET;
       
    33 +	sin->sin_addr.s_addr = ip_addr.s_addr;
       
    34 +
       
    35 +	ar.xarp_ha.sdl_alen = ETHERADDRL;
       
    36 +	(void) memcpy(LLADDR(&ar.xarp_ha), macaddr, ar.xarp_ha.sdl_alen); 
       
    37 +	ar.xarp_ha.sdl_family = AF_LINK; 
       
    38 +	if (ioctl(interface->set_arp_socket, SIOCSXARP, (caddr_t)&ar) < 0) {
       
    39 +		log_error("setup_arp: ioctl error for IP %s MAC %s",
       
    40 +		   inet_ntoa(ip_addr), ether_ntoa((const struct ether_addr *)
       
    41 +		    macaddr));
       
    42 +		return (1);
       
    43 +	}
       
    44 +        return (0);
       
    45 +}
       
    46 +#endif
       
    47 +
       
    48 +
       
    49  /* Reinitializes the specified interface after an address change.   This
       
    50     is not required for packet-filter APIs. */
       
    51  
       
    52 @@ -337,6 +367,9 @@
       
    53  #else
       
    54  	info->wfdesc = info->rfdesc;
       
    55  #endif
       
    56 +#if defined(sun)
       
    57 +	info->set_arp_socket = socket(AF_INET, SOCK_DGRAM, 0);
       
    58 +#endif
       
    59  	if (!quiet_interface_discovery)
       
    60  		log_info ("Sending on   Socket/%s%s%s",
       
    61  		      info->name,
       
    62 @@ -353,6 +386,9 @@
       
    63  	close (info -> wfdesc);
       
    64  #endif
       
    65  	info -> wfdesc = -1;
       
    66 +#if defined (sun)
       
    67 +	close (info -> set_arp_socket);
       
    68 +#endif
       
    69  
       
    70  	if (!quiet_interface_discovery)
       
    71  		log_info ("Disabling output on Socket/%s%s%s",
       
    72 @@ -1088,7 +1124,11 @@
       
    73  int can_unicast_without_arp (ip)
       
    74  	struct interface_info *ip;
       
    75  {
       
    76 +#if defined (sun)
       
    77 +	return 1;
       
    78 +#else
       
    79  	return 0;
       
    80 +#endif
       
    81  }
       
    82  
       
    83  int can_receive_unicast_unconfigured (ip)
       
    84 --- old/includes/dhcpd.h	Tue Mar  1 19:45:19 2016
       
    85 +++ new/includes/dhcpd.h	Tue Mar  1 19:45:18 2016
       
    86 @@ -1354,6 +1354,9 @@
       
    87  	int configured;			/* If set to 1, interface has at least
       
    88  					 * one valid IP address.
       
    89  					 */
       
    90 +#if defined (sun)
       
    91 +	int set_arp_socket;		/* IOCTL socket to set entry in cache */
       
    92 +#endif
       
    93  	u_int32_t flags;		/* Control flags... */
       
    94  #define INTERFACE_REQUESTED 1
       
    95  #define INTERFACE_AUTOMATIC 2
       
    96 @@ -2563,6 +2566,10 @@
       
    97  		       struct sockaddr_in6 *, struct hardware *);
       
    98  #endif
       
    99  
       
   100 +#if defined (sun)
       
   101 +int setup_arp(struct interface_info *, struct in_addr, unsigned char *);
       
   102 +#endif
       
   103 +
       
   104  #ifdef USE_SOCKET_SEND
       
   105  void if_reinitialize_send (struct interface_info *);
       
   106  void if_register_send (struct interface_info *);
       
   107 --- old/relay/dhcrelay.c	Tue Mar  1 19:45:19 2016
       
   108 +++ new/relay/dhcrelay.c	Tue Mar  1 19:45:18 2016
       
   109 @@ -653,6 +653,13 @@
       
   110  			to.sin_addr = packet->yiaddr;
       
   111  			to.sin_port = remote_port;
       
   112  
       
   113 +#if defined (sun)
       
   114 +			if (setup_arp(out, packet->yiaddr, packet->chaddr)) {
       
   115 +				log_error("do_relay4 : Set arp entry failed");
       
   116 +				return;
       
   117 +			}
       
   118 +#endif	
       
   119 +
       
   120  			/* and hardware address is not broadcast */
       
   121  			htop = &hto;
       
   122  		} else {
       
   123 --- old/server/bootp.c	Tue Mar  1 19:45:19 2016
       
   124 +++ new/server/bootp.c	Tue Mar  1 19:45:18 2016
       
   125 @@ -410,7 +410,12 @@
       
   126  		   can_unicast_without_arp (packet -> interface)) {
       
   127  		to.sin_addr = raw.yiaddr;
       
   128  		to.sin_port = remote_port;
       
   129 -
       
   130 +#if defined (__sun)
       
   131 +                if (setup_arp(packet->interface, raw.yiaddr, raw.chaddr)) {
       
   132 +                        log_error("bootp : Set arp entry failed");
       
   133 +                        goto out;
       
   134 +                }
       
   135 +#endif
       
   136  	/* Otherwise, broadcast it on the local network. */
       
   137  	} else {
       
   138  		to.sin_addr = limited_broadcast;
       
   139 --- old/server/dhcp.c	Tue Mar  1 19:45:19 2016
       
   140 +++ new/server/dhcp.c	Tue Mar  1 19:45:18 2016
       
   141 @@ -30,6 +30,8 @@
       
   142  #include <errno.h>
       
   143  #include <limits.h>
       
   144  #include <sys/time.h>
       
   145 +#include <sys/sockio.h>
       
   146 +#include <sys/ioccom.h>
       
   147  
       
   148  static void maybe_return_agent_options(struct packet *packet,
       
   149  				       struct option_state *options);
       
   150 @@ -3745,7 +3747,12 @@
       
   151  		   can_unicast_without_arp (state -> ip)) {
       
   152  		to.sin_addr = raw.yiaddr;
       
   153  		to.sin_port = remote_port;
       
   154 -
       
   155 +#if defined (sun)
       
   156 +		if (setup_arp(state->ip, raw.yiaddr, raw.chaddr)) {
       
   157 +			log_error("dhcp_reply : Set arp entry failed");
       
   158 +			goto err_out;
       
   159 +		}
       
   160 +#endif
       
   161  	/* Otherwise, broadcast it on the local network. */
       
   162  	} else {
       
   163  		to.sin_addr = limited_broadcast;
       
   164 @@ -3767,7 +3774,9 @@
       
   165  
       
   166  	/* Free all of the entries in the option_state structure
       
   167  	   now that we're done with them. */
       
   168 -
       
   169 +#if defined (sun)
       
   170 +err_out:
       
   171 +#endif
       
   172  	free_lease_state (state, MDL);
       
   173  	lease -> state = (struct lease_state *)0;
       
   174  }