Exemplo n.º 1
0
static void setup_ipv4_udp(struct net_pkt *pkt,
			   struct in_addr *remote_addr,
			   struct in_addr *local_addr,
			   u16_t remote_port,
			   u16_t local_port)
{
	NET_IPV4_HDR(pkt)->vhl = 0x45;
	NET_IPV4_HDR(pkt)->tos = 0;
	NET_IPV4_HDR(pkt)->len[0] = 0;
	NET_IPV4_HDR(pkt)->len[1] = NET_UDPH_LEN +
		sizeof(struct net_ipv4_hdr) + strlen(payload);

	NET_IPV4_HDR(pkt)->proto = IPPROTO_UDP;

	net_ipaddr_copy(&NET_IPV4_HDR(pkt)->src, remote_addr);
	net_ipaddr_copy(&NET_IPV4_HDR(pkt)->dst, local_addr);

	net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv4_hdr));
	net_pkt_set_ipv6_ext_len(pkt, 0);

	net_buf_add(pkt->frags, net_pkt_ip_hdr_len(pkt) +
				sizeof(struct net_udp_hdr));

	NET_UDP_HDR(pkt)->src_port = htons(remote_port);
	NET_UDP_HDR(pkt)->dst_port = htons(local_port);

	net_buf_add_mem(pkt->frags, payload, strlen(payload));
}
Exemplo n.º 2
0
static void setup_ipv6_udp(struct net_pkt *pkt,
			   struct in6_addr *remote_addr,
			   struct in6_addr *local_addr,
			   u16_t remote_port,
			   u16_t local_port)
{
	NET_IPV6_HDR(pkt)->vtc = 0x60;
	NET_IPV6_HDR(pkt)->tcflow = 0;
	NET_IPV6_HDR(pkt)->flow = 0;
	NET_IPV6_HDR(pkt)->len[0] = 0;
	NET_IPV6_HDR(pkt)->len[1] = NET_UDPH_LEN + strlen(payload);

	NET_IPV6_HDR(pkt)->nexthdr = IPPROTO_UDP;
	NET_IPV6_HDR(pkt)->hop_limit = 255;

	net_ipaddr_copy(&NET_IPV6_HDR(pkt)->src, remote_addr);
	net_ipaddr_copy(&NET_IPV6_HDR(pkt)->dst, local_addr);

	net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv6_hdr));
	net_pkt_set_ipv6_ext_len(pkt, 0);

	net_buf_add(pkt->frags, net_pkt_ip_hdr_len(pkt) +
				sizeof(struct net_udp_hdr));

	NET_UDP_HDR(pkt)->src_port = htons(remote_port);
	NET_UDP_HDR(pkt)->dst_port = htons(local_port);

	net_buf_add_mem(pkt->frags, payload, strlen(payload));
}
Exemplo n.º 3
0
u16_t net_calc_chksum(struct net_pkt *pkt, u8_t proto)
{
	u16_t upper_layer_len;
	u16_t sum;

	switch (net_pkt_family(pkt)) {
#if defined(CONFIG_NET_IPV4)
	case AF_INET:
		upper_layer_len = (NET_IPV4_HDR(pkt)->len[0] << 8) +
			NET_IPV4_HDR(pkt)->len[1] -
			net_pkt_ipv6_ext_len(pkt) -
			net_pkt_ip_hdr_len(pkt);

		if (proto == IPPROTO_ICMP) {
			return htons(calc_chksum(0, net_pkt_ip_data(pkt) +
						 net_pkt_ip_hdr_len(pkt),
						 upper_layer_len));
		} else {
			sum = calc_chksum(upper_layer_len + proto,
					  (u8_t *)&NET_IPV4_HDR(pkt)->src,
					  2 * sizeof(struct in_addr));
		}
		break;
#endif
#if defined(CONFIG_NET_IPV6)
	case AF_INET6:
		upper_layer_len = (NET_IPV6_HDR(pkt)->len[0] << 8) +
			NET_IPV6_HDR(pkt)->len[1] - net_pkt_ipv6_ext_len(pkt);
		sum = calc_chksum(upper_layer_len + proto,
				  (u8_t *)&NET_IPV6_HDR(pkt)->src,
				  2 * sizeof(struct in6_addr));
		break;
#endif
	default:
		NET_DBG("Unknown protocol family %d", net_pkt_family(pkt));
		return 0;
	}

	sum = calc_chksum_pkt(sum, pkt, upper_layer_len);

	sum = (sum == 0) ? 0xffff : htons(sum);

	return sum;
}
Exemplo n.º 4
0
static inline u16_t calc_chksum_pkt(u16_t sum, struct net_pkt *pkt,
				       u16_t upper_layer_len)
{
	struct net_buf *frag = pkt->frags;
	u16_t proto_len = net_pkt_ip_hdr_len(pkt) +
		net_pkt_ipv6_ext_len(pkt);
	s16_t len = frag->len - proto_len;
	u8_t *ptr = frag->data + proto_len;

	ARG_UNUSED(upper_layer_len);

	if (len < 0) {
		NET_DBG("1st fragment len %u < IP header len %u",
			frag->len, proto_len);
		return 0;
	}

	while (frag) {
		sum = calc_chksum(sum, ptr, len);
		frag = frag->frags;
		if (!frag) {
			break;
		}

		ptr = frag->data;

		/* Do we need to take first byte from next fragment */
		if (len % 2) {
			u16_t tmp = *ptr;
			sum += tmp;
			if (sum < tmp) {
				sum++;
			}
			len = frag->len - 1;
			ptr++;
		} else {
			len = frag->len;
		}
	}

	return sum;
}
Exemplo n.º 5
0
int http_request(struct http_client_ctx *ctx,
		 struct http_client_request *req,
		 s32_t timeout)
{
	const char *method = http_method_str(req->method);
	struct net_pkt *pkt;
	int ret = -ENOMEM;

	pkt = net_pkt_get_tx(ctx->tcp.ctx, timeout);
	if (!pkt) {
		return -ENOMEM;
	}

	if (!net_pkt_append_all(pkt, strlen(method), (u8_t *)method,
				timeout)) {
		goto out;
	}

	/* Space after method string. */
	if (!net_pkt_append_all(pkt, 1, (u8_t *)" ", timeout)) {
		goto out;
	}

	if (!net_pkt_append_all(pkt, strlen(req->url), (u8_t *)req->url,
				timeout)) {
		goto out;
	}

	if (!net_pkt_append_all(pkt, strlen(req->protocol),
				(u8_t *)req->protocol, timeout)) {
		goto out;
	}

	if (req->host) {
		if (!net_pkt_append_all(pkt, strlen(HTTP_HOST),
					(u8_t *)HTTP_HOST, timeout)) {
			goto out;
		}

		if (!net_pkt_append_all(pkt, strlen(req->host),
					(u8_t *)req->host, timeout)) {
			goto out;
		}

		if (!net_pkt_append_all(pkt, strlen(HTTP_CRLF),
					(u8_t *)HTTP_CRLF, timeout)) {
			goto out;
		}
	}

	if (req->header_fields) {
		if (!net_pkt_append_all(pkt, strlen(req->header_fields),
					(u8_t *)req->header_fields,
					timeout)) {
			goto out;
		}
	}

	if (req->content_type_value) {
		if (!net_pkt_append_all(pkt, strlen(HTTP_CONTENT_TYPE),
					(u8_t *)HTTP_CONTENT_TYPE,
					timeout)) {
			goto out;
		}

		if (!net_pkt_append_all(pkt, strlen(req->content_type_value),
					(u8_t *)req->content_type_value,
					timeout)) {
			goto out;
		}
	}

	if (req->payload && req->payload_size) {
		char content_len_str[HTTP_CONT_LEN_SIZE];

		ret = snprintk(content_len_str, HTTP_CONT_LEN_SIZE,
			       HTTP_CRLF "Content-Length: %u"
			       HTTP_CRLF HTTP_CRLF,
			       req->payload_size);
		if (ret <= 0 || ret >= HTTP_CONT_LEN_SIZE) {
			ret = -ENOMEM;
			goto out;
		}

		if (!net_pkt_append_all(pkt, ret, (u8_t *)content_len_str,
					timeout)) {
			ret = -ENOMEM;
			goto out;
		}

		if (!net_pkt_append_all(pkt, req->payload_size,
					(u8_t *)req->payload,
					timeout)) {
			ret = -ENOMEM;
			goto out;
		}
	} else {
		if (!net_pkt_append_all(pkt, strlen(HTTP_EOF),
					(u8_t *)HTTP_EOF,
					timeout)) {
			goto out;
		}
	}

#if defined(CONFIG_NET_IPV6)
	if (net_pkt_family(pkt) == AF_INET6) {
		net_pkt_set_appdatalen(pkt, net_pkt_get_len(pkt) -
				       net_pkt_ip_hdr_len(pkt) -
				       net_pkt_ipv6_ext_opt_len(pkt));
	} else
#endif
	{
		net_pkt_set_appdatalen(pkt, net_pkt_get_len(pkt) -
				       net_pkt_ip_hdr_len(pkt));
	}

	ret = ctx->tcp.send_data(pkt, NULL, timeout, NULL, ctx);
	if (ret == 0) {
		return 0;
	}

out:
	net_pkt_unref(pkt);

	return ret;
}
Exemplo n.º 6
0
/* This gets plain data and it sends encrypted one to peer */
static int https_send(struct net_pkt *pkt,
		      net_context_send_cb_t cb,
		      s32_t timeout,
		      void *token,
		      void *user_data)
{
	struct http_client_ctx *ctx = user_data;
	int ret;
	u16_t len;

	if (!ctx->rsp.response_buf || ctx->rsp.response_buf_len == 0) {
		NET_DBG("Response buf not setup");
		return -EINVAL;
	}

	len = net_pkt_appdatalen(pkt);
	if (len == 0) {
		NET_DBG("No application data to send");
		return -EINVAL;
	}

	ret = net_frag_linearize(ctx->rsp.response_buf,
				 ctx->rsp.response_buf_len,
				 pkt,
				 net_pkt_ip_hdr_len(pkt) +
				 net_pkt_ipv6_ext_opt_len(pkt),
				 len);
	if (ret < 0) {
		NET_DBG("Cannot linearize send data (%d)", ret);
		return ret;
	}

	if (ret != len) {
		NET_DBG("Linear copy error (%u vs %d)", len, ret);
		return -EINVAL;
	}

	do {
		ret = mbedtls_ssl_write(&ctx->https.mbedtls.ssl,
					ctx->rsp.response_buf, len);
		if (ret == MBEDTLS_ERR_NET_CONN_RESET) {
			NET_ERR("peer closed the connection -0x%x", ret);
			goto out;
		}

		if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
		    ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
			if (ret < 0) {
				print_error("mbedtls_ssl_write returned -0x%x",
					    ret);
				goto out;
			}
		}
	} while (ret <= 0);

out:
	if (cb) {
		cb(net_pkt_context(pkt), ret, token, user_data);
	}

	return ret;
}