The EVL network stack implements a raw
packet
interface, for
exchanging raw frames directly with the network device driver (OSI
Layer 2). This is the EVL equivalent of the AF_PACKET
protocol
family with raw sockets (SOCK_RAW
) available wih the in-band network
stack. Using out-of-band packet sockets with EVL is very similar to
using its in-band counterpart, as illustrated by the
oob-net-icmp demo program. This
boils down to:
SOCK_OOB
flag set, which extends the
associated protocol support to out-of-band handling, in this case
AF_PACKET
.#include <sys/socket.h>
/* Get a raw socket with out-of-band capabilities. */
s = socket(AF_PACKET, SOCK_RAW | SOCK_OOB, 0);
ioctl(SIOCGIFINDEX)
request to
the socket. An out-of-band port must be enabled for this device.#include <net/if.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
struct ifreq ifr;
/* Retrieve the interface index for 'eth0.42'. */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, "eth0.42", IFNAMSIZ - 1);
ret = ioctl(s, SIOCGIFINDEX, &ifr);
if (ret < 0)
error(1, errno, "ioctl(SIOCGIFINDEX)");
AF_PACKET
and a valid packet type to filter ingress packets in.#include <sys/socket.h>
#include <linux/if_packet.h>
struct sockaddr_ll addr;
/* Bind the socket to its address, receiving all (ethernet) packet types. */
memset(&addr, 0, sizeof(addr));
addr.sll_ifindex = ifr.ifr_ifindex;
addr.sll_family = AF_PACKET;
addr.sll_protocol = htons(ETH_P_ALL); /* All Ethernet packet types accepted. */
ret = bind(s, (struct sockaddr *)&addr, sizeof(addr));
if (ret)
error(1, errno, "cannot bind packet socket");
struct oob_msghdr msghdr;
struct sockaddr_ll addr;
struct iovec iov;
ssize_t count;
/* INPUT */
iov.iov_base = input_packet;
iov.iov_len = sizeof(input_packet);
msghdr.msg_iov = &iov;
msghdr.msg_iovlen = 1;
msghdr.msg_control = NULL;
msghdr.msg_controllen = 0;
msghdr.msg_name = &addr; /* or NULL, optional */
msghdr.msg_namelen = sizeof(addr); /* or zero, optional */
msghdr.msg_flags = 0;
count = oob_recvmsg(s, &msghdr, NULL, 0);
if (count < 0)
error(1, errno, "oob_recvmsg() failed");
/* OUTPUT */
iov.iov_base = output_packet;
iov.iov_len = sizeof(output_packet);
msghdr.msg_iov = &iov;
msghdr.msg_iovlen = 1;
msghdr.msg_control = NULL;
msghdr.msg_controllen = 0;
msghdr.msg_name = NULL; /* Optional, use bound device if NULL. */
msghdr.msg_namelen = 0;
msghdr.msg_flags = 0;
count = oob_sendmsg(s, &msghdr, NULL, 0);
if (count < 0)
error(1, errno, "oob_sendmsg() failed");
Threads issuing the oob_recvmsg() and/or oob_sendmsg() calls must be attached to the EVL core.