forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
samples: sockets: Add packet socket sample application
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
Showing
5 changed files
with
280 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |