67#if LWIP_IPV4 && LWIP_ACD
74#define ACD_FOREACH(acd, acd_list) for ((acd) = acd_list; (acd) != NULL; (acd) = (acd)->next)
76#define ACD_TICKS_PER_SECOND (1000 / ACD_TMR_INTERVAL)
80#define LWIP_ACD_RAND(netif, acd) LWIP_RAND()
82#ifdef LWIP_AUTOIP_RAND
84#define LWIP_ACD_RAND(netif, acd) LWIP_AUTOIP_RAND(netif)
86#define LWIP_ACD_RAND(netif, acd) ((((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \
87 ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \
88 ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \
89 ((u32_t)((netif->hwaddr[4]) & 0xff))) + \
95#define ACD_RANDOM_PROBE_WAIT(netif, acd) (LWIP_ACD_RAND(netif, acd) % \
96 (PROBE_WAIT * ACD_TICKS_PER_SECOND))
98#define ACD_RANDOM_PROBE_INTERVAL(netif, acd) ((LWIP_ACD_RAND(netif, acd) % \
99 ((PROBE_MAX - PROBE_MIN) * ACD_TICKS_PER_SECOND)) + \
100 (PROBE_MIN * ACD_TICKS_PER_SECOND ))
103static void acd_restart(
struct netif *
netif,
struct acd *acd);
104static void acd_handle_arp_conflict(
struct netif *
netif,
struct acd *acd);
105static void acd_put_in_passive_mode(
struct netif *
netif,
struct acd *acd);
119 acd_conflict_callback_t acd_conflict_callback)
125 LWIP_ASSERT(
"acd_conflict_callback != NULL", acd_conflict_callback !=
NULL);
126 acd->acd_conflict_callback = acd_conflict_callback;
129 for (acd2 =
netif->acd_list; acd2 !=
NULL; acd2 = acd2->
next) {
132 (
"acd_add(): acd already added to list\n"));
138 acd->next =
netif->acd_list;
139 netif->acd_list = acd;
152acd_remove(
struct netif *
netif,
struct acd *acd)
154 struct acd *acd2, *prev =
NULL;
158 for (acd2 =
netif->acd_list; acd2 !=
NULL; acd2 = acd2->
next) {
161 prev->next = acd->next;
169 LWIP_ASSERT((
"acd_remove(): acd not on list\n"), 0);
182acd_start(
struct netif *
netif,
struct acd *acd, ip4_addr_t ipaddr)
188 (
"acd_start(netif=%p) %c%c%"U16_F"\n",
194 acd->lastconflict = 0;
195 ip4_addr_copy(acd->ipaddr, ipaddr);
198 acd->ttw = (
u16_t)(ACD_RANDOM_PROBE_WAIT(
netif, acd));
210acd_stop(
struct acd *acd)
227acd_network_changed_link_down(
struct netif *
netif)
231 ACD_FOREACH(acd,
netif->acd_list) {
246 ACD_FOREACH(acd,
netif->acd_list) {
247 if (acd->lastconflict > 0) {
252 (
"acd_tmr() ACD-State: %"U16_F", ttw=%"U16_F"\n",
253 (
u16_t)(acd->state), acd->ttw));
259 switch (acd->state) {
264 etharp_acd_probe(
netif, &acd->ipaddr);
266 (
"acd_tmr() PROBING Sent Probe\n"));
278 acd->ttw = (
u16_t)(ACD_RANDOM_PROBE_INTERVAL(
netif, acd));
286 if (acd->sent_num == 0) {
290 acd->num_conflicts = 0;
294 ip4_addr1_16(&acd->ipaddr), ip4_addr2_16(&acd->ipaddr),
295 ip4_addr3_16(&acd->ipaddr), ip4_addr4_16(&acd->ipaddr)));
298 etharp_acd_announce(
netif, &acd->ipaddr);
300 (
"acd_tmr() ANNOUNCING Sent Announce\n"));
310 ip4_addr1_16(&acd->ipaddr), ip4_addr2_16(&acd->ipaddr),
311 ip4_addr3_16(&acd->ipaddr), ip4_addr4_16(&acd->ipaddr)));
344acd_restart(
struct netif *
netif,
struct acd *acd)
347 acd->num_conflicts++;
358 (
"acd_restart(): rate limiting initiated. too many conflicts\n"));
379 ip4_addr_t sipaddr, dipaddr;
393 ACD_FOREACH(acd,
netif->acd_list) {
410 if ((ip4_addr_eq(&sipaddr, &acd->ipaddr)) ||
411 (ip4_addr_isany_val(sipaddr) &&
412 ip4_addr_eq(&dipaddr, &acd->ipaddr) &&
415 (
"acd_arp_reply(): Probe Conflict detected\n"));
416 acd_restart(
netif, acd);
427 if (ip4_addr_eq(&sipaddr, &acd->ipaddr) &&
430 (
"acd_arp_reply(): Conflicting ARP-Packet detected\n"));
431 acd_handle_arp_conflict(
netif, acd);
442acd_handle_arp_conflict(
struct netif *
netif,
struct acd *acd)
464 (
"acd_handle_arp_conflict(): conflict when we are in passive mode -> back off\n"));
469 if (acd->lastconflict > 0) {
472 (
"acd_handle_arp_conflict(): conflict within DEFEND_INTERVAL -> retreating\n"));
476 acd_restart(
netif, acd);
479 (
"acd_handle_arp_conflict(): we are defending, send ARP Announce\n"));
480 etharp_acd_announce(
netif, &acd->ipaddr);
490acd_put_in_passive_mode(
struct netif *
netif,
struct acd *acd)
511 (
"acd_put_in_passive_mode()\n"));
531 (
"acd_netif_ip_addr_changed(): Address changed\n"));
534 (
"acd_netif_ip_addr_changed(): old address = %s\n",
ipaddr_ntoa(old_addr)));
536 (
"acd_netif_ip_addr_changed(): new address = %s\n",
ipaddr_ntoa(new_addr)));
543 ACD_FOREACH(acd,
netif->acd_list) {
545 if(ip4_addr_eq(&acd->ipaddr, ip_2_ip4(old_addr))) {
549 (
"acd_netif_ip_addr_changed(): changed from LL to routable address\n"));
551 acd_put_in_passive_mode(
netif, acd);
#define LWIP_DEBUGF(debug, message)
#define LWIP_ASSERT(message, assertion)
#define LWIP_UNUSED_ARG(x)
#define LWIP_DBG_LEVEL_WARNING
#define LWIP_ASSERT_CORE_LOCKED()
#define SMEMCPY(dst, src, len)
#define ip_addr_isany(ipaddr)
#define ip_addr_islinklocal(ipaddr)
#define ipaddr_ntoa(ipaddr)
#define IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(dest, src)
#define eth_addr_eq(addr1, addr2)
#define NETIF_FOREACH(netif)
#define RATE_LIMIT_INTERVAL
#define ANNOUNCE_INTERVAL
@ ACD_STATE_PASSIVE_ONGOING
@ ACD_STATE_ANNOUNCE_WAIT
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]