Beispiel #1
0
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);
}
Beispiel #2
0
/**
 * 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;
    }
}