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; }
/********************************************************************************************************* ** 函数名称: __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); } } }
/********************************************************************************************************* ** 函数名称: __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); }
/** * 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; }
/** * 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; } }
/** * 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; }
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; }
/****************************************************************************** * 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; } }
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 } }
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); }
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; }
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); }
/** * 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; }
/****************************************************************************** * 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; } } }
/** * 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(¤t_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), ¤t_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), ¤t_iphdr_dest) || #if LWIP_IGMP ip_addr_ismulticast(¤t_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), ¤t_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, ¤t_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, ¤t_iphdr_src, ¤t_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(¤t_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), ¤t_iphdr_dest) || #if LWIP_IGMP ip_addr_ismulticast(¤t_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 *)ðbroadcast; /* 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); }
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()); }
/****************************************************************************** * 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; } }