aboutsummaryrefslogtreecommitdiff
path: root/core/sys
diff options
context:
space:
mode:
Diffstat (limited to 'core/sys')
-rw-r--r--core/sys/freebsd/syscalls.odin504
-rw-r--r--core/sys/freebsd/types.odin1579
2 files changed, 2083 insertions, 0 deletions
diff --git a/core/sys/freebsd/syscalls.odin b/core/sys/freebsd/syscalls.odin
new file mode 100644
index 000000000..7aebde8a7
--- /dev/null
+++ b/core/sys/freebsd/syscalls.odin
@@ -0,0 +1,504 @@
+package sys_freebsd
+
+import "base:intrinsics"
+import "core:c"
+
+// FreeBSD 15 syscall numbers
+// See: https://alfonsosiciliano.gitlab.io/posts/2023-08-28-freebsd-15-system-calls.html
+
+SYS_open : uintptr : 5
+SYS_close : uintptr : 6
+SYS_getpid : uintptr : 20
+SYS_recvfrom : uintptr : 29
+SYS_accept : uintptr : 30
+SYS_fcntl : uintptr : 92
+SYS_socket : uintptr : 97
+SYS_connect : uintptr : 98
+SYS_bind : uintptr : 104
+SYS_listen : uintptr : 106
+SYS_sendto : uintptr : 133
+SYS_shutdown : uintptr : 134
+SYS_setsockopt : uintptr : 105
+SYS_sysctl : uintptr : 202
+SYS__umtx_op : uintptr : 454
+SYS_accept4 : uintptr : 541
+
+//
+// Odin syscall wrappers
+//
+
+// Open or create a file for reading, writing or executing.
+//
+// The open() function appeared in Version 1 AT&T UNIX.
+// The openat() function was introduced in FreeBSD 8.0.
+open :: proc "contextless" (path: string, flags: File_Status_Flags, mode: int = 0o000) -> (Fd, Errno) {
+ result, ok := intrinsics.syscall_bsd(SYS_open,
+ cast(uintptr)raw_data(path),
+ cast(uintptr)transmute(c.int)flags,
+ cast(uintptr)mode)
+
+ if !ok {
+ return 0, cast(Errno)result
+ }
+
+ return cast(Fd)result, nil
+}
+
+// Delete a descriptor.
+//
+// The open() function appeared in Version 1 AT&T UNIX.
+close :: proc "contextless" (fd: Fd) -> Errno {
+ result, _ := intrinsics.syscall_bsd(SYS_close,
+ cast(uintptr)fd)
+
+ return cast(Errno)result
+}
+
+// Get parent or calling process identification.
+//
+// The getpid() function appeared in Version 7 AT&T UNIX.
+getpid :: proc "contextless" () -> pid_t {
+ // always succeeds
+ result, _ := intrinsics.syscall_bsd(SYS_getpid)
+ return cast(pid_t)result
+}
+
+// Receive message(s) from a socket.
+//
+// The recv() function appeared in 4.2BSD.
+// The recvmmsg() function appeared in FreeBSD 11.0.
+recvfrom :: proc "contextless" (s: Fd, buf: []u8, flags: Recv_Flags, from: ^$T) -> (int, Errno)
+where
+ intrinsics.type_is_subtype_of(T, Socket_Address_Header)
+{
+ fromlen: socklen_t = size_of(T)
+
+ result, ok := intrinsics.syscall_bsd(SYS_recvfrom,
+ cast(uintptr)s,
+ cast(uintptr)raw_data(buf),
+ cast(uintptr)len(buf),
+ cast(uintptr)flags,
+ cast(uintptr)from,
+ cast(uintptr)fromlen)
+
+ if !ok {
+ return 0, cast(Errno)result
+ }
+
+ return cast(int)result, nil
+}
+
+// Receive message(s) from a socket.
+//
+// The recv() function appeared in 4.2BSD.
+// The recvmmsg() function appeared in FreeBSD 11.0.
+recv :: proc "contextless" (s: Fd, buf: []u8, flags: Recv_Flags) -> (int, Errno) {
+ // This is a wrapper over recvfrom().
+ result, ok := intrinsics.syscall_bsd(SYS_recvfrom,
+ cast(uintptr)s,
+ cast(uintptr)raw_data(buf),
+ cast(uintptr)len(buf),
+ cast(uintptr)flags,
+ 0,
+ 0)
+
+ if !ok {
+ return 0, cast(Errno)result
+ }
+
+ return cast(int)result, nil
+}
+
+// Accept a connection on a socket.
+//
+// The accept() system call appeared in 4.2BSD.
+accept_T :: proc "contextless" (s: Fd, sockaddr: ^$T) -> (Fd, Errno)
+where
+ intrinsics.type_is_subtype_of(T, Socket_Address_Header)
+{
+ // sockaddr must contain a valid pointer, or this will segfault because
+ // we're telling the syscall that there's memory available to write to.
+ addrlen: socklen_t = size_of(T)
+
+ result, ok := intrinsics.syscall_bsd(SYS_accept,
+ cast(uintptr)s,
+ cast(uintptr)sockaddr,
+ cast(uintptr)&addrlen)
+
+ if !ok {
+ return 0, cast(Errno)result
+ }
+
+ sockaddr.len = cast(u8)addrlen
+
+ return cast(Fd)result, nil
+}
+
+
+// Accept a connection on a socket.
+//
+// The accept() system call appeared in 4.2BSD.
+accept_nil :: proc "contextless" (s: Fd) -> (Fd, Errno) {
+ result, ok := intrinsics.syscall_bsd(SYS_accept,
+ cast(uintptr)s,
+ cast(uintptr)0,
+ cast(uintptr)0)
+
+ if !ok {
+ return 0, cast(Errno)result
+ }
+
+ return cast(Fd)result, nil
+}
+
+accept :: proc { accept_T, accept_nil }
+
+// File control.
+//
+// The fcntl() system call appeared in 4.2BSD.
+// The F_DUP2FD constant first appeared in FreeBSD 7.1.
+//
+// NOTE: If you know at compile-time what command you're calling, use one of the
+// `fcntl_*` procedures instead to preserve type safety.
+fcntl :: proc "contextless" (fd: Fd, cmd: File_Control_Command, arg: c.int) -> (int, Errno) {
+ result, ok := intrinsics.syscall_bsd(SYS_fcntl,
+ cast(uintptr)fd,
+ cast(uintptr)cmd,
+ cast(uintptr)arg)
+
+ if !ok {
+ return 0, cast(Errno)result
+ }
+
+ return cast(int)result, nil
+}
+
+// TODO: Implement more type-safe fcntl commands.
+
+fcntl_dupfd :: proc "contextless" (fd: Fd, newfd: Fd) -> (Fd, Errno) {
+ result, ok := intrinsics.syscall_bsd(SYS_fcntl,
+ cast(uintptr)fd,
+ cast(uintptr)File_Control_Command.DUPFD,
+ cast(uintptr)newfd)
+
+ if !ok {
+ return 0, cast(Errno)result
+ }
+
+ return cast(Fd)result, nil
+}
+
+fcntl_getfd :: proc "contextless" (fd: Fd) -> (bool, Errno) {
+ result, ok := intrinsics.syscall_bsd(SYS_fcntl,
+ cast(uintptr)fd,
+ cast(uintptr)File_Control_Command.GETFD)
+
+ if !ok {
+ return false, cast(Errno)result
+ }
+
+ return result & FD_CLOEXEC > 0, nil
+}
+
+fcntl_setfd :: proc "contextless" (fd: Fd, close_on_exec: bool) -> Errno {
+ result, _ := intrinsics.syscall_bsd(SYS_fcntl,
+ cast(uintptr)fd,
+ cast(uintptr)File_Control_Command.SETFD,
+ cast(uintptr)(close_on_exec ? FD_CLOEXEC : 0))
+
+ return cast(Errno)result
+}
+
+fcntl_getfl :: proc "contextless" (fd: Fd) -> (File_Status_Flags, Errno) {
+ result, ok := intrinsics.syscall_bsd(SYS_fcntl,
+ cast(uintptr)fd,
+ cast(uintptr)File_Control_Command.GETFL)
+
+ if !ok {
+ return nil, cast(Errno)result
+ }
+
+ return transmute(File_Status_Flags)cast(c.int)result, nil
+}
+
+fcntl_setfl :: proc "contextless" (fd: Fd, flags: File_Status_Flags) -> Errno {
+ result, _ := intrinsics.syscall_bsd(SYS_fcntl,
+ cast(uintptr)fd,
+ cast(uintptr)File_Control_Command.SETFL,
+ cast(uintptr)transmute(c.int)flags)
+
+ return cast(Errno)result
+}
+
+fcntl_getown :: proc "contextless" (fd: Fd) -> (pid_t, Errno) {
+ result, ok := intrinsics.syscall_bsd(SYS_fcntl,
+ cast(uintptr)fd,
+ cast(uintptr)File_Control_Command.GETOWN)
+
+ if !ok {
+ return 0, cast(Errno)result
+ }
+
+ return cast(pid_t)result, nil
+}
+
+fcntl_setown :: proc "contextless" (fd: Fd, pid: pid_t) -> Errno {
+ result, _ := intrinsics.syscall_bsd(SYS_fcntl,
+ cast(uintptr)fd,
+ cast(uintptr)File_Control_Command.SETOWN,
+ cast(uintptr)pid)
+
+ return cast(Errno)result
+}
+
+fcntl_getlk :: proc "contextless" (fd: Fd, flock: ^File_Lock) -> Errno {
+ result, _ := intrinsics.syscall_bsd(SYS_fcntl,
+ cast(uintptr)fd,
+ cast(uintptr)File_Control_Command.GETLK,
+ cast(uintptr)flock)
+
+ return cast(Errno)result
+}
+
+fcntl_setlk :: proc "contextless" (fd: Fd, flock: ^File_Lock) -> Errno {
+ result, _ := intrinsics.syscall_bsd(SYS_fcntl,
+ cast(uintptr)fd,
+ cast(uintptr)File_Control_Command.SETLK,
+ cast(uintptr)flock)
+
+ return cast(Errno)result
+}
+
+fcntl_add_seals :: proc "contextless" (fd: Fd, seals: File_Seals) -> Errno {
+ result, _ := intrinsics.syscall_bsd(SYS_fcntl,
+ cast(uintptr)fd,
+ cast(uintptr)File_Control_Command.ADD_SEALS,
+ cast(uintptr)transmute(c.int)seals)
+
+ return cast(Errno)result
+}
+
+fcntl_get_seals :: proc "contextless" (fd: Fd) -> (File_Seals, Errno) {
+ result, ok := intrinsics.syscall_bsd(SYS_fcntl,
+ cast(uintptr)fd,
+ cast(uintptr)File_Control_Command.GET_SEALS)
+
+ if !ok {
+ return nil, cast(Errno)result
+ }
+
+ return transmute(File_Seals)cast(c.int)result, nil
+}
+
+//
+// End type-safe fcntl commands.
+//
+
+// Create an endpoint for communication.
+//
+// The socket() system call appeared in 4.2BSD.
+socket :: proc "contextless" (domain: Protocol_Family, type: Socket_Type, protocol: Protocol) -> (Fd, Errno) {
+ result, ok := intrinsics.syscall_bsd(SYS_socket,
+ cast(uintptr)domain,
+ cast(uintptr)type,
+ cast(uintptr)protocol)
+
+ if !ok {
+ return 0, cast(Errno)result
+ }
+
+ return cast(Fd)result, nil
+}
+
+// Initiate a connection on a socket.
+//
+// The connect() system call appeared in 4.2BSD.
+connect :: proc "contextless" (fd: Fd, sockaddr: ^$T, addrlen: socklen_t) -> Errno
+where
+ intrinsics.type_is_subtype_of(T, Socket_Address_Header)
+{
+ result, _ := intrinsics.syscall_bsd(SYS_connect,
+ cast(uintptr)fd,
+ cast(uintptr)sockaddr,
+ cast(uintptr)addrlen)
+
+ return cast(Errno)result
+}
+
+
+// Assign a local protocol address to a socket.
+//
+// The bind() system call appeared in 4.2BSD.
+bind :: proc "contextless" (s: Fd, sockaddr: ^$T, addrlen: socklen_t) -> Errno
+where
+ intrinsics.type_is_subtype_of(T, Socket_Address_Header)
+{
+ result, _ := intrinsics.syscall_bsd(SYS_bind,
+ cast(uintptr)s,
+ cast(uintptr)sockaddr,
+ cast(uintptr)addrlen)
+
+ return cast(Errno)result
+}
+
+// Listen for connections on a socket.
+//
+// The listen() system call appeared in 4.2BSD.
+listen :: proc "contextless" (s: Fd, backlog: int) -> Errno {
+ result, _ := intrinsics.syscall_bsd(SYS_listen,
+ cast(uintptr)s,
+ cast(uintptr)backlog)
+
+ return cast(Errno)result
+}
+
+// Send message(s) from a socket.
+//
+// The send() function appeared in 4.2BSD.
+// The sendmmsg() function appeared in FreeBSD 11.0.
+sendto :: proc "contextless" (s: Fd, msg: []u8, flags: Send_Flags, to: ^$T) -> (int, Errno)
+where
+ intrinsics.type_is_subtype_of(T, Socket_Address_Header)
+{
+ result, ok := intrinsics.syscall_bsd(SYS_sendto,
+ cast(uintptr)s,
+ cast(uintptr)raw_data(msg),
+ cast(uintptr)len(msg),
+ cast(uintptr)flags,
+ cast(uintptr)to,
+ cast(uintptr)to.len)
+
+ if !ok {
+ return 0, cast(Errno)result
+ }
+
+ return cast(int)result, nil
+}
+
+// Send message(s) from a socket.
+//
+// The send() function appeared in 4.2BSD.
+// The sendmmsg() function appeared in FreeBSD 11.0.
+send :: proc "contextless" (s: Fd, msg: []u8, flags: Send_Flags) -> (int, Errno) {
+ // This is a wrapper over sendto().
+ result, ok := intrinsics.syscall_bsd(SYS_sendto,
+ cast(uintptr)s,
+ cast(uintptr)raw_data(msg),
+ cast(uintptr)len(msg),
+ cast(uintptr)flags,
+ 0,
+ 0)
+
+ if !ok {
+ return 0, cast(Errno)result
+ }
+
+ return cast(int)result, nil
+}
+
+// Disable sends and/or receives on a socket.
+//
+// The shutdown() system call appeared in 4.2BSD.
+shutdown :: proc "contextless" (s: Fd, how: Shutdown_Method) -> Errno {
+ result, _ := intrinsics.syscall_bsd(SYS_shutdown,
+ cast(uintptr)s,
+ cast(uintptr)how)
+
+ return cast(Errno)result
+}
+
+// Get and set options on sockets.
+//
+// The getsockopt() and setsockopt() system calls appeared in 4.2BSD.
+setsockopt :: proc "contextless" (s: Fd, level: Valid_Socket_Option_Level, optname: Socket_Option, optval: rawptr, optlen: socklen_t) -> Errno {
+ real_level: uintptr
+ switch which in level {
+ case Protocol_Family: real_level = cast(uintptr)which
+ case Socket_Option_Level: real_level = cast(uintptr)which
+ }
+
+ result, _ := intrinsics.syscall_bsd(SYS_setsockopt,
+ cast(uintptr)s,
+ real_level,
+ cast(uintptr)optname,
+ cast(uintptr)optval,
+ cast(uintptr)optlen)
+
+ return cast(Errno)result
+}
+
+// Get or set system information.
+//
+// The sysctl() function first appeared in 4.4BSD.
+sysctl :: proc "contextless" (mib: []MIB_Identifier, oldp: rawptr, oldlenp: ^c.size_t, newp: rawptr, newlen: c.size_t) -> Errno {
+ result, _ := intrinsics.syscall_bsd(SYS_sysctl,
+ cast(uintptr)raw_data(mib),
+ cast(uintptr)len(mib),
+ cast(uintptr)oldp,
+ cast(uintptr)oldlenp,
+ cast(uintptr)newp,
+ cast(uintptr)newlen)
+
+ return cast(Errno)result
+}
+
+// Interface for implementation of userspace threading synchronization primitives.
+//
+// The _umtx_op() system call is non-standard and is used by the 1:1 Threading
+// Library (libthr, -lthr) to implement IEEE Std 1003.1-2001 (“POSIX.1”)
+// pthread(3) functionality.
+_umtx_op :: proc "contextless" (obj: rawptr, op: Mutex_Operation, val: c.ulong, uaddr, uaddr2: rawptr) -> Errno {
+ result, _ := intrinsics.syscall_bsd(SYS__umtx_op,
+ cast(uintptr)obj,
+ cast(uintptr)op,
+ cast(uintptr)val,
+ cast(uintptr)uaddr,
+ cast(uintptr)uaddr2)
+
+ return cast(Errno)result
+}
+
+// Accept a connection on a socket.
+//
+// The accept4() system call appeared in FreeBSD 10.0.
+accept4_T :: proc "contextless" (s: Fd, sockaddr: ^$T, flags: Socket_Flags = {}) -> (Fd, Errno)
+where
+ intrinsics.type_is_subtype_of(T, Socket_Address_Header)
+{
+ // sockaddr must contain a valid pointer, or this will segfault because
+ // we're telling the syscall that there's memory available to write to.
+ addrlen: u32 = size_of(T)
+
+ result, ok := intrinsics.syscall_bsd(SYS_accept4,
+ cast(uintptr)s,
+ cast(uintptr)sockaddr,
+ cast(uintptr)&addrlen,
+ cast(uintptr)transmute(c.int)flags)
+
+ if !ok {
+ return 0, cast(Errno)result
+ }
+
+ sockaddr.len = cast(u8)addrlen
+
+ return cast(Fd)result, nil
+}
+
+// Accept a connection on a socket.
+//
+// The accept4() system call appeared in FreeBSD 10.0.
+accept4_nil :: proc "contextless" (s: Fd, flags: Socket_Flags = {}) -> (Fd, Errno) {
+ result, ok := intrinsics.syscall_bsd(SYS_accept4,
+ cast(uintptr)s,
+ cast(uintptr)0,
+ cast(uintptr)0,
+ cast(uintptr)transmute(c.int)flags)
+
+ if !ok {
+ return 0, cast(Errno)result
+ }
+
+ return cast(Fd)result, nil
+}
+
+accept4 :: proc { accept4_nil, accept4_T }
diff --git a/core/sys/freebsd/types.odin b/core/sys/freebsd/types.odin
new file mode 100644
index 000000000..8959c0703
--- /dev/null
+++ b/core/sys/freebsd/types.odin
@@ -0,0 +1,1579 @@
+package sys_freebsd
+
+import "core:c"
+
+// These definitions have been extracted from a system running FreeBSD 14.0-RELEASE.
+// Most comments come from system header files.
+//
+// Where applicable, original C struct and define names are indicated in line
+// comments above Odin declarations.
+//
+// This data is separated into blocks by original header file. If you happen to
+// add or change something in this file, mind the organizational structure.
+
+Fd :: distinct c.int
+
+//
+// #include <x86/_types.h>
+// &
+// #include <arm/_types.h>
+//
+
+time_t :: distinct i64
+
+//
+// #include <sys/_types.h>
+//
+
+off_t :: distinct i64
+pid_t :: distinct i32
+sa_family_t :: distinct u8
+socklen_t :: distinct u32
+suseconds_t :: distinct c.long /* microseconds (signed) */
+
+//
+// #include <sys/types.h>
+//
+
+in_port_t :: distinct u16be
+
+//
+// #include <sys/_timespec.h>
+//
+
+timespec :: struct {
+ sec: time_t, /* seconds */
+ nsec: c.long, /* and nanoseconds */
+}
+
+//
+// #include <sys/_timeval.h>
+//
+
+timeval :: struct {
+ sec: time_t, /* seconds */
+ usec: suseconds_t, /* and microseconds */
+}
+
+//
+// #include <sys/errno.h>
+//
+
+Errno :: enum c.int {
+ NONE = 0,
+ EPERM = 1,
+ ENOENT = 2,
+ ESRCH = 3,
+ EINTR = 4,
+ EIO = 5,
+ ENXIO = 6,
+ E2BIG = 7,
+ ENOEXEC = 8,
+ EBADF = 9,
+ ECHILD = 10,
+ EDEADLK = 11,
+ ENOMEM = 12,
+ EACCES = 13,
+ EFAULT = 14,
+ ENOTBLK = 15,
+ EBUSY = 16,
+ EEXIST = 17,
+ EXDEV = 18,
+ ENODEV = 19,
+ ENOTDIR = 20,
+ EISDIR = 21,
+ EINVAL = 22,
+ ENFILE = 23,
+ EMFILE = 24,
+ ENOTTY = 25,
+ ETXTBSY = 26,
+ EFBIG = 27,
+ ENOSPC = 28,
+ ESPIPE = 29,
+ EROFS = 30,
+ EMLINK = 31,
+ EPIPE = 32,
+ EDOM = 33,
+ ERANGE = 34,
+ EAGAIN = 35,
+ EWOULDBLOCK = EAGAIN,
+ EINPROGRESS = 36,
+ EALREADY = 37,
+ ENOTSOCK = 38,
+ EDESTADDRREQ = 39,
+ EMSGSIZE = 40,
+ EPROTOTYPE = 41,
+ ENOPROTOOPT = 42,
+ EPROTONOSUPPORT = 43,
+ ESOCKTNOSUPPORT = 44,
+ EOPNOTSUPP = 45,
+ ENOTSUP = EOPNOTSUPP,
+ EPFNOSUPPORT = 46,
+ EAFNOSUPPORT = 47,
+ EADDRINUSE = 48,
+ EADDRNOTAVAIL = 49,
+ ENETDOWN = 50,
+ ENETUNREACH = 51,
+ ENETRESET = 52,
+ ECONNABORTED = 53,
+ ECONNRESET = 54,
+ ENOBUFS = 55,
+ EISCONN = 56,
+ ENOTCONN = 57,
+ ESHUTDOWN = 58,
+ ETOOMANYREFS = 59,
+ ETIMEDOUT = 60,
+ ECONNREFUSED = 61,
+ ELOOP = 62,
+ ENAMETOOLONG = 63,
+ EHOSTDOWN = 64,
+ EHOSTUNREACH = 65,
+ ENOTEMPTY = 66,
+ EPROCLIM = 67,
+ EUSERS = 68,
+ EDQUOT = 69,
+ ESTALE = 70,
+ EREMOTE = 71,
+ EBADRPC = 72,
+ ERPCMISMATCH = 73,
+ EPROGUNAVAIL = 74,
+ EPROGMISMATCH = 75,
+ EPROCUNAVAIL = 76,
+ ENOLCK = 77,
+ ENOSYS = 78,
+ EFTYPE = 79,
+ EAUTH = 80,
+ ENEEDAUTH = 81,
+ EIDRM = 82,
+ ENOMSG = 83,
+ EOVERFLOW = 84,
+ ECANCELED = 85,
+ EILSEQ = 86,
+ ENOATTR = 87,
+ EDOOFUS = 88,
+ EBADMSG = 89,
+ EMULTIHOP = 90,
+ ENOLINK = 91,
+ EPROTO = 92,
+ ENOTCAPABLE = 93,
+ ECAPMODE = 94,
+ ENOTRECOVERABLE = 95,
+ EOWNERDEAD = 96,
+ EINTEGRITY = 97,
+}
+
+//
+// #include <sys/socket.h>
+//
+
+/*
+ * Types
+ */
+// #define SOCK_*
+Socket_Type :: enum c.int {
+ STREAM = 1, /* stream socket */
+ DGRAM = 2, /* datagram socket */
+ RAW = 3, /* raw-protocol interface */
+ RDM = 4, /* reliably-delivered message */
+ SEQPACKET = 5, /* sequenced packet stream */
+
+ /*
+ * Creation flags, OR'ed into socket() and socketpair() type argument.
+ */
+ CLOEXEC = 0x10000000,
+ NONBLOCK = 0x20000000,
+}
+
+Socket_Flag_Index :: enum c.int {
+ CLOEXEC = 28, // 0x10000000
+ NONBLOCK = 29, // 0x20000000
+}
+
+Socket_Flags :: bit_set[Socket_Flag_Index; c.int]
+
+/*
+ * Option flags per-socket.
+ */
+// #define SO_*
+Socket_Option :: enum c.int {
+ DEBUG = 0x00000001, /* turn on debugging info recording */
+ ACCEPTCONN = 0x00000002, /* socket has had listen() */
+ REUSEADDR = 0x00000004, /* allow local address reuse */
+ KEEPALIVE = 0x00000008, /* keep connections alive */
+ DONTROUTE = 0x00000010, /* just use interface addresses */
+ BROADCAST = 0x00000020, /* permit sending of broadcast msgs */
+ USELOOPBACK = 0x00000040, /* bypass hardware when possible */
+ LINGER = 0x00000080, /* linger on close if data present */
+ OOBINLINE = 0x00000100, /* leave received OOB data in line */
+ REUSEPORT = 0x00000200, /* allow local address & port reuse */
+ TIMESTAMP = 0x00000400, /* timestamp received dgram traffic */
+ NOSIGPIPE = 0x00000800, /* no SIGPIPE from EPIPE */
+ ACCEPTFILTER = 0x00001000, /* there is an accept filter */
+ BINTIME = 0x00002000, /* timestamp received dgram traffic */
+ NO_OFFLOAD = 0x00004000, /* socket cannot be offloaded */
+ NO_DDP = 0x00008000, /* disable direct data placement */
+ REUSEPORT_LB = 0x00010000, /* reuse with load balancing */
+ RERROR = 0x00020000, /* keep track of receive errors */
+
+ /*
+ * Additional options, not kept in so_options.
+ */
+ SNDBUF = 0x1001, /* send buffer size */
+ RCVBUF = 0x1002, /* receive buffer size */
+ SNDLOWAT = 0x1003, /* send low-water mark */
+ RCVLOWAT = 0x1004, /* receive low-water mark */
+ SNDTIMEO = 0x1005, /* send timeout */
+ RCVTIMEO = 0x1006, /* receive timeout */
+ ERROR = 0x1007, /* get error status and clear */
+ TYPE = 0x1008, /* get socket type */
+ LABEL = 0x1009, /* socket's MAC label */
+ PEERLABEL = 0x1010, /* socket's peer's MAC label */
+ LISTENQLIMIT = 0x1011, /* socket's backlog limit */
+ LISTENQLEN = 0x1012, /* socket's complete queue length */
+ LISTENINCQLEN = 0x1013, /* socket's incomplete queue length */
+ SETFIB = 0x1014, /* use this FIB to route */
+ USER_COOKIE = 0x1015, /* user cookie (dummynet etc.) */
+ PROTOCOL = 0x1016, /* get socket protocol (Linux name) */
+ PROTOTYPE = PROTOCOL, /* alias for SO_PROTOCOL (SunOS name) */
+ TS_CLOCK = 0x1017, /* clock type used for SO_TIMESTAMP */
+ MAX_PACING_RATE = 0x1018, /* socket's max TX pacing rate (Linux name) */
+ DOMAIN = 0x1019, /* get socket domain */
+
+ TS_REALTIME_MICRO = 0, /* microsecond resolution, realtime */
+ TS_BINTIME = 1, /* sub-nanosecond resolution, realtime */
+ TS_REALTIME = 2, /* nanosecond resolution, realtime */
+ TS_MONOTONIC = 3, /* nanosecond resolution, monotonic */
+ TS_DEFAULT = TS_REALTIME_MICRO,
+ TS_CLOCK_MAX = TS_MONOTONIC,
+}
+
+Valid_Socket_Option_Level :: union #no_nil {
+ Protocol_Family,
+ Socket_Option_Level,
+}
+
+/*
+ * Level number for (get/set)sockopt() to apply to socket itself.
+ */
+// #define SOL_*
+Socket_Option_Level :: enum c.int {
+ SOCKET = 0xffff, /* options for socket level */
+}
+
+// #define MSG_*
+Message_Flag :: enum c.int {
+ OOB = 0x00000001, /* process out-of-band data */
+ PEEK = 0x00000002, /* peek at incoming message */
+ DONTROUTE = 0x00000004, /* send without using routing tables */
+ EOR = 0x00000008, /* data completes record */
+ TRUNC = 0x00000010, /* data discarded before delivery */
+ CTRUNC = 0x00000020, /* control data lost before delivery */
+ WAITALL = 0x00000040, /* wait for full request or error */
+ DONTWAIT = 0x00000080, /* this message should be nonblocking */
+ EOF = 0x00000100, /* data completes connection */
+ /* 0x00000200 unused */
+ /* 0x00000400 unused */
+ /* 0x00000800 unused */
+ /* 0x00001000 unused */
+ NOTIFICATION = 0x00002000, /* SCTP notification */
+ NBIO = 0x00004000, /* FIONBIO mode, used by fifofs */
+ COMPAT = 0x00008000, /* used in sendit() */
+ SOCALLBCK = 0x00010000, /* for use by socket callbacks - soreceive (TCP) */
+ NOSIGNAL = 0x00020000, /* do not generate SIGPIPE on EOF */
+ CMSG_CLOEXEC = 0x00040000, /* make received fds close-on-exec */
+ WAITFORONE = 0x00080000, /* for recvmmsg() */
+}
+
+// Specific subset of `MSG_*` defines that are only for `recv*`.
+Recv_Flags :: enum c.int {
+ NONE = 0,
+ OOB = cast(c.int)Message_Flag.OOB, /* process out-of-band data */
+ PEEK = cast(c.int)Message_Flag.PEEK, /* peek at incoming message */
+ TRUNC = cast(c.int)Message_Flag.TRUNC, /* return real packet or datagram length */
+ WAITALL = cast(c.int)Message_Flag.WAITALL, /* wait for full request or error */
+ DONTWAIT = cast(c.int)Message_Flag.DONTWAIT, /* do not block */
+ CMSG_CLOEXEC = cast(c.int)Message_Flag.CMSG_CLOEXEC, /* set received fds close-on-exec */
+ WAITFORONE = cast(c.int)Message_Flag.WAITFORONE, /* do not block after receiving the first message */
+}
+
+// Specific subset of `MSG_*` defines that are only for `send*`.
+Send_Flags :: enum c.int {
+ NONE = 0,
+ OOB = cast(c.int)Message_Flag.OOB, /* process out-of-band data */
+ DONTROUTE = cast(c.int)Message_Flag.DONTROUTE, /* bypass routing, use direct interface */
+ EOR = cast(c.int)Message_Flag.EOR, /* data completes record */
+ DONTWAIT = cast(c.int)Message_Flag.DONTWAIT, /* do not block */
+ EOF = cast(c.int)Message_Flag.EOF, /* data completes transaction */
+ NOSIGNAL = cast(c.int)Message_Flag.NOSIGNAL, /* do not generate SIGPIPE on EOF */
+}
+
+// Socket address struct header without protocol-specific data.
+//
+// Inherit from this if you want a custom socket address datatype for use with
+// bind(), listen(), et cetera.
+Socket_Address_Header :: struct #packed {
+ len: c.uchar, /* address length */
+ family: Address_Family, /* address family */
+}
+
+// struct sockaddr
+Socket_Address_Basic :: struct #packed {
+ using _: Socket_Address_Header,
+ data: [14]c.char,
+}
+
+/*
+ * howto arguments for shutdown(2), specified by Posix.1g.
+ */
+// #define SHUT_*
+Shutdown_Method :: enum c.int {
+ RD = 0, /* shut down the reading side */
+ WR = 1, /* shut down the writing side */
+ RDWR = 2, /* shut down both sides */
+}
+
+// #define AF_*
+Address_Family :: enum sa_family_t {
+ UNSPEC = 0,
+ LOCAL = 1,
+ UNIX = LOCAL,
+ INET = 2,
+ IMPLINK = 3,
+ PUP = 4,
+ CHAOS = 5,
+ NETBIOS = 6,
+ ISO = 7,
+ OSI = ISO,
+ ECMA = 8,
+ DATAKIT = 9,
+ CCITT = 10,
+ SNA = 11,
+ DECnet = 12,
+ DLI = 13,
+ LAT = 14,
+ HYLINK = 15,
+ APPLETALK = 16,
+ ROUTE = 17,
+ LINK = 18,
+ PSEUDO_XTP = 19,
+ COIP = 20,
+ CNT = 21,
+ PSEUDO_RTIP = 22,
+ IPX = 23,
+ SIP = 24,
+ PSEUDO_PIP = 25,
+ ISDN = 26,
+ E164 = ISDN,
+ PSEUDO_KEY = 27,
+ INET6 = 28,
+ NATM = 29,
+ ATM = 30,
+ NETGRAPH = 32,
+ SLOW = 33,
+ SCLUSTER = 34,
+ ARP = 35,
+ BLUETOOTH = 36,
+ IEEE80211 = 37,
+ NETLINK = 38,
+ INET_SDP = 40,
+ INET6_SDP = 42,
+ HYPERV = 43,
+ DIVERT = 44,
+ MAX = 44,
+ VENDOR00 = 39,
+ VENDOR01 = 41,
+ VENDOR03 = 45,
+ VENDOR04 = 47,
+ VENDOR05 = 49,
+ VENDOR06 = 51,
+ VENDOR07 = 53,
+ VENDOR08 = 55,
+ VENDOR09 = 57,
+ VENDOR10 = 59,
+ VENDOR11 = 61,
+ VENDOR12 = 63,
+ VENDOR13 = 65,
+ VENDOR14 = 67,
+ VENDOR15 = 69,
+ VENDOR16 = 71,
+ VENDOR17 = 73,
+ VENDOR18 = 75,
+ VENDOR19 = 77,
+ VENDOR20 = 79,
+ VENDOR21 = 81,
+ VENDOR22 = 83,
+ VENDOR23 = 85,
+ VENDOR24 = 87,
+ VENDOR25 = 89,
+ VENDOR26 = 91,
+ VENDOR27 = 93,
+ VENDOR28 = 95,
+ VENDOR29 = 97,
+ VENDOR30 = 99,
+ VENDOR31 = 101,
+ VENDOR32 = 103,
+ VENDOR33 = 105,
+ VENDOR34 = 107,
+ VENDOR35 = 109,
+ VENDOR36 = 111,
+ VENDOR37 = 113,
+ VENDOR38 = 115,
+ VENDOR39 = 117,
+ VENDOR40 = 119,
+ VENDOR41 = 121,
+ VENDOR42 = 123,
+ VENDOR43 = 125,
+ VENDOR44 = 127,
+ VENDOR45 = 129,
+ VENDOR46 = 131,
+ VENDOR47 = 133,
+}
+
+// #define PF_*
+Protocol_Family :: enum sa_family_t {
+ UNSPEC = cast(sa_family_t)Address_Family.UNSPEC,
+ LOCAL = cast(sa_family_t)Address_Family.LOCAL,
+ UNIX = LOCAL,
+ INET = cast(sa_family_t)Address_Family.INET,
+ IMPLINK = cast(sa_family_t)Address_Family.IMPLINK,
+ PUP = cast(sa_family_t)Address_Family.PUP,
+ CHAOS = cast(sa_family_t)Address_Family.CHAOS,
+ NETBIOS = cast(sa_family_t)Address_Family.NETBIOS,
+ ISO = cast(sa_family_t)Address_Family.ISO,
+ OSI = cast(sa_family_t)Address_Family.ISO,
+ ECMA = cast(sa_family_t)Address_Family.ECMA,
+ DATAKIT = cast(sa_family_t)Address_Family.DATAKIT,
+ CCITT = cast(sa_family_t)Address_Family.CCITT,
+ SNA = cast(sa_family_t)Address_Family.SNA,
+ DECnet = cast(sa_family_t)Address_Family.DECnet,
+ DLI = cast(sa_family_t)Address_Family.DLI,
+ LAT = cast(sa_family_t)Address_Family.LAT,
+ HYLINK = cast(sa_family_t)Address_Family.HYLINK,
+ APPLETALK = cast(sa_family_t)Address_Family.APPLETALK,
+ ROUTE = cast(sa_family_t)Address_Family.ROUTE,
+ LINK = cast(sa_family_t)Address_Family.LINK,
+ XTP = cast(sa_family_t)Address_Family.PSEUDO_XTP,
+ COIP = cast(sa_family_t)Address_Family.COIP,
+ CNT = cast(sa_family_t)Address_Family.CNT,
+ SIP = cast(sa_family_t)Address_Family.SIP,
+ IPX = cast(sa_family_t)Address_Family.IPX,
+ RTIP = cast(sa_family_t)Address_Family.PSEUDO_RTIP,
+ PIP = cast(sa_family_t)Address_Family.PSEUDO_PIP,
+ ISDN = cast(sa_family_t)Address_Family.ISDN,
+ KEY = cast(sa_family_t)Address_Family.PSEUDO_KEY,
+ INET6 = cast(sa_family_t)Address_Family.INET6,
+ NATM = cast(sa_family_t)Address_Family.NATM,
+ ATM = cast(sa_family_t)Address_Family.ATM,
+ NETGRAPH = cast(sa_family_t)Address_Family.NETGRAPH,
+ SLOW = cast(sa_family_t)Address_Family.SLOW,
+ SCLUSTER = cast(sa_family_t)Address_Family.SCLUSTER,
+ ARP = cast(sa_family_t)Address_Family.ARP,
+ BLUETOOTH = cast(sa_family_t)Address_Family.BLUETOOTH,
+ IEEE80211 = cast(sa_family_t)Address_Family.IEEE80211,
+ NETLINK = cast(sa_family_t)Address_Family.NETLINK,
+ INET_SDP = cast(sa_family_t)Address_Family.INET_SDP,
+ INET6_SDP = cast(sa_family_t)Address_Family.INET6_SDP,
+ DIVERT = cast(sa_family_t)Address_Family.DIVERT,
+ MAX = cast(sa_family_t)Address_Family.MAX,
+}
+
+//
+// /etc/protocols
+//
+
+Protocol :: enum c.int {
+ IP = 0,
+ ICMP = 1,
+ IGMP = 2,
+ GGP = 3,
+ IP_ENCAP = 4,
+ ST2 = 5,
+ TCP = 6,
+ CBT = 7,
+ EGP = 8,
+ IGP = 9,
+ BBN_RCC_MON = 10,
+ NVP_II = 11,
+ PUP = 12,
+ ARGUS = 13,
+ EMCON = 14,
+ XNET = 15,
+ CHAOS = 16,
+ UDP = 17,
+ MUX = 18,
+ DCN_MEAS = 19,
+ HMP = 20,
+ PRM = 21,
+ XNS_IDP = 22,
+ TRUNK_1 = 23,
+ TRUNK_2 = 24,
+ LEAF_1 = 25,
+ LEAF_2 = 26,
+ RDP = 27,
+ IRTP = 28,
+ ISO_TP4 = 29,
+ NETBLT = 30,
+ MFE_NSP = 31,
+ MERIT_INP = 32,
+ DCCP = 33,
+ THREE_PC = 34,
+ IDPR = 35,
+ XTP = 36,
+ DDP = 37,
+ IDPR_CMTP = 38,
+ TP_PlusPlus = 39,
+ IL = 40,
+ IPV6 = 41,
+ SDRP = 42,
+ IPV6_ROUTE = 43,
+ IPV6_FRAG = 44,
+ IDRP = 45,
+ RSVP = 46,
+ GRE = 47,
+ DSR = 48,
+ BNA = 49,
+ ESP = 50,
+ AH = 51,
+ I_NLSP = 52,
+ SWIPE = 53,
+ NARP = 54,
+ MOBILE = 55,
+ TLSP = 56,
+ SKIP = 57,
+ IPV6_ICMP = 58,
+ IPV6_NONXT = 59,
+ IPV6_OPTS = 60,
+ CFTP = 62,
+ SAT_EXPAK = 64,
+ KRYPTOLAN = 65,
+ RVD = 66,
+ IPPC = 67,
+ SAT_MON = 69,
+ VISA = 70,
+ IPCV = 71,
+ CPNX = 72,
+ CPHB = 73,
+ WSN = 74,
+ PVP = 75,
+ BR_SAT_MON = 76,
+ SUN_ND = 77,
+ WB_MON = 78,
+ WB_EXPAK = 79,
+ ISO_IP = 80,
+ VMTP = 81,
+ SECURE_VMTP = 82,
+ VINES = 83,
+ TTP = 84,
+ IPTM = 84,
+ NSFNET_IGP = 85,
+ DGP = 86,
+ TCF = 87,
+ EIGRP = 88,
+ OSPFIGP = 89,
+ Sprite_RPC = 90,
+ LARP = 91,
+ MTP = 92,
+ AX_25 = 93,
+ IPIP = 94,
+ MICP = 95,
+ SCC_SP = 96,
+ ETHERIP = 97,
+ ENCAP = 98,
+ GMTP = 100,
+ IFMP = 101,
+ PNNI = 102,
+ PIM = 103,
+ ARIS = 104,
+ SCPS = 105,
+ QNX = 106,
+ A_N = 107,
+ IPComp = 108,
+ SNP = 109,
+ Compaq_Peer = 110,
+ IPX_in_IP = 111,
+ CARP = 112,
+ PGM = 113,
+ L2TP = 115,
+ DDX = 116,
+ IATP = 117,
+ STP = 118,
+ SRP = 119,
+ UTI = 120,
+ SMP = 121,
+ SM = 122,
+ PTP = 123,
+ ISIS = 124,
+ FIRE = 125,
+ CRTP = 126,
+ CRUDP = 127,
+ SSCOPMCE = 128,
+ IPLT = 129,
+ SPS = 130,
+ PIPE = 131,
+ SCTP = 132,
+ FC = 133,
+ RSVP_E2E_IGNORE = 134,
+ Mobility_Header = 135,
+ UDPLite = 136,
+ MPLS_IN_IP = 137,
+ MANET = 138,
+ HIP = 139,
+ SHIM6 = 140,
+ WESP = 141,
+ ROHC = 142,
+ PFSYNC = 240,
+ DIVERT = 258,
+}
+
+//
+// #include <sys/fcntl.h>
+//
+
+/*
+ * Constants used for fcntl(2)
+ */
+
+/* command values */
+// #define F_*
+File_Control_Command :: enum c.int {
+ DUPFD = 0, /* duplicate file descriptor */
+ GETFD = 1, /* get file descriptor flags */
+ SETFD = 2, /* set file descriptor flags */
+ GETFL = 3, /* get file status flags */
+ SETFL = 4, /* set file status flags */
+ GETOWN = 5, /* get SIGIO/SIGURG proc/pgrp */
+ SETOWN = 6, /* set SIGIO/SIGURG proc/pgrp */
+ OGETLK = 7, /* get record locking information */
+ OSETLK = 8, /* set record locking information */
+ OSETLKW = 9, /* F_SETLK; wait if blocked */
+ DUP2FD = 10, /* duplicate file descriptor to arg */
+ GETLK = 11, /* get record locking information */
+ SETLK = 12, /* set record locking information */
+ SETLKW = 13, /* F_SETLK; wait if blocked */
+ SETLK_REMOTE = 14, /* debugging support for remote locks */
+ READAHEAD = 15, /* read ahead */
+ RDAHEAD = 16, /* Darwin compatible read ahead */
+ DUPFD_CLOEXEC = 17, /* Like F_DUPFD, but FD_CLOEXEC is set */
+ DUP2FD_CLOEXEC = 18, /* Like F_DUP2FD, but FD_CLOEXEC is set */
+ ADD_SEALS = 19,
+ GET_SEALS = 20,
+ ISUNIONSTACK = 21, /* Kludge for libc, don't use it. */
+ KINFO = 22, /* Return kinfo_file for this fd */
+}
+
+/* Seals (F_ADD_SEALS, F_GET_SEALS). */
+// #define F_SEAL_*
+File_Seal_Index :: enum c.int {
+ SEAL = 0, // 0x0001, /* Prevent adding sealings */
+ SHRINK = 1, // 0x0002, /* May not shrink */
+ GROW = 2, // 0x0004, /* May not grow */
+ WRITE = 3, // 0x0008, /* May not write */
+}
+
+File_Seals :: bit_set[File_Seal_Index; c.int]
+
+/* file descriptor flags (F_GETFD, F_SETFD) */
+FD_CLOEXEC :: 1 /* close-on-exec flag */
+
+/* record locking flags (F_GETLK, F_SETLK, F_SETLKW) */
+// #define F_*
+Record_Lock_Flag :: enum c.int {
+ RDLCK = 1, /* shared or read lock */
+ UNLCK = 2, /* unlock */
+ WRLCK = 3, /* exclusive or write lock */
+ UNLCKSYS = 4, /* purge locks for a given system ID */
+ CANCEL = 5, /* cancel an async lock request */
+}
+
+// struct flock
+File_Lock :: struct {
+ start: off_t, /* starting offset */
+ len: off_t, /* len = 0 means until end of file */
+ pid: pid_t, /* lock owner */
+ type: Record_Lock_Flag, /* lock type: read/write, etc. */
+ whence: c.short, /* type of l_start */
+ sysid: c.int, /* remote system id or zero for local */
+}
+
+/*
+ * File status flags: these are used by open(2), fcntl(2).
+ * They are also used (indirectly) in the kernel file structure f_flags,
+ * which is a superset of the open/fcntl flags. Open flags and f_flags
+ * are inter-convertible using OFLAGS(fflags) and FFLAGS(oflags).
+ * Open/fcntl flags begin with O_; kernel-internal flags begin with F.
+ */
+File_Status_Flag :: enum c.int {
+ /* open-only flags */
+ RDONLY = 0x0000, /* open for reading only */
+ WRONLY = 0x0001, /* open for writing only */
+ RDWR = 0x0002, /* open for reading and writing */
+ ACCMODE = 0x0003, /* mask for above modes */
+
+ /**/
+ NONBLOCK = 0x0004, /* no delay */
+ APPEND = 0x0008, /* set append mode */
+ SHLOCK = 0x0010, /* open with shared file lock */
+ EXLOCK = 0x0020, /* open with exclusive file lock */
+ ASYNC = 0x0040, /* signal pgrp when data ready */
+ FSYNC = 0x0080, /* synchronous writes */
+ SYNC = 0x0080, /* POSIX synonym for O_FSYNC */
+ NOFOLLOW = 0x0100, /* don't follow symlinks */
+ CREAT = 0x0200, /* create if nonexistent */
+ TRUNC = 0x0400, /* truncate to zero length */
+ EXCL = 0x0800, /* error if already exists */
+
+ /* Defined by POSIX 1003.1; BSD default, but must be distinct from O_RDONLY. */
+ NOCTTY = 0x8000, /* don't assign controlling terminal */
+
+ /* Attempt to bypass buffer cache */
+ DIRECT = 0x00010000,
+
+ DIRECTORY = 0x00020000, /* Fail if not directory */
+ EXEC = 0x00040000, /* Open for execute only */
+ SEARCH = EXEC,
+
+ /* Defined by POSIX 1003.1-2008; BSD default, but reserve for future use. */
+ TTY_INIT = 0x00080000, /* Restore default termios attributes */
+
+ CLOEXEC = 0x00100000,
+ VERIFY = 0x00200000, /* open only after verification */
+ PATH = 0x00400000, /* fd is only a path */
+ RESOLVE_BENEATH = 0x00800000, /* Do not allow name resolution to walk out of cwd */
+ DSYNC = 0x01000000, /* POSIX data sync */
+ EMPTY_PATH = 0x02000000,
+}
+
+File_Status_Index :: enum c.int {
+ // No RDONLY (0x00), as that is implied and also impossible to express in a bit_set.
+
+ // The comments below come from the documentation for `fcntl`.
+ WRONLY = 0,
+ RDWR = 1,
+
+ /* Non-blocking I/O; if no data is available to a read(2)
+ system call, or if a write(2) operation would block, the
+ read or write call returns -1 with the error EAGAIN. */
+ NONBLOCK = 2,
+
+ /* Force each write to append at the end of file; corresponds
+ to the O_APPEND flag of open(2). */
+ APPEND = 3,
+
+ SHLOCK = 4,
+ EXLOCK = 5,
+
+ /* Enable the SIGIO signal to be sent to the process group when
+ I/O is possible, e.g., upon availability of data to be read. */
+ ASYNC = 6,
+
+ /* Enable synchronous writes. Corresponds to the O_SYNC flag
+ of open(2). O_FSYNC is an historical synonym for O_SYNC. */
+ SYNC = 7,
+
+ FSYNC = 7,
+ NOFOLLOW = 8,
+ CREAT = 9,
+ TRUNC = 10,
+ EXCL = 11,
+
+ NOCTTY = 15,
+
+ /* Minimize or eliminate the cache effects of reading and
+ writing. The system will attempt to avoid caching the data
+ you read or write. If it cannot avoid caching the data, it
+ will minimize the impact the data has on the cache. Use of
+ this flag can drastically reduce performance if not used
+ with care. */
+ DIRECT = 16,
+
+ DIRECTORY = 17,
+ EXEC = 18,
+ TTY_INIT = 19,
+ CLOEXEC = 20,
+ VERIFY = 21,
+ PATH = 22,
+ RESOLVE_BENEATH = 23,
+
+ /* Enable synchronous data writes. Corresponds to the O_DSYNC
+ flag of open(2). */
+ DSYNC = 24,
+
+ EMPTY_PATH = 25,
+}
+
+File_Status_Flags :: bit_set[File_Status_Index; c.int]
+
+//
+// #include <sys/_sockaddr_storage.h>
+//
+
+@private _SS_MAXSIZE :: 128
+@private _SS_ALIGNSIZE :: size_of(i64)
+@private _SS_PAD1SIZE :: _SS_ALIGNSIZE - size_of(c.uchar) - size_of(Address_Family)
+@private _SS_PAD2SIZE :: _SS_MAXSIZE - size_of(c.uchar) - size_of(Address_Family) - _SS_PAD1SIZE - _SS_ALIGNSIZE
+
+/*
+ * RFC 2553: protocol-independent placeholder for socket addresses
+ */
+// struct sockaddr_storage
+Socket_Address_Storage :: struct {
+ using _: Socket_Address_Header,
+ _pad1: [_SS_PAD1SIZE]c.char,
+ _align: i64, /* force desired struct alignment */
+ _pad2: [_SS_PAD2SIZE]c.char,
+}
+
+//
+// #include <sys/sysctl.h>
+//
+
+// MIB, or Management Information Base. Used in sysctl().
+MIB_Identifier :: enum c.int {
+ /*
+ * Top-level identifiers
+ */
+ CTL_SYSCTL = 0, /* "magic" numbers */
+ CTL_KERN = 1, /* "high kernel": proc, limits */
+ CTL_VM = 2, /* virtual memory */
+ CTL_VFS = 3, /* filesystem, mount type is next */
+ CTL_NET = 4, /* network, see socket.h */
+ CTL_DEBUG = 5, /* debugging parameters */
+ CTL_HW = 6, /* generic cpu/io */
+ CTL_MACHDEP = 7, /* machine dependent */
+ CTL_USER = 8, /* user-level */
+ CTL_P1003_1B = 9, /* POSIX 1003.1B */
+
+ /*
+ * CTL_SYSCTL identifiers
+ */
+ CTL_SYSCTL_DEBUG = 0, /* printf all nodes */
+ CTL_SYSCTL_NAME = 1, /* string name of OID */
+ CTL_SYSCTL_NEXT = 2, /* next OID, honoring CTLFLAG_SKIP */
+ CTL_SYSCTL_NAME2OID = 3, /* int array of name */
+ CTL_SYSCTL_OIDFMT = 4, /* OID's kind and format */
+ CTL_SYSCTL_OIDDESCR = 5, /* OID's description */
+ CTL_SYSCTL_OIDLABEL = 6, /* aggregation label */
+ CTL_SYSCTL_NEXTNOSKIP = 7, /* next OID, ignoring CTLFLAG_SKIP */
+
+ /*
+ * CTL_KERN identifiers
+ */
+ KERN_OSTYPE = 1, /* string: system version */
+ KERN_OSRELEASE = 2, /* string: system release */
+ KERN_OSREV = 3, /* int: system revision */
+ KERN_VERSION = 4, /* string: compile time info */
+ KERN_MAXVNODES = 5, /* int: max vnodes */
+ KERN_MAXPROC = 6, /* int: max processes */
+ KERN_MAXFILES = 7, /* int: max open files */
+ KERN_ARGMAX = 8, /* int: max arguments to exec */
+ KERN_SECURELVL = 9, /* int: system security level */
+ KERN_HOSTNAME = 10, /* string: hostname */
+ KERN_HOSTID = 11, /* int: host identifier */
+ KERN_CLOCKRATE = 12, /* struct: struct clockrate */
+ /* was: #define KERN_VNODE13; disabled in 2003 and removed in 2023 */
+ KERN_PROC = 14, /* struct: process entries */
+ KERN_FILE = 15, /* struct: file entries */
+ KERN_PROF = 16, /* node: kernel profiling info */
+ KERN_POSIX1 = 17, /* int: POSIX.1 version */
+ KERN_NGROUPS = 18, /* int: # of supplemental group ids */
+ KERN_JOB_CONTROL = 19, /* int: is job control available */
+ KERN_SAVED_IDS = 20, /* int: saved set-user/group-ID */
+ KERN_BOOTTIME = 21, /* struct: time kernel was booted */
+ KERN_NISDOMAINNAME = 22, /* string: YP domain name */
+ KERN_UPDATEINTERVAL = 23, /* int: update process sleep time */
+ KERN_OSRELDATE = 24, /* int: kernel release date */
+ KERN_NTP_PLL = 25, /* node: NTP PLL control */
+ KERN_BOOTFILE = 26, /* string: name of booted kernel */
+ KERN_MAXFILESPERPROC = 27, /* int: max open files per proc */
+ KERN_MAXPROCPERUID = 28, /* int: max processes per uid */
+ KERN_DUMPDEV = 29, /* struct cdev *: device to dump on */
+ KERN_IPC = 30, /* node: anything related to IPC */
+ KERN_DUMMY = 31, /* unused */
+ KERN_PS_STRINGS = 32, /* int: address of PS_STRINGS */
+ KERN_USRSTACK = 33, /* int: address of USRSTACK */
+ KERN_LOGSIGEXIT = 34, /* int: do we log sigexit procs? */
+ KERN_IOV_MAX = 35, /* int: value of UIO_MAXIOV */
+ KERN_HOSTUUID = 36, /* string: host UUID identifier */
+ KERN_ARND = 37, /* int: from arc4rand() */
+ KERN_MAXPHYS = 38, /* int: MAXPHYS value */
+ KERN_LOCKF = 39, /* struct: lockf reports */
+ /*
+ * KERN_PROC subtypes
+ */
+ KERN_PROC_ALL = 0, /* everything */
+ KERN_PROC_PID = 1, /* by process id */
+ KERN_PROC_PGRP = 2, /* by process group id */
+ KERN_PROC_SESSION = 3, /* by session of pid */
+ KERN_PROC_TTY = 4, /* by controlling tty */
+ KERN_PROC_UID = 5, /* by effective uid */
+ KERN_PROC_RUID = 6, /* by real uid */
+ KERN_PROC_ARGS = 7, /* get/set arguments/proctitle */
+ KERN_PROC_PROC = 8, /* only return procs */
+ KERN_PROC_SV_NAME = 9, /* get syscall vector name */
+ KERN_PROC_RGID = 10, /* by real group id */
+ KERN_PROC_GID = 11, /* by effective group id */
+ KERN_PROC_PATHNAME = 12, /* path to executable */
+ KERN_PROC_OVMMAP = 13, /* Old VM map entries for process */
+ KERN_PROC_OFILEDESC = 14, /* Old file descriptors for process */
+ KERN_PROC_KSTACK = 15, /* Kernel stacks for process */
+ KERN_PROC_INC_THREAD = 0x10, /* modifier for pid, pgrp, tty, uid, ruid, gid, rgid and proc. This effectively uses 16-31 */
+ KERN_PROC_VMMAP = 32, /* VM map entries for process */
+ KERN_PROC_FILEDESC = 33, /* File descriptors for process */
+ KERN_PROC_GROUPS = 34, /* process groups */
+ KERN_PROC_ENV = 35, /* get environment */
+ KERN_PROC_AUXV = 36, /* get ELF auxiliary vector */
+ KERN_PROC_RLIMIT = 37, /* process resource limits */
+ KERN_PROC_PS_STRINGS = 38, /* get ps_strings location */
+ KERN_PROC_UMASK = 39, /* process umask */
+ KERN_PROC_OSREL = 40, /* osreldate for process binary */
+ KERN_PROC_SIGTRAMP = 41, /* signal trampoline location */
+ KERN_PROC_CWD = 42, /* process current working directory */
+ KERN_PROC_NFDS = 43, /* number of open file descriptors */
+ KERN_PROC_SIGFASTBLK = 44, /* address of fastsigblk magic word */
+ KERN_PROC_VM_LAYOUT = 45, /* virtual address space layout info */
+
+ /*
+ * KERN_IPC identifiers
+ */
+ KIPC_MAXSOCKBUF = 1, /* int: max size of a socket buffer */
+ KIPC_SOCKBUF_WASTE = 2, /* int: wastage factor in sockbuf */
+ KIPC_SOMAXCONN = 3, /* int: max length of connection q */
+ KIPC_MAX_LINKHDR = 4, /* int: max length of link header */
+ KIPC_MAX_PROTOHDR = 5, /* int: max length of network header */
+ KIPC_MAX_HDR = 6, /* int: max total length of headers */
+ KIPC_MAX_DATALEN = 7, /* int: max length of data? */
+
+ /*
+ * Definitions for network related sysctl, CTL_NET.
+ *
+ * Second level is protocol family.
+ * Third level is protocol number.
+ *
+ * Further levels are defined by the individual families.
+ */
+
+ /*
+ * PF_ROUTE - Routing table
+ *
+ * Three additional levels are defined:
+ * Fourth: address family, 0 is wildcard
+ * Fifth: type of info, defined below
+ * Sixth: flag(s) to mask with for NET_RT_FLAGS
+ */
+ NET_RT_DUMP = 1, /* dump; may limit to a.f. */
+ NET_RT_FLAGS = 2, /* by flags, e.g. RESOLVING */
+ NET_RT_IFLIST = 3, /* survey interface list */
+ NET_RT_IFMALIST = 4, /* return multicast address list */
+ NET_RT_IFLISTL = 5, /* Survey interface list, using 'l'en versions of msghdr structs. */
+ NET_RT_NHOP = 6, /* dump routing nexthops */
+ NET_RT_NHGRP = 7, /* dump routing nexthop groups */
+
+ /*
+ * CTL_HW identifiers
+ */
+ HW_MACHINE = 1, /* string: machine class */
+ HW_MODEL = 2, /* string: specific machine model */
+ HW_NCPU = 3, /* int: number of cpus */
+ HW_BYTEORDER = 4, /* int: machine byte order */
+ HW_PHYSMEM = 5, /* int: total memory */
+ HW_USERMEM = 6, /* int: non-kernel memory */
+ HW_PAGESIZE = 7, /* int: software page size */
+ HW_DISKNAMES = 8, /* strings: disk drive names */
+ HW_DISKSTATS = 9, /* struct: diskstats[] */
+ HW_FLOATINGPT = 10, /* int: has HW floating point? */
+ HW_MACHINE_ARCH = 11, /* string: machine architecture */
+ HW_REALMEM = 12, /* int: 'real' memory */
+
+ /*
+ * CTL_USER definitions
+ */
+ USER_CS_PATH = 1, /* string: _CS_PATH */
+ USER_BC_BASE_MAX = 2, /* int: BC_BASE_MAX */
+ USER_BC_DIM_MAX = 3, /* int: BC_DIM_MAX */
+ USER_BC_SCALE_MAX = 4, /* int: BC_SCALE_MAX */
+ USER_BC_STRING_MAX = 5, /* int: BC_STRING_MAX */
+ USER_COLL_WEIGHTS_MAX = 6, /* int: COLL_WEIGHTS_MAX */
+ USER_EXPR_NEST_MAX = 7, /* int: EXPR_NEST_MAX */
+ USER_LINE_MAX = 8, /* int: LINE_MAX */
+ USER_RE_DUP_MAX = 9, /* int: RE_DUP_MAX */
+ USER_POSIX2_VERSION = 10, /* int: POSIX2_VERSION */
+ USER_POSIX2_C_BIND = 11, /* int: POSIX2_C_BIND */
+ USER_POSIX2_C_DEV = 12, /* int: POSIX2_C_DEV */
+ USER_POSIX2_CHAR_TERM = 13, /* int: POSIX2_CHAR_TERM */
+ USER_POSIX2_FORT_DEV = 14, /* int: POSIX2_FORT_DEV */
+ USER_POSIX2_FORT_RUN = 15, /* int: POSIX2_FORT_RUN */
+ USER_POSIX2_LOCALEDEF = 16, /* int: POSIX2_LOCALEDEF */
+ USER_POSIX2_SW_DEV = 17, /* int: POSIX2_SW_DEV */
+ USER_POSIX2_UPE = 18, /* int: POSIX2_UPE */
+ USER_STREAM_MAX = 19, /* int: POSIX2_STREAM_MAX */
+ USER_TZNAME_MAX = 20, /* int: POSIX2_TZNAME_MAX */
+ USER_LOCALBASE = 21, /* string: _PATH_LOCALBASE */
+
+ CTL_P1003_1B_ASYNCHRONOUS_IO = 1, /* boolean */
+ CTL_P1003_1B_MAPPED_FILES = 2, /* boolean */
+ CTL_P1003_1B_MEMLOCK = 3, /* boolean */
+ CTL_P1003_1B_MEMLOCK_RANGE = 4, /* boolean */
+ CTL_P1003_1B_MEMORY_PROTECTION = 5, /* boolean */
+ CTL_P1003_1B_MESSAGE_PASSING = 6, /* boolean */
+ CTL_P1003_1B_PRIORITIZED_IO = 7, /* boolean */
+ CTL_P1003_1B_PRIORITY_SCHEDULING = 8, /* boolean */
+ CTL_P1003_1B_REALTIME_SIGNALS = 9, /* boolean */
+ CTL_P1003_1B_SEMAPHORES = 10, /* boolean */
+ CTL_P1003_1B_FSYNC = 11, /* boolean */
+ CTL_P1003_1B_SHARED_MEMORY_OBJECTS = 12, /* boolean */
+ CTL_P1003_1B_SYNCHRONIZED_IO = 13, /* boolean */
+ CTL_P1003_1B_TIMERS = 14, /* boolean */
+ CTL_P1003_1B_AIO_LISTIO_MAX = 15, /* int */
+ CTL_P1003_1B_AIO_MAX = 16, /* int */
+ CTL_P1003_1B_AIO_PRIO_DELTA_MAX = 17, /* int */
+ CTL_P1003_1B_DELAYTIMER_MAX = 18, /* int */
+ CTL_P1003_1B_MQ_OPEN_MAX = 19, /* int */
+ CTL_P1003_1B_PAGESIZE = 20, /* int */
+ CTL_P1003_1B_RTSIG_MAX = 21, /* int */
+ CTL_P1003_1B_SEM_NSEMS_MAX = 22, /* int */
+ CTL_P1003_1B_SEM_VALUE_MAX = 23, /* int */
+ CTL_P1003_1B_SIGQUEUE_MAX = 24, /* int */
+ CTL_P1003_1B_TIMER_MAX = 25, /* int */
+}
+
+//
+// #include <net/route.h>
+//
+
+// struct rt_metrics
+Route_Metrics :: struct {
+ locks: c.ulong, /* Kernel must leave these values alone */
+ mtu: c.ulong, /* MTU for this path */
+ hopcount: c.ulong, /* max hops expected */
+ expire: c.ulong, /* lifetime for route, e.g. redirect */
+ recvpipe: c.ulong, /* inbound delay-bandwidth product */
+ sendpipe: c.ulong, /* outbound delay-bandwidth product */
+ ssthresh: c.ulong, /* outbound gateway buffer limit */
+ rtt: c.ulong, /* estimated round trip time */
+ rttvar: c.ulong, /* estimated rtt variance */
+ pksent: c.ulong, /* packets sent using this route */
+ weight: c.ulong, /* route weight */
+ nhidx: c.ulong, /* route nexhop index */
+ filler: [2]c.ulong, /* will be used for T/TCP later */
+}
+
+// struct rt_msghdr
+Route_Message_Header :: struct {
+ msglen: c.ushort, /* to skip over non-understood messages */
+ version: c.uchar, /* future binary compatibility */
+ type: Route_Message_Type, /* message type */
+ index: c.ushort, /* index for associated ifp */
+ _spare1: c.ushort,
+ flags: c.int, /* flags, incl. kern & message, e.g. DONE */
+ addrs: c.int, /* bitmask identifying sockaddrs in msg */
+ pid: pid_t, /* identify sender */
+ seq: c.int, /* for sender to identify action */
+ errno: c.int, /* why failed */
+ fmask: c.int, /* bitmask used in RTM_CHANGE message */
+ inits: c.ulong, /* which metrics we are initializing */
+ rmx: Route_Metrics, /* metrics themselves */
+}
+
+RTM_VERSION :: 5 /* Up the ante and ignore older versions */
+
+/*
+ * Message types.
+ *
+ * The format for each message is annotated below using the following
+ * identifiers:
+ *
+ * (1) struct rt_msghdr
+ * (2) struct ifa_msghdr
+ * (3) struct if_msghdr
+ * (4) struct ifma_msghdr
+ * (5) struct if_announcemsghdr
+ *
+ */
+// #define RTM_*
+Route_Message_Type :: enum c.uchar {
+ ADD = 0x1, /* (1) Add Route */
+ DELETE = 0x2, /* (1) Delete Route */
+ CHANGE = 0x3, /* (1) Change Metrics or flags */
+ GET = 0x4, /* (1) Report Metrics */
+ LOSING = 0x5, /* (1) Kernel Suspects Partitioning */
+ REDIRECT = 0x6, /* (1) Told to use different route */
+ MISS = 0x7, /* (1) Lookup failed on this address */
+ LOCK = 0x8, /* (1) fix specified metrics */
+ /* = 0x9 */
+ /* = 0xa */
+ RESOLVE = 0xb, /* (1) req to resolve dst to LL addr */
+ NEWADDR = 0xc, /* (2) address being added to iface */
+ DELADDR = 0xd, /* (2) address being removed from iface */
+ IFINFO = 0xe, /* (3) iface going up/down etc. */
+ NEWMADDR = 0xf, /* (4) mcast group membership being added to if */
+ DELMADDR = 0x10, /* (4) mcast group membership being deleted */
+ IFANNOUNCE = 0x11, /* (5) iface arrival/departure */
+ IEEE80211 = 0x12, /* (5) IEEE80211 wireless event */
+}
+
+/*
+ * Bitmask values for rtm_addrs.
+ */
+// #define RTA_*
+Route_Address_Flag :: enum c.int {
+ DST = 0x1, /* destination sockaddr present */
+ GATEWAY = 0x2, /* gateway sockaddr present */
+ NETMASK = 0x4, /* netmask sockaddr present */
+ GENMASK = 0x8, /* cloning mask sockaddr present */
+ IFP = 0x10, /* interface name sockaddr present */
+ IFA = 0x20, /* interface addr sockaddr present */
+ AUTHOR = 0x40, /* sockaddr for author of redirect */
+ BRD = 0x80, /* for NEWADDR, broadcast or p-p dest addr */
+}
+
+/*
+ * Index offsets for sockaddr array for alternate internal encoding.
+ */
+// #define RTAX_*
+Route_Address_Index :: enum c.int {
+ DST = 0, /* destination sockaddr present */
+ GATEWAY = 1, /* gateway sockaddr present */
+ NETMASK = 2, /* netmask sockaddr present */
+ GENMASK = 3, /* cloning mask sockaddr present */
+ IFP = 4, /* interface name sockaddr present */
+ IFA = 5, /* interface addr sockaddr present */
+ AUTHOR = 6, /* sockaddr for author of redirect */
+ BRD = 7, /* for NEWADDR, broadcast or p-p dest addr */
+ MAX = 8, /* size of array to allocate */
+}
+
+// The value stored in rtm_addrs and similar (ifm_addrs, etc.)
+Route_Address_Flags :: bit_set[Route_Address_Index; c.int]
+
+//
+// #include <net/if.h>
+//
+
+/*
+ * Values for if_link_state.
+ */
+// #define LINK_STATE_*
+Link_State :: enum u8 {
+ UNKNOWN = 0, /* link invalid/unknown */
+ DOWN = 1, /* link is down */
+ UP = 2, /* link is up */
+}
+
+/*
+ * Structure describing information about an interface
+ * which may be of interest to management entities.
+ */
+// struct if_data
+Interface_Data :: struct {
+ /* generic interface information */
+ type: u8, /* ethernet, tokenring, etc */
+ physical: u8, /* e.g., AUI, Thinnet, 10base-T, etc */
+ addrlen: u8, /* media address length */
+ hdrlen: u8, /* media header length */
+ link_state: Link_State, /* current link state */
+ vhid: u8, /* carp vhid */
+ datalen: u16, /* length of this data struct */
+ mtu: u32, /* maximum transmission unit */
+ metric: u32, /* routing metric (external only) */
+ baudrate: u64, /* linespeed */
+ /* volatile statistics */
+ ipackets: u64, /* packets received on interface */
+ ierrors: u64, /* input errors on interface */
+ opackets: u64, /* packets sent on interface */
+ oerrors: u64, /* output errors on interface */
+ collisions: u64, /* collisions on csma interfaces */
+ ibytes: u64, /* total number of octets received */
+ obytes: u64, /* total number of octets sent */
+ imcasts: u64, /* packets received via multicast */
+ omcasts: u64, /* packets sent via multicast */
+ iqdrops: u64, /* dropped on input */
+ oqdrops: u64, /* dropped on output */
+ noproto: u64, /* destined for unsupported protocol */
+ hwassist: u64, /* HW offload capabilities, see IFCAP */
+
+ /* Unions are here to make sizes MI. */
+ _epoch: struct #raw_union { /* uptime at attach or stat reset */
+ tt: time_t,
+ ph: u64,
+ },
+
+ _lastchange: struct #raw_union { /* time of last administrative change */
+ tv: timeval,
+ ph: struct {
+ ph1: u64,
+ ph2: u64,
+ },
+ },
+}
+
+/*
+ * The 'l' version shall be used by new interfaces, like NET_RT_IFLISTL. It is
+ * extensible after ifm_data_off or within ifm_data. Both the if_msghdr and
+ * if_data now have a member field detailing the struct length in addition to
+ * the routing message length. Macros are provided to find the start of
+ * ifm_data and the start of the socket address strucutres immediately following
+ * struct if_msghdrl given a pointer to struct if_msghdrl.
+ */
+// struct if_msghdrl
+Interface_Message_Header_Len :: struct {
+ msglen: c.ushort, /* to skip over non-understood messages */
+ version: c.uchar, /* future binary compatibility */
+ type: c.uchar, /* message type */
+ addrs: Route_Address_Flags, /* like rtm_addrs */
+ flags: c.int, /* value of if_flags */
+ index: c.ushort, /* index for associated ifp */
+ _spare1: c.ushort, /* spare space to grow if_index, see if_var.h */
+ len: c.ushort, /* length of if_msghdrl incl. if_data */
+ data_off: c.ushort, /* offset of if_data from beginning */
+ _spare2: c.int,
+ data: Interface_Data, /* statistics and other data about if */
+}
+
+/*
+ * The 'l' version shall be used by new interfaces, like NET_RT_IFLISTL. It is
+ * extensible after ifam_metric or within ifam_data. Both the ifa_msghdrl and
+ * if_data now have a member field detailing the struct length in addition to
+ * the routing message length. Macros are provided to find the start of
+ * ifm_data and the start of the socket address strucutres immediately following
+ * struct ifa_msghdrl given a pointer to struct ifa_msghdrl.
+ */
+// struct ifa_msghdrl
+Interface_Address_Message_Header_Len :: struct {
+ msglen: c.ushort, /* to skip over non-understood messages */
+ version: c.uchar, /* future binary compatibility */
+ type: c.uchar, /* message type */
+ addrs: Route_Address_Flags, /* like rtm_addrs */
+ flags: c.int, /* value of ifa_flags */
+ index: c.ushort, /* index for associated ifp */
+ _spare1: c.ushort, /* spare space to grow if_index, see if_var.h */
+ len: c.ushort, /* length of ifa_msghdrl incl. if_data */
+ data_off: c.ushort, /* offset of if_data from beginning */
+ metric: c.int, /* value of ifa_ifp->if_metric */
+ data: Interface_Data, /* statistics and other data about if or address */
+}
+
+//
+// #include <net/if_types.h>
+//
+
+// enum ifType
+Interface_Type :: enum c.uchar {
+ OTHER = 0x1, /* none of the following */
+ ARPA_1822 = 0x2, /* old-style arpanet imp */
+ HDH1822 = 0x3, /* HDH arpanet imp */
+ X25DDN = 0x4, /* x25 to imp */
+ X25 = 0x5, /* PDN X25 interface (RFC877) */
+ ETHER = 0x6, /* Ethernet CSMA/CD */
+ ISO88023 = 0x7, /* CMSA/CD */
+ ISO88024 = 0x8, /* Token Bus */
+ ISO88025 = 0x9, /* Token Ring */
+ ISO88026 = 0xa, /* MAN */
+ STARLAN = 0xb,
+ P10 = 0xc, /* Proteon 10MBit ring */
+ P80 = 0xd, /* Proteon 80MBit ring */
+ HY = 0xe, /* Hyperchannel */
+ FDDI = 0xf,
+ LAPB = 0x10,
+ SDLC = 0x11,
+ T1 = 0x12,
+ CEPT = 0x13, /* E1 - european T1 */
+ ISDNBASIC = 0x14,
+ ISDNPRIMARY = 0x15,
+ PTPSERIAL = 0x16, /* Proprietary PTP serial */
+ PPP = 0x17, /* RFC 1331 */
+ LOOP = 0x18, /* loopback */
+ EON = 0x19, /* ISO over IP */
+ XETHER = 0x1a, /* obsolete 3MB experimental ethernet */
+ NSIP = 0x1b, /* XNS over IP */
+ SLIP = 0x1c, /* IP over generic TTY */
+ ULTRA = 0x1d, /* Ultra Technologies */
+ DS3 = 0x1e, /* Generic T3 */
+ SIP = 0x1f, /* SMDS */
+ FRELAY = 0x20, /* Frame Relay DTE only */
+ RS232 = 0x21,
+ PARA = 0x22, /* parallel-port */
+ ARCNET = 0x23,
+ ARCNETPLUS = 0x24,
+ ATM = 0x25, /* ATM cells */
+ MIOX25 = 0x26,
+ SONET = 0x27, /* SONET or SDH */
+ X25PLE = 0x28,
+ ISO88022LLC = 0x29,
+ LOCALTALK = 0x2a,
+ SMDSDXI = 0x2b,
+ FRELAYDCE = 0x2c, /* Frame Relay DCE */
+ V35 = 0x2d,
+ HSSI = 0x2e,
+ HIPPI = 0x2f,
+ MODEM = 0x30, /* Generic Modem */
+ AAL5 = 0x31, /* AAL5 over ATM */
+ SONETPATH = 0x32,
+ SONETVT = 0x33,
+ SMDSICIP = 0x34, /* SMDS InterCarrier Interface */
+ PROPVIRTUAL = 0x35, /* Proprietary Virtual/internal */
+ PROPMUX = 0x36, /* Proprietary Multiplexing */
+ IEEE80212 = 0x37, /* 100BaseVG */
+ FIBRECHANNEL = 0x38, /* Fibre Channel */
+ HIPPIINTERFACE = 0x39, /* HIPPI interfaces */
+ FRAMERELAYINTERCONNECT = 0x3a, /* Obsolete, use 0x20 either 0x2c */
+ AFLANE8023 = 0x3b, /* ATM Emulated LAN for 802.3 */
+ AFLANE8025 = 0x3c, /* ATM Emulated LAN for 802.5 */
+ CCTEMUL = 0x3d, /* ATM Emulated circuit */
+ FASTETHER = 0x3e, /* Fast Ethernet (100BaseT) */
+ ISDN = 0x3f, /* ISDN and X.25 */
+ V11 = 0x40, /* CCITT V.11/X.21 */
+ V36 = 0x41, /* CCITT V.36 */
+ G703AT64K = 0x42, /* CCITT G703 at 64Kbps */
+ G703AT2MB = 0x43, /* Obsolete see DS1-MIB */
+ QLLC = 0x44, /* SNA QLLC */
+ FASTETHERFX = 0x45, /* Fast Ethernet (100BaseFX) */
+ CHANNEL = 0x46, /* channel */
+ IEEE80211 = 0x47, /* radio spread spectrum (unused) */
+ IBM370PARCHAN = 0x48, /* IBM System 360/370 OEMI Channel */
+ ESCON = 0x49, /* IBM Enterprise Systems Connection */
+ DLSW = 0x4a, /* Data Link Switching */
+ ISDNS = 0x4b, /* ISDN S/T interface */
+ ISDNU = 0x4c, /* ISDN U interface */
+ LAPD = 0x4d, /* Link Access Protocol D */
+ IPSWITCH = 0x4e, /* IP Switching Objects */
+ RSRB = 0x4f, /* Remote Source Route Bridging */
+ ATMLOGICAL = 0x50, /* ATM Logical Port */
+ DS0 = 0x51, /* Digital Signal Level 0 */
+ DS0BUNDLE = 0x52, /* group of ds0s on the same ds1 */
+ BSC = 0x53, /* Bisynchronous Protocol */
+ ASYNC = 0x54, /* Asynchronous Protocol */
+ CNR = 0x55, /* Combat Net Radio */
+ ISO88025DTR = 0x56, /* ISO 802.5r DTR */
+ EPLRS = 0x57, /* Ext Pos Loc Report Sys */
+ ARAP = 0x58, /* Appletalk Remote Access Protocol */
+ PROPCNLS = 0x59, /* Proprietary Connectionless Protocol*/
+ HOSTPAD = 0x5a, /* CCITT-ITU X.29 PAD Protocol */
+ TERMPAD = 0x5b, /* CCITT-ITU X.3 PAD Facility */
+ FRAMERELAYMPI = 0x5c, /* Multiproto Interconnect over FR */
+ X213 = 0x5d, /* CCITT-ITU X213 */
+ ADSL = 0x5e, /* Asymmetric Digital Subscriber Loop */
+ RADSL = 0x5f, /* Rate-Adapt. Digital Subscriber Loop*/
+ SDSL = 0x60, /* Symmetric Digital Subscriber Loop */
+ VDSL = 0x61, /* Very H-Speed Digital Subscrib. Loop*/
+ ISO88025CRFPINT = 0x62, /* ISO 802.5 CRFP */
+ MYRINET = 0x63, /* Myricom Myrinet */
+ VOICEEM = 0x64, /* voice recEive and transMit */
+ VOICEFXO = 0x65, /* voice Foreign Exchange Office */
+ VOICEFXS = 0x66, /* voice Foreign Exchange Station */
+ VOICEENCAP = 0x67, /* voice encapsulation */
+ VOICEOVERIP = 0x68, /* voice over IP encapsulation */
+ ATMDXI = 0x69, /* ATM DXI */
+ ATMFUNI = 0x6a, /* ATM FUNI */
+ ATMIMA = 0x6b, /* ATM IMA */
+ PPPMULTILINKBUNDLE = 0x6c, /* PPP Multilink Bundle */
+ IPOVERCDLC = 0x6d, /* IBM ipOverCdlc */
+ IPOVERCLAW = 0x6e, /* IBM Common Link Access to Workstn */
+ STACKTOSTACK = 0x6f, /* IBM stackToStack */
+ VIRTUALIPADDRESS = 0x70, /* IBM VIPA */
+ MPC = 0x71, /* IBM multi-protocol channel support */
+ IPOVERATM = 0x72, /* IBM ipOverAtm */
+ ISO88025FIBER = 0x73, /* ISO 802.5j Fiber Token Ring */
+ TDLC = 0x74, /* IBM twinaxial data link control */
+ GIGABITETHERNET = 0x75, /* Gigabit Ethernet */
+ HDLC = 0x76, /* HDLC */
+ LAPF = 0x77, /* LAP F */
+ V37 = 0x78, /* V.37 */
+ X25MLP = 0x79, /* Multi-Link Protocol */
+ X25HUNTGROUP = 0x7a, /* X25 Hunt Group */
+ TRANSPHDLC = 0x7b, /* Transp HDLC */
+ INTERLEAVE = 0x7c, /* Interleave channel */
+ FAST = 0x7d, /* Fast channel */
+ IP = 0x7e, /* IP (for APPN HPR in IP networks) */
+ DOCSCABLEMACLAYER = 0x7f, /* CATV Mac Layer */
+ DOCSCABLEDOWNSTREAM = 0x80, /* CATV Downstream interface */
+ DOCSCABLEUPSTREAM = 0x81, /* CATV Upstream interface */
+ A12MPPSWITCH = 0x82, /* Avalon Parallel Processor */
+ TUNNEL = 0x83, /* Encapsulation interface */
+ COFFEE = 0x84, /* coffee pot */
+ CES = 0x85, /* Circiut Emulation Service */
+ ATMSUBINTERFACE = 0x86, /* (x) ATM Sub Interface */
+ L2VLAN = 0x87, /* Layer 2 Virtual LAN using 802.1Q */
+ L3IPVLAN = 0x88, /* Layer 3 Virtual LAN - IP Protocol */
+ L3IPXVLAN = 0x89, /* Layer 3 Virtual LAN - IPX Prot. */
+ DIGITALPOWERLINE = 0x8a, /* IP over Power Lines */
+ MEDIAMAILOVERIP = 0x8b, /* (xxx) Multimedia Mail over IP */
+ DTM = 0x8c, /* Dynamic synchronous Transfer Mode */
+ DCN = 0x8d, /* Data Communications Network */
+ IPFORWARD = 0x8e, /* IP Forwarding Interface */
+ MSDSL = 0x8f, /* Multi-rate Symmetric DSL */
+ IEEE1394 = 0x90, /* IEEE1394 High Performance SerialBus*/
+ IFGSN = 0x91, /* HIPPI-6400 */
+ DVBRCCMACLAYER = 0x92, /* DVB-RCC MAC Layer */
+ DVBRCCDOWNSTREAM = 0x93, /* DVB-RCC Downstream Channel */
+ DVBRCCUPSTREAM = 0x94, /* DVB-RCC Upstream Channel */
+ ATMVIRTUAL = 0x95, /* ATM Virtual Interface */
+ MPLSTUNNEL = 0x96, /* MPLS Tunnel Virtual Interface */
+ SRP = 0x97, /* Spatial Reuse Protocol */
+ VOICEOVERATM = 0x98, /* Voice over ATM */
+ VOICEOVERFRAMERELAY = 0x99, /* Voice Over Frame Relay */
+ IDSL = 0x9a, /* Digital Subscriber Loop over ISDN */
+ COMPOSITELINK = 0x9b, /* Avici Composite Link Interface */
+ SS7SIGLINK = 0x9c, /* SS7 Signaling Link */
+ PROPWIRELESSP2P = 0x9d, /* Prop. P2P wireless interface */
+ FRFORWARD = 0x9e, /* Frame forward Interface */
+ RFC1483 = 0x9f, /* Multiprotocol over ATM AAL5 */
+ USB = 0xa0, /* USB Interface */
+ IEEE8023ADLAG = 0xa1, /* IEEE 802.3ad Link Aggregate*/
+ BGPPOLICYACCOUNTING = 0xa2, /* BGP Policy Accounting */
+ FRF16MFRBUNDLE = 0xa3, /* FRF.16 Multilink Frame Relay*/
+ H323GATEKEEPER = 0xa4, /* H323 Gatekeeper */
+ H323PROXY = 0xa5, /* H323 Voice and Video Proxy */
+ MPLS = 0xa6, /* MPLS */
+ MFSIGLINK = 0xa7, /* Multi-frequency signaling link */
+ HDSL2 = 0xa8, /* High Bit-Rate DSL, 2nd gen. */
+ SHDSL = 0xa9, /* Multirate HDSL2 */
+ DS1FDL = 0xaa, /* Facility Data Link (4Kbps) on a DS1*/
+ POS = 0xab, /* Packet over SONET/SDH Interface */
+ DVBASILN = 0xac, /* DVB-ASI Input */
+ DVBASIOUT = 0xad, /* DVB-ASI Output */
+ PLC = 0xae, /* Power Line Communications */
+ NFAS = 0xaf, /* Non-Facility Associated Signaling */
+ TR008 = 0xb0, /* TROO8 */
+ GR303RDT = 0xb1, /* Remote Digital Terminal */
+ GR303IDT = 0xb2, /* Integrated Digital Terminal */
+ ISUP = 0xb3, /* ISUP */
+ PROPDOCSWIRELESSMACLAYER = 0xb4, /* prop/Wireless MAC Layer */
+ PROPDOCSWIRELESSDOWNSTREAM = 0xb5, /* prop/Wireless Downstream */
+ PROPDOCSWIRELESSUPSTREAM = 0xb6, /* prop/Wireless Upstream */
+ HIPERLAN2 = 0xb7, /* HIPERLAN Type 2 Radio Interface */
+ PROPBWAP2MP = 0xb8, /* PropBroadbandWirelessAccess P2MP*/
+ SONETOVERHEADCHANNEL = 0xb9, /* SONET Overhead Channel */
+ DIGITALWRAPPEROVERHEADCHANNEL = 0xba, /* Digital Wrapper Overhead */
+ AAL2 = 0xbb, /* ATM adaptation layer 2 */
+ RADIOMAC = 0xbc, /* MAC layer over radio links */
+ ATMRADIO = 0xbd, /* ATM over radio links */
+ IMT = 0xbe, /* Inter-Machine Trunks */
+ MVL = 0xbf, /* Multiple Virtual Lines DSL */
+ REACHDSL = 0xc0, /* Long Reach DSL */
+ FRDLCIENDPT = 0xc1, /* Frame Relay DLCI End Point */
+ ATMVCIENDPT = 0xc2, /* ATM VCI End Point */
+ OPTICALCHANNEL = 0xc3, /* Optical Channel */
+ OPTICALTRANSPORT = 0xc4, /* Optical Transport */
+ INFINIBAND = 0xc7, /* Infiniband */
+ INFINIBANDLAG = 0xc8, /* Infiniband Link Aggregate */
+ BRIDGE = 0xd1, /* Transparent bridge interface */
+ STF = 0xd7, /* 6to4 interface */
+
+ /*
+ * Not based on IANA assignments. Conflicting with IANA assignments.
+ * We should make them negative probably.
+ * This requires changes to struct if_data.
+ */
+ GIF = 0xf0, /* Generic tunnel interface */
+ PVC = 0xf1, /* Unused */
+ ENC = 0xf4, /* Encapsulating interface */
+ PFLOG = 0xf6, /* PF packet filter logging */
+ PFSYNC = 0xf7, /* PF packet filter synchronization */
+ WIREGUARD = 0xf8, /* WireGuard tunnel */
+}
+
+//
+// #include <net/if_dl.h>
+//
+
+/*
+ * Structure of a Link-Level sockaddr:
+ */
+// struct sockaddr_dl
+Socket_Address_Data_Link :: struct {
+ using _: Socket_Address_Header,
+ index: c.ushort, /* if != 0, system given index for interface */
+ type: Interface_Type, /* interface type */
+ nlen: c.uchar, /* interface name length, no trailing 0 reqd. */
+ alen: c.uchar, /* link level address length */
+ slen: c.uchar, /* link layer selector length */
+ data: [46]c.char, /* minimum work area, can be larger; contains both if name and ll address */
+}
+
+//
+// #include <netinet/in.h>
+//
+
+in_addr_t :: distinct u32be
+
+/* Internet address (a structure for historical reasons). */
+// struct in_addr
+IP4_Address :: struct #raw_union {
+ // NOTE(Feoramund): I have modified this struct from its C definition by
+ // introducing the byte variant to make it easier to work with.
+ addr8: [4]u8,
+ addr32: in_addr_t,
+}
+
+/* Socket address, internet style. */
+// struct sockaddr_in
+Socket_Address_Internet :: struct #packed {
+ using _: Socket_Address_Header,
+ port: in_port_t,
+ addr: IP4_Address,
+ zero: [8]c.char,
+}
+
+//
+// #include <netinet6/in6.h>
+//
+
+/*
+ * IPv6 address
+ */
+// struct in6_addr
+IP6_Address :: struct #raw_union {
+ addr8: [16]u8,
+ addr16: [8]u16be,
+ addr32: [4]u32be,
+}
+
+/*
+ * Socket address for IPv6
+ */
+// struct sockaddr_in6
+Socket_Address_Internet6 :: struct #packed {
+ using _: Socket_Address_Header,
+ port: in_port_t, /* Transport layer port # */
+ flowinfo: u32, /* IP6 flow information */
+ addr: IP6_Address, /* IP6 address */
+ scope_id: u32, /* scope zone index */
+}
+
+//
+// #include <sys/umtx.h>
+//
+
+/* op code for _umtx_op */
+// #define UMTX_OP_*
+Mutex_Operation :: enum c.int {
+ LOCK = 0, /* COMPAT10 */
+ UNLOCK = 1, /* COMPAT10 */
+ WAIT = 2,
+ WAKE = 3,
+ MUTEX_TRYLOCK = 4,
+ MUTEX_LOCK = 5,
+ MUTEX_UNLOCK = 6,
+ SET_CEILING = 7,
+ CV_WAIT = 8,
+ CV_SIGNAL = 9,
+ CV_BROADCAST = 10,
+ WAIT_UINT = 11,
+ RW_RDLOCK = 12,
+ RW_WRLOCK = 13,
+ RW_UNLOCK = 14,
+ WAIT_UINT_PRIVATE = 15,
+ WAKE_PRIVATE = 16,
+ MUTEX_WAIT = 17,
+ MUTEX_WAKE = 18, /* deprecated */
+ SEM_WAIT = 19, /* deprecated */
+ SEM_WAKE = 20, /* deprecated */
+ NWAKE_PRIVATE = 21,
+ MUTEX_WAKE2 = 22,
+ SEM2_WAIT = 23,
+ SEM2_WAKE = 24,
+ SHM = 25,
+ ROBUST_LISTS = 26,
+ GET_MIN_TIMEOUT = 27,
+ SET_MIN_TIMEOUT = 28,
+}