⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 autoip.c

📁 lwip-1.4.0
💻 C
📖 第 1 页 / 共 2 页
字号:
/** * @file * AutoIP Automatic LinkLocal IP Configuration * *//* * * Copyright (c) 2007 Dominik Spies <kontakt@dspies.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, *    this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, *    this list of conditions and the following disclaimer in the documentation *    and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * Author: Dominik Spies <kontakt@dspies.de> * * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform * with RFC 3927. * * * Please coordinate changes and requests with Dominik Spies * <kontakt@dspies.de> *//******************************************************************************* * USAGE: *  * 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_start() after netif_add(). *  * With DHCP: * - define LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h. * - Configure your DHCP Client. * */#include "lwip/opt.h"#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */#include "lwip/mem.h"#include "lwip/udp.h"#include "lwip/ip_addr.h"#include "lwip/netif.h"#include "lwip/autoip.h"#include "netif/etharp.h"#include <stdlib.h>#include <string.h>/* 169.254.0.0 */#define AUTOIP_NET         0xA9FE0000/* 169.254.1.0 */#define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100)/* 169.254.254.255 */#define AUTOIP_RANGE_END   (AUTOIP_NET | 0xFEFF)/** Pseudo random macro based on netif informations. * You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */#ifndef LWIP_AUTOIP_RAND#define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \                                   ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \                                   ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \                                   ((u32_t)((netif->hwaddr[4]) & 0xff))) + \                                   (netif->autoip?netif->autoip->tried_llipaddr:0))#endif /* LWIP_AUTOIP_RAND *//** * Macro that generates the initial IP address to be tried by AUTOIP. * If you want to override this, define it to something else in lwipopts.h. */#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \  htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \                 ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR *//* static functions */static void autoip_handle_arp_conflict(struct netif *netif);/* creates a pseudo random LL IP-Address for a network interface */static void autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr);/* sends an ARP probe */static err_t autoip_arp_probe(struct netif *netif);/* sends an ARP announce */static err_t autoip_arp_announce(struct netif *netif);/* configure interface for use with current LL IP-Address */static err_t autoip_bind(struct netif *netif);/* start sending probes for llipaddr */static void autoip_start_probing(struct netif *netif);/** * Initialize this module */voidautoip_init(void){  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_init()\n"));}/** Set a statically allocated struct autoip to work with. * Using this prevents autoip_start to allocate it using mem_malloc. * * @param netif the netif for which to set the struct autoip * @param dhcp (uninitialised) dhcp struct allocated by the application */voidautoip_set_struct(struct netif *netif, struct autoip *autoip){  LWIP_ASSERT("netif != NULL", netif != NULL);  LWIP_ASSERT("autoip != NULL", autoip != NULL);  LWIP_ASSERT("netif already has a struct autoip set", netif->autoip == NULL);  /* clear data structure */  memset(autoip, 0, sizeof(struct autoip));  /* autoip->state = AUTOIP_STATE_OFF; */  netif->autoip = autoip;}/** Restart AutoIP client and check the next address (conflict detected) * * @param netif The netif under AutoIP control */static voidautoip_restart(struct netif *netif){  netif->autoip->tried_llipaddr++;  autoip_start(netif);}/** * Handle a IP address conflict after an ARP conflict detection */static voidautoip_handle_arp_conflict(struct netif *netif){  /* Somehow detect if we are defending or retreating */  unsigned char defend = 1; /* tbd */  if(defend) {    if(netif->autoip->lastconflict > 0) {      /* retreat, there was a conflicting ARP in the last       * DEFEND_INTERVAL seconds       */      LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,        ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));      /* TODO: close all TCP sessions */      autoip_restart(netif);    } else {      LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,        ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));      autoip_arp_announce(netif);      netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;    }  } else {    LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,      ("autoip_handle_arp_conflict(): we do not defend, retreating\n"));    /* TODO: close all TCP sessions */    autoip_restart(netif);  }}/** * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255 * * @param netif network interface on which create the IP-Address * @param ipaddr ip address to initialize */static voidautoip_create_addr(struct netif *netif, ip_addr_t *ipaddr){  /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255   * compliant to RFC 3927 Section 2.1   * We have 254 * 256 possibilities */  u32_t addr = ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));  addr += netif->autoip->tried_llipaddr;  addr = AUTOIP_NET | (addr & 0xffff);  /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */   if (addr < AUTOIP_RANGE_START) {    addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;  }  if (addr > AUTOIP_RANGE_END) {    addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;  }  LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&    (addr <= AUTOIP_RANGE_END));  ip4_addr_set_u32(ipaddr, htonl(addr));    LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,    ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",    (u16_t)(netif->autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr),    ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));}/** * Sends an ARP probe from a network interface * * @param netif network interface used to send the probe */static err_tautoip_arp_probe(struct netif *netif){  return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,    (struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, &ethzero,    &netif->autoip->llipaddr, ARP_REQUEST);}/** * Sends an ARP announce from a network interface * * @param netif network interface used to send the announce */static err_tautoip_arp_announce(struct netif *netif){  return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,    (struct eth_addr *)netif->hwaddr, &netif->autoip->llipaddr, &ethzero,    &netif->autoip->llipaddr, ARP_REQUEST);}/** * Configure interface for use with current LL IP-Address * * @param netif network interface to configure with current LL IP-Address */static err_tautoip_bind(struct netif *netif){  struct autoip *autoip = netif->autoip;  ip_addr_t sn_mask, gw_addr;  LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,    ("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -