diff --git a/src/api/tcpip.c b/src/api/tcpip.c index 4898ede8..8ab0fd91 100644 --- a/src/api/tcpip.c +++ b/src/api/tcpip.c @@ -166,6 +166,22 @@ dhcp_timer_fine(void *arg) } #endif /* LWIP_DHCP */ +#if LWIP_AUTOIP +/** + * Timer callback function that calls autoip_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +autoip_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip: autoip_tmr()\n")); + autoip_tmr(); + sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL); +} +#endif /* LWIP_AUTOIP */ + #if LWIP_IGMP /** * Timer callback function that calls igmp_tmr() and reschedules itself. @@ -256,6 +272,9 @@ tcpip_thread(void *arg) sys_timeout(DHCP_COARSE_TIMER_SECS*1000, dhcp_timer_coarse, NULL); sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); #endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL); +#endif /* LWIP_AUTOIP */ if (tcpip_init_done != NULL) { tcpip_init_done(tcpip_init_done_arg); @@ -483,7 +502,10 @@ tcpip_init(void (* initfunc)(void *), void *arg) { #if LWIP_ARP etharp_init(); -#endif /*LWIP_ARP */ +#endif /* LWIP_ARP */ +#if LWIP_AUTOIP + autoip_init(); +#endif /* LWIP_AUTOIP */ ip_init(); #if LWIP_UDP udp_init(); diff --git a/src/core/dhcp.c b/src/core/dhcp.c index 7b45a5a6..3cb55d08 100644 --- a/src/core/dhcp.c +++ b/src/core/dhcp.c @@ -539,10 +539,6 @@ err_t dhcp_start(struct netif *netif) struct dhcp *dhcp; err_t result = ERR_OK; -#if LWIP_DHCP_AUTOIP_COOP - autoip_init(); -#endif /* LWIP_DHCP_AUTOIP_COOP */ - LWIP_ERROR("netif == NULL", (netif == NULL), return ERR_ARG;); dhcp = netif->dhcp; LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); diff --git a/src/core/ipv4/autoip.c b/src/core/ipv4/autoip.c index 1e796a94..4a26d989 100644 --- a/src/core/ipv4/autoip.c +++ b/src/core/ipv4/autoip.c @@ -44,18 +44,21 @@ /******************************************************************************* * USAGE: * - * define LWIP_AUTOIP 1 - * call autoip_fine_tmr() all AUTOIP_FINE_TIMER_MSECS msces, - * that should be defined in autoip.h. - * I recommend a value of 100. The value must divide 1000 with a remainder almost 0. - * Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 .... + * define LWIP_AUTOIP 1 in your lwipopts.h * + * If you don't use tcpip.c (so, don't call, you don't call tcpip_init): + * - First, call autoip_init(). + * - call autoip_tmr() all AUTOIP_TMR_INTERVAL msces, + * that should be defined in autoip.h. + * I recommend a value of 100. The value must divide 1000 with a remainder almost 0. + * Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 .... + * * Without DHCP: - * call autoip_init() and autoip_start() after netif_add(). + * - Call autoip_start() after netif_add(). * * With DHCP: - * Configure your DHCP Client - * define LWIP_DHCP_AUTOIP_COOP 1 in lwipopts.h + * - define LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h. + * - Configure your DHCP Client. * */ @@ -70,6 +73,11 @@ #if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ +/* LWIP_ARP option should be configured in lwipopts.h */ +#if !LWIP_ARP +#error LWIP_ARP is need for LWIP_AUTOIP. Set it from your lwipopts.h. +#endif /* !LWIP_ARP */ + /* static functions */ static void autoip_handle_arp_conflict(struct netif *netif); @@ -89,21 +97,32 @@ static err_t autoip_bind(struct netif *netif); void autoip_init(void) { - /* TODO MAC_ADDRESS macaddr; */ - + struct netif *netif = netif_list; + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3, ("autoip_init()\n")); - - /* TODO Get_Current_MAC_Address(&macaddr);*/ - /*srand( - (macaddr.addr[2] << 24) | - (macaddr.addr[3] << 16) | - (macaddr.addr[4] << 8) | - (macaddr.addr[5] << 0) - );*/ + + /* loop through netif's */ + while (netif != NULL) { + /* if we find a ETHARP interface... */ + if (netif->flags & NETIF_FLAG_ETHARP) { + /* seed random with MAC-Address */ + srand( (netif->hwaddr[2] << 24) | + (netif->hwaddr[3] << 16) | + (netif->hwaddr[4] << 8) | + (netif->hwaddr[5] << 0)); + return; + } + + /* proceed to next network interface */ + netif = netif->next; + } + + /* we don't have found any ETHARP interface, initialize seed random with a magic number */ + srand(0xCA39B718 /* Any magic value */); } /** - * TODO: Add comment + * Handle a IP address conflict after an ARP conflict detection */ static void autoip_handle_arp_conflict(struct netif *netif) @@ -123,7 +142,7 @@ autoip_handle_arp_conflict(struct netif *netif) } else { LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 1, ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n")); autoip_arp_announce(netif); - netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_FINE_TIMER_TICK_PER_SECOND; + netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND; } } else { LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 1, ("autoip_handle_arp_conflict(): we do not defend, retreating\n")); @@ -133,7 +152,9 @@ autoip_handle_arp_conflict(struct netif *netif) } /** - * TODO: Add comment + * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255 + * + * @param RandomIPAddr ip address to initialize */ static void autoip_create_rand_addr(struct ip_addr *RandomIPAddr) @@ -147,7 +168,9 @@ autoip_create_rand_addr(struct ip_addr *RandomIPAddr) } /** - * TODO: Add comment + * Sends an ARP announce from a network interface + * + * @param netif network interface used to send the announce */ static err_t autoip_arp_announce(struct netif *netif) @@ -173,7 +196,9 @@ autoip_arp_announce(struct netif *netif) } /** - * TODO: Add comment + * Configure interface for use with current LL IP-Address + * + * @param netif network interface to configure with current LL IP-Address */ static err_t autoip_bind(struct netif *netif) @@ -196,7 +221,9 @@ autoip_bind(struct netif *netif) } /** - * TODO: Add comment + * Start AutoIP client + * + * @param netif network interface on which start the AutoIP client */ err_t autoip_start(struct netif *netif) @@ -245,7 +272,7 @@ autoip_start(struct netif *netif) * choosen out of 0 to PROBE_WAIT seconds. * compliant to RFC 3927 Section 2.2.1 */ - autoip->ttw = (rand() % (PROBE_WAIT * AUTOIP_FINE_TIMER_TICK_PER_SECOND)); + autoip->ttw = (rand() % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND)); /* * if we tried more then MAX_CONFLICTS we must limit our rate for @@ -254,14 +281,16 @@ autoip_start(struct netif *netif) */ if(autoip->tried_llipaddr > MAX_CONFLICTS) { - autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_FINE_TIMER_TICK_PER_SECOND; + autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND; } return result; } /** - * TODO: Add comment + * Stop AutoIP client + * + * @param netif network interface on which stop the AutoIP client */ err_t autoip_stop(struct netif *netif) @@ -272,10 +301,10 @@ autoip_stop(struct netif *netif) } /** - * TODO: Add comment + * Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */ void -autoip_fine_tmr() +autoip_tmr() { struct netif *netif = netif_list; /* loop through netif's */ @@ -286,7 +315,7 @@ autoip_fine_tmr() netif->autoip->lastconflict--; } - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3, ("autoip_fine_tmr()AutoIP-Sate: %d\n", netif->autoip->state)); + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3, ("autoip_tmr() AutoIP-State: %d\n", netif->autoip->state)); switch(netif->autoip->state) { case AUTOIP_STATE_PROBING: @@ -296,13 +325,13 @@ autoip_fine_tmr() if(netif->autoip->sent_num == PROBE_NUM) { netif->autoip->state = AUTOIP_STATE_ANNOUNCING; netif->autoip->sent_num = 0; - netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_FINE_TIMER_TICK_PER_SECOND; + netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; } else { etharp_request(netif, &(netif->autoip->llipaddr)); - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3, ("autoip_fine_tmr() PROBING Sent Probe\n")); + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3, ("autoip_tmr() PROBING Sent Probe\n")); netif->autoip->sent_num++; /* calculate time to wait to next probe */ - netif->autoip->ttw = (rand() % ((PROBE_MAX - PROBE_MIN) * AUTOIP_FINE_TIMER_TICK_PER_SECOND) ) + PROBE_MIN * AUTOIP_FINE_TIMER_TICK_PER_SECOND; + netif->autoip->ttw = (rand() % ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) + PROBE_MIN * AUTOIP_TICKS_PER_SECOND; } } break; @@ -324,9 +353,9 @@ autoip_fine_tmr() netif->autoip->ttw = 0; } else { autoip_arp_announce(netif); - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3, ("autoip_fine_tmr() ANNOUNCING Sent Announce\n")); + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3, ("autoip_tmr() ANNOUNCING Sent Announce\n")); netif->autoip->sent_num++; - netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_FINE_TIMER_TICK_PER_SECOND; + netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND; } } break; @@ -338,7 +367,10 @@ autoip_fine_tmr() } /** - * TODO: Add comment + * Handles every incoming ARP Packet, called by etharp_arp_input. + * + * @param netif network interface to use for autoip processing + * @param hdr Incoming ARP packet */ void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr) diff --git a/src/include/ipv4/lwip/autoip.h b/src/include/ipv4/lwip/autoip.h index 6b17d07c..53440320 100644 --- a/src/include/ipv4/lwip/autoip.h +++ b/src/include/ipv4/lwip/autoip.h @@ -50,32 +50,32 @@ #include "netif/etharp.h" /* AutoIP Timing */ -#define AUTOIP_FINE_TIMER_MSECS 100 -#define AUTOIP_FINE_TIMER_TICK_PER_SECOND 1000 / AUTOIP_FINE_TIMER_MSECS +#define AUTOIP_TMR_INTERVAL 100 +#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL) /* RFC 3927 Constants */ -#define PROBE_WAIT 1 /* second (initial random delay) */ -#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */ -#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */ -#define PROBE_NUM 3 /* (number of probe packets) */ -#define ANNOUNCE_NUM 2 /* (number of announcement packets) */ -#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */ -#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */ -#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */ -#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */ -#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */ +#define PROBE_WAIT 1 /* second (initial random delay) */ +#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */ +#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */ +#define PROBE_NUM 3 /* (number of probe packets) */ +#define ANNOUNCE_NUM 2 /* (number of announcement packets) */ +#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */ +#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */ +#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */ +#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */ +#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */ /* AutoIP client states */ -#define AUTOIP_STATE_OFF 0 -#define AUTOIP_STATE_PROBING 1 -#define AUTOIP_STATE_ANNOUNCING 2 -#define AUTOIP_STATE_BOUND 3 +#define AUTOIP_STATE_OFF 0 +#define AUTOIP_STATE_PROBING 1 +#define AUTOIP_STATE_ANNOUNCING 2 +#define AUTOIP_STATE_BOUND 3 struct autoip { u8_t state; /* current AutoIP state machine state */ u8_t sent_num; /* sent number of probes or announces, dependent on state */ - u16_t ttw; /* ticks to wait, tick is AUTOIP_FINE_TIMER_MSECS long */ + u16_t ttw; /* ticks to wait, tick is AUTOIP_TMR_INTERVAL long */ u8_t lastconflict; /* ticks until a conflict can be solved by defending */ u8_t tried_llipaddr; /* total number of probed/used Link Local IP-Addresses */ struct ip_addr llipaddr; /* the currently selected, probed, announced or used LL IP-Address */ @@ -94,7 +94,7 @@ err_t autoip_stop(struct netif *netif); /** Handles every incoming ARP Packet, called by etharp_arp_input */ void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr); -/** Has to be called in loop every AUTOIP_FINE_TIMER_MSECS milliseconds */ -void autoip_fine_tmr(void); +/** Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */ +void autoip_tmr(void); #endif /* __LWIP_AUTOIP_H__ */ diff --git a/src/include/lwip/netifapi.h b/src/include/lwip/netifapi.h index 81cdc7ed..1e1a6180 100644 --- a/src/include/lwip/netifapi.h +++ b/src/include/lwip/netifapi.h @@ -32,6 +32,7 @@ #include "lwip/sys.h" #include "lwip/netif.h" #include "lwip/dhcp.h" +#include "lwip/autoip.h" #if LWIP_NETIF_API