SEND(4) | Device Drivers Manual | SEND(4) |
send
— Kernel side
support for Secure Neighbor Discovery (SeND)
#include
<sys/socket.h>
#include <netinet/in.h>
#include <netinet6/send.h>
int
socket
(PF_INET6,
SOCK_RAW,
IPPROTO_SEND);
To load the driver as a module at boot time, place the following line in loader.conf(5):
send_load="YES"
IPv6 nodes use the Neighbor Discovery Protocol (NDP) to discover other nodes on the link, to determine their link-layer addresses to find routers, and to maintain reachability information about the paths to active members. NDP is vulnerable to various attacks [RFC3756]. Secure Neighbor Discovery is a set of extensions to NDP that counter threats to NDP [RFC3971].
Kernel side support for SeND consists of a kernel module with
hooks that divert relevant packets (Neighbor Solicitations, Neighbor
Advertisements, Router Solicitations, Router Advertisements and Redirects)
from the NDP stack, send them to user space on a dedicated socket and
reinject them back for further processing. Hooks are triggered only if the
send
module is loaded.
The native SeND socket is similar to a raw IP socket, but with its
own, internal pseudo-protocol (IPPROTO_SEND). Struct sockaddr_send is
defined in
<netinet6/send.h>
. It
defines the total length of the structure, the address family, packet's
incoming or outgoing direction from the interface's point of view, and the
interface index.
struct sockaddr_send { unsigned char send_len; /* total length */ sa_family_t send_family; /* address family */ int send_direction; int send_ifidx; char send_zero[8]; };
The address family is always AF_INET6. The
send_direction variable denotes the direction of the
packet from the interface's point of view and has either the value
SND_IN
or SND_OUT
. The
send_ifidx variable is the interface index of the
receiving or sending interface. The send_zero variable
is padding and must always be zero.
In case that no user space application is connected to the send socket, processing continues normally as if the module was not loaded.
The input hook is named after the input path of the incoming or
outgoing NDP packets, on the way from the wire, through the nd6 stack, to
user space. Relevant packets are identified by adding an mbuf_tag (see
mbuf_tags(9)) to the mbuf(9), if the
send
module is loaded. It is then passed on to the
kernel-userland interface for either cryptographic protection or validation
by the SeND application. The hook takes an argument that describes the
direction of the packet, both in case of incoming and outgoing packets.
SND_IN
is the direction of the incoming packets that
are usually protected by the SeND options and then sent to user space for
cryptographic validation. SND_OUT
is the outgoing
direction. It describes both reply and locally originated outgoing packets
that are sent to user space for the addition of SeND options.
The incoming ND packet from the wire:
kernelspace ( userspace ) incoming SeND/ND packet ( | ) v ( SND_IN ) ( icmp6_input() -> send_input_hook ---> send socket ----+ : ) | : # # ( | normal : # # ) v processing : # send.ko # ( SeND application path : # # ) | : # # ( | v ) | icmp6/nd6_??_input() <- protocol switch <--- send socket <---+ | structure (IPPPROTO_SEND) ) | ( SND_IN ) ( v ) continue normal ND processing (
Outgoing ND packet (reply or locally triggered):
kernelspace ( userspace ) nd6_na_input() ( +PACKET_TAG_ND_OUTGOING ) | ) | outgoing packet ( | | ) | v ( | icmp6_redirect_output() ) | nd6_ns_output() ( | nd6_na_output() ) | +PACKET_TAG_ND_OUTGOING ( | | ) | +-----------<- rip6_output() <----------)----- rtsol/rtadvd/.. | | +PACKET_TAG_ND_OUTGOING ( | v ) | ip6_output() ( | | ) +-------->-+ ( | ) v ( SND_OUT ) ( nd6_output_lle() -> send_input_hook ---> send socket ----+ -PACKET_TAG_ND_OUTGOING ) | : # # ( | normal : # # ) v processing : # send.ko # ( SeND application path : # # ) | : # # ( | v ) | (*ifp->if_output)() <- protocol switch <--- send socket <---+ | structure (IPPPROTO_SEND) ) | ( SND_OUT ) ( v ) continue with normal packet output (
A socket operation may fail with one of the following errors returned:
EEXIST
]ENOBUFS
]ENOSYS
]ENOENT
]The send
module first appeared in
FreeBSD 9.0.
Ana Kukec <anchie@FreeBSD.org>, University of Zagreb
Due to the lack of NDP locking, it is currently not possible to
unload the send
module.
September 19, 2010 | Debian |