33.17. Raw Socket Access
Prev | Chapter 33. Extensions Implemented as Modules | Next

## 33.17. Raw Socket Access

### 33.17.1. Introduction

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`.

### Try `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.

### Do not use `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.

### 33.17.2. Single System Call Functions

We implement access to

`(`accept` `socket` `address`)`
`(`bind` `socket` `address`)`
`(`connect` `socket` `address`)`
`(`getaddrinfo` `&KEY` node service protocol socktype family passive canonname numerichost numericserv v4mapped all addrconfig)`
`(`getnameinfo` `address` `&KEY` nofqdn numerichost namereqd numericserv numericscope dgram)`
`(`getpeername` `socket` `address`)`
`(`getsockname` `socket` `address`)`
`(`htonl` `n`)`
`(`htons` `n`)`
`(`ntohl` `n`)`
`(`ntohs` `n`)`
`(`recv` `socket` `buffer` `&KEY` start end peek oob waitall)`
`(`recvfrom` `socket` `buffer` `address` `&KEY` start end peek oob waitall)`
`(`recvmsg` `socket` `message` `&KEY` start end peek oob waitall)`
`(`send` `socket` `buffer` `&KEY` start end oob eor)`
`(`sendmsg` `socket` `message` `&KEY` start end oob eor)`
`(`sendto` `socket` `buffer` `address` `&KEY` start end oob eor)`
`(`sockatmark` `socket`)`
`(`socket` `domain` `type` `protocol`)`
`(`socketpair` `domain` `type` `protocol`)`

using same-named lisp functions in package “RAWSOCK”. Additionally,

`(`RAWSOCK:SOCK-CLOSE` `socket`)` calls `close`.
`(`RAWSOCK:SOCK-LISTEN` `socket` `&OPTIONAL` (`backlog` SOMAXCONN))` calls `listen`.

### Note

When the OS does not provide `socketpair`, it is emulated using `socket` + `connect` + `accept`.

### 33.17.3. Common arguments

void* `buffer`
  A `(`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.
int `socket`
  An `INTEGER` (returned by `socketpair` or `socket`).
int `family`
int `domain`
  A `NIL` (stands for `AF_UNSPEC`), `INTEGER`, or a platform-specific keyword, e.g., `:INET` stands for `AF_INET`.
int `type`
  A `NIL` (stands for 0); `INTEGER`; or a platform-specific keyword, e.g., `:DGRAM` stands for `SOCK_DGRAM`.
int `protocol`
  A `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`).
int `flags`
  This C argument corresponds to keyword arguments to the Lisp functions. E.g., `rawsock:send` accepts `:OOB` and `EOR` arguments, while `rawsock:recv` accepts `PEEK`, `OOB` and `WAITALL`.
struct sockaddr `address`
  A `STRUCTURE-OBJECT` RAWSOCK:SOCKADDR returned by `MAKE-SOCKADDR`. You do not need to supply its length because Lisp can determine it itself.
struct msghdr `message`

  A `STRUCTURE-OBJECT` RAWSOCK:MESSAGE with the following slots:

  addr | a SOCKADDR.
  iovec | a `(`VECTOR` `(`VECTOR` (`UNSIGNED-BYTE` 8))`)` (`:START` and `:END` arguments are applied to this vector)
  control | a `(`VECTOR` (`UNSIGNED-BYTE` 8))`
  flags | a `LIST`

#### 33.17.3.1. Platform-dependent Keywords

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)))

### 33.17.4. Return Values

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.

### 33.17.5. Not Implemented

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`.

### 33.17.6. Errors

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`).

### 33.17.7. High-Level Functions

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 `(`VECTOR` (`UNSIGNED-BYTE` 8))` or a `(`VECTOR` `(`VECTOR` (`UNSIGNED-BYTE` 8))`)`). Return the number of bytes read or written.

  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`)`
  Call `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`)`
  Call `getnetbyname` when `network` is a `STRING`, or call `getnetbynumber` 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`)`
  Call `if_nametoindex` when `network` is a `STRING` and return an `INTEGER`; or call `if_indextoname` when `network` is an `INTEGER` and return a `STRING`. When `what` is `NIL`, return an association list of pairs `(`index` . `name`)` using `if_nameindex`.
`(RAWSOCK:IFADDRS)`
  Call `getifaddrs` and return a `LIST` of ifaddrs objects.
`(RAWSOCK:SOCKET-OPTION `socket` `name` `&KEY` :LEVEL)`
`(`SETF` (RAWSOCK:SOCKET-OPTION `socket` `name` `&KEY` :LEVEL) `value`)`
  Call `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`)`
  Create a sockaddr object. `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`)`
  Return the numeric `family` of the sockaddr object.
`(RAWSOCK:SOCKADDR-DATA `address`)`

  Return a fresh `VECTOR` displaced to the `data` field of the C struct sockaddr object.

  ### Warning

  Modifying this `VECTOR`'s content will modify the `address` argument data!

`(RAWSOCK:OPEN-UNIX-SOCKET `pathname` `&OPTIONAL` (`type` `:STREAM`))`
  Open a UNIX socket special file. Returns two values: `socket` and `address`.
`(RAWSOCK:OPEN-UNIX-SOCKET-STREAM `pathname` `&REST` `options` `&KEY` (`type` `:STREAM`) `&ALLOW-OTHER-KEYS`)`
  Open a UNIX socket special file. Returns two values: `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 packet for the protocol, with the appropriate header etc. The 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` `name` `address` `&KEY` `promisc` `noarp`)`
  Set some socket options and IP `address` with `ioctl`.

| These notes document CLISP version 2.45 | Last modified: 2008-05-14

Enter your search termsSubmit search form
Webclisp.cons.orgclisp.podval.orgwww.lisp.org

Prev | Up | Next
33.16. ZLIB Interface | Home | 33.18. The FastCGI Interface