71
static struct dhcp_message *
72
ipv4ll_find_lease(uint32_t old_addr)
73
ipv4ll_pick_addr(const struct arp_state *astate)
76
struct interface *ifp;
77
const struct dhcp_state *state;
77
addr = htonl(LINKLOCAL_ADDR |
78
(((uint32_t)abs((int)arc4random())
80
if (addr != old_addr &&
81
IN_LINKLOCAL(ntohl(addr)))
80
/* RFC 3927 Section 2.1 states that the first 256 and
81
* last 256 addresses are reserved for future use.
82
* See ipv4ll_start for why we don't use arc4_random. */
83
addr = ntohl(LINKLOCAL_ADDR |
84
((uint32_t)(random() % 0xFD00) + 0x0100));
86
/* No point using a failed address */
87
if (addr == astate->failed.s_addr)
90
/* Ensure we don't have the address on another interface */
91
TAILQ_FOREACH(ifp, astate->iface->ctx->ifaces, next) {
92
state = D_CSTATE(ifp);
93
if (state && state->addr.s_addr == addr)
97
/* Yay, this should be a unique and workable IPv4LL address */
84
return ipv4ll_make_lease(addr);
88
ipv4ll_start(void *arg)
90
struct interface *ifp = arg;
91
struct dhcp_state *state = D_STATE(ifp);
94
eloop_timeout_delete(NULL, ifp);
97
if (state->addr.s_addr) {
99
if (IN_LINKLOCAL(htonl(state->addr.s_addr))) {
105
if (state->offer == NULL)
108
addr = state->offer->yiaddr;
111
/* We maybe rebooting an IPv4LL address. */
112
if (!IN_LINKLOCAL(htonl(addr))) {
113
syslog(LOG_INFO, "%s: probing for an IPv4LL address",
118
state->offer = ipv4ll_find_lease(addr);
120
state->offer = ipv4ll_make_lease(addr);
121
if (state->offer == NULL)
122
syslog(LOG_ERR, "%s: %m", __func__);
124
state->lease.frominfo = 0;
130
ipv4ll_handle_failure(void *arg)
132
struct interface *ifp = arg;
133
struct dhcp_state *state = D_STATE(ifp);
136
if (state->fail.s_addr == state->addr.s_addr) {
105
ipv4ll_probed(struct arp_state *astate)
107
struct dhcp_state *state = D_STATE(astate->iface);
109
if (state->state == DHS_IPV4LL_BOUND) {
110
ipv4_finaliseaddr(astate->iface);
114
if (state->state != DHS_BOUND) {
115
struct dhcp_message *offer;
117
/* A DHCP lease could have already been offered.
118
* Backup and replace once the IPv4LL address is bound */
119
offer = state->offer;
120
state->offer = ipv4ll_make_lease(astate->addr.s_addr);
121
if (state->offer == NULL)
122
logger(astate->iface->ctx, LOG_ERR, "%s: %m", __func__);
124
dhcp_bind(astate->iface, astate);
125
state->offer = offer;
130
ipv4ll_announced(struct arp_state *astate)
132
struct dhcp_state *state = D_STATE(astate->iface);
134
state->conflicts = 0;
135
/* Need to keep the arp state so we can defend our IP. */
139
ipv4ll_probe(void *arg)
142
#ifdef IN_IFF_TENTATIVE
150
ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
152
struct dhcp_state *state = D_STATE(astate->iface);
156
/* RFC 3927 2.2.1, Probe Conflict Detection */
158
(amsg->sip.s_addr == astate->addr.s_addr ||
159
(amsg->sip.s_addr == 0 && amsg->tip.s_addr == astate->addr.s_addr)))
160
fail = astate->addr.s_addr;
162
/* RFC 3927 2.5, Conflict Defense */
163
if (IN_LINKLOCAL(htonl(state->addr.s_addr)) &&
164
amsg && amsg->sip.s_addr == state->addr.s_addr)
165
fail = state->addr.s_addr;
170
astate->failed.s_addr = fail;
171
arp_report_conflicted(astate, amsg);
173
if (astate->failed.s_addr == state->addr.s_addr) {
176
/* RFC 3927 Section 2.5 */
138
178
if (state->defend + DEFEND_INTERVAL > up) {
140
"%s: IPv4LL %d second defence failed",
141
ifp->name, DEFEND_INTERVAL);
142
dhcp_drop(ifp, "EXPIRE");
143
state->conflicts = -1;
179
logger(astate->iface->ctx, LOG_WARNING,
180
"%s: IPv4LL %d second defence failed for %s",
181
astate->iface->name, DEFEND_INTERVAL,
182
inet_ntoa(state->addr));
183
dhcp_drop(astate->iface, "EXPIRE");
145
syslog(LOG_DEBUG, "%s: defended IPv4LL address",
185
logger(astate->iface->ctx, LOG_DEBUG,
186
"%s: defended IPv4LL address %s",
187
astate->iface->name, inet_ntoa(state->addr));
147
188
state->defend = up;
155
eloop_timeout_delete(NULL, ifp);
156
if (++state->conflicts > MAX_CONFLICTS) {
157
syslog(LOG_ERR, "%s: failed to acquire an IPv4LL address",
194
if (++state->conflicts == MAX_CONFLICTS)
195
logger(astate->iface->ctx, LOG_ERR,
196
"%s: failed to acquire an IPv4LL address",
197
astate->iface->name);
198
astate->addr.s_addr = ipv4ll_pick_addr(astate);
199
eloop_timeout_add_sec(astate->iface->ctx->eloop,
200
state->conflicts >= MAX_CONFLICTS ?
201
RATE_LIMIT_INTERVAL : PROBE_WAIT,
202
ipv4ll_probe, astate);
206
ipv4ll_start(void *arg)
208
struct interface *ifp = arg;
209
struct dhcp_state *state = D_STATE(ifp);
210
struct arp_state *astate;
211
struct ipv4_addr *ap;
213
if (state->arp_ipv4ll)
216
/* RFC 3927 Section 2.1 states that the random number generator
217
* SHOULD be seeded with a value derived from persistent information
218
* such as the IEEE 802 MAC address so that it usually picks
219
* the same address without persistent storage. */
220
if (state->conflicts == 0) {
223
if (sizeof(seed) > ifp->hwlen) {
225
memcpy(&seed, ifp->hwaddr, ifp->hwlen);
227
memcpy(&seed, ifp->hwaddr + ifp->hwlen - sizeof(seed),
229
initstate(seed, state->randomstate, sizeof(state->randomstate));
232
if ((astate = arp_new(ifp, NULL)) == NULL)
235
state->arp_ipv4ll = astate;
236
astate->probed_cb = ipv4ll_probed;
237
astate->announced_cb = ipv4ll_announced;
238
astate->conflicted_cb = ipv4ll_conflicted;
240
if (IN_LINKLOCAL(htonl(state->addr.s_addr))) {
241
astate->addr = state->addr;
242
arp_announce(astate);
246
if (state->offer && IN_LINKLOCAL(ntohl(state->offer->yiaddr))) {
247
astate->addr.s_addr = state->offer->yiaddr;
250
ap = ipv4_iffindaddr(ifp, &astate->addr, NULL);
252
ap = ipv4_iffindlladdr(ifp);
254
astate->addr = ap->addr;
255
ipv4ll_probed(astate);
259
setstate(state->randomstate);
260
/* We maybe rebooting an IPv4LL address. */
261
if (!IN_LINKLOCAL(htonl(astate->addr.s_addr))) {
262
logger(ifp->ctx, LOG_INFO, "%s: probing for an IPv4LL address",
159
state->interval = RATE_LIMIT_INTERVAL / 2;
162
eloop_timeout_add_sec(PROBE_WAIT, ipv4ll_start, ifp);
264
astate->addr.s_addr = INADDR_ANY;
266
if (astate->addr.s_addr == INADDR_ANY)
267
astate->addr.s_addr = ipv4ll_pick_addr(astate);
268
#ifdef IN_IFF_TENTATIVE
269
ipv4ll_probed(astate);
276
ipv4ll_stop(struct interface *ifp)
278
struct dhcp_state *state = D_STATE(ifp);
280
eloop_timeout_delete(ifp->ctx->eloop, NULL, state->arp_ipv4ll);