2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2008 Roy Marples <roy@marples.name>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 #include "if-options.h"
45 (sizeof(struct arphdr) + (2 * sizeof(uint32_t)) + (2 * HWADDR_LEN))
48 send_arp(const struct interface
*iface
, int op
, in_addr_t sip
, in_addr_t tip
)
50 uint8_t arp_buffer
[ARP_LEN
];
56 ar
.ar_hrd
= htons(iface
->family
);
57 ar
.ar_pro
= htons(ETHERTYPE_IP
);
58 ar
.ar_hln
= iface
->hwlen
;
59 ar
.ar_pln
= sizeof(sip
);
61 memcpy(arp_buffer
, &ar
, sizeof(ar
));
62 p
= arp_buffer
+ sizeof(ar
);
63 memcpy(p
, iface
->hwaddr
, iface
->hwlen
);
65 memcpy(p
, &sip
, sizeof(sip
));
67 /* ARP requests should ignore this */
68 retval
= iface
->hwlen
;
71 memcpy(p
, &tip
, sizeof(tip
));
74 retval
= send_raw_packet(iface
, ETHERTYPE_ARP
, arp_buffer
, len
);
79 handle_arp_failure(struct interface
*iface
)
81 if (IN_LINKLOCAL(htonl(iface
->state
->fail
.s_addr
))) {
82 handle_ipv4ll_failure(iface
);
85 unlink(iface
->leasefile
);
86 if (!iface
->state
->lease
.frominfo
)
89 delete_timeout(NULL
, iface
);
90 if (iface
->state
->lease
.frominfo
)
91 start_interface(iface
);
93 add_timeout_sec(DHCP_ARP_FAIL
, start_interface
, iface
);
97 handle_arp_packet(void *arg
)
99 struct interface
*iface
= arg
;
100 uint8_t arp_buffer
[ARP_LEN
];
104 uint8_t *hw_s
, *hw_t
;
106 struct if_state
*state
= iface
->state
;
107 struct if_options
*opts
= state
->options
;
111 state
->fail
.s_addr
= 0;
113 bytes
= get_raw_packet(iface
, ETHERTYPE_ARP
,
114 arp_buffer
, sizeof(arp_buffer
));
115 if (bytes
== 0 || bytes
== -1)
117 /* We must have a full ARP header */
118 if ((size_t)bytes
< sizeof(ar
))
120 memcpy(&ar
, arp_buffer
, sizeof(ar
));
121 /* Protocol must be IP. */
122 if (ar
.ar_pro
!= htons(ETHERTYPE_IP
))
124 if (ar
.ar_pln
!= sizeof(reply_s
))
126 /* Only these types are recognised */
127 if (ar
.ar_op
!= htons(ARPOP_REPLY
) &&
128 ar
.ar_op
!= htons(ARPOP_REQUEST
))
131 /* Get pointers to the hardware addreses */
132 hw_s
= arp_buffer
+ sizeof(ar
);
133 hw_t
= hw_s
+ ar
.ar_hln
+ ar
.ar_pln
;
134 /* Ensure we got all the data */
135 if ((hw_t
+ ar
.ar_hln
+ ar
.ar_pln
) - arp_buffer
> bytes
)
137 /* Ignore messages from ourself */
138 if (ar
.ar_hln
== iface
->hwlen
&&
139 memcmp(hw_s
, iface
->hwaddr
, iface
->hwlen
) == 0)
141 /* Copy out the IP addresses */
142 memcpy(&reply_s
, hw_s
+ ar
.ar_hln
, ar
.ar_pln
);
143 memcpy(&reply_t
, hw_t
+ ar
.ar_hln
, ar
.ar_pln
);
145 /* Check for arping */
146 if (state
->arping_index
&&
147 state
->arping_index
<= opts
->arping_len
&&
148 (reply_s
== opts
->arping
[state
->arping_index
- 1] ||
150 reply_t
== opts
->arping
[state
->arping_index
- 1])))
152 ina
.s_addr
= reply_s
;
153 hwaddr
= hwaddr_ntoa((unsigned char *)hw_s
,
156 "%s: found %s on hardware address %s",
157 iface
->name
, inet_ntoa(ina
), hwaddr
);
158 if (select_profile(iface
, hwaddr
) == -1 &&
160 select_profile(iface
, inet_ntoa(ina
));
161 close_sockets(iface
);
162 delete_timeout(NULL
, iface
);
163 start_interface(iface
);
167 /* Check for conflict */
169 (reply_s
== state
->offer
->yiaddr
||
170 (reply_s
== 0 && reply_t
== state
->offer
->yiaddr
)))
171 state
->fail
.s_addr
= state
->offer
->yiaddr
;
173 /* Handle IPv4LL conflicts */
174 if (IN_LINKLOCAL(htonl(iface
->addr
.s_addr
)) &&
175 (reply_s
== iface
->addr
.s_addr
||
176 (reply_s
== 0 && reply_t
== iface
->addr
.s_addr
)))
177 state
->fail
.s_addr
= iface
->addr
.s_addr
;
179 if (state
->fail
.s_addr
) {
180 syslog(LOG_ERR
, "%s: hardware address %s claims %s",
182 hwaddr_ntoa((unsigned char *)hw_s
,
184 inet_ntoa(state
->fail
));
186 handle_arp_failure(iface
);
193 send_arp_announce(void *arg
)
195 struct interface
*iface
= arg
;
196 struct if_state
*state
= iface
->state
;
199 if (iface
->arp_fd
== -1) {
200 open_socket(iface
, ETHERTYPE_ARP
);
201 add_event(iface
->arp_fd
, handle_arp_packet
, iface
);
203 if (++state
->claims
< ANNOUNCE_NUM
)
205 "%s: sending ARP announce (%d of %d), "
206 "next in %d.00 seconds",
207 iface
->name
, state
->claims
, ANNOUNCE_NUM
, ANNOUNCE_WAIT
);
210 "%s: sending ARP announce (%d of %d)",
211 iface
->name
, state
->claims
, ANNOUNCE_NUM
);
212 if (send_arp(iface
, ARPOP_REQUEST
,
213 state
->new->yiaddr
, state
->new->yiaddr
) == -1)
214 syslog(LOG_ERR
, "send_arp: %m");
215 if (state
->claims
< ANNOUNCE_NUM
) {
216 add_timeout_sec(ANNOUNCE_WAIT
, send_arp_announce
, iface
);
219 if (IN_LINKLOCAL(htonl(state
->new->yiaddr
))) {
220 /* We should pretend to be at the end
221 * of the DHCP negotation cycle unless we rebooted */
222 if (state
->interval
!= 0)
223 state
->interval
= 64;
226 tv
.tv_sec
= state
->interval
- DHCP_RAND_MIN
;
227 tv
.tv_usec
= arc4random() % (DHCP_RAND_MAX_U
- DHCP_RAND_MIN_U
);
229 add_timeout_tv(&tv
, start_discover
, iface
);
231 delete_event(iface
->arp_fd
);
232 close(iface
->arp_fd
);
238 send_arp_probe(void *arg
)
240 struct interface
*iface
= arg
;
241 struct if_state
*state
= iface
->state
;
246 if (state
->arping_index
< state
->options
->arping_len
) {
247 addr
.s_addr
= state
->options
->arping
[state
->arping_index
];
249 } else if (state
->offer
) {
250 if (state
->offer
->yiaddr
)
251 addr
.s_addr
= state
->offer
->yiaddr
;
253 addr
.s_addr
= state
->offer
->ciaddr
;
255 addr
.s_addr
= iface
->addr
.s_addr
;
257 if (iface
->arp_fd
== -1) {
258 open_socket(iface
, ETHERTYPE_ARP
);
259 add_event(iface
->arp_fd
, handle_arp_packet
, iface
);
261 if (state
->probes
== 0) {
263 syslog(LOG_INFO
, "%s: searching for %s",
264 iface
->name
, inet_ntoa(addr
));
266 syslog(LOG_INFO
, "%s: checking for %s",
267 iface
->name
, inet_ntoa(addr
));
269 if (++state
->probes
< PROBE_NUM
) {
270 tv
.tv_sec
= PROBE_MIN
;
271 tv
.tv_usec
= arc4random() % (PROBE_MAX_U
- PROBE_MIN_U
);
273 add_timeout_tv(&tv
, send_arp_probe
, iface
);
275 tv
.tv_sec
= ANNOUNCE_WAIT
;
279 if (++state
->arping_index
< state
->options
->arping_len
)
280 add_timeout_tv(&tv
, send_arp_probe
, iface
);
282 add_timeout_tv(&tv
, start_interface
, iface
);
284 add_timeout_tv(&tv
, bind_interface
, iface
);
287 "%s: sending ARP probe (%d of %d), next in %0.2f seconds",
288 iface
->name
, state
->probes
? state
->probes
: PROBE_NUM
, PROBE_NUM
,
289 timeval_to_double(&tv
));
290 if (send_arp(iface
, ARPOP_REQUEST
, 0, addr
.s_addr
) == -1)
291 syslog(LOG_ERR
, "send_arp: %m");
295 start_arping(struct interface
*iface
)
297 iface
->state
->probes
= 0;
298 iface
->state
->arping_index
= 0;
299 send_arp_probe(iface
);