예제 #1
0
/**
 * 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 void
autoip_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)));
}
예제 #2
0
파일: netif.c 프로젝트: EarlGray/ling
/**
 * Change the IP address of a network interface
 *
 * @param netif the network interface to change
 * @param ipaddr the new IP address
 *
 * @note call netif_set_addr() if you also want to change netmask and
 * default gateway
 */
void
netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr)
{
  /* TODO: Handling of obsolete pcbs */
  /* See:  http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */
#if LWIP_TCP
  struct tcp_pcb *pcb;
  struct tcp_pcb_listen *lpcb;

  /* address is actually being changed? */
  if (ipaddr && (ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) {
    /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */
    LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n"));
    pcb = tcp_active_pcbs;
    while (pcb != NULL) {
      /* PCB bound to current local interface address? */
      if (ip_addr_cmp(ipX_2_ip(&pcb->local_ip), &(netif->ip_addr))
#if LWIP_AUTOIP
        /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */
        && !ip_addr_islinklocal(ipX_2_ip(&pcb->local_ip))
#endif /* LWIP_AUTOIP */
        ) {
        /* this connection must be aborted */
        struct tcp_pcb *next = pcb->next;
        LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %pp\n", (void *)pcb));
        tcp_abort(pcb);
        pcb = next;
      } else {
        pcb = pcb->next;
      }
    }
    for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
      /* PCB bound to current local interface address? */
      if ((!(ip_addr_isany(ipX_2_ip(&lpcb->local_ip)))) &&
          (ip_addr_cmp(ipX_2_ip(&lpcb->local_ip), &(netif->ip_addr)))) {
        /* The PCB is listening to the old ipaddr and
         * is set to listen to the new one instead */
        ip_addr_set(ipX_2_ip(&lpcb->local_ip), ipaddr);
      }
    }
  }
#endif
  snmp_delete_ipaddridx_tree(netif);
  snmp_delete_iprteidx_tree(0,netif);
  /* set new IP address to netif */
  ip_addr_set(&(netif->ip_addr), ipaddr);
  snmp_insert_ipaddridx_tree(netif);
  snmp_insert_iprteidx_tree(0,netif);

  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
	((netif->name[0]) ?netif->name[0] :'-'),
	((netif->name[1]) ?netif->name[1] :'-'),
    ip4_addr1_16(&netif->ip_addr),
    ip4_addr2_16(&netif->ip_addr),
    ip4_addr3_16(&netif->ip_addr),
    ip4_addr4_16(&netif->ip_addr)));
}
예제 #3
0
/******************************************************************************
 * FunctionName : espconn_tcp_accept
 * Description  : A new incoming connection has been accepted.
 * Parameters   : arg -- Additional argument to pass to the callback function
 *                pcb -- The connection pcb which is accepted
 *                err -- An unused error code, always ERR_OK currently
 * Returns      : acception result
*******************************************************************************/
static err_t ICACHE_FLASH_ATTR
espconn_tcp_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
    struct espconn *espconn = arg;
    espconn_msg *paccept = NULL;
    remot_info *pinfo = NULL;
    LWIP_UNUSED_ARG(err);

    if(system_get_free_heap_size() < 8192) return ERR_MEM; // added PV`

    paccept = (espconn_msg *)os_zalloc(sizeof(espconn_msg));
    tcp_arg(pcb, paccept);
	tcp_err(pcb, esponn_server_err);
	if (paccept == NULL)
		return ERR_MEM;
	/*insert the node to the active connection list*/
	espconn_list_creat(&plink_active, paccept);

    paccept->preverse = espconn;
	paccept->pespconn = (struct espconn *)os_zalloc(sizeof(struct espconn));
	if (paccept->pespconn == NULL)
		return ERR_MEM;
	paccept->pespconn->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));
	if (paccept->pespconn->proto.tcp == NULL)
		return ERR_MEM;

	//paccept->pcommon.timeout = 0x0a;
	//link_timer = 0x0a;

	paccept->pcommon.pcb = pcb;

	paccept->pcommon.remote_port = pcb->remote_port;
	paccept->pcommon.remote_ip[0] = ip4_addr1_16(&pcb->remote_ip);
	paccept->pcommon.remote_ip[1] = ip4_addr2_16(&pcb->remote_ip);
	paccept->pcommon.remote_ip[2] = ip4_addr3_16(&pcb->remote_ip);
	paccept->pcommon.remote_ip[3] = ip4_addr4_16(&pcb->remote_ip);

	os_memcpy(espconn->proto.tcp->remote_ip, paccept->pcommon.remote_ip, 4);
	espconn->proto.tcp->remote_port = pcb->remote_port;
	espconn->state = ESPCONN_CONNECT;
	espconn_copy_partial(paccept->pespconn, espconn);
	espconn_get_connection_info(espconn, &pinfo , 0);
	espconn_printf("espconn_tcp_accept link_cnt: %d\n", espconn->link_cnt);
	if (espconn->link_cnt == espconn_tcp_get_max_con_allow(espconn) + 1)
		return ERR_ISCONN;

	tcp_sent(pcb, espconn_server_sent);
	tcp_recv(pcb, espconn_server_recv);
	tcp_poll(pcb, espconn_server_poll, 8); /* every 1 seconds */

	if (paccept->pespconn->proto.tcp->connect_callback != NULL) {
		paccept->pespconn->proto.tcp->connect_callback(paccept->pespconn);
	}

    return ERR_OK;
}
예제 #4
0
파일: netif.c 프로젝트: projectarkc/psiphon
/**
 * Change the default gateway for a network interface
 *
 * @param netif the network interface to change
 * @param gw the new default gateway
 *
 * @note call netif_set_addr() if you also want to change ip address and netmask
 */
void
netif_set_gw(struct netif *netif, ip_addr_t *gw)
{
  ip_addr_set(&(netif->gw), gw);
  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
    netif->name[0], netif->name[1],
    ip4_addr1_16(&netif->gw),
    ip4_addr2_16(&netif->gw),
    ip4_addr3_16(&netif->gw),
    ip4_addr4_16(&netif->gw)));
}
예제 #5
0
파일: netif.c 프로젝트: EagleSmith/ESP31B
/**
 * Change the default gateway for a network interface
 *
 * @param netif the network interface to change
 * @param gw the new default gateway
 *
 * @note call netif_set_addr() if you also want to change ip address and netmask
 */
void
netif_set_gw(struct netif *netif, const ip4_addr_t *gw)
{
  ip4_addr_set(ip_2_ip4(&netif->gw), gw);
  IP_SET_TYPE_VAL(netif->gw, IPADDR_TYPE_V4);
  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
    netif->name[0], netif->name[1],
    ip4_addr1_16(netif_ip4_gw(netif)),
    ip4_addr2_16(netif_ip4_gw(netif)),
    ip4_addr3_16(netif_ip4_gw(netif)),
    ip4_addr4_16(netif_ip4_gw(netif))));
}
예제 #6
0
static void show_ip_pkt(struct pbuf *p)
{
	struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
	u8_t *payload;

	payload = (u8_t *)iphdr + IP_HLEN;

	_hx_printf("[%s]IP header:\r\n",__func__);
	_hx_printf("+-------------------------------+\r\n");
	_hx_printf("|%2"S16_F" |%2"S16_F" |  0x%02"X16_F" |     %5"U16_F"     | (v, hl, tos, len)\r\n",
		IPH_V(iphdr),
		IPH_HL(iphdr),
		IPH_TOS(iphdr),
		ntohs(IPH_LEN(iphdr)));
	_hx_printf("+-------------------------------+\r\n");
	_hx_printf("|    %5"U16_F"      |%"U16_F"%"U16_F"%"U16_F"|    %4"U16_F"   | (id, flags, offset)\r\n",
		ntohs(IPH_ID(iphdr)),
		ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
		ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
		ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
		ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK);
	_hx_printf("+-------------------------------+\r\n");
	_hx_printf("|  %3"U16_F"  |  %3"U16_F"  |    0x%04"X16_F"     | (ttl, proto, chksum)\r\n",
		IPH_TTL(iphdr),
		IPH_PROTO(iphdr),
		ntohs(IPH_CHKSUM(iphdr)));
	_hx_printf("+-------------------------------+\r\n");
	_hx_printf("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (src)\r\n",
		ip4_addr1_16(&iphdr->src),
		ip4_addr2_16(&iphdr->src),
		ip4_addr3_16(&iphdr->src),
		ip4_addr4_16(&iphdr->src));
	_hx_printf("+-------------------------------+\r\n");
	_hx_printf("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (dest)\r\n",
		ip4_addr1_16(&iphdr->dest),
		ip4_addr2_16(&iphdr->dest),
		ip4_addr3_16(&iphdr->dest),
		ip4_addr4_16(&iphdr->dest));
	_hx_printf("+-------------------------------+\r\n");
}
예제 #7
0
파일: netif.c 프로젝트: projectarkc/psiphon
/**
 * Change the netmask of a network interface
 *
 * @param netif the network interface to change
 * @param netmask the new netmask
 *
 * @note call netif_set_addr() if you also want to change ip address and
 * default gateway
 */
void
netif_set_netmask(struct netif *netif, ip_addr_t *netmask)
{
  snmp_delete_iprteidx_tree(0, netif);
  /* set new netmask to netif */
  ip_addr_set(&(netif->netmask), netmask);
  snmp_insert_iprteidx_tree(0, netif);
  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
    netif->name[0], netif->name[1],
    ip4_addr1_16(&netif->netmask),
    ip4_addr2_16(&netif->netmask),
    ip4_addr3_16(&netif->netmask),
    ip4_addr4_16(&netif->netmask)));
}
예제 #8
0
파일: netif.c 프로젝트: EagleSmith/ESP31B
/**
 * Change the netmask of a network interface
 *
 * @param netif the network interface to change
 * @param netmask the new netmask
 *
 * @note call netif_set_addr() if you also want to change ip address and
 * default gateway
 */
void
netif_set_netmask(struct netif *netif, const ip4_addr_t *netmask)
{
  mib2_remove_route_ip4(0, netif);
  /* set new netmask to netif */
  ip4_addr_set(ip_2_ip4(&netif->netmask), netmask);
  IP_SET_TYPE_VAL(netif->netmask, IPADDR_TYPE_V4);
  mib2_add_route_ip4(0, netif);
  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
    netif->name[0], netif->name[1],
    ip4_addr1_16(netif_ip4_netmask(netif)),
    ip4_addr2_16(netif_ip4_netmask(netif)),
    ip4_addr3_16(netif_ip4_netmask(netif)),
    ip4_addr4_16(netif_ip4_netmask(netif))));
}
예제 #9
0
파일: etharp.c 프로젝트: CNCBASHER/gcc4mbed
/** Add a new static entry to the ARP table. If an entry exists for the
 * specified IP address, this entry is overwritten.
 * If packets are queued for the specified IP address, they are sent out.
 *
 * @param ipaddr IP address for the new static entry
 * @param ethaddr ethernet address for the new static entry
 * @return @see return values of etharp_add_static_entry
 */
err_t
etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr)
{
  struct netif *netif;
  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
    ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
    ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
    ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));

  netif = ip_route(ipaddr);
  if (netif == NULL) {
    return ERR_RTE;
  }

  return update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
}
예제 #10
0
파일: netif.c 프로젝트: altran-nl/esp-idf
/**
 * Change the IP address of a network interface
 *
 * @param netif the network interface to change
 * @param ipaddr the new IP address
 *
 * @note call netif_set_addr() if you also want to change netmask and
 * default gateway
 */
void
netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr)
{
  ip4_addr_t new_addr = (ipaddr ? *ipaddr : *IP4_ADDR_ANY);
#if ESP_LWIP
  ip4_addr_t *last_addr = ip_2_ip4(&netif->last_ip_addr);
#else
  ip4_addr_t *last_addr = netif_ip4_addr(netif);
#endif

  /* address is actually being changed? */
  if (ip4_addr_cmp(&new_addr, netif_ip4_addr(netif)) == 0) {
    LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n"));
#if LWIP_TCP
    tcp_netif_ipv4_addr_changed(last_addr, ipaddr);
#endif /* LWIP_TCP */
#if LWIP_UDP
    udp_netif_ipv4_addr_changed(last_addr, ipaddr);
#endif /* LWIP_UDP */

    mib2_remove_ip4(netif);
    mib2_remove_route_ip4(0, netif);
    /* set new IP address to netif */
    ip4_addr_set(ip_2_ip4(&netif->ip_addr), ipaddr);
    IP_SET_TYPE_VAL(netif->ip_addr, IPADDR_TYPE_V4);
    mib2_add_ip4(netif);
    mib2_add_route_ip4(0, netif);

    netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4);

    NETIF_STATUS_CALLBACK(netif);
  }

  LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
    netif->name[0], netif->name[1],
    ip4_addr1_16(netif_ip4_addr(netif)),
    ip4_addr2_16(netif_ip4_addr(netif)),
    ip4_addr3_16(netif_ip4_addr(netif)),
    ip4_addr4_16(netif_ip4_addr(netif))));

  if (ipaddr && !ip4_addr_isany(ipaddr)) {
    ip4_addr_set(ip_2_ip4(&netif->last_ip_addr), ipaddr);
  }
}
예제 #11
0
/******************************************************************************
 * FunctionName : espconn_client_connect
 * Description  : A new incoming connection has been connected.
 * Parameters   : arg -- Additional argument to pass to the callback function
 *                tpcb -- The connection pcb which is connected
 *                err -- An unused error code, always ERR_OK currently
 * Returns      : connection result
*******************************************************************************/
static err_t ICACHE_FLASH_ATTR
espconn_client_connect(void *arg, struct tcp_pcb *tpcb, err_t err)
{
    espconn_msg *pcon = arg;

    espconn_printf("espconn_client_connect pcon %p tpcb %p\n", pcon, tpcb);
    if (err == ERR_OK){
    	/*Reserve the remote information for current active connection*/
		pcon->pespconn->state = ESPCONN_CONNECT;
		pcon->pcommon.err = err;
		pcon->pcommon.pcb = tpcb;
		pcon->pcommon.local_port = tpcb->local_port;
		pcon->pcommon.local_ip = tpcb->local_ip.u_addr.ip4.addr;
		pcon->pcommon.remote_port = tpcb->remote_port;
		pcon->pcommon.remote_ip[0] = ip4_addr1_16(&tpcb->remote_ip.u_addr.ip4);
		pcon->pcommon.remote_ip[1] = ip4_addr2_16(&tpcb->remote_ip.u_addr.ip4);
		pcon->pcommon.remote_ip[2] = ip4_addr3_16(&tpcb->remote_ip.u_addr.ip4);
		pcon->pcommon.remote_ip[3] = ip4_addr4_16(&tpcb->remote_ip.u_addr.ip4);
		pcon->pcommon.write_flag = true;
		tcp_arg(tpcb, (void *) pcon);

		/*Set the specify function that should be called
		 * when TCP data has been successfully delivered,
		 * when active connection receives data*/
		tcp_sent(tpcb, espconn_client_sent);
		tcp_recv(tpcb, espconn_client_recv);
		/*Disable Nagle algorithm default*/
		tcp_nagle_disable(tpcb);
		/*Default set the total number of espconn_buf on the unsent lists for one*/
		espconn_tcp_set_buf_count(pcon->pespconn, 1);

		if (pcon->pespconn->proto.tcp->connect_callback != NULL) {
			pcon->pespconn->proto.tcp->connect_callback(pcon->pespconn);
		}

		/*Enable keep alive option*/
		if (espconn_keepalive_disabled(pcon))
			espconn_keepalive_enable(tpcb);

    } else{
    	printf("err in host connected (%s)\n",lwip_strerr(err));
    }
    return err;
}
예제 #12
0
파일: if.c 프로젝트: balajig/Layer3Switch
/**
 * Change the netmask of a network interface
 *
 * @param netif the network interface to change
 * @param netmask the new netmask
 *
 * @note call if_set_addr() if you also want to change ip address and
 * default gateway
 */
void
if_set_netmask (struct interface *netif, ip_addr_t * netmask)
{
#ifdef CONFIG_OPENSWITCH_TCP_IP
    snmp_delete_iprteidx_tree (0, netif);
#endif
    /* set new netmask to netif */
    ip_addr_set (&(netif->netmask), netmask);
#ifdef CONFIG_OPENSWITCH_TCP_IP
    snmp_insert_iprteidx_tree (0, netif);
#endif
    LWIP_DEBUGF (NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
                 ("netif: netmask of interface %c%c set to %" U16_F ".%" U16_F
                  ".%" U16_F ".%" U16_F "\n", netif->ifDescr[0], netif->ifDescr[1],
                  ip4_addr1_16 (&netif->netmask),
                  ip4_addr2_16 (&netif->netmask),
                  ip4_addr3_16 (&netif->netmask),
                  ip4_addr4_16 (&netif->netmask)));
}
예제 #13
0
파일: tcp_out.c 프로젝트: AlexeyAB/libvma
/**
 * Send keepalive packets to keep a connection active although
 * no data is sent over it.
 *
 * Called by tcp_slowtmr()
 *
 * @param pcb the tcp_pcb for which to send a keepalive packet
 */
void
tcp_keepalive(struct tcp_pcb *pcb)
{
  struct pbuf *p;
  struct tcp_hdr *tcphdr;

  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
                          ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
                          ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));

  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F"   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
                          tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));

  p = tcp_output_alloc_header(pcb, 0, 0, htonl(pcb->snd_nxt - 1));
  if(p == NULL) {
    LWIP_DEBUGF(TCP_DEBUG,
                ("tcp_keepalive: could not allocate memory for pbuf\n"));
    return;
  }
  tcphdr = (struct tcp_hdr *)p->payload;

#if CHECKSUM_GEN_TCP
  tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
                                      IP_PROTO_TCP, (u16_t)p->tot_len);
#endif
  TCP_STATS_INC(tcp.xmit);

  /* Send output to IP */
#if LWIP_NETIF_HWADDRHINT
  ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP,
    &(pcb->addr_hint));
#elif LWIP_3RD_PARTY_L3
  pcb->ip_output(p, pcb, 0);
#else /* LWIP_NETIF_HWADDRHINT*/
  ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
#endif /* LWIP_NETIF_HWADDRHINT*/

  tcp_tx_pbuf_free(pcb, p);

  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n",
                          pcb->snd_nxt - 1, pcb->rcv_nxt));
  (void)tcphdr; /* Fix warning -Wunused-but-set-variable*/
}
예제 #14
0
/**
 * 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)
{
  struct autoip *autoip = netif->autoip;
  ip4_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",
    (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num,
    ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
    ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));

  IP4_ADDR(&sn_mask, 255, 255, 0, 0);
  IP4_ADDR(&gw_addr, 0, 0, 0, 0);

  netif_set_addr(netif, &autoip->llipaddr, &sn_mask, &gw_addr);
  /* interface is used by routing now that an address is set */

  return ERR_OK;
}
예제 #15
0
파일: etharp.c 프로젝트: CNCBASHER/gcc4mbed
/** Remove a static entry from the ARP table previously added with a call to
 * etharp_add_static_entry.
 *
 * @param ipaddr IP address of the static entry to remove
 * @return ERR_OK: entry removed
 *         ERR_MEM: entry wasn't found
 *         ERR_ARG: entry wasn't a static entry but a dynamic one
 */
err_t
etharp_remove_static_entry(ip_addr_t *ipaddr)
{
  s8_t i;
  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
    ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));

  /* find or create ARP entry */
  i = find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
  /* bail out if no entry could be found */
  if (i < 0) {
    return (err_t)i;
  }

  if ((arp_table[i].state != ETHARP_STATE_STABLE) ||
    (arp_table[i].static_entry == 0)) {
    /* entry wasn't a static entry, cannot remove it */
    return ERR_ARG;
  }
  /* entry found, free it */
  free_entry(i);
  return ERR_OK;
}
예제 #16
0
/**
 * 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 void
autoip_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;
	if (prev_llipaddr.addr) {
	  /* Use previously announced IP address, if any.
	   * Previously announced IP doesn't persist across device reboot.
	   * Its useful only in case of network hot-plugging/link-loss. */
		addr = ntohl(prev_llipaddr.addr);
	} else {
		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)));
}
예제 #17
0
/**
 * 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)
{
  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",
    (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num,
    ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
    ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));

  IP4_ADDR(&sn_mask, 255, 255, 0, 0);
  IP4_ADDR(&gw_addr, 0, 0, 0, 0);

  netif_set_ipaddr(netif, &autoip->llipaddr);
  netif_set_netmask(netif, &sn_mask);
  netif_set_gw(netif, &gw_addr);  

  /* bring the interface up */
  netif_set_up(netif);

  return ERR_OK;
}
예제 #18
0
/******************************************************************************
 * FunctionName : espconn_udp_server_recv
 * Description  : This callback will be called when receiving a datagram.
 * Parameters   : arg -- user supplied argument
 *                upcb -- the udp_pcb which received data
 *                p -- the packet buffer that was received
 *                addr -- the remote IP address from which the packet was received
 *                port -- the remote port from which the packet was received
 * Returns      : none
*******************************************************************************/
static void ICACHE_FLASH_ATTR
espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p,
                 struct ip_addr *addr, u16_t port)
{
    espconn_msg *precv = arg;
    struct pbuf *q = NULL;
    u8_t *pdata = NULL;
    u16_t length = 0;
    struct ip_info ipconfig;

    LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_server_recv %d %p\n", __LINE__, upcb));

    upcb->remote_port = port;
    upcb->remote_ip = *addr;

    precv->pcommon.remote_ip[0] = ip4_addr1_16(&upcb->remote_ip);
    precv->pcommon.remote_ip[1] = ip4_addr2_16(&upcb->remote_ip);
    precv->pcommon.remote_ip[2] = ip4_addr3_16(&upcb->remote_ip);
    precv->pcommon.remote_ip[3] = ip4_addr4_16(&upcb->remote_ip);
    os_memcpy(precv->pespconn->proto.udp->remote_ip, precv->pcommon.remote_ip, 4);
    precv->pespconn->proto.udp->remote_port = port;
    precv->pcommon.remote_port = port;
    precv->pcommon.pcb = upcb;

	if (wifi_get_opmode() != 1) {
		wifi_get_ip_info(1, &ipconfig);

		if (!ip_addr_netcmp((struct ip_addr *)precv->pespconn->proto.udp->remote_ip, &ipconfig.ip, &ipconfig.netmask)) {
			wifi_get_ip_info(0, &ipconfig);
		}
	} else {
		wifi_get_ip_info(0, &ipconfig);
	}
	upcb->local_ip = ipconfig.ip;
	precv->pespconn->proto.udp->local_ip[0] = ip4_addr1_16(&upcb->local_ip);
	precv->pespconn->proto.udp->local_ip[1] = ip4_addr2_16(&upcb->local_ip);
	precv->pespconn->proto.udp->local_ip[2] = ip4_addr3_16(&upcb->local_ip);
	precv->pespconn->proto.udp->local_ip[3] = ip4_addr4_16(&upcb->local_ip);

    if (p != NULL) {
//        q = p;

//        while (q != NULL) {
//            pdata = (u8_t *)os_zalloc(q ->len + 1);
//            length = pbuf_copy_partial(q, pdata, q ->len, 0);
//
//            LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_server_recv %d %x\n", __LINE__, length));
//            precv->pcommon.pcb = upcb;
//
//            if (length != 0) {
//                if (precv->pespconn->recv_callback != NULL) {
//                    precv->pespconn->recv_callback(precv->pespconn, pdata, length);
//                }
//            }
//
//            q = q->next;
//            os_free(pdata);
//        }
    	pdata = (u8_t *)os_zalloc(p ->tot_len + 1);
    	length = pbuf_copy_partial(p, pdata, p ->tot_len, 0);
    	precv->pcommon.pcb = upcb;
        pbuf_free(p);
		if (length != 0) {
			if (precv->pespconn->recv_callback != NULL) {
				precv->pespconn->recv_callback(precv->pespconn, pdata, length);
			}
		}
		os_free(pdata);
    } else {
        return;
    }
}
예제 #19
0
파일: etharp.c 프로젝트: CNCBASHER/gcc4mbed
/**
 * Update (or insert) a IP/MAC address pair in the ARP cache.
 *
 * If a pending entry is resolved, any queued packets will be sent
 * at this point.
 * 
 * @param netif netif related to this entry (used for NETIF_ADDRHINT)
 * @param ipaddr IP address of the inserted ARP entry.
 * @param ethaddr Ethernet address of the inserted ARP entry.
 * @param flags @see definition of ETHARP_FLAG_*
 *
 * @return
 * - ERR_OK Succesfully updated ARP cache.
 * - ERR_MEM If we could not add a new ARP entry when ETHARP_FLAG_TRY_HARD was set.
 * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
 *
 * @see pbuf_free()
 */
static err_t
update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags)
{
  s8_t i;
  LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN);
  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
    ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
    ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
    ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
  /* non-unicast address? */
  if (ip_addr_isany(ipaddr) ||
      ip_addr_isbroadcast(ipaddr, netif) ||
      ip_addr_ismulticast(ipaddr)) {
    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
    return ERR_ARG;
  }
  /* find or create ARP entry */
  i = find_entry(ipaddr, flags);
  /* bail out if no entry could be found */
  if (i < 0) {
    return (err_t)i;
  }

#if ETHARP_SUPPORT_STATIC_ENTRIES
  if (flags & ETHARP_FLAG_STATIC_ENTRY) {
    /* record static type */
    arp_table[i].static_entry = 1;
  }
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */

  /* mark it stable */
  arp_table[i].state = ETHARP_STATE_STABLE;

#if LWIP_SNMP
  /* record network interface */
  arp_table[i].netif = netif;
#endif /* LWIP_SNMP */
  /* insert in SNMP ARP index tree */
  snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr);

  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));
  /* update address */
  ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
  /* reset time stamp */
  arp_table[i].ctime = 0;
#if ARP_QUEUEING
  /* this is where we will send out queued packets! */
  while (arp_table[i].q != NULL) {
    struct pbuf *p;
    /* remember remainder of queue */
    struct etharp_q_entry *q = arp_table[i].q;
    /* pop first item off the queue */
    arp_table[i].q = q->next;
    /* get the packet pointer */
    p = q->p;
    /* now queue entry can be freed */
    memp_free(MEMP_ARP_QUEUE, q);
    /* send the queued IP packet */
    etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr);
    /* free the queued IP packet */
    pbuf_free(p);
  }
#endif /* ARP_QUEUEING */
  return ERR_OK;
}
예제 #20
0
파일: lwip_etharp.c 프로젝트: NXPmicro/mbed
/**
 * Update (or insert) a IP/MAC address pair in the ARP cache.
 *
 * If a pending entry is resolved, any queued packets will be sent
 * at this point.
 *
 * @param netif netif related to this entry (used for NETIF_ADDRHINT)
 * @param ipaddr IP address of the inserted ARP entry.
 * @param ethaddr Ethernet address of the inserted ARP entry.
 * @param flags See @ref etharp_state
 *
 * @return
 * - ERR_OK Successfully updated ARP cache.
 * - ERR_MEM If we could not add a new ARP entry when ETHARP_FLAG_TRY_HARD was set.
 * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
 *
 * @see pbuf_free()
 */
static err_t
etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags)
{
  s8_t i;
  LWIP_ASSERT("netif->hwaddr_len == ETH_HWADDR_LEN", netif->hwaddr_len == ETH_HWADDR_LEN);
  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
    ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
    (u16_t)ethaddr->addr[0], (u16_t)ethaddr->addr[1], (u16_t)ethaddr->addr[2],
    (u16_t)ethaddr->addr[3], (u16_t)ethaddr->addr[4], (u16_t)ethaddr->addr[5]));
  /* non-unicast address? */
  if (ip4_addr_isany(ipaddr) ||
      ip4_addr_isbroadcast(ipaddr, netif) ||
      ip4_addr_ismulticast(ipaddr)) {
    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
    return ERR_ARG;
  }
  /* find or create ARP entry */
  i = etharp_find_entry(ipaddr, flags, netif);
  /* bail out if no entry could be found */
  if (i < 0) {
    return (err_t)i;
  }

#if ETHARP_SUPPORT_STATIC_ENTRIES
  if (flags & ETHARP_FLAG_STATIC_ENTRY) {
    /* record static type */
    arp_table[i].state = ETHARP_STATE_STATIC;
  } else if (arp_table[i].state == ETHARP_STATE_STATIC) {
    /* found entry is a static type, don't overwrite it */
    return ERR_VAL;
  } else
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
  {
    /* mark it stable */
    arp_table[i].state = ETHARP_STATE_STABLE;
  }

  /* record network interface */
  arp_table[i].netif = netif;
  /* insert in SNMP ARP index tree */
  mib2_add_arp_entry(netif, &arp_table[i].ipaddr);

  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));
  /* update address */
  ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
  /* reset time stamp */
  arp_table[i].ctime = 0;
  /* this is where we will send out queued packets! */
#if ARP_QUEUEING
  while (arp_table[i].q != NULL) {
    struct pbuf *p;
    /* remember remainder of queue */
    struct etharp_q_entry *q = arp_table[i].q;
    /* pop first item off the queue */
    arp_table[i].q = q->next;
    /* get the packet pointer */
    p = q->p;
    /* now queue entry can be freed */
    memp_free(MEMP_ARP_QUEUE, q);
#else /* ARP_QUEUEING */
  if (arp_table[i].q != NULL) {
    struct pbuf *p = arp_table[i].q;
    arp_table[i].q = NULL;
#endif /* ARP_QUEUEING */
    /* send the queued IP packet */
    ethernet_output(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr, ETHTYPE_IP);
    /* free the queued IP packet */
    pbuf_free(p);
  }
  return ERR_OK;
}

#if ETHARP_SUPPORT_STATIC_ENTRIES
/** Add a new static entry to the ARP table. If an entry exists for the
 * specified IP address, this entry is overwritten.
 * If packets are queued for the specified IP address, they are sent out.
 *
 * @param ipaddr IP address for the new static entry
 * @param ethaddr ethernet address for the new static entry
 * @return See return values of etharp_add_static_entry
 */
err_t
etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr)
{
  struct netif *netif;
  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
    ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
    (u16_t)ethaddr->addr[0], (u16_t)ethaddr->addr[1], (u16_t)ethaddr->addr[2],
    (u16_t)ethaddr->addr[3], (u16_t)ethaddr->addr[4], (u16_t)ethaddr->addr[5]));

  netif = ip4_route(ipaddr);
  if (netif == NULL) {
    return ERR_RTE;
  }

  return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
}

/** Remove a static entry from the ARP table previously added with a call to
 * etharp_add_static_entry.
 *
 * @param ipaddr IP address of the static entry to remove
 * @return ERR_OK: entry removed
 *         ERR_MEM: entry wasn't found
 *         ERR_ARG: entry wasn't a static entry but a dynamic one
 */
err_t
etharp_remove_static_entry(const ip4_addr_t *ipaddr)
{
  s8_t i;
  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
    ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));

  /* find or create ARP entry */
  i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, NULL);
  /* bail out if no entry could be found */
  if (i < 0) {
    return (err_t)i;
  }

  if (arp_table[i].state != ETHARP_STATE_STATIC) {
    /* entry wasn't a static entry, cannot remove it */
    return ERR_ARG;
  }
  /* entry found, free it */
  etharp_free_entry(i);
  return ERR_OK;
}
예제 #21
0
파일: tcp_out.c 프로젝트: AlexeyAB/libvma
/**
 * Send persist timer zero-window probes to keep a connection active
 * when a window update is lost.
 *
 * Called by tcp_slowtmr()
 *
 * @param pcb the tcp_pcb for which to send a zero-window probe packet
 */
void
tcp_zero_window_probe(struct tcp_pcb *pcb)
{
  struct pbuf *p;
  struct tcp_hdr *tcphdr;
  struct tcp_seg *seg;
  u16_t len;
  u8_t is_fin;

  LWIP_DEBUGF(TCP_DEBUG,
              ("tcp_zero_window_probe: sending ZERO WINDOW probe to %"
               U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
               ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
               ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));

  LWIP_DEBUGF(TCP_DEBUG,
              ("tcp_zero_window_probe: tcp_ticks %"U32_F
               "   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
               tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));

  seg = pcb->unacked;

  if(seg == NULL) {
    seg = pcb->unsent;
  }
  if(seg == NULL) {
    return;
  }

  is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0);
  /* we want to send one seqno: either FIN or data (no options) */
  len = is_fin ? 0 : 1;

  p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno);
  if(p == NULL) {
    LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));
    return;
  }
  tcphdr = (struct tcp_hdr *)p->payload;

  if (is_fin) {
    /* FIN segment, no data */
    TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN);
  } else {
    /* Data segment, copy in one byte from the head of the unacked queue */
    *((char *)p->payload + TCP_HLEN) = *(char *)seg->dataptr;
  }

#if CHECKSUM_GEN_TCP
  tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
                                      IP_PROTO_TCP, (u16_t)p->tot_len);
#endif
  TCP_STATS_INC(tcp.xmit);

  /* Send output to IP */
#if LWIP_NETIF_HWADDRHINT
  ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP,
    &(pcb->addr_hint));
#elif LWIP_3RD_PARTY_L3
  pcb->ip_output(p, pcb, 0);
#else /* LWIP_NETIF_HWADDRHINT*/
  ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
#endif /* LWIP_NETIF_HWADDRHINT*/

  tcp_tx_pbuf_free(pcb, p);

  LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F
                          " ackno %"U32_F".\n",
                          pcb->snd_nxt - 1, pcb->rcv_nxt));
}
예제 #22
0
/******************************************************************************
 * FunctionName : espconn_tcp_accept
 * Description  : A new incoming connection has been accepted.
 * Parameters   : arg -- Additional argument to pass to the callback function
 *                pcb -- The connection pcb which is accepted
 *                err -- An unused error code, always ERR_OK currently
 * Returns      : acception result
*******************************************************************************/
static err_t ICACHE_FLASH_ATTR
espconn_tcp_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
    struct espconn *espconn = arg;
    espconn_msg *paccept = NULL;
    remot_info *pinfo = NULL;
    LWIP_UNUSED_ARG(err);

    if (!espconn || !espconn->proto.tcp) {
    	return ERR_ARG;
    }

    tcp_arg(pcb, paccept);
    tcp_err(pcb, esponn_server_err);
    /*Ensure the active connection is less than the count of active connections on the server*/
    espconn_get_connection_info(espconn, &pinfo , 0);
	espconn_printf("espconn_tcp_accept link_cnt: %d\n", espconn->link_cnt);
	if (espconn->link_cnt == espconn_tcp_get_max_con_allow(espconn))
		return ERR_ISCONN;

	/*Creates a new active connect control message*/
    paccept = (espconn_msg *)malloc(sizeof(espconn_msg));
	memset(paccept, 0, sizeof(espconn_msg));
    tcp_arg(pcb, paccept);

	if (paccept == NULL)
		return ERR_MEM;
	/*Insert the node to the active connection list*/
	espconn_list_creat(&plink_active, paccept);

    paccept->preverse = espconn;
	paccept->pespconn = (struct espconn *)malloc(sizeof(struct espconn));
	if (paccept->pespconn == NULL)
		return ERR_MEM;
	paccept->pespconn->proto.tcp = (esp_tcp *)malloc(sizeof(esp_tcp));
	if (paccept->pespconn->proto.tcp == NULL)
		return ERR_MEM;

	/*Reserve the remote information for current active connection*/
	paccept->pcommon.pcb = pcb;

	paccept->pcommon.remote_port = pcb->remote_port;
	paccept->pcommon.remote_ip[0] = ip4_addr1_16(&pcb->remote_ip.u_addr.ip4);
	paccept->pcommon.remote_ip[1] = ip4_addr2_16(&pcb->remote_ip.u_addr.ip4);
	paccept->pcommon.remote_ip[2] = ip4_addr3_16(&pcb->remote_ip.u_addr.ip4);
	paccept->pcommon.remote_ip[3] = ip4_addr4_16(&pcb->remote_ip.u_addr.ip4);
	paccept->pcommon.write_flag = true;

	memcpy(espconn->proto.tcp->remote_ip, paccept->pcommon.remote_ip, 4);
	espconn->proto.tcp->remote_port = pcb->remote_port;
	espconn->state = ESPCONN_CONNECT;
	espconn_copy_partial(paccept->pespconn, espconn);

	/*Set the specify function that should be called
	 * when TCP data has been successfully delivered,
	 * when active connection receives data,
	 * or periodically from active connection*/
	tcp_sent(pcb, espconn_server_sent);
	tcp_recv(pcb, espconn_server_recv);
	tcp_poll(pcb, espconn_server_poll, 8); /* every 1 seconds */
	/*Disable Nagle algorithm default*/
	tcp_nagle_disable(pcb);
	/*Default set the total number of espconn_buf on the unsent lists for one*/
	espconn_tcp_set_buf_count(paccept->pespconn, 1);

	if (paccept->pespconn->proto.tcp->connect_callback != NULL) {
		paccept->pespconn->proto.tcp->connect_callback(paccept->pespconn);
	}

	/*Enable keep alive option*/
	if (espconn_keepalive_disabled(paccept))
		espconn_keepalive_enable(pcb);

    return ERR_OK;
}
예제 #23
0
파일: dns.c 프로젝트: someburner/esp-rfm69
static void ICACHE_FLASH_ATTR dnsQueryReceived(void *arg, char *data, unsigned short length)
{
   // parse incoming query domain
   char domain[30];
   char *writePos=domain;
   memset(domain,0,30);

   int offSet=12;
   int len=data[offSet];
   while(len!=0 && offSet<length)
   {
      offSet++;
      memcpy(writePos,data+offSet,len);
      writePos+=len; //advance
      offSet+=len;
      len=data[offSet];

      if(len!=0) { *writePos='.'; writePos++; }
   }

   DNS_DBG("DNS Query Received: %s",domain);
   if(!isKnownDNS(domain))
   return;

   struct espconn *conn=arg;

   remot_info *premot = NULL;

   if (espconn_get_connection_info(conn,&premot,0) == ESPCONN_OK)
   {
      os_memcpy(conn->proto.udp->remote_ip, premot->remote_ip, 4);
      conn->proto.udp->remote_port = premot->remote_port;

      uint8_t *ip1 = conn->proto.udp->remote_ip;
      NODE_DBG("UDP:\nremote_ip: %d.%d.%d.%d remote_port: %d\n",ip4_addr1_16(ip1),ip4_addr2_16(ip1), ip4_addr3_16(ip1), ip4_addr4_16(ip1), premot->remote_port);
   }
   else
      { NODE_ERR("UDP: connection_info == NULL?\n"); }

   //build response
   char response[100] = {data[0], data[1],
                        0b10000100 | (0b00000001 & data[2]), //response, authorative answer, not truncated, copy the recursion bit
                        0b00000000, //no recursion available, no errors
                        data[4], data[5], //Question count
                        data[4], data[5], //answer count
                        0x00, 0x00,       //NS record count
                        0x00, 0x00};      //Resource record count

   int idx = 12;
   memcpy(response+12, data+12, length-12); //Copy the rest of the query section
   idx += length-12;

   //Set a pointer to the domain name in the question section
   response[idx] = 0xC0;
   response[idx+1] = 0x0C;

   //Set the type to "Host Address"
   response[idx+2] = 0x00;
   response[idx+3] = 0x01;

   //Set the response class to IN
   response[idx+4] = 0x00;
   response[idx+5] = 0x01;

   //A 32 bit integer specifying TTL in seconds, 0 means no caching
   response[idx+6] = 0x00;
   response[idx+7] = 0x00;
   response[idx+8] = 0x00;
   response[idx+9] = 0x00;

   //RDATA length
   response[idx+10] = 0x00;
   response[idx+11] = 0x04; //4 byte IP address

   //The IP address
   response[idx + 12] = 192;
   response[idx + 13] = 168;
   response[idx + 14] = 4;
   response[idx + 15] = 1;

   int ret = espconn_send(conn, (uint8_t*)response, idx+16);

   uint8_t *ip = conn->proto.udp->local_ip;
   NODE_DBG("local_ip: %d.%d.%d.%d local_port: %d\n",ip4_addr1_16(ip),ip4_addr2_16(ip), ip4_addr3_16(ip), ip4_addr4_16(ip),conn->proto.udp->local_port);
   NODE_DBG("DNS reply sent\n");
}
예제 #24
0
파일: raw.c 프로젝트: CNCBASHER/gcc4mbed
/**
 * Send the raw IP packet to the given address. Note that actually you cannot
 * modify the IP headers (this is inconsistent with the receive callback where
 * you actually get the IP headers), you can only specify the IP payload here.
 * It requires some more changes in lwIP. (there will be a raw_send() function
 * then.)
 *
 * @param pcb the raw pcb which to send
 * @param p the IP payload to send
 * @param ipaddr the destination address of the IP packet
 *
 */
err_t
raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
{
  err_t err;
  struct netif *netif;
  ip_addr_t *src_ip;
  struct pbuf *q; /* q will be sent down the stack */
  
  LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
  
  /* not enough space to add an IP header to first pbuf in given p chain? */
  if (pbuf_header(p, IP_HLEN)) {
    /* allocate header in new pbuf */
    q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
    /* new header pbuf could not be allocated? */
    if (q == NULL) {
      LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n"));
      return ERR_MEM;
    }
    /* chain header q in front of given pbuf p */
    pbuf_chain(q, p);
    /* { first pbuf q points to header pbuf } */
    LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
  }  else {
    /* first pbuf q equals given pbuf */
    q = p;
    if(pbuf_header(q, -IP_HLEN)) {
      LWIP_ASSERT("Can't restore header we just removed!", 0);
      return ERR_MEM;
    }
  }

  if ((netif = ip_route(ipaddr)) == NULL) {
    LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
      ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
    /* free any temporary header pbuf allocated by pbuf_header() */
    if (q != p) {
      pbuf_free(q);
    }
    return ERR_RTE;
  }

#if IP_SOF_BROADCAST
  /* broadcast filter? */
  if (((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(ipaddr, netif)) {
    LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
    /* free any temporary header pbuf allocated by pbuf_header() */
    if (q != p) {
      pbuf_free(q);
    }
    return ERR_VAL;
  }
#endif /* IP_SOF_BROADCAST */

  if (ip_addr_isany(&pcb->local_ip)) {
    /* use outgoing network interface IP address as source address */
    src_ip = &(netif->ip_addr);
  } else {
    /* use RAW PCB local IP address as source address */
    src_ip = &(pcb->local_ip);
  }

#if LWIP_NETIF_HWADDRHINT
  netif->addr_hint = &(pcb->addr_hint);
#endif /* LWIP_NETIF_HWADDRHINT*/
  err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif);
#if LWIP_NETIF_HWADDRHINT
  netif->addr_hint = NULL;
#endif /* LWIP_NETIF_HWADDRHINT*/

  /* did we chain a header earlier? */
  if (q != p) {
    /* free the header */
    pbuf_free(q);
  }
  return err;
}
예제 #25
0
/**
 * Process an incoming UDP datagram.
 *
 * Given an incoming UDP datagram (as a chain of pbufs) this function
 * finds a corresponding UDP PCB and hands over the pbuf to the pcbs
 * recv function. If no pcb is found or the datagram is incorrect, the
 * pbuf is freed.
 *
 * @param p pbuf to be demultiplexed to a UDP PCB.
 * @param inp network interface on which the datagram was received.
 *
 */
void
udp_input(struct pbuf *p, struct netif *inp)
{
    struct udp_hdr *udphdr;
    struct udp_pcb *pcb, *prev;
    struct udp_pcb *uncon_pcb;
    struct ip_hdr *iphdr;
    u16_t src, dest;
    u8_t local_match;
    u8_t broadcast;

    PERF_START;

    UDP_STATS_INC(udp.recv);

    iphdr = (struct ip_hdr *)p->payload;

    /* Check minimum length (IP header + UDP header)
     * and move payload pointer to UDP header */
    if (p->tot_len < (IPH_HL(iphdr) * 4 + UDP_HLEN) || pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4))) {
        /* drop short packets */
        LWIP_DEBUGF(UDP_DEBUG,
                    ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len));
        UDP_STATS_INC(udp.lenerr);
        UDP_STATS_INC(udp.drop);
        snmp_inc_udpinerrors();
        pbuf_free(p);
        goto end;
    }

    udphdr = (struct udp_hdr *)p->payload;

    /* is broadcast packet ? */
    broadcast = ip_addr_isbroadcast(&current_iphdr_dest, inp);

    LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len));

    /* convert src and dest ports to host byte order */
    src = ntohs(udphdr->src);
    dest = ntohs(udphdr->dest);

    udp_debug_print(udphdr);

    /* print the UDP source and destination */
    LWIP_DEBUGF(UDP_DEBUG,
                ("udp (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") <-- "
                 "(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",
                 ip4_addr1_16(&iphdr->dest), ip4_addr2_16(&iphdr->dest),
                 ip4_addr3_16(&iphdr->dest), ip4_addr4_16(&iphdr->dest), ntohs(udphdr->dest),
                 ip4_addr1_16(&iphdr->src), ip4_addr2_16(&iphdr->src),
                 ip4_addr3_16(&iphdr->src), ip4_addr4_16(&iphdr->src), ntohs(udphdr->src)));

#if LWIP_DHCP
    pcb = NULL;
    /* when LWIP_DHCP is active, packets to DHCP_CLIENT_PORT may only be processed by
       the dhcp module, no other UDP pcb may use the local UDP port DHCP_CLIENT_PORT */
    if (dest == DHCP_CLIENT_PORT) {
        /* all packets for DHCP_CLIENT_PORT not coming from DHCP_SERVER_PORT are dropped! */
        if (src == DHCP_SERVER_PORT) {
            if ((inp->dhcp != NULL) && (inp->dhcp->pcb != NULL)) {
                /* accept the packe if
                   (- broadcast or directed to us) -> DHCP is link-layer-addressed, local ip is always ANY!
                   - inp->dhcp->pcb->remote == ANY or iphdr->src */
                if ((ip_addr_isany(&inp->dhcp->pcb->remote_ip) ||
                        ip_addr_cmp(&(inp->dhcp->pcb->remote_ip), &current_iphdr_src))) {
                    pcb = inp->dhcp->pcb;
                }
            }
        }
    } else
#endif /* LWIP_DHCP */
    {
        prev = NULL;
        local_match = 0;
        uncon_pcb = NULL;
        /* Iterate through the UDP pcb list for a matching pcb.
         * 'Perfect match' pcbs (connected to the remote port & ip address) are
         * preferred. If no perfect match is found, the first unconnected pcb that
         * matches the local port and ip address gets the datagram. */
        for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
            local_match = 0;
            /* print the PCB local and remote address */
            LWIP_DEBUGF(UDP_DEBUG,
                        ("pcb (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") --- "
                         "(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",
                         ip4_addr1_16(&pcb->local_ip), ip4_addr2_16(&pcb->local_ip),
                         ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip), pcb->local_port,
                         ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
                         ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip), pcb->remote_port));

            /* compare PCB local addr+port to UDP destination addr+port */
            if (pcb->local_port == dest) {
                if (
                    (!broadcast && ip_addr_isany(&pcb->local_ip)) ||
                    ip_addr_cmp(&(pcb->local_ip), &current_iphdr_dest) ||
#if LWIP_IGMP
                    ip_addr_ismulticast(&current_iphdr_dest) ||
#endif /* LWIP_IGMP */
#if IP_SOF_BROADCAST_RECV
                    (broadcast && ip_get_option(pcb, SOF_BROADCAST) &&
                     (ip_addr_isany(&pcb->local_ip) ||
                      ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), &inp->netmask)))) {
#else /* IP_SOF_BROADCAST_RECV */
                    (broadcast &&
                     (ip_addr_isany(&pcb->local_ip) ||
                      ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), &inp->netmask)))) {
#endif /* IP_SOF_BROADCAST_RECV */
                    local_match = 1;
                    if ((uncon_pcb == NULL) &&
                            ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) {
                        /* the first unconnected matching PCB */
                        uncon_pcb = pcb;
                    }
                }
            }
            /* compare PCB remote addr+port to UDP source addr+port */
            if ((local_match != 0) &&
                    (pcb->remote_port == src) &&
                    (ip_addr_isany(&pcb->remote_ip) ||
                     ip_addr_cmp(&(pcb->remote_ip), &current_iphdr_src))) {
                /* the first fully matching PCB */
                if (prev != NULL) {
                    /* move the pcb to the front of udp_pcbs so that is
                       found faster next time */
                    prev->next = pcb->next;
                    pcb->next = udp_pcbs;
                    udp_pcbs = pcb;
                } else {
                    UDP_STATS_INC(udp.cachehit);
                }
                break;
            }
            prev = pcb;
        }
        /* no fully matching pcb found? then look for an unconnected pcb */
        if (pcb == NULL) {
            pcb = uncon_pcb;
        }
    }

    /* Check checksum if this is a match or if it was directed at us. */
    if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, &current_iphdr_dest)) {
        LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n"));
#if LWIP_UDPLITE
        if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
            /* Do the UDP Lite checksum */
#if CHECKSUM_CHECK_UDP
            u16_t chklen = ntohs(udphdr->len);
            if (chklen < sizeof(struct udp_hdr)) {
                if (chklen == 0) {
                    /* For UDP-Lite, checksum length of 0 means checksum
                       over the complete packet (See RFC 3828 chap. 3.1) */
                    chklen = p->tot_len;
                } else {
                    /* At least the UDP-Lite header must be covered by the
                       checksum! (Again, see RFC 3828 chap. 3.1) */
                    UDP_STATS_INC(udp.chkerr);
                    UDP_STATS_INC(udp.drop);
                    snmp_inc_udpinerrors();
                    pbuf_free(p);
                    goto end;
                }
            }
            if (inet_chksum_pseudo_partial(p, &current_iphdr_src, &current_iphdr_dest,
                                           IP_PROTO_UDPLITE, p->tot_len, chklen) != 0) {
                LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
                            ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
                UDP_STATS_INC(udp.chkerr);
                UDP_STATS_INC(udp.drop);
                snmp_inc_udpinerrors();
                pbuf_free(p);
                goto end;
            }
#endif /* CHECKSUM_CHECK_UDP */
        } else
#endif /* LWIP_UDPLITE */
        {
#if CHECKSUM_CHECK_UDP
            if (udphdr->chksum != 0) {
                if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(),
                                       IP_PROTO_UDP, p->tot_len) != 0) {
                    LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
                                ("udp_input: UDP datagram discarded due to failing checksum\n"));
                    UDP_STATS_INC(udp.chkerr);
                    UDP_STATS_INC(udp.drop);
                    snmp_inc_udpinerrors();
                    pbuf_free(p);
                    goto end;
                }
            }
#endif /* CHECKSUM_CHECK_UDP */
        }
        if(pbuf_header(p, -UDP_HLEN)) {
            /* Can we cope with this failing? Just assert for now */
            LWIP_ASSERT("pbuf_header failed\n", 0);
            UDP_STATS_INC(udp.drop);
            snmp_inc_udpinerrors();
            pbuf_free(p);
            goto end;
        }
        if (pcb != NULL) {
            snmp_inc_udpindatagrams();
#if SO_REUSE && SO_REUSE_RXTOALL
            if ((broadcast || ip_addr_ismulticast(&current_iphdr_dest)) &&
                    ip_get_option(pcb, SOF_REUSEADDR)) {
                /* pass broadcast- or multicast packets to all multicast pcbs
                   if SOF_REUSEADDR is set on the first match */
                struct udp_pcb *mpcb;
                u8_t p_header_changed = 0;
                for (mpcb = udp_pcbs; mpcb != NULL; mpcb = mpcb->next) {
                    if (mpcb != pcb) {
                        /* compare PCB local addr+port to UDP destination addr+port */
                        if ((mpcb->local_port == dest) &&
                                ((!broadcast && ip_addr_isany(&mpcb->local_ip)) ||
                                 ip_addr_cmp(&(mpcb->local_ip), &current_iphdr_dest) ||
#if LWIP_IGMP
                                 ip_addr_ismulticast(&current_iphdr_dest) ||
#endif /* LWIP_IGMP */
#if IP_SOF_BROADCAST_RECV
                                 (broadcast && ip_get_option(mpcb, SOF_BROADCAST)))) {
#else  /* IP_SOF_BROADCAST_RECV */
                                 (broadcast))) {
#endif /* IP_SOF_BROADCAST_RECV */
                            /* pass a copy of the packet to all local matches */
                            if (mpcb->recv != NULL) {
                                struct pbuf *q;
                                /* for that, move payload to IP header again */
                                if (p_header_changed == 0) {
                                    pbuf_header(p, (s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN));
                                    p_header_changed = 1;
                                }
                                q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
                                if (q != NULL) {
                                    err_t err = pbuf_copy(q, p);
                                    if (err == ERR_OK) {
                                        /* move payload to UDP data */
                                        pbuf_header(q, -(s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN));
                                        mpcb->recv(mpcb->recv_arg, mpcb, q, ip_current_src_addr(), src);
                                    }
                                }
                            }
                        }
                    }
                }
                if (p_header_changed) {
                    /* and move payload to UDP data again */
                    pbuf_header(p, -(s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN));
                }
            }
#endif /* SO_REUSE && SO_REUSE_RXTOALL */
            /* callback */
            if (pcb->recv != NULL) {
                /* now the recv function is responsible for freeing p */
                pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr(), src);
            } else {
                /* no recv function registered? then we have to free the pbuf! */
                pbuf_free(p);
                goto end;
            }
        } else {
예제 #26
0
/**
 * Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds
 */
void
autoip_tmr()
{
  struct netif *netif = netif_list;
  /* loop through netif's */
  while (netif != NULL) {
    /* only act on AutoIP configured interfaces */
    if (netif->autoip != NULL) {
      if(netif->autoip->lastconflict > 0) {
        netif->autoip->lastconflict--;
      }

      LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
        ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
        (u16_t)(netif->autoip->state), netif->autoip->ttw));

      switch(netif->autoip->state) {
        case AUTOIP_STATE_PROBING:
          if(netif->autoip->ttw > 0) {
            netif->autoip->ttw--;
          } else {
            if(netif->autoip->sent_num >= PROBE_NUM) {
              netif->autoip->state = AUTOIP_STATE_ANNOUNCING;
              netif->autoip->sent_num = 0;
              netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
              LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
                 ("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
                  ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
                  ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
            } else {
              autoip_arp_probe(netif);
              LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
                ("autoip_tmr() PROBING Sent Probe\n"));
              netif->autoip->sent_num++;
              /* calculate time to wait to next probe */
              netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
                ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
                PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
            }
          }
          break;

        case AUTOIP_STATE_ANNOUNCING:
          if(netif->autoip->ttw > 0) {
            netif->autoip->ttw--;
          } else {
            if(netif->autoip->sent_num == 0) {
             /* We are here the first time, so we waited ANNOUNCE_WAIT seconds
              * Now we can bind to an IP address and use it.
              *
              * autoip_bind calls netif_set_up. This triggers a gratuitous ARP
              * which counts as an announcement.
              */
              autoip_bind(netif);
            } else {
              autoip_arp_announce(netif);
              LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
                ("autoip_tmr() ANNOUNCING Sent Announce\n"));
            }
            netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
            netif->autoip->sent_num++;

            if(netif->autoip->sent_num >= ANNOUNCE_NUM) {
                netif->autoip->state = AUTOIP_STATE_BOUND;
                netif->autoip->sent_num = 0;
                netif->autoip->ttw = 0;
                 LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
                    ("autoip_tmr(): changing state to BOUND: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
                     ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr),
                     ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
            }
          }
          break;
      }
    }
    /* proceed to next network interface */
    netif = netif->next;
  }
}