Beispiel #1
0
END_TEST

START_TEST(test_pbuf_queueing_bigger_than_64k)
{
  int i;
  err_t err;
  struct pbuf *p1, *p2, *p3, *rest2=NULL, *rest3=NULL;
  LWIP_UNUSED_ARG(_i);

  for(i = 0; i < TESTBUFSIZE_1; i++) {
    testbuf_1[i] = (u8_t)rand();
  }
  for(i = 0; i < TESTBUFSIZE_2; i++) {
    testbuf_2[i] = (u8_t)rand();
  }
  for(i = 0; i < TESTBUFSIZE_3; i++) {
    testbuf_3[i] = (u8_t)rand();
  }

  p1 = pbuf_alloc(PBUF_RAW, TESTBUFSIZE_1, PBUF_POOL);
  fail_unless(p1 != NULL);
  p2 = pbuf_alloc(PBUF_RAW, TESTBUFSIZE_2, PBUF_POOL);
  fail_unless(p2 != NULL);
  p3 = pbuf_alloc(PBUF_RAW, TESTBUFSIZE_3, PBUF_POOL);
  fail_unless(p3 != NULL);
  err = pbuf_take(p1, testbuf_1, TESTBUFSIZE_1);
  fail_unless(err == ERR_OK);
  err = pbuf_take(p2, testbuf_2, TESTBUFSIZE_2);
  fail_unless(err == ERR_OK);
  err = pbuf_take(p3, testbuf_3, TESTBUFSIZE_3);
  fail_unless(err == ERR_OK);

  pbuf_cat(p1, p2);
  pbuf_cat(p1, p3);

  pbuf_split_64k(p1, &rest2);
  fail_unless(p1->tot_len == TESTBUFSIZE_1);
  fail_unless(rest2->tot_len == (u16_t)((TESTBUFSIZE_2+TESTBUFSIZE_3) & 0xFFFF));
  pbuf_split_64k(rest2, &rest3);
  fail_unless(rest2->tot_len == TESTBUFSIZE_2);
  fail_unless(rest3->tot_len == TESTBUFSIZE_3);

  pbuf_copy_partial(p1, testbuf_1a, TESTBUFSIZE_1, 0);
  pbuf_copy_partial(rest2, testbuf_2a, TESTBUFSIZE_2, 0);
  pbuf_copy_partial(rest3, testbuf_3a, TESTBUFSIZE_3, 0);
  for(i = 0; i < TESTBUFSIZE_1; i++)
    fail_unless(testbuf_1[i] == testbuf_1a[i]);
  for(i = 0; i < TESTBUFSIZE_2; i++)
    fail_unless(testbuf_2[i] == testbuf_2a[i]);
  for(i = 0; i < TESTBUFSIZE_3; i++)
    fail_unless(testbuf_3[i] == testbuf_3a[i]);

  pbuf_free(p1);
  pbuf_free(rest2);
  pbuf_free(rest3);
}
Beispiel #2
0
void insert_pBuf(struct pbuf* q, uint8_t sock, void* _pcb)
{
	if (q == NULL)
		return;

	if (pBufStore[headBuf][sock].data != NULL)
	{
		WARN("Overwriting buffer %p idx:%d!\n", pBufStore[headBuf][sock].data, headBuf);
		// to avoid memory leak free the oldest buffer
		freetDataIdx(headBuf, sock);
	}

	u8_t* p = (u8_t*)calloc(q->tot_len,sizeof(u8_t));
    if(p != NULL) {
      if (pbuf_copy_partial(q, p, q->tot_len,0) != q->tot_len) {
    	  WARN("pbuf_copy_partial failed: src:%p, dst:%p, len:%d\n", q, p, q->tot_len);
    	  free(p);
    	  p = NULL;
    	  return;
      }

      pBufStore[headBuf][sock].data = p;
      pBufStore[headBuf][sock].len = q->tot_len;
      pBufStore[headBuf][sock].idx = 0;
      pBufStore[headBuf][sock].pcb = _pcb;
      headBuf++;

  	  if (headBuf == MAX_PBUF_STORED)
  		headBuf = 0;
  	  if (headBuf == tailBuf)
  		  WARN("Overwriting data [%d-%d]!\n", headBuf, tailBuf);
  	  INFO_UTIL("Insert: %p:%d-%d [%d,%d]\n", p, q->tot_len, p[0], headBuf, tailBuf);
    }
}
Beispiel #3
0
int ssl_socket_recv(void *ctx, unsigned char *buf, size_t len) {
  struct mg_connection *nc = (struct mg_connection *) ctx;
  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
  struct pbuf *seg = cs->rx_chain;
  if (seg == NULL) {
    DBG(("%u - nothing to read", len));
    return MBEDTLS_ERR_SSL_WANT_READ;
  }
  size_t seg_len = (seg->len - cs->rx_offset);
  DBG(("%u %u %u %u", len, cs->rx_chain->len, seg_len, cs->rx_chain->tot_len));
  mgos_lock();
  len = MIN(len, seg_len);
  pbuf_copy_partial(seg, buf, len, cs->rx_offset);
  cs->rx_offset += len;
  /* TCP PCB may be NULL if connection has already been closed
   * but we still have data to deliver to SSL. */
  if (cs->pcb.tcp != NULL) tcp_recved(cs->pcb.tcp, len);
  if (cs->rx_offset == cs->rx_chain->len) {
    cs->rx_chain = pbuf_dechain(cs->rx_chain);
    pbuf_free(seg);
    cs->rx_offset = 0;
  }
  mgos_unlock();
  LOG(LL_DEBUG, ("%p <- %d", nc, (int) len));
  return len;
}
Beispiel #4
0
/* Copy out all the pbufs in a chain into a string, and ack/free pbuf.
 * @return 0: nothing, -1: closed connection, +n: bytes read
 */
CAMLprim value
caml_tcp_read(value v_tw)
{
    CAMLparam1(v_tw);
    CAMLlocal1(v_str);
    /* Not using tcp_wrap_of_value as we need to clear out the remaining
       RX queue before raising the Connection_closed exception. Check that
       tw->pcb is set for the rest of the function before using it. */
    tcp_wrap *tw = Tcp_wrap_val(v_tw);
    struct pbuf_list *pl = tw->desc->rx;
    unsigned int tot_len;
    char *s;

    LWIP_STUB_DPRINTF("caml_tcp_rx_read");
    if (!pl) {
        v_str = caml_alloc_string(0);
        CAMLreturn(v_str);
    }

    tot_len = pbuf_list_length(pl);
    v_str = caml_alloc_string(tot_len);
    s = String_val(v_str);
    do {
        pbuf_copy_partial(pl->p, s, pl->p->tot_len, 0);
        s += pl->p->tot_len;
    } while ((pl = pl->next));
    if (tw->pcb)
        tcp_recved(tw->pcb, tot_len);
    pbuf_list_free(tw->desc->rx);
    tw->desc->rx = NULL;
    CAMLreturn(v_str);   
}
Beispiel #5
0
void ol_tcp_animate(outlet_t *new_ol, struct tcp_pcb *pcb, struct pbuf *ante)
{
	//
	// lwIP tries hard to allocate a new PCB. If there is not enough memory it
	// first kills TIME-WAIT connections and then active connections. The
	// error_cb callback is used along the way. The callback may sent an exit
	// signal to an outlet and the chain of exit signal may reach the current
	// outlet. To avoid this the priority of all PCBs is set to TCP_PRIO_MAX+1.
	//

	tcp_setprio(pcb, TCP_PRIO_MAX +1);

	tcp_arg(pcb, new_ol);	// callback arg
	tcp_recv(pcb, recv_cb);
	tcp_sent(pcb, sent_cb);
	tcp_err(pcb, error_cb);

	new_ol->tcp = pcb;
	if (ante != 0)	// data receive while enqueued
	{
		uint16_t len = ante->tot_len;
		if (len > new_ol->recv_bufsize)
		{
			debug("ol_tcp_animate: tot_len=%d, recv_bufsize=%d, truncating\n",
				  ante->tot_len, new_ol->recv_bufsize);
			len = new_ol->recv_bufsize;	
		}
		pbuf_copy_partial(ante, new_ol->recv_buffer, len, 0);
		new_ol->recv_buf_off = len;
		pbuf_free(ante);
	}
}
Beispiel #6
0
err_t TcpClient::onReceive(pbuf *buf)
{
	if (buf == NULL)
	{
		// Disconnected, close it
		TcpConnection::onReceive(buf);
	}
	else
	{
		if (receive)
		{
			char* data = new char[buf->tot_len + 1];
			pbuf_copy_partial(buf, data, buf->tot_len, 0);
			data[buf->tot_len] = '\0';

			if (!receive(*this, data, buf->tot_len))
			{
				delete[] data;
				return ERR_MEM;
			}

			delete[] data;
		}

		// Fire ReadyToSend callback
		TcpConnection::onReceive(buf);
	}

	return ERR_OK;
}
Beispiel #7
0
/** Wait for all headers to be received, return its length and content-length (if available) */
static err_t
http_wait_headers(struct pbuf *p, u32_t *content_length, u16_t *total_header_len)
{
  u16_t end1 = pbuf_memfind(p, "\r\n\r\n", 4, 0);
  if (end1 < (0xFFFF - 2)) {
    /* all headers received */
    /* check if we have a content length (@todo: case insensitive?) */
    u16_t content_len_hdr;
    *content_length = HTTPC_CONTENT_LEN_INVALID;
    *total_header_len = end1 + 4;

    content_len_hdr = pbuf_memfind(p, "Content-Length: ", 16, 0);
    if (content_len_hdr != 0xFFFF) {
      u16_t content_len_line_end = pbuf_memfind(p, "\r\n", 2, content_len_hdr);
      if (content_len_line_end != 0xFFFF) {
        char content_len_num[16];
        u16_t content_len_num_len = (u16_t)(content_len_line_end - content_len_hdr - 16);
        memset(content_len_num, 0, sizeof(content_len_num));
        if (pbuf_copy_partial(p, content_len_num, content_len_num_len, content_len_hdr + 16) == content_len_num_len) {
          int len = atoi(content_len_num);
          if ((len >= 0) && ((u32_t)len < HTTPC_CONTENT_LEN_INVALID)) {
            *content_length = (u32_t)len;
          }
        }
      }
    }
    return ERR_OK;
  }
  return ERR_VAL;
}
static err_t mg_lwip_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb,
                                 struct pbuf *p, err_t err) {
  struct mg_connection *nc = (struct mg_connection *) arg;
  char *data;
  size_t len = (p != NULL ? p->len : 0);
  DBG(("%p %u %d", nc, len, err));
  if (nc == NULL) {
    tcp_abort(tpcb);
    return ERR_ARG;
  }
  if (p == NULL) {
    system_os_post(MG_TASK_PRIORITY, MG_SIG_CLOSE_CONN, (uint32_t) nc);
    return ERR_OK;
  }
  data = (char *) malloc(len);
  if (data == NULL) {
    DBG(("OOM"));
    return ERR_MEM;
  }
  pbuf_copy_partial(p, data, len, 0);
  pbuf_free(p);
  mg_if_recv_tcp_cb(nc, data, len);
  if (nc->send_mbuf.len > 0) {
    mg_lwip_mgr_schedule_poll(nc->mgr);
  }
  return ERR_OK;
}
Beispiel #9
0
char* NetUtils::pbufAllocateStrCopy(pbuf *buf, int startPos, int length)
{
    char* stringPtr = new char[length + 1];
    stringPtr[length] = '\0';
    pbuf_copy_partial(buf, stringPtr, length, startPos);
    return stringPtr;
}
Beispiel #10
0
void NtpClient::onReceive(pbuf *buf, IPAddress remoteIP, uint16_t remotePort)
{
	// We do some basic check to see if it really is a ntp packet we receive.
	// NTP version should be set to same as we used to send, NTP_VERSION
	// Mode should be set to NTP_MODE_SERVER

	if (onCompleted != NULL)
	{
		uint8_t versionMode = pbuf_get_at(buf, 0);
		uint8_t ver = (versionMode & 0b00111000) >> 3;
		uint8_t mode = (versionMode & 0x07);

		if (mode == NTP_MODE_SERVER && ver == NTP_VERSION)
		{
			//Most likely a correct NTP packet received.

			uint8_t data[4];
			pbuf_copy_partial(buf, data, 4, 40); // Copy only timestamp.

			uint32_t timestamp = (data[0] << 24 | data[1] << 16 | data[2] << 8
					| data[3]);

			// Unix time starts on Jan 1 1970, subtract 70 years:
			uint32_t epoch = timestamp - 0x83AA7E80;

			this->onCompleted(*this, epoch);
		}
	}
Beispiel #11
0
void NtpClient::onReceive(pbuf *buf, IPAddress remoteIP, uint16_t remotePort)
{
    // We do some basic check to see if it really is a ntp packet we receive.
    // NTP version should be set to same as we used to send, NTP_VERSION
    // NTP_VERSION 3 has time in same location so accept that too
    // Mode should be set to NTP_MODE_SERVER

    uint8_t versionMode = pbuf_get_at(buf, 0);
    uint8_t ver = (versionMode & 0b00111000) >> 3;
    uint8_t mode = (versionMode & 0x07);

    if (mode == NTP_MODE_SERVER && (ver == NTP_VERSION || ver == (NTP_VERSION -1)))
    {
        //Most likely a correct NTP packet received.

        uint8_t data[4];
        pbuf_copy_partial(buf, data, 4, 40); // Copy only timestamp.

        uint32_t timestamp = (data[0] << 24 | data[1] << 16 | data[2] << 8
                              | data[3]);

        // Unix time starts on Jan 1 1970, subtract 70 years:
        uint32_t epoch = timestamp - 0x83AA7E80;

        if (autoUpdateSystemClock)
        {
            SystemClock.setTime(epoch, eTZ_UTC); // update systemclock utc value
        }

        if (delegateCompleted)
        {
            this->delegateCompleted(*this, epoch);
        }
    }
}
Beispiel #12
0
// Helper function for recv/recvfrom to handle UDP packets
STATIC mp_uint_t lwip_udp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) {

    if (socket->incoming == NULL) {
        if (socket->timeout != -1) {
            for (mp_uint_t retries = socket->timeout / 100; retries--;) {
                mp_hal_delay_ms(100);
                if (socket->incoming != NULL) break;
            }
            if (socket->incoming == NULL) {
                *_errno = ETIMEDOUT;
                return -1;
            }
        } else {
            while (socket->incoming == NULL) {
                mp_hal_delay_ms(100);
            }
        }
    }

    if (ip != NULL) {
        memcpy(ip, &socket->peer, 4);
        *port = socket->peer_port;
    }

    struct pbuf *p = (struct pbuf*)socket->incoming;

    u16_t result = pbuf_copy_partial(p, buf, ((p->tot_len > len) ? len : p->tot_len), 0);
    pbuf_free(p);
    socket->incoming = NULL;

    return (mp_uint_t) result;
}
Beispiel #13
0
/*
 * Some browsers use a hybrid SSLv2 "client hello"
 */
int process_sslv23_client_hello(SSL *ssl) {
	uint8_t *buf = ssl->bm_data;
	int bytes_needed = ((buf[0] & 0x7f) << 8) + buf[1];
	int ret = SSL_OK;

	/* we have already read 3 extra bytes so far */
//    int read_len = SOCKET_READ(ssl->client_fd, buf, bytes_needed-3);
	int read_len = pbuf_copy_partial(ssl->ssl_pbuf, buf, bytes_needed - 3, 0);
	int cs_len = buf[1];
	int id_len = buf[3];
	int ch_len = buf[5];
	int i, j, offset = 8;   /* start at first cipher */
	int random_offset = 0;

	DISPLAY_BYTES(ssl, "received %d bytes", buf, read_len, read_len);

	add_packet(ssl, buf, read_len);

	/* connection has gone, so die */
	if (bytes_needed < 0) {
		return SSL_ERROR_CONN_LOST;
	}

	/* now work out what cipher suite we are going to use */
	for (j = 0; j < NUM_PROTOCOLS; j++) {
		for (i = 0; i < cs_len; i += 3) {
			if (ssl_prot_prefs[j] == buf[offset + i]) {
				ssl->cipher = ssl_prot_prefs[j];
				goto server_hello;
			}
		}
	}

	/* ouch! protocol is not supported */
	ret = SSL_ERROR_NO_CIPHER;
	goto error;

server_hello:
	/* get the session id */
	offset += cs_len - 2;   /* we've gone 2 bytes past the end */
#ifndef CONFIG_SSL_SKELETON_MODE
	ssl->session = ssl_session_update(ssl->ssl_ctx->num_sessions,
									  ssl->ssl_ctx->ssl_sessions, ssl, id_len ? &buf[offset] : NULL);
#endif

	/* get the client random data */
	offset += id_len;

	/* random can be anywhere between 16 and 32 bytes long - so it is padded
	 * with 0's to the left */
	if (ch_len == 0x10) {
		random_offset += 0x10;
	}

	memcpy(&ssl->dc->client_random[random_offset], &buf[offset], ch_len);
	ret = send_server_hello_sequence(ssl);

error:
	return ret;
}
Beispiel #14
0
String NetUtils::pbufStrCopy(pbuf *buf, int startPos, int length)
{
    char* stringPtr = new char[length + 1];
    stringPtr[length] = '\0';
    pbuf_copy_partial(buf, stringPtr, length, startPos);
    String res = String(stringPtr);
    delete[] stringPtr;
    return res;
}
Beispiel #15
0
// Helper function for recv/recvfrom to handle TCP packets
STATIC mp_uint_t lwip_tcp_receive(lwip_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) {
    // Check for any pending errors
    STREAM_ERROR_CHECK(socket);

    if (socket->incoming.pbuf == NULL) {

        // Non-blocking socket
        if (socket->timeout == 0) {
            if (socket->state == STATE_PEER_CLOSED) {
                return 0;
            }
            *_errno = MP_EAGAIN;
            return -1;
        }

        mp_uint_t start = mp_hal_ticks_ms();
        while (socket->state == STATE_CONNECTED && socket->incoming.pbuf == NULL) {
            if (socket->timeout != -1 && mp_hal_ticks_ms() - start > socket->timeout) {
                *_errno = MP_ETIMEDOUT;
                return -1;
            }
            poll_sockets();
        }

        if (socket->state == STATE_PEER_CLOSED) {
            if (socket->incoming.pbuf == NULL) {
                // socket closed and no data left in buffer
                return 0;
            }
        } else if (socket->state != STATE_CONNECTED) {
            assert(socket->state < 0);
            *_errno = error_lookup_table[-socket->state];
            return -1;
        }
    }

    assert(socket->pcb.tcp != NULL);

    struct pbuf *p = socket->incoming.pbuf;

    if (socket->leftover_count == 0) {
        socket->leftover_count = p->tot_len;
    }

    u16_t result = pbuf_copy_partial(p, buf, ((socket->leftover_count >= len) ? len : socket->leftover_count), (p->tot_len - socket->leftover_count));
    if (socket->leftover_count > len) {
        // More left over...
        socket->leftover_count -= len;
    } else {
        pbuf_free(p);
        socket->incoming.pbuf = NULL;
        socket->leftover_count = 0;
    }

    tcp_recved(socket->pcb.tcp, result);
    return (mp_uint_t) result;
}
Beispiel #16
0
static void
pxdns_query(struct pxdns *pxdns, struct udp_pcb *pcb, struct pbuf *p,
            ipX_addr_t *addr, u16_t port)
{
    struct request *req;
    int sent;

    if (pxdns->nresolvers == 0) {
        /* nothing we can do */
        pbuf_free(p);
        return;
    }

    req = calloc(1, sizeof(struct request) - 1 + p->tot_len);
    if (req == NULL) {
        pbuf_free(p);
        return;
    }

    /* copy request data */
    req->size = p->tot_len;
    pbuf_copy_partial(p, req->data, p->tot_len, 0);

    /* save client identity and client's request id */
    req->pcb = pcb;
    ipX_addr_copy(PCB_ISIPV6(pcb), req->client_addr, *addr);
    req->client_port = port;
    memcpy(&req->client_id, req->data, sizeof(req->client_id));

    /* slap our request id onto it */
    req->id = pxdns->id++;
    memcpy(req->data, &req->id, sizeof(u16_t));

    /* resolver to forward to */
    req->generation = pxdns->generation;
    req->residx = 0;

    /* prepare for relaying the reply back to guest */
    req->msg_reply.type = TCPIP_MSG_CALLBACK_STATIC;
    req->msg_reply.sem = NULL;
    req->msg_reply.msg.cb.function = pxdns_pcb_reply;
    req->msg_reply.msg.cb.ctx = (void *)req;

    DPRINTF2(("%s: req=%p: client id %d -> id %d\n",
              __func__, (void *)req, req->client_id, req->id));

    pxdns_request_register(pxdns, req);

    sent = pxdns_forward_outbound(pxdns, req);
    if (!sent) {
        sent = pxdns_rexmit(pxdns, req);
    }
    if (!sent) {
        pxdns_request_deregister(pxdns, req);
        pxdns_request_free(req);
    }
}
/*-------------------------------------------------------------------------
	Description:	
		When an incoming DHCP message is to me, this function process it and trigger the state machine.
		
	Arguments:
		Arg: Pointer to the user supplied argument.
		Pcb: Pointer to the udp_pcb which received data.
		P: Pointer to 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	.
		
	Return Value:
		None.
		
	Note:	
		
-------------------------------------------------------------------------*/
VOID DHCPS_RecvCb(VOID *Arg, struct udp_pcb *Pcb, struct pbuf *P, struct ip_addr *Addr, INT16U Port)
{
	INT32U Xid;
	INT8U MsgType;
	PDHCP_MSG pDhcpMsg;
	INT32U MsgLen;
	INT32U ReqIpAddr;
	INT32U ServerId;
	INT8U ClientMacAddr[6];
	PDHCP_CLIENT pClient;

	do
	{
		pDhcpMsg = &DhcpMsg;

		/* Copy the DHCP message. */
		MsgLen = pbuf_copy_partial(P, (VOID *)pDhcpMsg, sizeof(DHCP_MSG), 0);

		/* Filter out the frame that is not request frame or has wrong magic number or has wrong hardware address type. */
		if((MsgLen == 0) || (pDhcpMsg->Op != DHCP_OP_REQUEST) || 
			(ntohl(pDhcpMsg->Magic) != DHCP_MAGIC) || (pDhcpMsg->HType != DHCP_HWTYPE_ETHERNET))
		{
			break;
		}

		/* Parse the packet to get message type, ip address requested by client and server ID. */
		MsgType = 0xff;
		ReqIpAddr = 0;
		ServerId = 0;
		if((_ParseDhcpOptions(pDhcpMsg, &MsgType, &ReqIpAddr, &ServerId) & 0x01) == 0)
		{
			break;
		}

		/* Get the Xid and client's MAC address. */
		Xid = ntohl(pDhcpMsg->Xid);
		NST_MOVE_MEM(ClientMacAddr, pDhcpMsg->Chaddr, 6);

		/* Get the client entry that is free or negotiating. */
		pClient = _ClientTableLookup(ClientMacAddr, MsgType, ReqIpAddr, ServerId);
		if(pClient == NULL)
		{
			if((MsgType != DHCP_MSG_RELEASE) && (MsgType != DHCP_MSG_DECLINE))
			{
				/* Ip is already allocated, so send nack. */
				_DHCPNakGenAndSend(ClientMacAddr, Xid);
			}
			break;
		}

		/* Push to client state machine. */
		_DhcpClientSMEHandle(pClient, MsgType, Xid, ClientMacAddr);
	}while(0);

	pbuf_free(P);
}
Beispiel #18
0
/* 
 * NOTE: we allow 0 count reads to transparently handle the case where we are 
 *       reading in data of size 0
 */
void
pb_read(struct pbuf* pbuf, void* data, int count, int* pos)
{
    u16_t read;
    assert(*pos <= pbuf->tot_len);
    assert(*pos + count <= pbuf->tot_len);
    read = pbuf_copy_partial(pbuf, data, count, *pos);
    assert(count == read);
    *pos = *pos + read;
}
Beispiel #19
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;
    }
}
Beispiel #20
0
/******************************************************************************
 * FunctionName : espconn_server_recv
 * Description  : Data has been received on this pcb.
 * Parameters   : arg -- Additional argument to pass to the callback function
 *                pcb -- The connection pcb which received data
 *                p -- The received data (or NULL when the connection has been closed!)
 *                err -- An error code if there has been an error receiving
 * Returns      : ERR_ABRT: if you have called tcp_abort from within the function!
*******************************************************************************/
static err_t ICACHE_FLASH_ATTR
espconn_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
	espconn_msg *precv_cb = arg;

    tcp_arg(pcb, arg);
    espconn_printf("server has application data received: %d\n", system_get_free_heap_size());
    if (p != NULL) {
    	/*To update and advertise a larger window*/
		if(precv_cb->recv_hold_flag == 0)
        	tcp_recved(pcb, p->tot_len);
		else
			precv_cb->recv_holded_buf_Len += p->tot_len;
    }

    if (err == ERR_OK && p != NULL) {
    	u8_t *data_ptr = NULL;
    	u32_t data_cntr = 0;
    	/*clear the count for connection timeout*/
		precv_cb->pcommon.recv_check = 0;
		/*Copy the contents of a packet buffer to an application buffer.
		 *to prevent memory leaks, ensure that each allocated is deleted*/
        data_ptr = (u8_t *)os_zalloc(p ->tot_len + 1);
        data_cntr = pbuf_copy_partial(p, data_ptr, p ->tot_len, 0);
        pbuf_free(p);

        if (data_cntr != 0) {
        	/*switch the state of espconn for application process*/
        	precv_cb->pespconn ->state = ESPCONN_READ;
        	precv_cb->pcommon.pcb = pcb;
            if (precv_cb->pespconn->recv_callback != NULL) {
            	precv_cb->pespconn->recv_callback(precv_cb->pespconn, data_ptr, data_cntr);
            }

            /*switch the state of espconn for next packet copy*/
            if (pcb->state == ESTABLISHED)
            	precv_cb->pespconn ->state = ESPCONN_CONNECT;
        }

        /*to prevent memory leaks, ensure that each allocated is deleted*/
        os_free(data_ptr);
        data_ptr = NULL;
        espconn_printf("server's application data has been processed: %d\n", system_get_free_heap_size());
    } else {
        if (p != NULL) {
            pbuf_free(p);
        }

        espconn_server_close(precv_cb, pcb);
    }

    return ERR_OK;
}
Beispiel #21
0
void DNSServer::onReceive(pbuf* buf, IPAddress remoteIP, uint16_t remotePort)
{


    if (_buffer != NULL) free(_buffer);
    _buffer = (char*)malloc(buf->tot_len * sizeof(char));
    if (_buffer == NULL) return;
    pbuf_copy_partial(buf, _buffer, buf->tot_len, 0);
    debugf("DNS REQ for %s from %s:%d", getDomainNameWithoutWwwPrefix().c_str(), remoteIP.toString().c_str(), remotePort);
    _dnsHeader = (DNSHeader*) _buffer;
	if (_dnsHeader->QR == DNS_QR_QUERY &&
	        _dnsHeader->OPCode == DNS_OPCODE_QUERY &&
	        requestIncludesOnlyOneQuestion() &&
	        (_domainName == "*" || getDomainNameWithoutWwwPrefix() == _domainName)
	       )
		{
			char response[buf->tot_len+16];
			int idx = buf->tot_len;
			_dnsHeader->QR = DNS_QR_RESPONSE;
			_dnsHeader->ANCount = _dnsHeader->QDCount;
			_dnsHeader->QDCount = _dnsHeader->QDCount;
			memcpy(response, _buffer, idx);
			//Set a pointer to the domain name in the question section
			response[idx] = 0xC0;
			response[idx+1] = 0x0C;

			//Type: "Host Address"
			response[idx+2] = 0x00;
			response[idx+3] = 0x01;

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

			//TTL
			response[idx+6] = _ttl >> 24;
			response[idx+7] = _ttl >> 16;
			response[idx+8] = _ttl >> 8;
			response[idx+9] = _ttl;

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

			//The IP address
			response[idx+12] = _resolvedIP[0];
			response[idx+13] = _resolvedIP[1];
			response[idx+14] = _resolvedIP[2];
			response[idx+15] = _resolvedIP[3];

			sendTo(remoteIP, remotePort, response, idx+16);
	    }
Beispiel #22
0
/** Parse last server response (in rx_buf) for supported authentication method,
 * create data to send out (to tx_buf), set tx_data_len correctly
 * and return the next state.
 */
static enum smtp_session_state
smtp_prepare_auth_or_mail(struct smtp_session *s, u16_t *tx_buf_len)
{
  /* check response for supported authentication method */
  u16_t auth = pbuf_strstr(s->p, SMTP_KEYWORD_AUTH_SP);
  if (auth == 0xFFFF) {
    auth = pbuf_strstr(s->p, SMTP_KEYWORD_AUTH_EQ);
  }
  if (auth != 0xFFFF) {
    u16_t crlf = pbuf_memfind(s->p, SMTP_CRLF, SMTP_CRLF_LEN, auth);
    if ((crlf != 0xFFFF) && (crlf > auth)) {
      /* use tx_buf temporarily */
      u16_t copied = pbuf_copy_partial(s->p, s->tx_buf, crlf - auth, auth);
      if (copied != 0) {
        char *sep = s->tx_buf + SMTP_KEYWORD_AUTH_LEN;
        s->tx_buf[copied] = 0;
#if SMTP_SUPPORT_AUTH_PLAIN
        /* favour PLAIN over LOGIN since it involves less requests */
        if (strstr(sep, SMTP_AUTH_PARAM_PLAIN) != NULL) {
          size_t auth_len;
          /* server supports AUTH PLAIN */
          SMEMCPY(s->tx_buf, SMTP_CMD_AUTHPLAIN_1, SMTP_CMD_AUTHPLAIN_1_LEN);

          /* add base64-encoded string "\0username\0password" */
          auth_len = smtp_base64_encode(&s->tx_buf[SMTP_CMD_AUTHPLAIN_1_LEN],
            SMTP_TX_BUF_LEN - SMTP_CMD_AUTHPLAIN_1_LEN, SMTP_AUTH_PLAIN_DATA(s),
            SMTP_AUTH_PLAIN_LEN(s));
          LWIP_ASSERT("string too long", auth_len <= 0xffff);
         *tx_buf_len = SMTP_CMD_AUTHPLAIN_1_LEN + SMTP_CMD_AUTHPLAIN_2_LEN + (u16_t)auth_len;
          LWIP_ASSERT("tx_buf overflow detected", *tx_buf_len <= SMTP_TX_BUF_LEN);
          SMEMCPY(&s->tx_buf[SMTP_CMD_AUTHPLAIN_1_LEN + auth_len], SMTP_CMD_AUTHPLAIN_2,
            SMTP_CMD_AUTHPLAIN_2_LEN);
          return SMTP_AUTH_PLAIN;
        } else
#endif /* SMTP_SUPPORT_AUTH_PLAIN */
        {
#if SMTP_SUPPORT_AUTH_LOGIN
          if (strstr(sep, SMTP_AUTH_PARAM_LOGIN) != NULL) {
            /* server supports AUTH LOGIN */
            *tx_buf_len = SMTP_CMD_AUTHLOGIN_LEN;
            SMEMCPY(s->tx_buf, SMTP_CMD_AUTHLOGIN, SMTP_CMD_AUTHLOGIN_LEN);
            return SMTP_AUTH_LOGIN_UNAME;
          }
#endif /* SMTP_SUPPORT_AUTH_LOGIN */
        }
      }
    }
  }
  /* server didnt's send correct keywords for AUTH, try sending directly */
  return smtp_prepare_mail(s, tx_buf_len);
}
Beispiel #23
0
void UdpConnection::onReceive(pbuf* buf, IPAddress remoteIP, uint16_t remotePort)
{
	debugf("UDP received: %d bytes", buf->tot_len);
	if (onDataCallback)
	{
		char* data = new char[buf->tot_len + 1];
		pbuf_copy_partial(buf, data, buf->tot_len, 0);
		data[buf->tot_len] = '\0';

		onDataCallback(*this, data, buf->tot_len, remoteIP, remotePort);

		delete[] data;
	}
}
Beispiel #24
0
void eth_onUDPDataReceived(void* arg, struct udp_pcb* upcb, struct pbuf* p, struct ip_addr* addr, u16_t port)
{
	char *srcAddr = ipaddr_ntoa(addr);
	myprintf("src addr: %s %d\r\n", srcAddr, p->tot_len);

	uint16_t packetId;
	uint8_t d[p->tot_len];

	pbuf_copy_partial(p, d, p->tot_len, 0);

	provProcess(d, p->tot_len);

	pbuf_free(p);
}
static socket_error_t recv_copy_free(struct socket *socket, void * buf,
        size_t *len) {
    struct pbuf *p;
    size_t copied;

    p = (struct pbuf *) socket->rxBufChain;
    if (p == NULL) {
        return SOCKET_ERROR_WOULD_BLOCK;
    }

    switch (socket->family) {
        case SOCKET_STREAM: {
            /* Copy out of the pbuf chain */
            copied = pbuf_copy_partial(p, buf, *len, 0);
            /* Set the external length to the number of bytes copied */
            *len = copied;
            p = pbuf_consume(p, copied, 0);
            socket->rxBufChain = p;
            /* Update the TCP window */
            tcp_recved(socket->impl, copied);
            break;
        }
        case SOCKET_DGRAM: {
            size_t cplen = ((*len) < (p->tot_len) ? (*len) : (p->tot_len));
            copied = pbuf_copy_partial(p, buf, cplen, 0);
            *len = copied;
            /* a single read must always consume the whole UDP packet */
            p = pbuf_consume(p, p->tot_len, 1); /* free partial */
            socket->rxBufChain = p;
            break;
        }
        default:
            break;
    }

    return SOCKET_ERROR_NONE;
}
Beispiel #26
0
/** Receive callback function called from mbedtls (set via mbedtls_ssl_set_bio)
 * This function mainly copies data from pbufs and frees the pbufs after copying.
 */
static int
altcp_mbedtls_bio_recv(void *ctx, unsigned char *buf, size_t len)
{
  struct altcp_pcb *conn = (struct altcp_pcb *)ctx;
  altcp_mbedtls_state_t *state;
  struct pbuf *p;
  u16_t ret;
  u16_t copy_len;
  err_t err;

  LWIP_UNUSED_ARG(err); /* for LWIP_NOASSERT */
  if ((conn == NULL) || (conn->state == NULL)) {
    return MBEDTLS_ERR_NET_INVALID_CONTEXT;
  }
  state = (altcp_mbedtls_state_t *)conn->state;
  p = state->rx;

  /* @todo: return MBEDTLS_ERR_NET_CONN_RESET/MBEDTLS_ERR_NET_RECV_FAILED? */

  if ((p == NULL) || ((p->len == 0) && (p->next == NULL))) {
    if (p) {
      pbuf_free(p);
    }
    state->rx = NULL;
    if ((state->flags & (ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED | ALTCP_MBEDTLS_FLAGS_RX_CLOSED)) ==
        ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED) {
      /* close queued but not passed up yet */
      return 0;
    }
    return MBEDTLS_ERR_SSL_WANT_READ;
  }
  /* limit number of bytes again to copy from first pbuf in a chain only */
  copy_len = (u16_t)LWIP_MIN(len, p->len);
  /* copy the data */
  ret = pbuf_copy_partial(p, buf, copy_len, 0);
  LWIP_ASSERT("ret == copy_len", ret == copy_len);
  /* hide the copied bytes from the pbuf */
  err = pbuf_remove_header(p, ret);
  LWIP_ASSERT("error", err == ERR_OK);
  if (p->len == 0) {
    /* the first pbuf has been fully read, free it */
    state->rx = p->next;
    p->next = NULL;
    pbuf_free(p);
  }

  state->bio_bytes_read += (int)ret;
  return ret;
}
Beispiel #27
0
/* transmit packet. */
rt_err_t lpc_emac_tx(rt_device_t dev, struct pbuf *p)
{
    rt_uint32_t Index, IndexNext;
    rt_uint8_t *ptr;

    /* calculate next index */
    IndexNext = LPC_EMAC->TxProduceIndex + 1;
    if (IndexNext > LPC_EMAC->TxDescriptorNumber) IndexNext = 0;

    /* check whether block is full */
    while (IndexNext == LPC_EMAC->TxConsumeIndex)
    {
        rt_err_t result;
        rt_uint32_t recved;

        /* there is no block yet, wait a flag */
        result = rt_event_recv(&tx_event, 0x01,
                               RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &recved);

        RT_ASSERT(result == RT_EOK);
    }

    /* lock EMAC device */
    rt_sem_take(&sem_lock, RT_WAITING_FOREVER);

    /* get produce index */
    Index = LPC_EMAC->TxProduceIndex;

    /* calculate next index */
    IndexNext = LPC_EMAC->TxProduceIndex + 1;
    if (IndexNext > LPC_EMAC->TxDescriptorNumber)
        IndexNext = 0;

    /* copy data to tx buffer */
    ptr = (rt_uint8_t *)TX_BUF(Index);
    pbuf_copy_partial(p, ptr, p->tot_len, 0);

    TX_DESC_CTRL(Index) &= ~0x7ff;
    TX_DESC_CTRL(Index) |= (p->tot_len - 1) & 0x7ff;

    /* change index to the next */
    LPC_EMAC->TxProduceIndex = IndexNext;

    /* unlock EMAC device */
    rt_sem_release(&sem_lock);

    return RT_EOK;
}
Beispiel #28
0
static ssize_t pkt_read_cb(char *dst,
                           void *src_handle,
                           size_t read_len,
                           int offset) {
        ssize_t rc;

        rc = pbuf_copy_partial((struct pbuf *)src_handle,
                               dst,
                               read_len,
                               offset + WL_HEADER_SIZE);
        if ( 0 == rc ) {
                return -1;
        }

        return rc;
}
Beispiel #29
0
err_t
snmp_pbuf_stream_read(struct snmp_pbuf_stream *pbuf_stream, u8_t *data)
{
  if (pbuf_stream->length == 0) {
    return ERR_BUF;
  }

  if (pbuf_copy_partial(pbuf_stream->pbuf, data, 1, pbuf_stream->offset) == 0) {
    return ERR_BUF;
  }

  pbuf_stream->offset++;
  pbuf_stream->length--;

  return ERR_OK;
}
Beispiel #30
0
/******************************************************************************
 * FunctionName : espconn_client_recv
 * Description  : Data has been received on this pcb.
 * Parameters   : arg -- Additional argument to pass to the callback function
 *                pcb -- The connection pcb which received data
 *                p -- The received data (or NULL when the connection has been closed!)
 *                err -- An error code if there has been an error receiving
 * Returns      : ERR_ABRT: if you have called tcp_abort from within the function!
*******************************************************************************/
static err_t ICACHE_FLASH_ATTR
espconn_client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
	espconn_msg *precv_cb = arg;

	tcp_arg(pcb, arg);

    if (p != NULL) {
    	/*To update and advertise a larger window*/
		if(precv_cb->recv_hold_flag == 0)
        	tcp_recved(pcb, p->tot_len);
		else
			precv_cb->recv_holded_buf_Len += p->tot_len;
    }

    if (err == ERR_OK && p != NULL) {
    	char *pdata = NULL;
    	u16_t length = 0;
    	/*Copy the contents of a packet buffer to an application buffer.
    	 *to prevent memory leaks, ensure that each allocated is deleted*/
        pdata = (char *)malloc(p ->tot_len + 1);
        length = pbuf_copy_partial(p, pdata, p ->tot_len, 0);
        pbuf_free(p);

        if (length != 0) {
        	/*switch the state of espconn for application process*/
        	precv_cb->pespconn ->state = ESPCONN_READ;
        	precv_cb->pcommon.pcb = pcb;
            if (precv_cb->pespconn->recv_callback != NULL) {
            	precv_cb->pespconn->recv_callback(precv_cb->pespconn, pdata, length);
            }
            /*switch the state of espconn for next packet copy*/
            if (pcb->state == ESTABLISHED)
            	precv_cb->pespconn ->state = ESPCONN_CONNECT;
        }

        /*to prevent memory leaks, ensure that each allocated is deleted*/
        free(pdata);
        pdata = NULL;
    }

    if (err == ERR_OK && p == NULL) {
        espconn_client_close(precv_cb, pcb,0);
    }

    return ERR_OK;
}