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-STREAMs 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.
socketINTEGER (returned by socketpair or
socket).familydomainNIL (stands for AF_UNSPEC),
INTEGER, or a platform-specific keyword, e.g.,
:INET stands for AF_INET.
typeNIL (stands for 0); INTEGER; or a
platform-specific keyword, e.g.,
:DGRAM stands for SOCK_DGRAM.
protocolNIL (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).
flagsrawsock:send
accepts :OOB and EOR arguments,
while rawsock:recv accepts PEEK,
OOB and WAITALL.
addressSTRUCTURE-OBJECT RAWSOCK:SOCKADDR
returned by
MAKE-SOCKADDR.
You do not need to supply its length because Lisp can determine it itself.
messageA 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:
(BLOCKNIL(HANDLER-BIND((TYPE-ERROR(LAMBDA(c) (FORMATT"~&error: ~A~%" c) (RETURN(CDDR(THIRD(TYPE-ERROR-EXPECTED-TYPEc))))))) (rawsock:socket "bad"NILNIL)))
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 SIGNALed.
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.
We do not interface to gethostbyname
or gethostbyaddr in this module,
they are already available through POSIX:RESOLVE-HOST-IPADDR.
Errors in getaddrinfo
and getnameinfo are SIGNALed
as CONDITIONs 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 '(a b)
:flags-and '(c d)) will return a list of objects which have
flags c and d and at
least one of a or b 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 INTEGER IP
address representations using
inet_addr | inet_ntop |
inet_ntoa | inet_pton |
(RAWSOCK:MAKE-SOCKADDR
family &OPTIONAL data)data should be a sequence of (UNSIGNED-BYTE 8) or an INTEGER
(meaning (MAKE-LIST data :initial-element 0)).
When omitted, the standard platform-specific size is 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)
- UDPCompute 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 | Last modified: 2010-07-07 |