This is the raw socket interface, as described in
<sys/socket.h
>.
Sockets are represented by their FIXNUM
file descriptors.
When this module is present, *FEATURES*
contains the
symbol :RAWSOCK
.
SOCKET:SOCKET-STREAM
first!For most uses of sockets, the facilities described in
Section 32.4, “Socket Streams” are adequate and much more convenient than these.
You are encouraged to consider SOCKET:SOCKET-STREAM
s and ensure that they
are not adequate for your purposes before you use raw sockets.
EXT:MAKE-STREAM
!You can turn such a raw socket into a usual lisp STREAM
using EXT:MAKE-STREAM
, but you should be extremely
careful with such dubious actions!
See the clisp-devel
mailing list archives for more details.
Note that EXT:MAKE-STREAM
will duplicate the file descriptor (using dup
),
so you still have to CLOSE
the original raw socket.
Test file modules/rawsock/test.tst
and the demos in modules/rawsock/demos/
contain plenty of examples.
We implement access to
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
( |
using same-named lisp functions in package “RAWSOCK”. Additionally,
(
calls close . |
(
calls listen . |
When the OS does not provide socketpair
, it is emulated
using socket
+ connect
+
accept
.
buffer
(VECTOR
(UNSIGNED-BYTE
8))
. The vector may be adjustable
and have a fill pointer. Whenever a function accepts a buffer
argument, it also accepts :START
and :END
keyword arguments
with the usual meaning and defaults. You do not have to supply the
vector length because Lisp can determine it itself, but, if you want
to, you can use :END
argument for that.
socket
INTEGER
(returned by socketpair
or
socket
).family
domain
NIL
(stands for AF_UNSPEC
),
INTEGER
, or a platform-specific keyword, e.g.,
:INET
stands for AF_INET
.
type
NIL
(stands for 0); INTEGER
; or a
platform-specific keyword, e.g.,
:DGRAM
stands for SOCK_DGRAM
.
protocol
NIL
(stands for 0); INTEGER
; a
platform-specific keyword, e.g., :ETH_P_ARP
stands
for ETH_P_ARP
, :IPPROTO-ICMP
stands for IPPROTO_ICMP
; or a STRING
(passed
to getprotobyname
).
flags
rawsock:send
accepts :OOB
and :EOR
arguments,
while rawsock:recv
accepts :PEEK
,
:OOB
and :WAITALL
.
address
STRUCTURE-OBJECT
RAWSOCK:SOCKADDR
returned by
MAKE-SOCKADDR
.
message
A STRUCTURE-OBJECT
RAWSOCK:MESSAGE
with the following slots:
addr | a SOCKADDR. |
iovec |
a (
(:START and :END arguments are applied to this vector)
|
control |
a ( |
flags |
a LIST |
One can extract the list of acceptable platform-dependent keywords for, e.g., socket domain, using the following code:
(BLOCK
NIL
(HANDLER-BIND
((TYPE-ERROR
(LAMBDA
(c) (FORMAT
T
"~&error: ~A~%" c) (RETURN
(CDDR
(THIRD
(TYPE-ERROR-EXPECTED-TYPE
c))))))) (rawsock:socket "bad"NIL
NIL
)))
The return values of the functions described in section
Section 33.17.2, “Single System Call Functions” are derived from the return values of
the underlying system call: if, say, the address
argument is modified
by the system call, two values are returned (in addition to the
possible values coming from the return value of the system call):
the (modified) address
structure and its new size.
If the system call fails, an ERROR
is SIGNAL
ed.
We do not interface to select
or poll
in this module, they are already available through SOCKET:SOCKET-STATUS
.
We do not interface to shutdown
in this module, it is already available through SOCKET:SOCKET-STREAM-SHUTDOWN
.
Errors in getaddrinfo
and getnameinfo
are SIGNAL
ed
as CONDITION
s of type RAWSOCK:EAI
using gai_strerror
.
Errors in other functions are reported as the usual OS errors
(using strerror
).
Functions that do not correspond to a single system call
(RAWSOCK:SOCK-READ
socket
buffer
&KEY
start end)
(RAWSOCK:SOCK-WRITE
socket
buffer
&KEY
start end)
Call one of read
/readv
or write
/writev
(depending on whether buffer
is a (
or
a VECTOR
(UNSIGNED-BYTE
8))(
).
Return the number of bytes read or written.VECTOR
(
)VECTOR
(UNSIGNED-BYTE
8))
When readv
and
writev
and not available, they are
emulated by repeated calls to read
and write
.
On Win32 we have to use recv
instead of read
and send
instead of
write
because Win32 read
and write
do not work on sockets,
only on regular files.
(RAWSOCK:PROTOCOL
&OPTIONAL
protocol
)
getprotobyname
when protocol
is a STRING
,
or call getprotobynumber
when
protocol
is an INTEGER
.
Return a RAWSOCK:PROTOCOL structure object.
When protocol
is NIL
, return a LIST
of all known protocols using
setprotoent
,
getprotoent
, and
endprotoent
.
(RAWSOCK:NETWORK
&OPTIONAL
network
type
)
getnetbyname
when network
is a STRING
,
or call getnetbyaddr
when
network
is an INTEGER
.
Return a RAWSOCK:NETWORK structure object.
When network
is NIL
, return a LIST
of all known networks
using setnetent
,
getnetent
, and
endnetent
.
(RAWSOCK:IF-NAME-INDEX
&OPTIONAL
what
)
if_nametoindex
when what
is a STRING
and return an INTEGER
;
or call if_indextoname
when
what
is an INTEGER
and return a STRING
.
When what
is NIL
, return an association list of
pairs (index
. name
)
using if_nameindex
.
(RAWSOCK:IFADDRS
&KEY
:FLAGS-OR :FLAGS-AND)
getifaddrs
and return a LIST
of ifaddrs objects, optionally
filtered using flags, e.g., (ifaddrs :flags-or '(k
l
)
:flags-and '(m
n
))
will return a list of objects
which have both flags m
and n
and at least one of
k
or l
set.(RAWSOCK:SOCKET-OPTION
socket
name
&KEY
:LEVEL)
(SETF
(RAWSOCK:SOCKET-OPTION socket
name
&KEY
:LEVEL) value
)
getsockopt
and setsockopt
, returns and sets individual (for specific option
name
and level
) and multiple (when name
is NIL
and/or level
is :ALL
) options.
(See also SOCKET:SOCKET-OPTIONS
.)(RAWSOCK:CONVERT-ADDRESS
family
address
)
Convert between STRING
and (
VECTOR
(UNSIGNED-BYTE
8))IP
address
representations using
inet_addr | inet_ntop |
inet_ntoa | inet_pton |
(INTEGER
s are also accepted for backward
compatibility)
(RAWSOCK:MAKE-SOCKADDR
family
&OPTIONAL
data
)
Create a sockaddr object.
data
should be a sequence of (
or an UNSIGNED-BYTE
8)INTEGER
(meaning (
).
When omitted, the standard platform-specific size is used.MAKE-LIST
data
:initial-element 0)
It is critical to use data
of the corrent size (usually
sizeof(struct sockaddr)
, but may be something depending
on the protocol to be used).
(RAWSOCK:SOCKADDR-FAMILY address
)
family
of the
sockaddr object.(RAWSOCK:SOCKADDR-DATA address
)
Return a fresh VECTOR
displaced to the
data
field of the
C struct sockaddr object.
Modifying this VECTOR
's content will modify the
address
argument data!
(RAWSOCK:OPEN-UNIX-SOCKET
pathname
&OPTIONAL
(type
:STREAM
))
socket
and address
.
(RAWSOCK:OPEN-UNIX-SOCKET-STREAM pathname
&REST
options
&KEY
(type
:STREAM
)
&ALLOW-OTHER-KEYS
)
stream
and address
. type
is passed
to RAWSOCK:OPEN-UNIX-SOCKET
, other options
to EXT:MAKE-STREAM
(but see Do not use EXT:MAKE-STREAM
!).
(RAWSOCK:IPCSUM buffer
&KEY
start end)
- IP
(RAWSOCK:ICMPCSUM buffer
&KEY
start end)
- ICMP
(RAWSOCK:TCPCSUM buffer
&KEY
start end)
- TCP
(RAWSOCK:UDPCSUM buffer
&KEY
start end)
- UDP
Compute the appropriate protocol checksum and record
it in the appropriate location. buffer
is assumed to be a suitable
ethernet frame for the protocol, with the appropriate header etc.
Note that buffer
is an ethernet frame,
starting with 6 bytes of the destination MAC address, 6 bytes of the
source MAC address, and 2 bytes specifying the next level protocol,
(e.g., #x0800
for IP
and #x0806
for ARP
), i.e., the first 14 bytes of buffer
are ignored by these
functions.
A typical packet you send is both IP
and TCP
and thus
has two checksums, so you would want to call two functions.
(RAWSOCK:CONFIGDEV socket
ifname
address
&KEY
promisc
noarp
)
IP
address
with ioctl
.
These notes document CLISP version 2.49.93+ | Last modified: 2018-02-19 |