|
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 } |