NG_SOCKET(4)
π NG_SOCKET π
okay so bestie, we're in section 4 of the Kernel Interfaces Manual, and this page is literally called ng_socket β it's the manual for the netgraph socket node type. netgraph? yeah. socket node? yeah. it's giving both. let's get into it π«Ά
β¨ SYNOPSIS β¨
#include <sys/types.h>
#include <netgraph/ng_socket.h>
πΈ DESCRIPTION πΈ
so. a socket node is both a BSD socket and a netgraph node. not one or the other. both. main character energy fr fr π
the ng_socket node type is what lets user-mode processes join in on the kernel's netgraph(4) networking subsystem, using the plain old BSD socket interface. cute right?
β οΈ okay important: the process must have root privileges to be able to create netgraph sockets. but once it's created, any process that has one may use it. so it's like a velvet rope situation at the door only π
to make a new ng_socket node, you create a new socket of type NG_CONTROL in the protocol family PF_NETGRAPH, using the socket(2) system call. easy.
any control messages that the node receives and that don't have a cookie value of NGM_SOCKET_COOKIE get handed up to the process, via recvfrom(2). the socket address argument there is a struct sockaddr_ng containing the sender's netgraph address π¬
and conversely! you can send control messages to any node by calling sendto(2) and supplying the recipient's address in a struct sockaddr_ng. also, the bind(2) system call may be used to assign a global netgraph name to the node. iconic.
now, to actually transmit and receive netgraph data packets, you need a NG_DATA socket too β also created with socket(2) β and it has to be associated with a ng_socket node. here's the thing tho: NG_DATA sockets do not automatically have nodes associated with them. nope. they get bound to a specific node via the connect(2) system call, and the address argument you pass is the netgraph address of the ng_socket node you already created.
once a data socket is associated with a node:
- any data packets received by the node are read using
recvfrom(2) - any packets to be sent out from the node are written using
sendto(2)
and for data sockets specifically, the struct sockaddr_ng contains the name of the hook on which the data was received or should be sent π
okay and here's a special case that's lowkey genius: to allow netgraph data sockets to be used as stdin or stdout on naive programs, a sendto(2) with a NULL sockaddr pointer, a send(2), or a write(2) will succeed in the case where there is exactly ONE hook attached to the socket node β because then the path is unambiguous. one hook. that's the whole rule. β¨
also there's a user library that simplifies using netgraph sockets; peep netgraph(3) π¦
π HOOKS π
this node type supports hooks with arbitrary names (as long as they're unique, bestie, we're not out here doing duplicates) and it always accepts hook connection requests. no gatekeeping π
π CONTROL MESSAGES π
this node type supports the generic control messages, plus these two:
NGM_SOCK_CMD_NOLINGERβ when the last hook is removed from this node, it will shut down as if it had received aNGM_SHUTDOWNmessage. attempts to access the sockets associated will returnENOTCONN. πNGM_SOCK_CMD_LINGERβ this is the default mode. when the last hook is removed, the node will continue to exist, ready to accept new hooks, until it is explicitly shut down. patient queen πΈ
and, all other messages with neither the NGM_SOCKET_COOKIE nor the NGM_GENERIC_COOKIE will be passed unaltered up the NG_CONTROL socket. periodt.
π SHUTDOWN π
this node type shuts down and disappears when both the associated NG_CONTROL and NG_DATA sockets have been closed, or when a NGM_SHUTDOWN control message is received.
in that latter case, attempts to write to the still-open sockets will return ENOTCONN. rude but okay.
and if the NGM_SOCK_CMD_NOLINGER message has been received, then closure of the last hook will also initiate a shutdown of the node.
β SEE ALSO β
π HISTORY π
the ng_socket node type was implemented in FreeBSD 4.0. old money π
π«Ά AUTHORS π«Ά
Julian Elischer <julian@FreeBSD.org> β thank you king π
π BUGS π
ngl, a couple things:
- it is not possible to reject the connection of a hook, though any data received on that hook can certainly be ignored. so like, you can't say no, but you can ignore them. we've all been there.
- the controlling process is not notified of all events that an in-kernel node would be notified of β e.g. a new hook, or hook removal. some node-initiated messages should be defined for this purpose (to be sent up the control socket). so that's... a known gap. noted. π
and that's the whole page bestie!! this one came from the Debian crew, dated January 19, 1999 β a whole vintage moment π°οΈβ¨ go forth and netgraph responsibly π
π¦ where this page comes from
- debian bookworm: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- debian trixie: freebsd-manpages 12.2-2 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu jammy: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu noble: freebsd-manpages 12.2-1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu questing: freebsd-manpages 12.2-2
- ubuntu resolute: freebsd-manpages 12.2-2build1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- ubuntu stonking: freebsd-manpages 12.2-2build1 Β· BSD-2-Clause-FreeBSD AND BSD-4-Clause
- Copyright (c) 1996-1999 Whistle Communications, Inc
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms