Skip to content

Commit

Permalink
samples: sockets: Add packet socket sample application
Browse files Browse the repository at this point in the history
Sample application which opens a packet socket and receives
every packet on the wire and send some dummy packet over
socket. Simple demo of how to use packet sockets.

Signed-off-by: Ravi kumar Veeramally <[email protected]>
  • Loading branch information
rveerama1 authored and jukkar committed Feb 7, 2019
1 parent a9a2b3e commit 7e8ded9
Show file tree
Hide file tree
Showing 5 changed files with 280 additions and 0 deletions.
16 changes: 16 additions & 0 deletions samples/net/sockets/packet/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.13.1)

macro(set_conf_file)
if(EXISTS ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.conf)
set(CONF_FILE "prj.conf ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.conf")
else()
set(CONF_FILE "prj.conf")
endif()
endmacro()

include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(sockets_echo_server)

target_sources( app PRIVATE src/packet.c)

include($ENV{ZEPHYR_BASE}/samples/net/common/common.cmake)
28 changes: 28 additions & 0 deletions samples/net/sockets/packet/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.. _packet-socket-sample:

Packet socket sample
####################

Overview
********

This sample is a simple packet socket application showing usage
of packet sockets over Ethernet. The sample prints every packet
received, and sends a dummy packet every 5 seconds.
The Zephyr network subsystem does not touch any of the headers
(L2, L3, etc.).

Building and Running
********************

When the application is run, it opens a packet socket and prints
the length of the packet it receives. After that it sends a dummy
packet every 5 seconds. You can use Wireshark to observe these
sent and received packets.

See the `net-tools`_ project for more details.

This sample can be built and executed on QEMU as described
in :ref:`networking_with_qemu`.

.. _`net-tools`: https://github.com/zephyrproject-rtos/net-tools
43 changes: 43 additions & 0 deletions samples/net/sockets/packet/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Generic networking options
CONFIG_NETWORKING=y
CONFIG_NET_UDP=n
CONFIG_NET_TCP=n
CONFIG_NET_IPV6=n
CONFIG_NET_IPV4=y
CONFIG_NET_MAX_CONTEXTS=10
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_POSIX_MAX_FDS=6
# Packet socket configuration
CONFIG_NET_SOCKETS_PACKET=y

# Kernel options
CONFIG_MAIN_STACK_SIZE=2048
CONFIG_ENTROPY_GENERATOR=y
CONFIG_INIT_STACKS=y

# Network buffers
CONFIG_NET_PKT_RX_COUNT=16
CONFIG_NET_PKT_TX_COUNT=16
CONFIG_NET_BUF_RX_COUNT=64
CONFIG_NET_BUF_TX_COUNT=64
CONFIG_NET_CONTEXT_NET_PKT_POOL=y

# Network shell
CONFIG_NET_SHELL=y

# Logging
CONFIG_LOG=y
CONFIG_NET_LOG=y
CONFIG_NET_STATISTICS=y
CONFIG_PRINTK=y
CONFIG_LOG_BACKEND_NATIVE_POSIX=y

CONFIG_NET_SOCKETS_LOG_LEVEL_DBG=n
CONFIG_NET_CONTEXT_LOG_LEVEL_DBG=n
CONFIG_NET_CORE_LOG_LEVEL_DBG=n
CONFIG_NET_CONN_LOG_LEVEL_DBG=n
CONFIG_NET_IF_LOG_LEVEL_DBG=n
CONFIG_NET_L2_ETHERNET_LOG_LEVEL_DBG=n
CONFIG_ETHERNET_LOG_LEVEL_DBG=n
CONFIG_NET_PKT_LOG_LEVEL_ERR=n
8 changes: 8 additions & 0 deletions samples/net/sockets/packet/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
sample:
description: Packet socket sample
name: packet-socket
tests:
test:
harness: net
platform_whitelist: native_posix
tags: net sockets packet-socket
185 changes: 185 additions & 0 deletions samples/net/sockets/packet/src/packet.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/*
* Copyright (c) 2019 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <logging/log.h>
LOG_MODULE_REGISTER(net_pkt_sock_sample, LOG_LEVEL_DBG);

#include <zephyr.h>
#include <errno.h>
#include <stdio.h>

#include <net/socket.h>
#include <net/ethernet.h>

#define STACK_SIZE 1024
#define THREAD_PRIORITY K_PRIO_COOP(8)
#define RECV_BUFFER_SIZE 1280
#define RAW_WAIT K_SECONDS(5)

static struct packet_data packet;

static struct k_sem quit_lock;

struct packet_data {
int sock;
char recv_buffer[RECV_BUFFER_SIZE];
struct k_delayed_work send;
};

static void process_packet(void);
static void send_packet(void);

K_THREAD_DEFINE(packet_thread_id, STACK_SIZE,
process_packet, NULL, NULL, NULL,
THREAD_PRIORITY, 0, K_FOREVER);

/* Generated by http://www.lipsum.com/
* 2 paragraphs, 179 words, 1160 bytes of Lorem Ipsum
*/
const char lorem_ipsum[] =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque "
"sodales lorem lorem, sed congue enim vehicula a. Sed finibus diam sed "
"odio ultrices pharetra. Nullam dictum arcu ultricies turpis congue, "
"vel venenatis turpis venenatis. Nam tempus arcu eros, ac congue libero "
"tristique congue. Proin velit lectus, euismod sit amet quam in, "
"maximus condimentum urna. Cras vel erat luctus, mattis orci ut, varius "
"urna. Nam eu lobortis velit."
"\n"
"Nullam sit amet diam vel odio sodales cursus vehicula eu arcu. Proin "
"fringilla, enim nec consectetur mollis, lorem orci interdum nisi, "
"vitae suscipit nisi mauris eu mi. Proin diam enim, mollis ac rhoncus "
"vitae, placerat et eros. Suspendisse convallis, ipsum nec rhoncus "
"aliquam, ex augue ultrices nisl, id aliquet mi diam quis ante. "
"Pellentesque venenatis ornare ultrices. Quisque et porttitor lectus. "
"Ut venenatis nunc et urna imperdiet porttitor non laoreet massa. Donec "
"eleifend eros in mi sagittis egestas. Sed et mi nunc. Nunc vulputate, "
"mauris non ullamcorper viverra, lorem nulla vulputate diam, et congue "
"dui velit non erat. Duis interdum leo et ipsum tempor consequat. In "
"faucibus enim quis purus vulputate nullam."
"\n";

static void quit(void)
{
k_sem_give(&quit_lock);
}

static int start_packet_socket(void)
{
struct sockaddr_ll dst;
int ret;

packet.sock = socket(AF_PACKET, SOCK_RAW, ETH_P_ALL);
if (packet.sock < 0) {
LOG_ERR("Failed to create RAW socket : %d", errno);
return -errno;
}

dst.sll_ifindex = 0;
dst.sll_family = AF_PACKET;

ret = bind(packet.sock, (const struct sockaddr *)&dst,
sizeof(struct sockaddr_ll));
if (ret < 0) {
LOG_ERR("Failed to bind packet socket : %d", errno);
return -errno;
}

return 0;
}

static void wait_send(struct k_work *work)
{
/* Send a new packet at this point */
send_packet();
}

static void send_packet(void)
{
struct sockaddr_ll dst;
u8_t send = 100;
int ret;

dst.sll_ifindex = 0;

/* Sending dummy data */
ret = sendto(packet.sock, lorem_ipsum, send, 0,
(const struct sockaddr *)&dst,
sizeof(struct sockaddr_ll));
if (ret < 0) {
LOG_ERR("Failed to send, errno %d", errno);
} else {
LOG_DBG("Sent %d bytes", send);
}

k_delayed_work_submit(&packet.send, RAW_WAIT);
}

static int process_packet_socket(void)
{
int ret = 0;
int received;

LOG_INF("Waiting for packets ...");

send_packet();

do {
received = recv(packet.sock, packet.recv_buffer,
sizeof(packet.recv_buffer), 0);

if (received < 0) {
LOG_ERR("RAW : recv error %d", errno);
ret = -errno;
break;
}

LOG_DBG("Received %d bytes", received);

} while (true);

return ret;
}

static void process_packet(void)
{
int ret;

ret = start_packet_socket();
if (ret < 0) {
quit();
return;
}

while (ret == 0) {
ret = process_packet_socket();
if (ret < 0) {
quit();
return;
}
}
}

void main(void)
{
k_sem_init(&quit_lock, 0, UINT_MAX);
k_delayed_work_init(&packet.send, wait_send);

LOG_INF("Packet socket sample is running");

k_thread_start(packet_thread_id);

k_sem_take(&quit_lock, K_FOREVER);

LOG_INF("Stopping...");

k_thread_abort(packet_thread_id);

k_delayed_work_cancel(&packet.send);

if (packet.sock > 0) {
(void)close(packet.sock);
}
}

0 comments on commit 7e8ded9

Please sign in to comment.