zephyr/samples/net/echo_server/src/echo-server.c
Ravi kumar Veeramally 6cadd380b7 samples: net: Fix echo_server reply packet preparation
If the incoming packet fragments doesn't have any link layer
header then build_reply_pkt() will set reply packet fragment's link
layer header space to zero. Which is causing issue in case of IPv4.
ARP layer is trying to fill Ethernet headers, but fragments
ll header length is set to zero.

Just use net_pkt_copy_all() to copy payload. That should be enough.

Fixes #6564

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
2018-05-16 16:40:27 +03:00

145 lines
2.6 KiB
C

/* echo.c - Networking echo server */
/*
* Copyright (c) 2016 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#if 1
#define SYS_LOG_DOMAIN "echo-server"
#define NET_SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG
#define NET_LOG_ENABLED 1
#endif
#include <zephyr.h>
#include <linker/sections.h>
#include <errno.h>
#include <net/net_pkt.h>
#include <net/net_core.h>
#include <net/net_context.h>
#include <net/net_app.h>
#include "common.h"
/* The startup time needs to be longish if DHCP is enabled as setting
* DHCP up takes some time.
*/
#define APP_STARTUP_TIME K_SECONDS(20)
#define APP_BANNER "Run echo server"
static struct k_sem quit_lock;
void panic(const char *msg)
{
if (msg) {
NET_ERR("%s", msg);
}
for (;;) {
k_sleep(K_FOREVER);
}
}
void quit(void)
{
k_sem_give(&quit_lock);
}
struct net_pkt *build_reply_pkt(const char *name,
struct net_app_ctx *ctx,
struct net_pkt *pkt)
{
struct net_pkt *reply_pkt;
struct net_buf *frag, *tmp;
int header_len = 0, recv_len;
NET_INFO("%s received %d bytes", name, net_pkt_appdatalen(pkt));
if (net_pkt_appdatalen(pkt) == 0) {
return NULL;
}
reply_pkt = net_app_get_net_pkt(ctx, net_pkt_family(pkt), K_FOREVER);
NET_ASSERT(reply_pkt);
NET_ASSERT(net_pkt_family(reply_pkt) == net_pkt_family(pkt));
recv_len = net_pkt_get_len(pkt);
tmp = pkt->frags;
/* If we have link layer headers, then get rid of them here. */
if (recv_len != net_pkt_appdatalen(pkt)) {
/* First fragment will contain IP header so move the data
* down in order to get rid of it.
*/
header_len = net_pkt_appdata(pkt) - tmp->data;
NET_ASSERT(header_len < CONFIG_NET_BUF_DATA_SIZE);
/* After this pull, the tmp->data points directly to application
* data.
*/
net_buf_pull(tmp, header_len);
}
net_pkt_set_appdatalen(reply_pkt, net_pkt_appdatalen(pkt));
frag = net_pkt_copy_all(pkt, 0, K_FOREVER);
if (!frag) {
NET_ERR("Failed to copy all data");
net_pkt_unref(reply_pkt);
return NULL;
}
net_pkt_frag_add(reply_pkt, frag);
return reply_pkt;
}
void pkt_sent(struct net_app_ctx *ctx,
int status,
void *user_data_send,
void *user_data)
{
if (!status) {
NET_INFO("Sent %d bytes", POINTER_TO_UINT(user_data_send));
}
}
static inline int init_app(void)
{
k_sem_init(&quit_lock, 0, UINT_MAX);
return 0;
}
void main(void)
{
init_app();
if (IS_ENABLED(CONFIG_NET_TCP)) {
start_tcp();
}
if (IS_ENABLED(CONFIG_NET_UDP)) {
start_udp();
}
k_sem_take(&quit_lock, K_FOREVER);
NET_INFO("Stopping...");
if (IS_ENABLED(CONFIG_NET_TCP)) {
stop_tcp();
}
if (IS_ENABLED(CONFIG_NET_UDP)) {
stop_udp();
}
}