static void pxdns_recv4(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) { struct pxdns *pxdns = (struct pxdns *)arg; pxdns_query(pxdns, pcb, p, ip_2_ipX(addr), port); }
/** * 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 ICACHE_FLASH_ATTR raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) { err_t err; struct netif *netif; ipX_addr_t *src_ip; struct pbuf *q; /* q will be sent down the stack */ s16_t header_size; ipX_addr_t *dst_ip = ip_2_ipX(ipaddr); LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n")); header_size = ( #if LWIP_IPV6 PCB_ISIPV6(pcb) ? IP6_HLEN : #endif /* LWIP_IPV6 */ IP_HLEN); /* not enough space to add an IP header to first pbuf in given p chain? */ if (pbuf_header(p, header_size)) { /* 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; } if (p->tot_len != 0) { /* 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, -header_size)) { LWIP_ASSERT("Can't restore header we just removed!", 0); return ERR_MEM; } } netif = ipX_route(PCB_ISIPV6(pcb), &pcb->local_ip, dst_ip); if (netif == NULL) { LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to ")); ipX_addr_debug_print(PCB_ISIPV6(pcb), RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, dst_ip); /* free any temporary header pbuf allocated by pbuf_header() */ if (q != p) { pbuf_free(q); } return ERR_RTE; } #if IP_SOF_BROADCAST #if LWIP_IPV6 /* @todo: why does IPv6 not filter broadcast with SOF_BROADCAST enabled? */ if (!PCB_ISIPV6(pcb)) #endif /* LWIP_IPV6 */ { /* broadcast filter? */ if (!ip_get_option(pcb, SOF_BROADCAST) && 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 (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->local_ip)) { /* use outgoing network interface IP address as source address */ src_ip = ipX_netif_get_local_ipX(PCB_ISIPV6(pcb), netif, dst_ip); #if LWIP_IPV6 if (src_ip == NULL) { if (q != p) { pbuf_free(q); } return ERR_RTE; } #endif /* LWIP_IPV6 */ } else { /* use RAW PCB local IP address as source address */ src_ip = &pcb->local_ip; } NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); err = ipX_output_if(PCB_ISIPV6(pcb), q, ipX_2_ip(src_ip), ipX_2_ip(dst_ip), pcb->ttl, pcb->tos, pcb->protocol, netif); NETIF_SET_HWADDRHINT(netif, NULL); /* did we chain a header earlier? */ if (q != p) { /* free the header */ pbuf_free(q); } return err; }
/****************************************************************************** * FunctionName : espconn_udp_sendto * Description : sent data for UDP * Parameters : void *arg -- UDP to send * uint8* psent -- Data to send * uint16 length -- Length of data to send * Returns : return espconn error code. * - ESPCONN_OK. Successful. No error occured. * - ESPCONN_MEM. Out of memory. * - ESPCONN_RTE. Could not find route to destination address. * - More errors could be returned by lower protocol layers. *******************************************************************************/ err_t ICACHE_FLASH_ATTR espconn_udp_sendto(void* arg, uint8* psent, uint16 length) { espconn_msg* pudp_sent = arg; struct udp_pcb* upcb = pudp_sent->pcommon.pcb; struct espconn* pespconn = pudp_sent->pespconn; struct pbuf* p, *q , *p_temp; struct ip_addr dst_ip; u16_t dst_port; u8_t* data = NULL; u16_t cnt = 0; u16_t datalen = 0; u16_t i = 0; err_t err; LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d %p\n", __LINE__, length, upcb)); if (pudp_sent == NULL || upcb == NULL || psent == NULL || length == 0) { return ESPCONN_ARG; } if ((IP_MAX_MTU - 20 - 8) < length) { datalen = IP_MAX_MTU - 20 - 8; } else { datalen = length; } p = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p)); if (p != NULL) { q = p; while (q != NULL) { data = (u8_t*)q->payload; LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, data)); for (i = 0; i < q->len; i++) { data[i] = ((u8_t*) psent)[cnt++]; } q = q->next; } } else { return ESPCONN_MEM; } dst_port = pespconn->proto.udp->remote_port; IP4_ADDR(&dst_ip, pespconn->proto.udp->remote_ip[0], pespconn->proto.udp->remote_ip[1], pespconn->proto.udp->remote_ip[2], pespconn->proto.udp->remote_ip[3]); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %x %d\n", __LINE__, upcb->remote_ip, upcb->remote_port)); #if LWIP_IPV6 || LWIP_IGMP ipX_addr_t* dst_ip_route = ip_2_ipX(&dst_ip); if (ipX_addr_ismulticast(PCB_ISIPV6(upcb), dst_ip_route)) { /* For multicast, find a netif based on source address. */ #if LWIP_IPV6 if (PCB_ISIPV6(upcb)) { dst_ip_route = &upcb->local_ip; } else #endif /* LWIP_IPV6 */ { #if LWIP_IGMP upcb->multicast_ip.addr = dst_ip.addr; #endif /* LWIP_IGMP */ } } #endif /* LWIP_IPV6 || LWIP_IGMP */ struct netif* sta_netif = (struct netif*)eagle_lwip_getif(0x00); struct netif* ap_netif = (struct netif*)eagle_lwip_getif(0x01); if (wifi_get_opmode() == ESPCONN_AP_STA && default_interface == ESPCONN_AP_STA && sta_netif != NULL && ap_netif != NULL) { if (netif_is_up(sta_netif) && netif_is_up(ap_netif) && \ ip_addr_isbroadcast(&(upcb->remote_ip.ip4), sta_netif) && \ ip_addr_isbroadcast(&(upcb->remote_ip.ip4), ap_netif)) { p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); if (pbuf_copy(p_temp, p) != ERR_OK) { LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sendto: copying to new pbuf failed\n")); return ESPCONN_ARG; } netif_set_default(sta_netif); err = udp_sendto(upcb, p_temp, &dst_ip, dst_port); pbuf_free(p_temp); netif_set_default(ap_netif); } } err = udp_sendto(upcb, p, &dst_ip, dst_port); if (p->ref != 0) { pbuf_free(p); pudp_sent->pcommon.ptrbuf = psent + datalen; pudp_sent->pcommon.cntr = length - datalen; pudp_sent->pcommon.err = err; espconn_data_sent(pudp_sent, ESPCONN_SENDTO); if (err > 0) { return ESPCONN_IF; } return err; } else { pbuf_free(p); return ESPCONN_RTE; } }