FPPS4/sys/vfs/vsocket.pas

319 lines
8.9 KiB
Plaintext

unit vsocket;
{$mode ObjFPC}{$H+}
{$CALLING SysV_ABI_CDecl}
interface
uses
vuio;
{
* Definitions related to sockets: types, address families, options.
}
{
* Data types.
}
type
sa_family_t=Byte;
p_socklen_t=^socklen_t;
socklen_t =Integer;
const
//socket types
SOCK_STREAM =1; { stream socket }
SOCK_DGRAM =2; { datagram socket }
SOCK_RAW =3; { raw-protocol interface }
//socket options
SO_DEBUG =$0001; { turn on debugging info recording }
SO_ACCEPTCONN =$0002; { socket has had listen() }
SO_REUSEADDR =$0004; { allow local address reuse }
SO_KEEPALIVE =$0008; { keep connections alive }
SO_DONTROUTE =$0010; { just use interface addresses }
SO_BROADCAST =$0020; { permit sending of broadcast msgs }
SO_USELOOPBACK =$0040; { bypass hardware when possible }
SO_LINGER =$0080; { linger on close if data present }
SO_OOBINLINE =$0100; { leave received OOB data in line }
SO_REUSEPORT =$0200; { allow local address & port reuse }
SO_TIMESTAMP =$0400; { timestamp received dgram traffic }
SO_NOSIGPIPE =$0800; { no SIGPIPE from EPIPE }
SO_ACCEPTFILTER=$1000; { there is an accept filter }
SO_BINTIME =$2000; { timestamp received dgram traffic }
SO_NO_OFFLOAD =$4000; { socket cannot be offloaded }
SO_NO_DDP =$8000; { disable direct data placement }
//Additional options, not kept in so_options.
SO_SNDBUF =$1001; { send buffer size }
SO_RCVBUF =$1002; { receive buffer size }
SO_SNDLOWAT =$1003; { send low-water mark }
SO_RCVLOWAT =$1004; { receive low-water mark }
SO_SNDTIMEO =$1005; { send timeout }
SO_RCVTIMEO =$1006; { receive timeout }
SO_ERROR =$1007; { get error status and clear }
SO_TYPE =$1008; { get socket type }
SO_LABEL =$1009; { socket's MAC label }
SO_PEERLABEL =$1010; { socket's peer's MAC label }
SO_LISTENQLIMIT =$1011; { socket's backlog limit }
SO_LISTENQLEN =$1012; { socket's complete queue length }
SO_LISTENINCQLEN=$1013; { socket's incomplete queue length }
SO_SETFIB =$1014; { use this FIB to route }
SO_USER_COOKIE =$1015; { user cookie (dummynet etc.) }
SO_PROTOCOL =$1016; { get socket protocol (Linux name) }
SO_PROTOTYPE =SO_PROTOCOL; { alias for SO_PROTOCOL (SunOS name) }
{
* Space reserved for new socket options added by third-party vendors.
* This range applies to all socket option levels. New socket options
* in FreeBSD should always use an option value less than SO_VENDOR.
}
SO_VENDOR=$80000000;
type
{
* Structure used for manipulating linger option.
}
p_linger=^t_linger;
t_linger=packed record
l_onoff :Integer; { option on/off }
l_linger:Integer; { linger time }
end;
t_accept_filter_arg=packed record
af_name:array[0..15] of AnsiChar;
af_arg :array[0..256-15] of Byte;
end;
const
{
* Level number for (get/set)sockopt() to apply to socket itself.
}
SOL_SOCKET=$ffff; { options for socket level }
{ address families }
AF_UNSPEC=0;
AF_UNIX =1;
AF_LOCAL =AF_UNIX;
AF_INET =2;
AF_INET6 =28;
AF_MAX =38;
PF_UNSPEC=AF_UNSPEC;
PF_LOCAL =AF_LOCAL;
PF_UNIX =PF_LOCAL;
PF_INET =AF_INET;
PF_INET6 =AF_INET6;
PF_MAX =AF_MAX;
type
{
* Structure used by kernel to store most
* addresses.
}
pp_sockaddr=^p_sockaddr;
p_sockaddr=^t_sockaddr;
t_sockaddr=packed record
sa_len :Byte; { total length }
sa_family:sa_family_t; { address family }
sa_data :array[0..13] of Byte; { actually longer; address value }
end;
const
SOCK_MAXADDRLEN=255; { longest possible addresses }
{
* Structure used by kernel to pass protocol
* information in raw sockets.
}
type
p_sockproto=^t_sockproto;
t_sockproto=packed record
sp_family :Word; { address family }
sp_protocol:Word; { protocol }
end;
const
{
* 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 len versions of msghdr structs. }
NET_RT_MAXID =6;
{
* Maximum queue length specifiable by listen.
}
SOMAXCONN=128;
type
{
* Message header for recvmsg and sendmsg calls.
* Used value-result for recvmsg, value only for sendmsg.
}
p_msghdr=^t_msghdr;
t_msghdr=packed record
msg_name :Pointer; { optional address }
msg_namelen :socklen_t; { size of address }
_align1 :Integer;
msg_iov :p_iovec; { scatter/gather array }
msg_iovlen :Integer; { # elements in msg_iov }
_align2 :Integer;
msg_control :Pointer; { ancillary data, see below }
msg_controllen:socklen_t; { ancillary data buffer len }
msg_flags :Integer; { flags on received message }
end;
const
MSG_OOB =$1 ; { process out-of-band data }
MSG_PEEK =$2 ; { peek at incoming message }
MSG_DONTROUTE =$4 ; { send without using routing tables }
MSG_EOR =$8 ; { data completes record }
MSG_TRUNC =$10 ; { data discarded before delivery }
MSG_CTRUNC =$20 ; { control data lost before delivery }
MSG_WAITALL =$40 ; { wait for full request or error }
MSG_NOTIFICATION=$2000 ; { SCTP notification }
MSG_DONTWAIT =$80 ; { this message should be nonblocking }
MSG_EOF =$100 ; { data completes connection }
MSG_NBIO =$4000 ; { FIONBIO mode, used by fifofs }
MSG_COMPAT =$8000 ; { used in sendit() }
MSG_SOCALLBCK =$10000; { for use by socket callbacks - soreceive (TCP) }
MSG_NOSIGNAL =$20000; { do not generate SIGPIPE on EOF }
type
{
* Header for ancillary data objects in msg_control buffer.
* Used for additional information with/about a datagram
* not expressible by flags. The format is a sequence
* of message elements headed by cmsghdr structures.
}
p_cmsghdr=^t_cmsghdr;
t_cmsghdr=packed record
cmsg_len :socklen_t; { data byte count, including hdr }
cmsg_level:Integer; { originating protocol }
cmsg_type :Integer; { protocol-specific type }
{ followed by u_char cmsg_data[]; }
end;
const
{
* While we may have more groups than this, the cmsgcred struct must
* be able to fit in an mbuf and we have historically supported a
* maximum of 16 groups.
}
CMGROUP_MAX=16;
{ "Socket"-level control message types: }
SCM_RIGHTS =$01; { access rights (array of int) }
SCM_TIMESTAMP=$02; { timestamp (struct timeval) }
SCM_CREDS =$03; { process creds (struct cmsgcred) }
SCM_BINTIME =$04; { timestamp (struct bintime) }
{
* howto arguments for shutdown(2), specified by Posix.1g.
}
SHUT_RD =0; { shut down the reading side }
SHUT_WR =1; { shut down the writing side }
SHUT_RDWR=2; { shut down both sides }
{ we cheat and use the SHUT_XX defines for these }
PRU_FLUSH_RD =SHUT_RD ;
PRU_FLUSH_WR =SHUT_WR ;
PRU_FLUSH_RDWR=SHUT_RDWR;
type
{
* sendfile(2) header/trailer struct
}
p_sf_hdtr=^t_sf_hdtr;
t_sf_hdtr=packed record
headers :p_iovec; { pointer to an array of header struct iovec's }
hdr_cnt :Integer; { number of header iovec's }
_align :Integer;
trailers:p_iovec; { pointer to an array of trailer struct iovec's }
trl_cnt :Integer; { number of trailer iovec's }
end;
const
{
* Sendfile-specific flag(s)
}
SF_NODISKIO=$00000001;
SF_MNOWAIT =$00000002;
SF_SYNC =$00000004;
function CMSG_ALIGN(p:ptrint):ptrint; inline;
function CMSG_DATA(cmsg:Pointer):Pointer; inline;
function CMSG_FIRSTHDR(mhdr:p_msghdr):p_msghdr; inline;
function CMSG_NXTHDR(mhdr:p_msghdr;cmsg:p_cmsghdr):p_msghdr; inline;
function CMSG_SPACE(l:Ptruint):Ptruint;
function CMSG_LEN(l:Ptruint):Ptruint;
implementation
const
_ALIGNBYTES=SizeOf(ptrint)-1;
function CMSG_ALIGN(p:ptrint):ptrint; inline;
begin
Result:=(p+_ALIGNBYTES) and (not _ALIGNBYTES);
end;
{ given pointer to struct cmsghdr, return pointer to data }
function CMSG_DATA(cmsg:Pointer):Pointer; inline;
begin
Result:=cmsg+CMSG_ALIGN(SizeOf(t_cmsghdr));
end;
{
* RFC 2292 requires to check msg_controllen, in case that the kernel returns
* an empty list for some reasons.
}
function CMSG_FIRSTHDR(mhdr:p_msghdr):p_msghdr; inline;
begin
if (mhdr^.msg_controllen>=SizeOf(t_cmsghdr)) then
Result:=mhdr^.msg_control
else
Result:=nil;
end;
{ given pointer to struct cmsghdr, return pointer to next cmsghdr }
function CMSG_NXTHDR(mhdr:p_msghdr;cmsg:p_cmsghdr):p_msghdr; inline;
begin
if (cmsg=nil) then
Result:=CMSG_FIRSTHDR(mhdr)
else
if (Ptruint(cmsg)+CMSG_ALIGN(cmsg^.cmsg_len)+CMSG_ALIGN(SizeOf(t_cmsghdr)))>
(Ptruint(mhdr^.msg_control)+mhdr^.msg_controllen) then
begin
Result:=nil;
end else
begin
Result:=Pointer(cmsg)+CMSG_ALIGN(cmsg^.cmsg_len);
end;
end;
{ RFC 2292 additions }
function CMSG_SPACE(l:Ptruint):Ptruint;
begin
Result:=CMSG_ALIGN(SizeOf(t_cmsghdr))+CMSG_ALIGN(l);
end;
function CMSG_LEN(l:Ptruint):Ptruint;
begin
Result:=CMSG_ALIGN(SizeOf(t_cmsghdr))+l;
end;
end.