Пример #1
0
struct netif *
ip_router(ip_addr_t *dest, ip_addr_t *source){
	struct netif *netif;
	/* iterate through netifs */
  	for(netif = netif_list; netif != NULL; netif = netif->next) {
	    /* network mask matches? */
		
		if (netif_is_up(netif)) {
	      if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
	        /* return netif on which to forward IP packet */
	        return netif;
	      }
	    }

		if (netif_is_up(netif)) {
	      if (ip_addr_netcmp(source, &(netif->ip_addr), &(netif->netmask))) {
	        /* return netif on which to forward IP packet */
	        return netif;
	      }
	    }
  	}

	if ((netif_default == NULL) || (!netif_is_up(netif_default))) {
	    LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
	      ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
	    IP_STATS_INC(ip.rterr);
	    snmp_inc_ipoutnoroutes();
	    return NULL;
  	}
  	/* no matching netif found, use default netif */
  	return netif_default;
}
Пример #2
0
/*********************************************************************************************************
** 函数名称: __rtFind
** 功能描述: 遍历 sylixos 路由条目
** 输 入  : pfuncHook     遍历回调函数
**           pvArg0...4    参数
** 输 出  : NONE
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static VOID __rtTraversal (VOIDFUNCPTR  pfuncHook,
                           PVOID        pvArg0,
                           PVOID        pvArg1,
                           PVOID        pvArg2,
                           PVOID        pvArg3,
                           PVOID        pvArg4)
{
    INT             i;
    PLW_LIST_LINE   plineTemp;
    PLW_RT_ENTRY    prte;
    
    for (i = 0; i < LW_RT_TABLESIZE; i++) {
        for (plineTemp  = _G_plineRtHashHeader[i];
             plineTemp != LW_NULL;
             plineTemp  = _list_line_get_next(plineTemp)) {
             
            prte = (PLW_RT_ENTRY)plineTemp;
            if (prte->RTE_pnetif) {
                prte->RTE_uiFlag |= LW_RT_FLAG_U;                       /*  路由有效                    */
                if ((prte->RTE_ipaddrDest.addr != IPADDR_BROADCAST) &&
                    !ip_addr_netcmp(&prte->RTE_ipaddrDest,
                                    &(prte->RTE_pnetif->ip_addr),
                                    &(prte->RTE_pnetif->netmask))) {    /*  不在同一网络                */
                    prte->RTE_uiFlag |= LW_RT_FLAG_G;                   /*  间接路由                    */
                } else {
                    prte->RTE_uiFlag &= ~LW_RT_FLAG_G;
                }
            }
            pfuncHook(prte, pvArg0, pvArg1, pvArg2, pvArg3, pvArg4);
        }
    }
}
Пример #3
0
/*********************************************************************************************************
** 函数名称: __rtMatch
** 功能描述: 匹配一个 sylixos 路由条目 (优先选择主机路由, 然后选择网络路由)
** 输 入  : pipaddrDest    目标地址
** 输 出  : 如果查询到, 则返回路由表节点
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
static PLW_RT_ENTRY __rtMatch (const ip_addr_t *pipaddrDest)
{
    INT             iHash = LW_RT_HASHINDEX(pipaddrDest);
    PLW_LIST_LINE   plineTemp;
    PLW_RT_ENTRY    prte;
    PLW_RT_ENTRY    prteNet = LW_NULL;                                  /*  缓冲遍历是产生的网络地址    */
    
    for (plineTemp  = _G_plineRtHashHeader[iHash];
         plineTemp != LW_NULL;
         plineTemp  = _list_line_get_next(plineTemp)) {
         
        prte = (PLW_RT_ENTRY)plineTemp;
        if (prte->RTE_uiFlag & LW_RT_FLAG_U) {                          /*  路由节点有效                */
            if ((prte->RTE_uiFlag & LW_RT_FLAG_H) &&
                (prte->RTE_ipaddrDest.addr == pipaddrDest->addr)) {     /*  主机匹配检查                */
                return  (prte);
            
            } else if ((prteNet == LW_NULL) && 
                       (ip_addr_netcmp(pipaddrDest, 
                                       &(prte->RTE_pnetif->ip_addr),
                                       &(prte->RTE_pnetif->netmask)))) {/*  网络匹配检查                */
                prteNet = prte;
            }
        }
    }
    
    return  (prteNet);
}
Пример #4
0
/**
 * Determine if an address is a broadcast address on a network interface 
 * 
 * @param addr address to be checked
 * @param netif the network interface against which the address is checked
 * @return returns non-zero if the address is a broadcast address
 */
u8_t ip_addr_isbroadcast(struct ip_addr *addr, struct netif *netif)
{
  u32_t addr2test;

  addr2test = addr->addr;
  /* all ones (broadcast) or all zeroes (old skool broadcast) */
  if ((~addr2test == IP_ADDR_ANY_VALUE) ||
      (addr2test == IP_ADDR_ANY_VALUE))
    return 1;
  /* no broadcast support on this network interface? */
  else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0)
    /* the given address cannot be a broadcast address
     * nor can we check against any broadcast addresses */
    return 0;
  /* address matches network interface address exactly? => no broadcast */
  else if (addr2test == netif->ip_addr.addr)
    return 0;
  /*  on the same (sub) network... */
  else if (ip_addr_netcmp(addr, &(netif->ip_addr), &(netif->netmask))
         /* ...and host identifier bits are all ones? =>... */
          && ((addr2test & ~netif->netmask.addr) ==
           (IP_ADDR_BROADCAST_VALUE & ~netif->netmask.addr)))
    /* => network broadcast address */
    return 1;
  else
    return 0;
}
Пример #5
0
/**
 * Determine if an address is a broadcast address on a network interface 
 * 
 * @param addr address to be checked
 * @param netif the network interface against which the address is checked
 * @return returns non-zero if the address is a broadcast address
 */
u8_t
ip4_addr_isbroadcast(u32_t addr, const struct netif *netif)
{
  ip_addr_t ipaddr;
  ip4_addr_set_u32(&ipaddr, addr);

  /* all ones (broadcast) or all zeroes (old skool broadcast) */
  if ((~addr == IPADDR_ANY) ||
      (addr == IPADDR_ANY)) {
    return 1;
  /* no broadcast support on this network interface? */
  } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) {
    /* the given address cannot be a broadcast address
     * nor can we check against any broadcast addresses */
    return 0;
  /* address matches network interface address exactly? => no broadcast */
  } else if (addr == ip4_addr_get_u32(&netif->ip_addr)) {
    return 0;
  /*  on the same (sub) network... */
  } else if (ip_addr_netcmp(&ipaddr, &(netif->ip_addr), &(netif->netmask))
         /* ...and host identifier bits are all ones? =>... */
          && ((addr & ~ip4_addr_get_u32(&netif->netmask)) ==
           (IPADDR_BROADCAST & ~ip4_addr_get_u32(&netif->netmask)))) {
    /* => network broadcast address */
    return 1;
  } else {
    return 0;
  }
}
Пример #6
0
/**
 * Check if "dst" is an IPv4 address that proxy remaps to host's
 * loopback.
 */
static int
proxy_ip4_is_mapped_loopback(struct netif *netif, const ip_addr_t *dst, ip_addr_t *lo)
{
    u32_t off;
    const struct ip4_lomap *lomap;
    size_t i;

    LWIP_ASSERT1(dst != NULL);

    if (g_proxy_options->lomap_desc == NULL) {
        return 0;
    }

    if (!ip_addr_netcmp(dst, &netif->ip_addr, &netif->netmask)) {
        return 0;
    }

    /* XXX: TODO: check netif is a proxying netif! */

    off = ntohl(ip4_addr_get_u32(dst) & ~ip4_addr_get_u32(&netif->netmask));
    lomap = g_proxy_options->lomap_desc->lomap;
    for (i = 0; i < g_proxy_options->lomap_desc->num_lomap; ++i) {
        if (off == lomap[i].off) {
            if (lo != NULL) {
                ip_addr_copy(*lo, lomap[i].loaddr);
            }
            return 1;
        }
    }
    return 0;
}
Пример #7
0
struct uip_netif* uip_iproute(struct uip_ip_addr *dst)
{
	struct uip_netif *netif;

	for(netif=uip_netif_list;netif!=NULL;netif=netif->next) {
		if(ip_addr_netcmp(dst,&netif->ip_addr,&netif->netmask)) return netif;
	}

	return uip_netif_default;
}
Пример #8
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));

    precv->pcommon.remote_ip[0] = ip4_addr1_16(addr);
    precv->pcommon.remote_ip[1] = ip4_addr2_16(addr);
    precv->pcommon.remote_ip[2] = ip4_addr3_16(addr);
    precv->pcommon.remote_ip[3] = ip4_addr4_16(addr);
    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);
	}

	precv->pespconn->proto.udp->local_ip[0] = ip4_addr1_16(&ipconfig.ip);
	precv->pespconn->proto.udp->local_ip[1] = ip4_addr2_16(&ipconfig.ip);
	precv->pespconn->proto.udp->local_ip[2] = ip4_addr3_16(&ipconfig.ip);
	precv->pespconn->proto.udp->local_ip[3] = ip4_addr4_16(&ipconfig.ip);

    precv->pespconn->proto.udp->remote_ip[0] = precv->pcommon.remote_ip[0];
    precv->pespconn->proto.udp->remote_ip[1] = precv->pcommon.remote_ip[1];
    precv->pespconn->proto.udp->remote_ip[2] = precv->pcommon.remote_ip[2];
    precv->pespconn->proto.udp->remote_ip[3] = precv->pcommon.remote_ip[3];
    precv->pespconn->proto.udp->remote_port = port;

    if (p != NULL) {
    	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;
    }
}
Пример #9
0
LOCAL void ICACHE_FLASH_ATTR
user_udp_recv(void *arg, char *pusrdata, unsigned short length)
{
	char DeviceBuffer[40] = { 0 };
	char Device_mac_buffer[60] = { 0 };
	char hwaddr[6];

	struct ip_info ipconfig;

	if (wifi_get_opmode() != STATION_MODE) {
		wifi_get_ip_info(SOFTAP_IF, &ipconfig);
		wifi_get_macaddr(SOFTAP_IF, hwaddr);

		if (!ip_addr_netcmp
		    ((struct ip_addr *)ptrespconn.proto.udp->remote_ip,
		     &ipconfig.ip, &ipconfig.netmask)) {
			//udp packet is received from ESP8266 station
			wifi_get_ip_info(STATION_IF, &ipconfig);
			wifi_get_macaddr(STATION_IF, hwaddr);
		} else {
			//udp packet is received from ESP8266 softAP
		}

	} else {
		//udp packet is received from ESP8266 station
		wifi_get_ip_info(STATION_IF, &ipconfig);
		wifi_get_macaddr(STATION_IF, hwaddr);
	}

	if (pusrdata == NULL)
		return;

	if (length == os_strlen(device_find_request) &&
	    os_strncmp(pusrdata, device_find_request,
		       os_strlen(device_find_request)) == 0) {
		//received device find message

		os_sprintf(DeviceBuffer, "%s" MACSTR " " IPSTR,
			   device_find_response_ok, MAC2STR(hwaddr),
			   IP2STR(&ipconfig.ip));

		os_printf("%s\n", DeviceBuffer);
		length = os_strlen(DeviceBuffer);

		//if received "Are You ESP8266 ?" ,
		//response "Yes,I'm ESP8266!" + ESP8266 mac + ESP8266 ip
		espconn_sent(&ptrespconn, DeviceBuffer, length);

	} else {
		//received some other data
	}

}
Пример #10
0
static void
esp8266_cb_connect(void *arg)
{
	struct espconn *cs = arg;
//	struct ip_addr *ipa = (struct ip_addr *)cs->proto.tcp->remote_ip;
	struct lws_vhost *vh = hacky_context->vhost_list;
//	struct ip_info info;
	struct lws *wsi;
	int n;

	lwsl_notice("%s: (wsi coming): %p\n", __func__, cs->reverse);
#if 0
	wifi_get_ip_info(0, &info);
	if (ip_addr_netcmp(ipa, &info.ip, &info.netmask)) {
		/* we are on the same subnet as the AP, ie, connected to AP */
		while (vh && strcmp(vh->name, "ap"))
			vh = vh->vhost_next;
	} else
		while (vh && !strcmp(vh->name, "ap"))
			vh = vh->vhost_next;

	if (!vh)
		goto bail;
#endif
	n = esp8266_find_free_conn(hacky_context);
	if (n < 0)
		goto bail;

	hacky_context->connpool[n] = cs;

	espconn_recv_hold(cs);

	wsi = lws_adopt_socket_vhost(vh, cs);
	if (!wsi)
		goto bail;

	lwsl_err("%s: wsi %p (using free_conn %d): vh %s\n", __func__, wsi, n, vh->name);

	espconn_regist_recvcb(cs, esp8266_cb_rx);
	espconn_regist_reconcb(cs, esp8266_cb_recon);
	espconn_regist_disconcb(cs, esp8266_cb_disconnected);
	espconn_regist_sentcb(cs, esp8266_cb_sent);

	espconn_set_opt(cs, ESPCONN_NODELAY | ESPCONN_REUSEADDR);
	espconn_regist_time(cs, 7200, 1);

	return;

bail:
	lwsl_err("%s: bailed]n", __func__);
	espconn_disconnect(cs);
}
Пример #11
0
Файл: ip6.c Проект: 0xBADCA7/lk
struct netif *
ip_route(struct ip_addr *dest)
{
  struct netif *netif;

  for(netif = netif_list; netif != NULL; netif = netif->next) {
    if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
      return netif;
    }
  }

  return netif_default;
}
Пример #12
0
u8_t uip_ipaddr_isbroadcast(struct uip_ip_addr *addr,struct uip_netif *netif)
{
	if(addr->addr==ipaddr_broadcast.addr
		|| addr->addr==ipaddr_any.addr)
		return 1;
	else if(!(netif->flags&UIP_NETIF_FLAG_BROADCAST))
		return 0;
	else if(addr->addr==netif->ip_addr.addr)
		return 0;
	else if(ip_addr_netcmp(addr,&netif->ip_addr,&netif->netmask)
		&& ((addr->addr&~netif->netmask.addr)==(ipaddr_broadcast.addr&~netif->netmask.addr)))
		return 1;
	else
		return 0;
}
struct netif *
ip_route(struct ip_addr *dest)
{
  struct netif *netif;

  /* iterate through netifs */
  for(netif = netif_list; netif != NULL; netif = netif->next) {
    /* network mask matches? */
    if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
      /* return netif on which to forward IP packet */
      return netif;
    }
  }
  /* no matching netif found, use default netif */
  return netif_default;
}
/**
 * Updates the ARP table using the given IP packet.
 *
 * Uses the incoming IP packet's source address to update the
 * ARP cache for the local network. The function does not alter
 * or free the packet. This function must be called before the
 * packet p is passed to the IP layer.
 *
 * @param netif The lwIP network interface on which the IP packet pbuf arrived.
 * @param pbuf The IP packet that arrived on netif.
 *
 * @return NULL
 *
 * @see pbuf_free()
 */
void
etharp_ip_input(struct netif *netif, struct pbuf *p)
{
  struct ethip_hdr *hdr;
  LWIP_ASSERT("netif != NULL", netif != NULL);
  /* Only insert an entry if the source IP address of the
     incoming IP packet comes from a host on the local network. */
  hdr = p->payload;
  /* source is not on the local network? */
  if (!ip_addr_netcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {
    /* do nothing */
    return;
  }

  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
  /* update ARP table */
  /* @todo We could use ETHARP_TRY_HARD if we think we are going to talk
   * back soon (for example, if the destination IP address is ours. */
  update_arp_entry(netif, &(hdr->ip.src), &(hdr->eth.src), 0);
}
Пример #15
0
/**
 * Finds the appropriate network interface for a given IP address. It
 * searches the list of network interfaces linearly. A match is found
 * if the masked IP address of the network interface equals the masked
 * IP address given to the function.
 *
 * @param dest the destination IP address for which to find the route
 * @return the netif on which to send to reach dest
 */
struct netif *
ip_route(struct ip_addr *dest)
{
  struct netif *netif;

  /* iterate through netifs */
  for(netif = netif_list; netif != NULL; netif = netif->next) {
    /* network mask matches? */
    if (netif_is_up(netif)) {
      if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
        /* return netif on which to forward IP packet */
        return netif;
      }
    }
  }
  if ((netif_default == NULL) || (!netif_is_up(netif_default))) {
    LWIP_DEBUGF(IP_DEBUG | 2, ("ip_route: No route to 0x%"X32_F"\n", dest->addr));
    IP_STATS_INC(ip.rterr);
    snmp_inc_ipoutnoroutes();
    return NULL;
  }
  /* no matching netif found, use default netif */
  return netif_default;
}
Пример #16
0
/******************************************************************************
 * FunctionName : user_devicefind_recv
 * Description  : Processing the received data from the host
 * Parameters   : arg -- Additional argument to pass to the callback function
 *                pusrdata -- The received data (or NULL when the connection has been closed!)
 *                length -- The length of received data
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
user_devicefind_recv(void *arg, char *pusrdata, unsigned short length)
{
	os_printf("1-----------\n");
    char DeviceBuffer[40] = {0};
    char Device_mac_buffer[60] = {0};
    char hwaddr[6];
    remot_info *premot = NULL;
    struct ip_info ipconfig;

    if (wifi_get_opmode() != STATION_MODE) {
        wifi_get_ip_info(SOFTAP_IF, &ipconfig);
        wifi_get_macaddr(SOFTAP_IF, hwaddr);

        if (!ip_addr_netcmp((struct ip_addr *)ptrespconn.proto.udp->remote_ip, &ipconfig.ip, &ipconfig.netmask)) {
            wifi_get_ip_info(STATION_IF, &ipconfig);
            wifi_get_macaddr(STATION_IF, hwaddr);
        }
    } else {
        wifi_get_ip_info(STATION_IF, &ipconfig);
        wifi_get_macaddr(STATION_IF, hwaddr);
    }

    if (pusrdata == NULL) {
        return;
    }

    if (length == os_strlen(device_find_request) &&
            os_strncmp(pusrdata, device_find_request, os_strlen(device_find_request)) == 0) {
        os_sprintf(DeviceBuffer, "%s" MACSTR " " IPSTR, device_find_response_ok,
                   MAC2STR(hwaddr), IP2STR(&ipconfig.ip));

        os_printf("%s\n", DeviceBuffer);
        length = os_strlen(DeviceBuffer);
        if (espconn_get_connection_info(&ptrespconn, &premot, 0) != ESPCONN_OK)
        	return;
        os_memcpy(ptrespconn.proto.udp->remote_ip, premot->remote_ip, 4);
        ptrespconn.proto.udp->remote_port = premot->remote_port;
        espconn_sent(&ptrespconn, DeviceBuffer, length);
    } else if (length == (os_strlen(device_find_request) + 18)) {
        os_sprintf(Device_mac_buffer, "%s " MACSTR , device_find_request, MAC2STR(hwaddr));
        os_printf("%s", Device_mac_buffer);

        if (os_strncmp(Device_mac_buffer, pusrdata, os_strlen(device_find_request) + 18) == 0) {
            //os_printf("%s\n", Device_mac_buffer);
            length = os_strlen(DeviceBuffer);
            os_sprintf(DeviceBuffer, "%s" MACSTR " " IPSTR, device_find_response_ok,
                       MAC2STR(hwaddr), IP2STR(&ipconfig.ip));

            os_printf("%s\n", DeviceBuffer);
            length = os_strlen(DeviceBuffer);
			if (espconn_get_connection_info(&ptrespconn, &premot, 0) != ESPCONN_OK)
				return;
			os_memcpy(ptrespconn.proto.udp->remote_ip, premot->remote_ip, 4);
			ptrespconn.proto.udp->remote_port = premot->remote_port;
            espconn_sent(&ptrespconn, DeviceBuffer, length);
        } else {
            return;
        }
    }
}
Пример #17
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 {
/******************************************************************************
 * FunctionName : user_devicefind_recv
 * Description  : Processing the received data from the host
 * Parameters   : arg -- Additional argument to pass to the callback function
 *                pusrdata -- The received data (or NULL when the connection has been closed!)
 *                length -- The length of received data
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
user_devicefind_recv(void *arg, char *pusrdata, unsigned short length)
{
    char DeviceBuffer[40] = {0};
    char Device_mac_buffer[60] = {0};
    char hwaddr[6];

    struct ip_info ipconfig;

    if (wifi_get_opmode() != STATION_MODE) {
        wifi_get_ip_info(SOFTAP_IF, &ipconfig);
        wifi_get_macaddr(SOFTAP_IF, hwaddr);

        if (!ip_addr_netcmp((struct ip_addr *)ptrespconn.proto.udp->remote_ip, &ipconfig.ip, &ipconfig.netmask)) {
            wifi_get_ip_info(STATION_IF, &ipconfig);
            wifi_get_macaddr(STATION_IF, hwaddr);
        }
    } else {
        wifi_get_ip_info(STATION_IF, &ipconfig);
        wifi_get_macaddr(STATION_IF, hwaddr);
    }

    if (pusrdata == NULL) {
        return;
    }

    if (length == os_strlen(device_find_request) &&
        os_strncmp(pusrdata, device_find_request, os_strlen(device_find_request)) == 0) {
        length = os_sprintf(DeviceBuffer, "%s" MACSTR " " IPSTR, device_find_response_ok,
                   MAC2STR(hwaddr), IP2STR(&ipconfig.ip));

        DF_DBG("%s\n", DeviceBuffer);
        //length = os_strlen(DeviceBuffer);


        //==================================
        //This is add in sdk lib v1.4.0
        DF_DBG("--------DEBUG IN DEV----------\r\n");
        remote_info* pcon_info = NULL;
        DF_DBG("link num: %d \r\n",ptrespconn.link_cnt);
        espconn_get_connection_info(&ptrespconn, &pcon_info, 0);
        DF_DBG("remote ip: %d.%d.%d.%d \r\n",pcon_info->remote_ip[0],pcon_info->remote_ip[1],
                                                pcon_info->remote_ip[2],pcon_info->remote_ip[3]);
        DF_DBG("remote port: %d \r\n",pcon_info->remote_port);
        //=================================
        ptrespconn.proto.udp->remote_port = pcon_info->remote_port;
        os_memcpy(ptrespconn.proto.udp->remote_ip,pcon_info->remote_ip,4);
        espconn_sendto(&ptrespconn, DeviceBuffer, length);
    } else if (length == (os_strlen(device_find_request) + 18)) {
        os_sprintf(Device_mac_buffer, "%s " MACSTR , device_find_request, MAC2STR(hwaddr));
        DF_DBG("%s", Device_mac_buffer);

        if (os_strncmp(Device_mac_buffer, pusrdata, os_strlen(device_find_request) + 18) == 0) {
            length = os_sprintf(DeviceBuffer, "%s" MACSTR " " IPSTR, device_find_response_ok,MAC2STR(hwaddr), IP2STR(&ipconfig.ip));
            DF_DBG("%s\n", DeviceBuffer);
            espconn_sendto(&ptrespconn, DeviceBuffer, length);
        } else {
            return;
        }
    }
}
/**
 * Resolve and fill-in Ethernet address header for outgoing packet.
 *
 * For IP multicast and broadcast, corresponding Ethernet addresses
 * are selected and the packet is transmitted on the link.
 *
 * For unicast addresses, the packet is submitted to etharp_query(). In
 * case the IP address is outside the local network, the IP address of
 * the gateway is used.
 *
 * @param netif The lwIP network interface which the IP packet will be sent on.
 * @param ipaddr The IP address of the packet destination.
 * @param pbuf The pbuf(s) containing the IP packet to be sent.
 *
 * @return
 * - ERR_RTE No route to destination (no gateway to external networks),
 * or the return type of either etharp_query() or netif->linkoutput().
 */
err_t
etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
{
  struct eth_addr *dest, *srcaddr, mcastaddr;
  struct eth_hdr *ethhdr;
  u8_t i;

  /* make room for Ethernet header - should not fail */
  if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
    /* bail out */
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n"));
    LINK_STATS_INC(link.lenerr);
    return ERR_BUF;
  }

  /* assume unresolved Ethernet address */
  dest = NULL;
  /* Determine on destination hardware address. Broadcasts and multicasts
   * are special, other IP addresses are looked up in the ARP table. */

  /* broadcast destination IP address? */
  if (ip_addr_isbroadcast(ipaddr, netif)) {
    /* broadcast on Ethernet also */
    dest = (struct eth_addr *)&ethbroadcast;
  /* multicast destination IP address? */
  } else if (ip_addr_ismulticast(ipaddr)) {
    /* Hash IP multicast address to MAC address.*/
    mcastaddr.addr[0] = 0x01;
    mcastaddr.addr[1] = 0x00;
    mcastaddr.addr[2] = 0x5e;
    mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
    mcastaddr.addr[4] = ip4_addr3(ipaddr);
    mcastaddr.addr[5] = ip4_addr4(ipaddr);
    /* destination Ethernet address is multicast */
    dest = &mcastaddr;
  /* unicast destination IP address? */
  } else {
    /* outside local network? */
    if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
      /* interface has default gateway? */
      if (netif->gw.addr != 0) {
        /* send to hardware address of default gateway IP address */
        ipaddr = &(netif->gw);
      /* no default gateway available */
      } else {
        /* no route to destination error (default gateway missing) */
        return ERR_RTE;
      }
    }
    /* queue on destination Ethernet address belonging to ipaddr */
    return etharp_query(netif, ipaddr, q);
  }

  /* continuation for multicast/broadcast destinations */
  /* obtain source Ethernet address of the given interface */
  srcaddr = (struct eth_addr *)netif->hwaddr;
  ethhdr = q->payload;
  for (i = 0; i < netif->hwaddr_len; i++) {
    ethhdr->dest.addr[i] = dest->addr[i];
    ethhdr->src.addr[i] = srcaddr->addr[i];
  }
  ethhdr->type = htons(ETHTYPE_IP);
  /* send packet directly on the link */
  return netif->linkoutput(netif, q);
}
/******************************************************************************
 * FunctionName : user_devicefind_data_process
 * Description  : Processing the received data from the host
 * Parameters   : arg -- Additional argument to pass to the callback function
 *                pusrdata -- The received data (or NULL when the connection has been closed!)
 *                length -- The length of received data
 * Returns      : none
*******************************************************************************/
LOCAL void  
user_devicefind_data_process(char *pusrdata, unsigned short length, struct sockaddr_in *premote_addr)
{
    char *DeviceBuffer;//40
    char *Device_mac_buffer;//60
    char hwaddr[6];
    int   len;
    
    struct ip_info ipconfig;
    struct ip_info ipconfig_r;
    
    if (pusrdata == NULL) {
        return;
    }

    if (wifi_get_opmode() != STATION_MODE) {
        
        wifi_get_ip_info(SOFTAP_IF, &ipconfig);
        wifi_get_macaddr(SOFTAP_IF, hwaddr);
        
        inet_addr_to_ipaddr(&ipconfig_r.ip,&premote_addr->sin_addr);
        if(!ip_addr_netcmp(&ipconfig_r.ip, &ipconfig.ip, &ipconfig.netmask)) {
            //printf("udpclient connect with sta\n");
            wifi_get_ip_info(STATION_IF, &ipconfig);
            wifi_get_macaddr(STATION_IF, hwaddr);
        }
    } else {
        wifi_get_ip_info(STATION_IF, &ipconfig);
        wifi_get_macaddr(STATION_IF, hwaddr);
    }
    
    //DF_DEBUG("%s\n", pusrdata);
    DeviceBuffer = (char*)malloc(len_ip_rsp);
    memset(DeviceBuffer, 0, len_ip_rsp);

    if (length == strlen(device_find_request) &&
        strncmp(pusrdata, device_find_request, strlen(device_find_request)) == 0) {
        sprintf(DeviceBuffer, "%s" MACSTR " " IPSTR, device_find_response_ok,
               MAC2STR(hwaddr), IP2STR(&ipconfig.ip));

        length = strlen(DeviceBuffer);
        DF_DEBUG("%s %d\n", DeviceBuffer,length);

        sendto(sock_fd,DeviceBuffer, length, 0, (struct sockaddr *)premote_addr, sizeof(struct sockaddr_in));
        
    } else if (length == (strlen(device_find_request) + 18)) {
    
        Device_mac_buffer = (char*)malloc(len_mac_msg);
        memset(Device_mac_buffer, 0, len_mac_msg);
        sprintf(Device_mac_buffer, "%s " MACSTR , device_find_request, MAC2STR(hwaddr));
        
        if (strncmp(Device_mac_buffer, pusrdata, strlen(device_find_request) + 18) == 0){

            sprintf(DeviceBuffer, "%s" MACSTR " " IPSTR, device_find_response_ok,
                       MAC2STR(hwaddr), IP2STR(&ipconfig.ip));

            length = strlen(DeviceBuffer);
            DF_DEBUG("%s %d\n", DeviceBuffer,length);
            
            sendto(sock_fd,DeviceBuffer, length, 0, (struct sockaddr *)premote_addr, sizeof(struct sockaddr_in));
        } 

        if(Device_mac_buffer)free(Device_mac_buffer);
    }

    if(DeviceBuffer)free(DeviceBuffer);
    
}
Пример #21
0
void LLMNRResponder::_process_packet() {
    if (!_conn || !_conn->next())
        return;

#ifdef LLMNR_DEBUG
    Serial.println("LLMNR: RX'd packet");
#endif

    uint16_t id = _conn_read16();
    uint16_t flags = _conn_read16();
    uint16_t qdcount = _conn_read16();
    uint16_t ancount = _conn_read16();
    uint16_t nscount = _conn_read16();
    uint16_t arcount = _conn_read16();

#ifdef LLMNR_DEBUG
    Serial.print("LLMNR: ID=");
    Serial.println(id, HEX);
    Serial.print("LLMNR: FLAGS=");
    Serial.println(flags, HEX);
    Serial.print("LLMNR: QDCOUNT=");
    Serial.println(qdcount);
    Serial.print("LLMNR: ANCOUNT=");
    Serial.println(ancount);
    Serial.print("LLMNR: NSCOUNT=");
    Serial.println(nscount);
    Serial.print("LLMNR: ARCOUNT=");
    Serial.println(arcount);
#endif

#define BAD_FLAGS (FLAGS_QR | (FLAGS_OP_MASK << FLAGS_OP_SHIFT) | FLAGS_C)
    if (flags & BAD_FLAGS) {
#ifdef LLMNR_DEBUG
        Serial.println("Bad flags");
#endif
        return;
    }

    if (qdcount != 1) {
#ifdef LLMNR_DEBUG
        Serial.println("QDCOUNT != 1");
#endif
        return;
    }

    if (ancount || nscount || arcount) {
#ifdef LLMNR_DEBUG
        Serial.println("AN/NS/AR-COUNT != 0");
#endif
        return;
    }

    uint8_t namelen = _conn_read8();
#ifdef LLMNR_DEBUG
    Serial.print("QNAME len ");
    Serial.println(namelen);
#endif
    if (namelen != _hostname.length()) {
#ifdef LLMNR_DEBUG
        Serial.println("QNAME len mismatch");
#endif
        return;
    }

    char qname[64];
    _conn_readS(qname, namelen);
    _conn_read8();
    qname[namelen] = '\0';
#ifdef LLMNR_DEBUG
    Serial.print("QNAME ");
    Serial.println(qname);
#endif

    if (strcmp(_hostname.c_str(), qname)) {
#ifdef LLMNR_DEBUG
        Serial.println("QNAME mismatch");
#endif
        return;
    }

    uint16_t qtype = _conn_read16();
    uint16_t qclass = _conn_read16();

#ifdef LLMNR_DEBUG
    Serial.print("QTYPE ");
    Serial.print(qtype);
    Serial.print(" QCLASS ");
    Serial.println(qclass);
#endif

    bool have_rr =
        (qtype == 1) && /* A */
        (qclass == 1); /* IN */

    _conn->flush();

#ifdef LLMNR_DEBUG
    Serial.println("Match; responding");
    if (!have_rr)
        Serial.println("(no matching RRs)");
#endif

    ip_addr_t remote_ip;
    remote_ip.addr = _conn->getRemoteAddress();

    struct ip_info ip_info;
    bool match_ap = false;
    if (wifi_get_opmode() & SOFTAP_MODE) {
        wifi_get_ip_info(SOFTAP_IF, &ip_info);
    if (ip_info.ip.addr && ip_addr_netcmp(&remote_ip, &ip_info.ip, &ip_info.netmask))
        match_ap = true;
    }
    if (!match_ap)
        wifi_get_ip_info(STATION_IF, &ip_info);
    uint32_t ip = ip_info.ip.addr;

    // Header
    uint8_t header[] = {
        id >> 8, id & 0xff, // ID
        FLAGS_QR >> 8, 0, // FLAGS
        0, 1, // QDCOUNT
        0, !!have_rr, // ANCOUNT
        0, 0, // NSCOUNT
        0, 0, // ARCOUNT
    };
    _conn->append(reinterpret_cast<const char*>(header), sizeof(header));
    // Question
    _conn->append(reinterpret_cast<const char*>(&namelen), 1);
    _conn->append(qname, namelen);
    uint8_t q[] = {
        0, // Name terminator
        0, 1, // TYPE (A)
        0, 1, // CLASS (IN)
    };
    _conn->append(reinterpret_cast<const char*>(q), sizeof(q));
    // Answer, if we have one
    if (have_rr) {
        _conn->append(reinterpret_cast<const char*>(&namelen), 1);
        _conn->append(qname, namelen);
        uint8_t rr[] = {
            0, // Name terminator
            0, 1, // TYPE (A)
            0, 1, // CLASS (IN)
            0, 0, 0, 30, // TTL (30 seconds)
            0, 4, // RDLENGTH
            ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff, // RDATA
        };
        _conn->append(reinterpret_cast<const char*>(rr), sizeof(rr));
    }
    _conn->setMulticastInterface(remote_ip);
    _conn->send(&remote_ip, _conn->getRemotePort());
}
Пример #22
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 
espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p,
                 const ip_addr_t *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, (char*)pdata, length);
                }
            }

            q = q->next;
            os_free(pdata);
        }

        pbuf_free(p);
    } else {
        return;
    }
}