1<?xml version="1.0" encoding="UTF-8"?>
2
3<section id="rawsock"><title>Raw Socket Access</title>
4
5<section id="rawsock-intro"><title>Introduction</title>
6
7<para>This is the raw socket interface, as described in
8 <filename role="unix">sys/socket.h</filename>.
9Sockets are represented by their &fixnum-t; &file-des;s.</para>
10
11<simpara>When this module is present, &features-my; contains the
12 symbol <constant>:RAWSOCK</constant>.</simpara>
13
14<warning id="rawsock-use-sockets"><title>Try &socket-stream; first!</title>
15 <simpara>For most uses of sockets, the facilities described in
16  <xref linkend="socket"/> are adequate and much more convenient than these.
17  You are encouraged to consider &socket-stream;s and ensure that they
18  are not adequate for your purposes before you use raw sockets.
19</simpara></warning>
20
21<warning id="rawsock-not-streams"><title>Do &not-e; use &make-stream;!</title>
22 <simpara>You can turn such a raw socket into a usual lisp &stream-t;
23  using &make-stream;, but you should be <emphasis>extremely</emphasis>
24  careful with such dubious actions!
25  See the <ulink url="ml">clisp-devel</ulink>
26  <ulink url="http://sourceforge.net/mailarchive/message.php?msg_id=7203955"
27         >mailing list archives</ulink> for more details.
28  Note that &make-stream; will duplicate the &file-des; (using &dup;),
29  so you <emphasis>still</emphasis> have to &close; the original raw socket.
30</simpara></warning>
31
32<para>Test file <filename role="clisp-cvs">modules/rawsock/test.tst</filename>
33 and the demos in <filename role="clisp-cvs">modules/rawsock/demos/</filename>
34 contain plenty of examples.</para>
35</section>
36
37<section id="rawsock-func"><title>Single System Call Functions</title>
38
39<para>We implement access to
40 <simplelist columns="1">
41  <member><code>(<function role="unix">accept</function>
42    &sock-r; &addr-r;)</code></member>
43  <member><code>(<function role="unix">bind</function>
44    &sock-r; &addr-r;)</code></member>
45  <member><code>(<function role="unix">connect</function>
46    &sock-r; &addr-r;)</code></member>
47  <member><code>(<function role="unix">getaddrinfo</function> &key-amp;
48    node service protocol socktype family passive canonname numerichost
49    numericserv v4mapped all addrconfig)</code></member>
50  <member><code>(<function role="unix">getnameinfo</function> &addr-r;
51    &key-amp; nofqdn numerichost namereqd numericserv numericscope
52    dgram)</code></member>
53  <member><code>(<function role="unix">getpeername</function>
54    &sock-r; &addr-r;)</code></member>
55  <member><code>(<function role="unix">getsockname</function>
56    &sock-r; &addr-r;)</code></member>
57  <member><code>(<function role="unix">htonl</function> &n-r;)</code></member>
58  <member><code>(<function role="unix">htons</function> &n-r;)</code></member>
59  <member><code>(<function role="unix">ntohl</function> &n-r;)</code></member>
60  <member><code>(<function role="unix">ntohs</function> &n-r;)</code></member>
61  <member><code>(<function role="unix">recv</function>
62    &sock-r; &buf-r; &key-amp; start end peek oob waitall)</code></member>
63  <member><code>(<function role="unix">recvfrom</function> &sock-r;
64    &buf-r; &addr-r; &key-amp; start end peek oob waitall)</code></member>
65  <member><code>(<function role="unix">recvmsg</function>
66    &sock-r; &mesg-r; &key-amp; start end peek oob waitall)</code></member>
67  <member><code>(<function role="unix">send</function>
68    &sock-r; &buf-r; &key-amp; start end oob eor)</code></member>
69  <member><code>(<function role="unix">sendmsg</function>
70    &sock-r; &mesg-r; &key-amp; start end oob eor)</code></member>
71  <member><code>(<function role="unix">sendto</function>
72    &sock-r; &buf-r; &addr-r; &key-amp; start end oob eor)</code></member>
73  <member><code>(<function role="unix">sockatmark</function>
74    &sock-r;)</code></member>
75  <member><code>(&socket; &dom-r; &type-r; &proto-r;)</code></member>
76  <member><code>(&socketpair; &dom-r; &type-r; &proto-r;)</code></member>
77 </simplelist>using same-named lisp functions in package
78 <quote role="package">RAWSOCK</quote>.
79 Additionally,<simplelist columns="1">
80  <member><code>(<function>RAWSOCK:SOCK-CLOSE</function> &sock-r;)</code>
81   calls <function role="unix">close</function>.</member>
82  <member><code>(<function>RAWSOCK:SOCK-LISTEN</function> &sock-r;
83    &optional-amp; (<replaceable>backlog</replaceable> SOMAXCONN))</code>
84   calls <function role="unix">listen</function>.</member>
85</simplelist></para>
86<note><para>When the OS does not provide &socketpair;, it is emulated
87  using &socket; + <function role="unix">connect</function> +
88  <function role="unix">accept</function>.</para></note>
89</section>
90
91<section id="rawsock-args"><title>Common arguments</title>
92<variablelist id="rawsock-args-list">
93<varlistentry><term><type>void*</type> &buf-r;</term>
94 <listitem><simpara>A &ubyte-vec;.  The vector may be adjustable
95   and have a fill pointer.  Whenever a function accepts a &buf-r;
96   argument, it also accepts &start-k; and &end-k; keyword arguments
97   with the usual meaning and defaults.  You do not have to supply the
98   vector length because Lisp can determine it itself, but, if you want
99   to, you can use &end-k; argument for that.
100</simpara></listitem></varlistentry>
101<varlistentry><term>&int-t; &sock-r;</term>
102 <listitem><simpara>An &integer-t; (returned by &socketpair; or
103   &socket;).</simpara></listitem></varlistentry>
104<varlistentry><term>&int-t; &family-r;</term>
105 <term>&int-t; &dom-r;</term>
106 <listitem><simpara>A &nil; (stands for <constant>AF_UNSPEC</constant>),
107   &integer-t;, or a platform-specific keyword, e.g.,
108   <constant>:INET</constant> stands for <constant>AF_INET</constant>.
109</simpara></listitem></varlistentry>
110<varlistentry><term>&int-t; &type-r;</term>
111 <listitem><simpara>A &nil; (stands for 0); &integer-t;; or a
112   platform-specific keyword, e.g.,
113   <constant>:DGRAM</constant> stands for <constant>SOCK_DGRAM</constant>.
114</simpara></listitem></varlistentry>
115<varlistentry><term>&int-t; &proto-r;</term>
116 <listitem><simpara>A &nil; (stands for 0); &integer-t;; a
117   platform-specific keyword, e.g., <constant>:ETH_P_ARP</constant> stands
118   for <constant>ETH_P_ARP</constant>, <constant>:IPPROTO-ICMP</constant>
119   stands for <constant>IPPROTO_ICMP</constant>; or a &string-t; (passed
120   to <function role="unix">getprotobyname</function>).
121</simpara></listitem></varlistentry>
122<varlistentry><term>&int-t; <replaceable>flags</replaceable></term>
123 <listitem><simpara>This &c-lang; argument corresponds to keyword
124   arguments to the Lisp functions.  E.g., <function>rawsock:send</function>
125   accepts <constant>:OOB</constant> and <constant>:EOR</constant> arguments,
126   while <function>rawsock:recv</function> accepts <constant>:PEEK</constant>,
127   <constant>:OOB</constant> and <constant>:WAITALL</constant>.
128</simpara></listitem></varlistentry>
129<varlistentry><term><type>struct sockaddr</type> &addr-r;</term>
130 <listitem><simpara>A &structure-object-t; <type>RAWSOCK:SOCKADDR</type>
131   returned by
132   <link linkend="make-sockaddr"><function>MAKE-SOCKADDR</function></link>.
133</simpara></listitem></varlistentry>
134<varlistentry><term><type>struct msghdr</type> &mesg-r;</term>
135 <listitem><para>A &structure-object-t; <type>RAWSOCK:MESSAGE</type>
136   with the following slots:
137   <variablelist>&varlist-table;
138    <varlistentry><term>addr</term><listitem><simpara>
139       a <link linkend="make-sockaddr"><type>SOCKADDR</type></link>.
140    </simpara></listitem></varlistentry>
141    <varlistentry><term>iovec</term><listitem><simpara>
142       a <literal role="type">(&vector-t; &ubyte-vec;)</literal>
143       (&start-k; and &end-k; arguments are applied to this vector)
144    </simpara></listitem></varlistentry>
145    <varlistentry><term>control</term><listitem><simpara>
146       a &ubyte-vec;</simpara></listitem></varlistentry>
147    <varlistentry><term>flags</term><listitem><simpara>
148       a &list-t;</simpara></listitem></varlistentry>
149</variablelist></para></listitem></varlistentry>
150</variablelist>
151
152<section id="rawsock-plat-dep-constants">
153 <title>Platform-dependent Keywords</title>
154<para>One can extract the list of acceptable platform-dependent
155 keywords for, e.g., socket domain, using the following code:
156<programlisting language="lisp">
157 (&block; &nil;
158   (&handler-bind; ((&type-error-t;
159                    (&lambda-m; (c)
160                      (&format; &t; "~&amp;error: ~A~%" c)
161                      (&return; (&cddr; (&third; (&type-error-expected-type; c)))))))
162     (rawsock:socket "bad" &nil; &nil;)))
163</programlisting></para></section>
164</section>
165
166<section id="rawsock-return"><title>Return Values</title>
167<para>The return values of the functions described in section
168 <xref linkend="rawsock-func"/> are derived from the return values of
169 the underlying system call: if, say, the &addr-r; argument is modified
170 by the system call, two values are returned (in addition to the
171 possible values coming from the return value of the system call):
172 the (modified) &addr-r; structure and its new size.
173 If the system call fails, an &err-sig;.</para>
174</section>
175
176<section id="rawsock-not-implemented"><title>Not Implemented</title>
177
178<para>We do not interface to &select; or <function role="unix">poll</function>
179 in this module, they are already available through &so-status;.</para>
180
181<para>We do not interface to <function role="unix">shutdown</function>
182 in this module, it is already available through &sost-shut;.</para>
183
184</section>
185
186<section id="rawsock-errors"><title>Errors</title>
187<para>Errors in <function role="unix">getaddrinfo</function>
188 and <function role="unix">getnameinfo</function> are &signal;ed
189 as &condition-t;s of type <type>RAWSOCK:EAI</type>
190 using <function role="unix">gai_strerror</function>.</para>
191<para>Errors in other functions are reported as the usual OS errors
192 (using &strerror;).</para></section>
193
194<section id="rawsock-high-level"><title>High-Level Functions</title>
195<variablelist id="rawsock-high-level-list"><title>Functions that do not
196  correspond to a single system call</title>
197<varlistentry id="sock-read"><term><code>(<function>RAWSOCK:SOCK-READ</function>
198   &sock-r; &buf-r; &key-amp; start end)</code></term>
199 <term><code>(<function>RAWSOCK:SOCK-WRITE</function>
200   &sock-r; &buf-r; &key-amp; start end)</code></term>
201<listitem><simpara>Call one of &read-U;/<function role="unix">readv</function>
202  or &write-U;/<function role="unix">writev</function>
203  (depending on whether &buf-r; is a &ubyte-vec; or
204  a <literal role="type">(&vector-t; &ubyte-vec;)</literal>).
205  Return the number of bytes read or written.</simpara>
206 <simpara>When <function role="unix">readv</function> and
207  <function role="unix">writev</function> and not available, they are
208  emulated by repeated calls to &read-U; and &write-U;.</simpara>
209 <simpara>On &win32; we have to use <function role="unix">recv</function>
210  instead of &read-U; and <function role="unix">send</function> instead of
211  &write-U; because &win32; &read-U; and &write-U; do not work on sockets,
212  only on regular files.</simpara></listitem></varlistentry>
213<varlistentry id="rawsock-protocol"><term><code>(RAWSOCK:PROTOCOL
214   &optional-amp; &proto-r;)</code></term>
215 <listitem><simpara>Call <function role="unix">getprotobyname</function>
216   when &proto-r; is a &string-t;,
217   or call <function role="unix">getprotobynumber</function> when
218   &proto-r; is an &integer-t;.
219   Return a <type>RAWSOCK:PROTOCOL</type> structure object.
220   When &proto-r; is &nil;, return a &list-t; of all known protocols using
221   <function role="unix">setprotoent</function>,
222   <function role="unix">getprotoent</function>, and
223   <function role="unix">endprotoent</function>.
224</simpara></listitem></varlistentry>
225<varlistentry id="rawsock-network"><term><code>(RAWSOCK:NETWORK
226   &optional-amp; &net-r; &type-r;)</code></term>
227 <listitem><simpara>Call <function role="unix">getnetbyname</function>
228   when &net-r; is a &string-t;,
229   or call <function role="unix">getnetbyaddr</function> when
230   &net-r; is an &integer-t;.
231   Return a <type>RAWSOCK:NETWORK</type> structure object.
232   When &net-r; is &nil;, return a &list-t; of all known networks
233   using <function role="unix">setnetent</function>,
234   <function role="unix">getnetent</function>, and
235   <function role="unix">endnetent</function>.
236</simpara></listitem></varlistentry>
237<varlistentry id="rawsock-if-name-index"><term><code>(RAWSOCK:IF-NAME-INDEX
238   &optional-amp; &what-r;)</code></term>
239 <listitem><simpara>Call <function role="unix">if_nametoindex</function>
240   when &what-r; is a &string-t; and return an &integer-t;;
241   or call <function role="unix">if_indextoname</function> when
242   &what-r; is an &integer-t; and return a &string-t;.
243   When &what-r; is &nil;, return an &alist; of
244   pairs <literal role="data">(&index-r; . &name-r;)</literal>
245   using <function role="unix">if_nameindex</function>.
246</simpara></listitem></varlistentry>
247<varlistentry id="rawsock-ifaddrs"><term><code>(RAWSOCK:IFADDRS
248   &key-amp; :FLAGS-OR :FLAGS-AND)</code></term>
249 <listitem><simpara>Call <function role="bsd">getifaddrs</function>
250   and return a &list-t; of <type>ifaddrs</type> objects, optionally
251   filtered using flags, e.g., <code>(ifaddrs :flags-or '(&k-r; &l-r;)
252    :flags-and '(&m-r; &n-r;))</code> will return a list of objects
253   which have &both-e; flags &m-r; &and-e; &n-r; &and-e; at least one of
254   &k-r; &or-e; &l-r; set.</simpara></listitem></varlistentry>
255<varlistentry id="rawsock-sockopt"><term><code>(RAWSOCK:SOCKET-OPTION
256   &sock-r; &name-r; &key-amp; :LEVEL)</code></term>
257 <term><code>(&setf; (RAWSOCK:SOCKET-OPTION &sock-r; &name-r;
258   &key-amp; :LEVEL) &value-r;)</code></term>
259 <listitem><simpara>Call <function role="unix">getsockopt</function>
260   and &setsockopt;, returns and sets individual (for specific option
261   &name-r; and <replaceable>level</replaceable>) and multiple (when &name-r;
262   is &nil; and/or <replaceable>level</replaceable> is &all-k;) options.
263   (See also &so-opt;.)</simpara></listitem></varlistentry>
264<varlistentry id="rawsock-convert-address"><term><code>(&convert-address;
265   &family-r; &addr-r;)</code></term>
266 <listitem><para>Convert between &string-t; and &ubyte-vec; &ip;
267   &addr-r; representations using<simplelist columns="2">
268    <member><function role="unix">inet_addr</function></member>
269    <member><function role="unix">inet_ntoa</function></member>
270    <member><function role="unix">inet_ntop</function></member>
271    <member><function role="unix">inet_pton</function></member>
272</simplelist>(&integer-t;s are also accepted for backward
273 compatibility)</para></listitem></varlistentry>
274<varlistentry id="make-sockaddr"><term><code>(RAWSOCK:MAKE-SOCKADDR
275   &family-r; &optional-amp; &data-r;)</code></term>
276 <listitem><simpara>Create a <type>sockaddr</type> object.
277   &data-r; should be a sequence of &ubyte-8; or an &integer-t;
278   (meaning <code>(&make-list; &data-r; :initial-element 0)</code>).
279   When omitted, the standard platform-specific size is used.</simpara>
280  <note><simpara>It is critical to use &data-r; of the corrent size (usually
281   <code>sizeof(struct sockaddr)</code>, but may be something depending
282   on the protocol to be used).</simpara></note></listitem></varlistentry>
283<varlistentry><term><code>(RAWSOCK:SOCKADDR-FAMILY &addr-r;)</code></term>
284 <listitem><simpara>Return the symbolic &family-r; of the
285   <type>sockaddr</type> object.</simpara></listitem></varlistentry>
286<varlistentry><term><code>(RAWSOCK:SOCKADDR-DATA &addr-r;)</code></term>
287 <listitem><simpara>Return a &fresh; &vector-t; displaced to the
288   <structfield>data</structfield> field of the
289   &c-lang; <type>struct sockaddr</type> object.</simpara>
290  <warning><simpara>Modifying this &vector-t;'s content will modify the
291    &addr-r; argument data!</simpara></warning></listitem></varlistentry>
292<varlistentry id="rawsock-unix-socket"><term><code>(RAWSOCK:OPEN-UNIX-SOCKET
293   &path-r; &optional-amp; (&type-r; &stream-k;))</code></term>
294 <listitem><simpara>Open a &unix; socket special file.
295   Returns two values: &sock-r; and &addr-r;.
296</simpara></listitem></varlistentry>
297<varlistentry><term><code>(RAWSOCK:OPEN-UNIX-SOCKET-STREAM &path-r;
298   &rest-amp; &options-r; &key-amp; (&type-r; &stream-k;)
299   &allow-other-keys-amp;)</code></term>
300 <listitem><simpara>Open a &unix; socket special file.
301   Returns two values: &stream-r; and &addr-r;.  &type-r; is passed
302   to <function>RAWSOCK:OPEN-UNIX-SOCKET</function>, other &options-r;
303   to &make-stream; (but see <xref linkend="rawsock-not-streams"/>).
304</simpara></listitem></varlistentry>
305<varlistentry>
306 <term><code>(RAWSOCK:IPCSUM &buf-r; &key-amp; start end)</code>
307  - &ip;</term>
308 <term><code>(RAWSOCK:ICMPCSUM &buf-r; &key-amp; start end)</code>
309  - &icmp;</term>
310 <term><code>(RAWSOCK:TCPCSUM &buf-r; &key-amp; start end)</code>
311  - &tcp;</term>
312 <term><code>(RAWSOCK:UDPCSUM &buf-r; &key-amp; start end)</code>
313  - &udp;</term>
314 <listitem><simpara>Compute the appropriate protocol checksum and record
315   it in the appropriate location.  &buf-r; is assumed to be a suitable
316   ethernet frame for the protocol, with the appropriate header etc.</simpara>
317  <simpara>Note that &buf-r; is an <emphasis>ethernet frame</emphasis>,
318   starting with 6 bytes of the destination MAC address, 6 bytes of the
319   source MAC address, and 2 bytes specifying the next level protocol,
320   (e.g., <literal>#x0800</literal> for &ip; and <literal>#x0806</literal>
321   for &arp;), i.e., the first 14 bytes of &buf-r; are ignored by these
322   functions.</simpara>
323  <simpara>A typical packet you send is both &ip; and &tcp; and thus
324   has two checksums, so you would want to call &two-e; functions.
325</simpara></listitem></varlistentry>
326<varlistentry><term><code>(RAWSOCK:CONFIGDEV &sock-r;
327   <replaceable>ifname</replaceable> &addr-r; &key-amp;
328   <replaceable>promisc</replaceable>
329   <replaceable>noarp</replaceable>)</code></term>
330 <listitem><simpara>Set some socket options and &ip; &addr-r;
331   with <function role="unix">ioctl</function>.
332</simpara></listitem></varlistentry>
333</variablelist>
334</section>
335
336</section>
337