net.c revision b05fc5463be8df587b4acc8f522f51e21bc22be8
1/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-2000 Wichert Akkerman <wichert@cistron.nl>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 *    derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 *	$Id$
31 */
32
33#include "defs.h"
34
35#include <sys/stat.h>
36#include <sys/socket.h>
37#include <sys/un.h>
38
39#if defined(HAVE_SIN6_SCOPE_ID_LINUX)
40#define in6_addr in6_addr_libc
41#define ipv6_mreq ipv6_mreq_libc
42#define sockaddr_in6 sockaddr_in6_libc
43#endif
44
45#include <netinet/in.h>
46#ifdef HAVE_NETINET_TCP_H
47#include <netinet/tcp.h>
48#endif
49#ifdef HAVE_NETINET_UDP_H
50#include <netinet/udp.h>
51#endif
52#ifdef HAVE_NETINET_SCTP_H
53#include <netinet/sctp.h>
54#endif
55#include <arpa/inet.h>
56#include <net/if.h>
57#if defined(LINUX)
58#include <asm/types.h>
59#if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC__ + __GLIBC_MINOR__ >= 3)
60#  include <netipx/ipx.h>
61#else
62#  include <linux/ipx.h>
63#endif
64#endif /* LINUX */
65
66#if defined (__GLIBC__) && (((__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1)) || defined(HAVE_SIN6_SCOPE_ID_LINUX))
67#if defined(HAVE_LINUX_IN6_H)
68#if defined(HAVE_SIN6_SCOPE_ID_LINUX)
69#undef in6_addr
70#undef ipv6_mreq
71#undef sockaddr_in6
72#define in6_addr in6_addr_kernel
73#define ipv6_mreq ipv6_mreq_kernel
74#define sockaddr_in6 sockaddr_in6_kernel
75#endif
76#include <linux/in6.h>
77#if defined(HAVE_SIN6_SCOPE_ID_LINUX)
78#undef in6_addr
79#undef ipv6_mreq
80#undef sockaddr_in6
81#define in6_addr in6_addr_libc
82#define ipv6_mreq ipv6_mreq_libc
83#define sockaddr_in6 sockaddr_in6_kernel
84#endif
85#endif
86#endif
87
88#if defined(HAVE_SYS_UIO_H)
89#include <sys/uio.h>
90#endif
91
92#if defined(HAVE_LINUX_NETLINK_H)
93#include <linux/netlink.h>
94#endif
95
96#if defined(HAVE_LINUX_IF_PACKET_H)
97#include <linux/if_packet.h>
98#endif
99
100#if defined(HAVE_LINUX_ICMP_H)
101#include <linux/icmp.h>
102#endif
103
104#ifndef PF_UNSPEC
105#define PF_UNSPEC AF_UNSPEC
106#endif
107
108#if UNIXWARE >= 7
109#define HAVE_SENDMSG		1		/* HACK - *FIXME* */
110#endif
111
112#ifdef LINUX
113/* Under Linux these are enums so we can't test for them with ifdef. */
114#define IPPROTO_EGP IPPROTO_EGP
115#define IPPROTO_PUP IPPROTO_PUP
116#define IPPROTO_IDP IPPROTO_IDP
117#define IPPROTO_IGMP IPPROTO_IGMP
118#define IPPROTO_RAW IPPROTO_RAW
119#define IPPROTO_MAX IPPROTO_MAX
120#endif
121
122static const struct xlat domains[] = {
123#ifdef PF_AAL5
124	{ PF_AAL5,	"PF_AAL5"	},
125#endif
126#ifdef PF_APPLETALK
127	{ PF_APPLETALK,	"PF_APPLETALK"	},
128#endif
129#ifdef PF_ASH
130	{ PF_ASH,	"PF_ASH"	},
131#endif
132#ifdef PF_ATMPVC
133	{ PF_ATMPVC,	"PF_ATMPVC"	},
134#endif
135#ifdef PF_ATMSVC
136	{ PF_ATMSVC,	"PF_ATMSVC"	},
137#endif
138#ifdef PF_AX25
139	{ PF_AX25,	"PF_AX25"	},
140#endif
141#ifdef PF_BLUETOOTH
142	{ PF_BLUETOOTH,	"PF_BLUETOOTH"	},
143#endif
144#ifdef PF_BRIDGE
145	{ PF_BRIDGE,	"PF_BRIDGE"	},
146#endif
147#ifdef PF_DECnet
148	{ PF_DECnet,	"PF_DECnet"	},
149#endif
150#ifdef PF_DECNET
151	{ PF_DECNET,	"PF_DECNET"	},
152#endif
153#ifdef PF_ECONET
154	{ PF_ECONET,	"PF_ECONET"	},
155#endif
156#ifdef PF_FILE
157	{ PF_FILE,	"PF_FILE"	},
158#endif
159#ifdef PF_IMPLINK
160	{ PF_IMPLINK,	"PF_IMPLINK"	},
161#endif
162#ifdef PF_INET
163	{ PF_INET,	"PF_INET"	},
164#endif
165#ifdef PF_INET6
166	{ PF_INET6,	"PF_INET6"	},
167#endif
168#ifdef PF_IPX
169	{ PF_IPX,	"PF_IPX"	},
170#endif
171#ifdef PF_IRDA
172	{ PF_IRDA,	"PF_IRDA"	},
173#endif
174#ifdef PF_ISO
175	{ PF_ISO,	"PF_ISO"	},
176#endif
177#ifdef PF_KEY
178	{ PF_KEY,	"PF_KEY"	},
179#endif
180#ifdef PF_UNIX
181	{ PF_UNIX,	"PF_UNIX"	},
182#endif
183#ifdef PF_LOCAL
184	{ PF_LOCAL,	"PF_LOCAL"	},
185#endif
186#ifdef PF_NETBEUI
187	{ PF_NETBEUI,	"PF_NETBEUI"	},
188#endif
189#ifdef PF_NETLINK
190	{ PF_NETLINK,	"PF_NETLINK"	},
191#endif
192#ifdef PF_NETROM
193	{ PF_NETROM,	"PF_NETROM"	},
194#endif
195#ifdef PF_PACKET
196	{ PF_PACKET,	"PF_PACKET"	},
197#endif
198#ifdef PF_PPPOX
199	{ PF_PPPOX,	"PF_PPPOX"	},
200#endif
201#ifdef PF_ROSE
202	{ PF_ROSE,	"PF_ROSE"	},
203#endif
204#ifdef PF_ROUTE
205	{ PF_ROUTE,	"PF_ROUTE"	},
206#endif
207#ifdef PF_SECURITY
208	{ PF_SECURITY,	"PF_SECURITY"	},
209#endif
210#ifdef PF_SNA
211	{ PF_SNA,	"PF_SNA"	},
212#endif
213#ifdef PF_UNSPEC
214	{ PF_UNSPEC,	"PF_UNSPEC"	},
215#endif
216#ifdef PF_WANPIPE
217	{ PF_WANPIPE,	"PF_WANPIPE"	},
218#endif
219#ifdef PF_X25
220	{ PF_X25,	"PF_X25"	},
221#endif
222	{ 0,		NULL		},
223};
224const struct xlat addrfams[] = {
225#ifdef AF_APPLETALK
226	{ AF_APPLETALK,	"AF_APPLETALK"	},
227#endif
228#ifdef AF_ASH
229	{ AF_ASH,	"AF_ASH"	},
230#endif
231#ifdef AF_ATMPVC
232	{ AF_ATMPVC,	"AF_ATMPVC"	},
233#endif
234#ifdef AF_ATMSVC
235	{ AF_ATMSVC,	"AF_ATMSVC"	},
236#endif
237#ifdef AF_AX25
238	{ AF_AX25,	"AF_AX25"	},
239#endif
240#ifdef AF_BLUETOOTH
241	{ AF_BLUETOOTH,	"AF_BLUETOOTH"	},
242#endif
243#ifdef AF_BRIDGE
244	{ AF_BRIDGE,	"AF_BRIDGE"	},
245#endif
246#ifdef AF_DECnet
247	{ AF_DECnet,	"AF_DECnet"	},
248#endif
249#ifdef AF_ECONET
250	{ AF_ECONET,	"AF_ECONET"	},
251#endif
252#ifdef AF_FILE
253	{ AF_FILE,	"AF_FILE"	},
254#endif
255#ifdef AF_IMPLINK
256	{ AF_IMPLINK,	"AF_IMPLINK"	},
257#endif
258#ifdef AF_INET
259	{ AF_INET,	"AF_INET"	},
260#endif
261#ifdef AF_INET6
262	{ AF_INET6,	"AF_INET6"	},
263#endif
264#ifdef AF_IPX
265	{ AF_IPX,	"AF_IPX"	},
266#endif
267#ifdef AF_IRDA
268	{ AF_IRDA,	"AF_IRDA"	},
269#endif
270#ifdef AF_ISO
271	{ AF_ISO,	"AF_ISO"	},
272#endif
273#ifdef AF_KEY
274	{ AF_KEY,	"AF_KEY"	},
275#endif
276#ifdef AF_UNIX
277	{ AF_UNIX,	"AF_UNIX"	},
278#endif
279#ifdef AF_LOCAL
280	{ AF_LOCAL,	"AF_LOCAL"	},
281#endif
282#ifdef AF_NETBEUI
283	{ AF_NETBEUI,	"AF_NETBEUI"	},
284#endif
285#ifdef AF_NETLINK
286	{ AF_NETLINK,	"AF_NETLINK"	},
287#endif
288#ifdef AF_NETROM
289	{ AF_NETROM,	"AF_NETROM"	},
290#endif
291#ifdef AF_PACKET
292	{ AF_PACKET,	"AF_PACKET"	},
293#endif
294#ifdef AF_PPPOX
295	{ AF_PPPOX,	"AF_PPPOX"	},
296#endif
297#ifdef AF_ROSE
298	{ AF_ROSE,	"AF_ROSE"	},
299#endif
300#ifdef AF_ROUTE
301	{ AF_ROUTE,	"AF_ROUTE"	},
302#endif
303#ifdef AF_SECURITY
304	{ AF_SECURITY,	"AF_SECURITY"	},
305#endif
306#ifdef AF_SNA
307	{ AF_SNA,	"AF_SNA"	},
308#endif
309#ifdef AF_UNSPEC
310	{ AF_UNSPEC,	"AF_UNSPEC"	},
311#endif
312#ifdef AF_WANPIPE
313	{ AF_WANPIPE,	"AF_WANPIPE"	},
314#endif
315#ifdef AF_X25
316	{ AF_X25,	"AF_X25"	},
317#endif
318	{ 0,		NULL		},
319};
320static const struct xlat socktypes[] = {
321	{ SOCK_STREAM,	"SOCK_STREAM"	},
322	{ SOCK_DGRAM,	"SOCK_DGRAM"	},
323#ifdef SOCK_RAW
324	{ SOCK_RAW,	"SOCK_RAW"	},
325#endif
326#ifdef SOCK_RDM
327	{ SOCK_RDM,	"SOCK_RDM"	},
328#endif
329#ifdef SOCK_SEQPACKET
330	{ SOCK_SEQPACKET,"SOCK_SEQPACKET"},
331#endif
332#ifdef SOCK_DCCP
333	{ SOCK_DCCP,	"SOCK_DCCP"	},
334#endif
335#ifdef SOCK_PACKET
336	{ SOCK_PACKET,	"SOCK_PACKET"	},
337#endif
338	{ 0,		NULL		},
339};
340static const struct xlat sock_type_flags[] = {
341#ifdef SOCK_CLOEXEC
342	{ SOCK_CLOEXEC,	"SOCK_CLOEXEC"	},
343#endif
344#ifdef SOCK_NONBLOCK
345	{ SOCK_NONBLOCK,"SOCK_NONBLOCK"	},
346#endif
347	{ 0,		NULL		},
348};
349#ifndef SOCK_TYPE_MASK
350# define SOCK_TYPE_MASK 0xf
351#endif
352static const struct xlat socketlayers[] = {
353#if defined(SOL_IP)
354	{ SOL_IP,	"SOL_IP"	},
355#endif
356#if defined(SOL_ICMP)
357	{ SOL_ICMP,	"SOL_ICMP"	},
358#endif
359#if defined(SOL_TCP)
360	{ SOL_TCP,	"SOL_TCP"	},
361#endif
362#if defined(SOL_UDP)
363	{ SOL_UDP,	"SOL_UDP"	},
364#endif
365#if defined(SOL_IPV6)
366	{ SOL_IPV6,	"SOL_IPV6"	},
367#endif
368#if defined(SOL_ICMPV6)
369	{ SOL_ICMPV6,	"SOL_ICMPV6"	},
370#endif
371#if defined(SOL_SCTP)
372	{ SOL_SCTP,	"SOL_SCTP"	},
373#endif
374#if defined(SOL_UDPLITE)
375	{ SOL_UDPLITE,	"SOL_UDPLITE"	},
376#endif
377#if defined(SOL_RAW)
378	{ SOL_RAW,	"SOL_RAW"	},
379#endif
380#if defined(SOL_IPX)
381	{ SOL_IPX,	"SOL_IPX"	},
382#endif
383#if defined(SOL_AX25)
384	{ SOL_AX25,	"SOL_AX25"	},
385#endif
386#if defined(SOL_ATALK)
387	{ SOL_ATALK,	"SOL_ATALK"	},
388#endif
389#if defined(SOL_NETROM)
390	{ SOL_NETROM,	"SOL_NETROM"	},
391#endif
392#if defined(SOL_ROSE)
393	{ SOL_ROSE,	"SOL_ROSE"	},
394#endif
395#if defined(SOL_DECNET)
396	{ SOL_DECNET,	"SOL_DECNET"	},
397#endif
398#if defined(SOL_X25)
399	{ SOL_X25,	"SOL_X25"	},
400#endif
401#if defined(SOL_PACKET)
402	{ SOL_PACKET,	"SOL_PACKET"	},
403#endif
404#if defined(SOL_ATM)
405	{ SOL_ATM,	"SOL_ATM"	},
406#endif
407#if defined(SOL_AAL)
408	{ SOL_AAL,	"SOL_AAL"	},
409#endif
410#if defined(SOL_IRDA)
411	{ SOL_IRDA,	"SOL_IRDA"	},
412#endif
413#if defined(SOL_NETBEUI)
414	{ SOL_NETBEUI,	"SOL_NETBEUI"	},
415#endif
416#if defined(SOL_LLC)
417	{ SOL_LLC,	"SOL_LLC"	},
418#endif
419#if defined(SOL_DCCP)
420	{ SOL_DCCP,	"SOL_DCCP"	},
421#endif
422#if defined(SOL_NETLINK)
423	{ SOL_NETLINK,	"SOL_NETLINK"	},
424#endif
425#if defined(SOL_TIPC)
426	{ SOL_TIPC,	"SOL_TIPC"	},
427#endif
428#if defined(SOL_RXRPC)
429	{ SOL_RXRPC,	"SOL_RXRPC"	},
430#endif
431#if defined(SOL_PPPOL2TP)
432	{ SOL_PPPOL2TP,	"SOL_PPPOL2TP"	},
433#endif
434#if defined(SOL_BLUETOOTH)
435	{ SOL_BLUETOOTH,"SOL_BLUETOOTH" },
436#endif
437#if defined(SOL_PNPIPE)
438	{ SOL_PNPIPE,	"SOL_PNPIPE"	},
439#endif
440#if defined(SOL_RDS)
441	{ SOL_RDS,	"SOL_RDS"	},
442#endif
443#if defined(SOL_IUVC)
444	{ SOL_IUCV,	"SOL_IUCV"	},
445#endif
446#if defined(SOL_CAIF)
447	{ SOL_CAIF,	"SOL_CAIF"	},
448#endif
449	{ SOL_SOCKET,	"SOL_SOCKET"	},	/* Never used! */
450	/* The SOL_* array should remain not NULL-terminated. */
451};
452/*** WARNING: DANGER WILL ROBINSON: NOTE "socketlayers" array above
453     falls into "protocols" array below!!!!   This is intended!!! ***/
454static const struct xlat protocols[] = {
455	{ IPPROTO_IP,	"IPPROTO_IP"	},
456	{ IPPROTO_ICMP,	"IPPROTO_ICMP"	},
457	{ IPPROTO_TCP,	"IPPROTO_TCP"	},
458	{ IPPROTO_UDP,	"IPPROTO_UDP"	},
459#ifdef IPPROTO_IGMP
460	{ IPPROTO_IGMP,	"IPPROTO_IGMP"	},
461#endif
462#ifdef IPPROTO_GGP
463	{ IPPROTO_GGP,	"IPPROTO_GGP"	},
464#endif
465#ifdef IPPROTO_IPIP
466	{ IPPROTO_IPIP,	"IPPROTO_IPIP"	},
467#endif
468#ifdef IPPROTO_EGP
469	{ IPPROTO_EGP,	"IPPROTO_EGP"	},
470#endif
471#ifdef IPPROTO_PUP
472	{ IPPROTO_PUP,	"IPPROTO_PUP"	},
473#endif
474#ifdef IPPROTO_IDP
475	{ IPPROTO_IDP,	"IPPROTO_IDP"	},
476#endif
477#ifdef IPPROTO_TP
478	{ IPPROTO_TP,	"IPPROTO_TP"	},
479#endif
480#ifdef IPPROTO_DCCP
481	{ IPPROTO_DCCP,	"IPPROTO_DCCP"	},
482#endif
483#ifdef IPPROTO_IPV6
484	{ IPPROTO_IPV6,	"IPPROTO_IPV6"	},
485#endif
486#ifdef IPPROTO_ROUTING
487	{ IPPROTO_ROUTING, "IPPROTO_ROUTING" },
488#endif
489#ifdef IPPROTO_FRAGMENT
490	{ IPPROTO_FRAGMENT, "IPPROTO_FRAGMENT" },
491#endif
492#ifdef IPPROTO_RSVP
493	{ IPPROTO_RSVP,	"IPPROTO_RSVP"	},
494#endif
495#ifdef IPPROTO_GRE
496	{ IPPROTO_GRE,	"IPPROTO_GRE"	},
497#endif
498#ifdef IPPROTO_ESP
499	{ IPPROTO_ESP,	"IPPROTO_ESP"	},
500#endif
501#ifdef IPPROTO_AH
502	{ IPPROTO_AH,	"IPPROTO_AH"	},
503#endif
504#ifdef IPPROTO_ICMPV6
505	{ IPPROTO_ICMPV6, "IPPROTO_ICMPV6" },
506#endif
507#ifdef IPPROTO_NONE
508	{ IPPROTO_NONE,	"IPPROTO_NONE"	},
509#endif
510#ifdef IPPROTO_DSTOPTS
511	{ IPPROTO_DSTOPTS, "IPPROTO_DSTOPTS" },
512#endif
513#ifdef IPPROTO_HELLO
514	{ IPPROTO_HELLO, "IPPROTO_HELLO" },
515#endif
516#ifdef IPPROTO_ND
517	{ IPPROTO_ND,	"IPPROTO_ND"	},
518#endif
519#ifdef IPPROTO_MTP
520	{ IPPROTO_MTP,	"IPPROTO_MTP"	},
521#endif
522#ifdef IPPROTO_ENCAP
523	{ IPPROTO_ENCAP, "IPPROTO_ENCAP" },
524#endif
525#ifdef IPPROTO_PIM
526	{ IPPROTO_PIM,	"IPPROTO_PIM"	},
527#endif
528#ifdef IPPROTO_COMP
529	{ IPPROTO_COMP,	"IPPROTO_COMP"	},
530#endif
531#ifdef IPPROTO_SCTP
532	{ IPPROTO_SCTP,	"IPPROTO_SCTP"	},
533#endif
534#ifdef IPPROTO_UDPLITE
535	{ IPPROTO_UDPLITE, "IPPROTO_UDPLITE" },
536#endif
537#ifdef IPPROTO_RAW
538	{ IPPROTO_RAW,	"IPPROTO_RAW"	},
539#endif
540#ifdef IPPROTO_MAX
541	{ IPPROTO_MAX,	"IPPROTO_MAX"	},
542#endif
543	{ 0,		NULL		},
544};
545static const struct xlat msg_flags[] = {
546	{ MSG_OOB,		"MSG_OOB"		},
547#ifdef MSG_DONTROUTE
548	{ MSG_DONTROUTE,	"MSG_DONTROUTE"		},
549#endif
550#ifdef MSG_PEEK
551	{ MSG_PEEK,		"MSG_PEEK"		},
552#endif
553#ifdef MSG_CTRUNC
554	{ MSG_CTRUNC,		"MSG_CTRUNC"		},
555#endif
556#ifdef MSG_PROXY
557	{ MSG_PROXY,		"MSG_PROXY"		},
558#endif
559#ifdef MSG_EOR
560	{ MSG_EOR,		"MSG_EOR"		},
561#endif
562#ifdef MSG_WAITALL
563	{ MSG_WAITALL,		"MSG_WAITALL"		},
564#endif
565#ifdef MSG_TRUNC
566	{ MSG_TRUNC,		"MSG_TRUNC"		},
567#endif
568#ifdef MSG_CTRUNC
569	{ MSG_CTRUNC,		"MSG_CTRUNC"		},
570#endif
571#ifdef MSG_ERRQUEUE
572	{ MSG_ERRQUEUE,		"MSG_ERRQUEUE"		},
573#endif
574#ifdef MSG_DONTWAIT
575	{ MSG_DONTWAIT,		"MSG_DONTWAIT"		},
576#endif
577#ifdef MSG_CONFIRM
578	{ MSG_CONFIRM,		"MSG_CONFIRM"		},
579#endif
580#ifdef MSG_PROBE
581	{ MSG_PROBE,		"MSG_PROBE"		},
582#endif
583#ifdef MSG_FIN
584	{ MSG_FIN,		"MSG_FIN"		},
585#endif
586#ifdef MSG_SYN
587	{ MSG_SYN,		"MSG_SYN"		},
588#endif
589#ifdef MSG_RST
590	{ MSG_RST,		"MSG_RST"		},
591#endif
592#ifdef MSG_NOSIGNAL
593	{ MSG_NOSIGNAL,		"MSG_NOSIGNAL"		},
594#endif
595#ifdef MSG_MORE
596	{ MSG_MORE,		"MSG_MORE"		},
597#endif
598#ifdef MSG_CMSG_CLOEXEC
599	{ MSG_CMSG_CLOEXEC,	"MSG_CMSG_CLOEXEC"	},
600#endif
601	{ 0,			NULL			},
602};
603
604static const struct xlat sockoptions[] = {
605#ifdef SO_ACCEPTCONN
606	{ SO_ACCEPTCONN,	"SO_ACCEPTCONN"	},
607#endif
608#ifdef SO_ALLRAW
609	{ SO_ALLRAW,	"SO_ALLRAW"	},
610#endif
611#ifdef SO_ATTACH_FILTER
612	{ SO_ATTACH_FILTER,	"SO_ATTACH_FILTER"	},
613#endif
614#ifdef SO_BINDTODEVICE
615	{ SO_BINDTODEVICE,	"SO_BINDTODEVICE"	},
616#endif
617#ifdef SO_BROADCAST
618	{ SO_BROADCAST,	"SO_BROADCAST"	},
619#endif
620#ifdef SO_BSDCOMPAT
621	{ SO_BSDCOMPAT,	"SO_BSDCOMPAT"	},
622#endif
623#ifdef SO_DEBUG
624	{ SO_DEBUG,	"SO_DEBUG"	},
625#endif
626#ifdef SO_DETACH_FILTER
627	{ SO_DETACH_FILTER,	"SO_DETACH_FILTER"	},
628#endif
629#ifdef SO_DONTROUTE
630	{ SO_DONTROUTE,	"SO_DONTROUTE"	},
631#endif
632#ifdef SO_ERROR
633	{ SO_ERROR,	"SO_ERROR"	},
634#endif
635#ifdef SO_ICS
636	{ SO_ICS,	"SO_ICS"	},
637#endif
638#ifdef SO_IMASOCKET
639	{ SO_IMASOCKET,	"SO_IMASOCKET"	},
640#endif
641#ifdef SO_KEEPALIVE
642	{ SO_KEEPALIVE,	"SO_KEEPALIVE"	},
643#endif
644#ifdef SO_LINGER
645	{ SO_LINGER,	"SO_LINGER"	},
646#endif
647#ifdef SO_LISTENING
648	{ SO_LISTENING,	"SO_LISTENING"	},
649#endif
650#ifdef SO_MGMT
651	{ SO_MGMT,	"SO_MGMT"	},
652#endif
653#ifdef SO_NO_CHECK
654	{ SO_NO_CHECK,	"SO_NO_CHECK"	},
655#endif
656#ifdef SO_OOBINLINE
657	{ SO_OOBINLINE,	"SO_OOBINLINE"	},
658#endif
659#ifdef SO_ORDREL
660	{ SO_ORDREL,	"SO_ORDREL"	},
661#endif
662#ifdef SO_PARALLELSVR
663	{ SO_PARALLELSVR,	"SO_PARALLELSVR"	},
664#endif
665#ifdef SO_PASSCRED
666	{ SO_PASSCRED,	"SO_PASSCRED"	},
667#endif
668#ifdef SO_PEERCRED
669	{ SO_PEERCRED,	"SO_PEERCRED"	},
670#endif
671#ifdef SO_PEERNAME
672	{ SO_PEERNAME,	"SO_PEERNAME"	},
673#endif
674#ifdef SO_PEERSEC
675	{ SO_PEERSEC,	"SO_PEERSEC"	},
676#endif
677#ifdef SO_PRIORITY
678	{ SO_PRIORITY,	"SO_PRIORITY"	},
679#endif
680#ifdef SO_PROTOTYPE
681	{ SO_PROTOTYPE,	"SO_PROTOTYPE"	},
682#endif
683#ifdef SO_RCVBUF
684	{ SO_RCVBUF,	"SO_RCVBUF"	},
685#endif
686#ifdef SO_RCVLOWAT
687	{ SO_RCVLOWAT,	"SO_RCVLOWAT"	},
688#endif
689#ifdef SO_RCVTIMEO
690	{ SO_RCVTIMEO,	"SO_RCVTIMEO"	},
691#endif
692#ifdef SO_RDWR
693	{ SO_RDWR,	"SO_RDWR"	},
694#endif
695#ifdef SO_REUSEADDR
696	{ SO_REUSEADDR,	"SO_REUSEADDR"	},
697#endif
698#ifdef SO_REUSEPORT
699	{ SO_REUSEPORT,	"SO_REUSEPORT"	},
700#endif
701#ifdef SO_SECURITY_AUTHENTICATION
702	{ SO_SECURITY_AUTHENTICATION,"SO_SECURITY_AUTHENTICATION"},
703#endif
704#ifdef SO_SECURITY_ENCRYPTION_NETWORK
705	{ SO_SECURITY_ENCRYPTION_NETWORK,"SO_SECURITY_ENCRYPTION_NETWORK"},
706#endif
707#ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
708	{ SO_SECURITY_ENCRYPTION_TRANSPORT,"SO_SECURITY_ENCRYPTION_TRANSPORT"},
709#endif
710#ifdef SO_SEMA
711	{ SO_SEMA,	"SO_SEMA"	},
712#endif
713#ifdef SO_SNDBUF
714	{ SO_SNDBUF,	"SO_SNDBUF"	},
715#endif
716#ifdef SO_SNDLOWAT
717	{ SO_SNDLOWAT,	"SO_SNDLOWAT"	},
718#endif
719#ifdef SO_SNDTIMEO
720	{ SO_SNDTIMEO,	"SO_SNDTIMEO"	},
721#endif
722#ifdef SO_TIMESTAMP
723	{ SO_TIMESTAMP,	"SO_TIMESTAMP"	},
724#endif
725#ifdef SO_TYPE
726	{ SO_TYPE,	"SO_TYPE"	},
727#endif
728#ifdef SO_USELOOPBACK
729	{ SO_USELOOPBACK,	"SO_USELOOPBACK"	},
730#endif
731	{ 0,		NULL		},
732};
733
734#if !defined (SOL_IP) && defined (IPPROTO_IP)
735#define SOL_IP IPPROTO_IP
736#endif
737
738#ifdef SOL_IP
739static const struct xlat sockipoptions[] = {
740#ifdef IP_TOS
741	{ IP_TOS,		"IP_TOS"		},
742#endif
743#ifdef IP_TTL
744	{ IP_TTL,		"IP_TTL"		},
745#endif
746#ifdef IP_HDRINCL
747	{ IP_HDRINCL,		"IP_HDRINCL"		},
748#endif
749#ifdef IP_OPTIONS
750	{ IP_OPTIONS,		"IP_OPTIONS"		},
751#endif
752#ifdef IP_ROUTER_ALERT
753	{ IP_ROUTER_ALERT,	"IP_ROUTER_ALERT"	},
754#endif
755#ifdef IP_RECVOPTIONS
756	{ IP_RECVOPTIONS,	"IP_RECVOPTIONS"	},
757#endif
758#ifdef IP_RECVOPTS
759	{ IP_RECVOPTS,		"IP_RECVOPTS"		},
760#endif
761#ifdef IP_RECVRETOPTS
762	{ IP_RECVRETOPTS,	"IP_RECVRETOPTS"	},
763#endif
764#ifdef IP_RECVDSTADDR
765	{ IP_RECVDSTADDR,	"IP_RECVDSTADDR"	},
766#endif
767#ifdef IP_RETOPTS
768	{ IP_RETOPTS,		"IP_RETOPTS"		},
769#endif
770#ifdef IP_PKTINFO
771	{ IP_PKTINFO,		"IP_PKTINFO"		},
772#endif
773#ifdef IP_PKTOPTIONS
774	{ IP_PKTOPTIONS,	"IP_PKTOPTIONS"		},
775#endif
776#ifdef IP_MTU_DISCOVER
777	{ IP_MTU_DISCOVER,	"IP_MTU_DISCOVER"	},
778#endif
779#ifdef IP_RECVERR
780	{ IP_RECVERR,		"IP_RECVERR"		},
781#endif
782#ifdef IP_RECVTTL
783	{ IP_RECVTTL,		"IP_RECVTTL"		},
784#endif
785#ifdef IP_RECVTOS
786	{ IP_RECVTOS,		"IP_RECVTOS"		},
787#endif
788#ifdef IP_MTU
789	{ IP_MTU,		"IP_MTU"		},
790#endif
791#ifdef IP_MULTICAST_IF
792	{ IP_MULTICAST_IF,	"IP_MULTICAST_IF"	},
793#endif
794#ifdef IP_MULTICAST_TTL
795	{ IP_MULTICAST_TTL,	"IP_MULTICAST_TTL"	},
796#endif
797#ifdef IP_MULTICAST_LOOP
798	{ IP_MULTICAST_LOOP,	"IP_MULTICAST_LOOP"	},
799#endif
800#ifdef IP_ADD_MEMBERSHIP
801	{ IP_ADD_MEMBERSHIP,	"IP_ADD_MEMBERSHIP"	},
802#endif
803#ifdef IP_DROP_MEMBERSHIP
804	{ IP_DROP_MEMBERSHIP,	"IP_DROP_MEMBERSHIP"	},
805#endif
806#ifdef IP_BROADCAST_IF
807	{ IP_BROADCAST_IF,	"IP_BROADCAST_IF"	},
808#endif
809#ifdef IP_RECVIFINDEX
810	{ IP_RECVIFINDEX,	"IP_RECVIFINDEX"	},
811#endif
812#ifdef IP_MSFILTER
813	{ IP_MSFILTER,		"IP_MSFILTER"		},
814#endif
815#ifdef MCAST_MSFILTER
816	{ MCAST_MSFILTER,	"MCAST_MSFILTER"	},
817#endif
818#ifdef IP_FREEBIND
819	{ IP_FREEBIND,		"IP_FREEBIND"		},
820#endif
821	{ 0,			NULL			},
822};
823#endif /* SOL_IP */
824
825#ifdef SOL_IPV6
826static const struct xlat sockipv6options[] = {
827#ifdef IPV6_ADDRFORM
828	{ IPV6_ADDRFORM,	"IPV6_ADDRFORM"		},
829#endif
830#ifdef MCAST_FILTER
831	{ MCAST_FILTER,		"MCAST_FILTER"		},
832#endif
833#ifdef IPV6_PKTOPTIONS
834	{ IPV6_PKTOPTIONS,	"IPV6_PKTOPTIONS"	},
835#endif
836#ifdef IPV6_MTU
837	{ IPV6_MTU,		"IPV6_MTU"		},
838#endif
839#ifdef IPV6_V6ONLY
840	{ IPV6_V6ONLY,		"IPV6_V6ONLY"		},
841#endif
842#ifdef IPV6_PKTINFO
843	{ IPV6_PKTINFO,		"IPV6_PKTINFO"		},
844#endif
845#ifdef IPV6_HOPLIMIT
846	{ IPV6_HOPLIMIT,	"IPV6_HOPLIMIT"		},
847#endif
848#ifdef IPV6_RTHDR
849	{ IPV6_RTHDR,		"IPV6_RTHDR"		},
850#endif
851#ifdef IPV6_HOPOPTS
852	{ IPV6_HOPOPTS,		"IPV6_HOPOPTS"		},
853#endif
854#ifdef IPV6_DSTOPTS
855	{ IPV6_DSTOPTS,		"IPV6_DSTOPTS"		},
856#endif
857#ifdef IPV6_FLOWINFO
858	{ IPV6_FLOWINFO,	"IPV6_FLOWINFO"		},
859#endif
860#ifdef IPV6_UNICAST_HOPS
861	{ IPV6_UNICAST_HOPS,	"IPV6_UNICAST_HOPS"	},
862#endif
863#ifdef IPV6_MULTICAST_HOPS
864	{ IPV6_MULTICAST_HOPS,	"IPV6_MULTICAST_HOPS"	},
865#endif
866#ifdef IPV6_MULTICAST_LOOP
867	{ IPV6_MULTICAST_LOOP,	"IPV6_MULTICAST_LOOP"	},
868#endif
869#ifdef IPV6_MULTICAST_IF
870	{ IPV6_MULTICAST_IF,	"IPV6_MULTICAST_IF"	},
871#endif
872#ifdef IPV6_MTU_DISCOVER
873	{ IPV6_MTU_DISCOVER,	"IPV6_MTU_DISCOVER"	},
874#endif
875#ifdef IPV6_RECVERR
876	{ IPV6_RECVERR,		"IPV6_RECVERR"		},
877#endif
878#ifdef IPV6_FLOWINFO_SEND
879	{ IPV6_FLOWINFO_SEND,	"IPV6_FLOWINFO_SEND"	},
880#endif
881#ifdef IPV6_ADD_MEMBERSHIP
882	{ IPV6_ADD_MEMBERSHIP,	"IPV6_ADD_MEMBERSHIP"	},
883#endif
884#ifdef IPV6_DROP_MEMBERSHIP
885	{ IPV6_DROP_MEMBERSHIP,	"IPV6_DROP_MEMBERSHIP"	},
886#endif
887#ifdef IPV6_ROUTER_ALERT
888	{ IPV6_ROUTER_ALERT,	"IPV6_ROUTER_ALERT"	},
889#endif
890	{ 0,			NULL			},
891};
892#endif /* SOL_IPV6 */
893
894#ifdef SOL_IPX
895static const struct xlat sockipxoptions[] = {
896	{ IPX_TYPE,	"IPX_TYPE"	},
897	{ 0,		NULL		},
898};
899#endif /* SOL_IPX */
900
901#ifdef SOL_RAW
902static const struct xlat sockrawoptions[] = {
903#if defined(ICMP_FILTER)
904	{ ICMP_FILTER,		"ICMP_FILTER"	},
905#endif
906	{ 0,			NULL		},
907};
908#endif /* SOL_RAW */
909
910#ifdef SOL_PACKET
911static const struct xlat sockpacketoptions[] = {
912#ifdef PACKET_ADD_MEMBERSHIP
913	{ PACKET_ADD_MEMBERSHIP,	"PACKET_ADD_MEMBERSHIP"	},
914#endif
915#ifdef PACKET_DROP_MEMBERSHIP
916	{ PACKET_DROP_MEMBERSHIP,	"PACKET_DROP_MEMBERSHIP"},
917#endif
918#if defined(PACKET_RECV_OUTPUT)
919	{ PACKET_RECV_OUTPUT,		"PACKET_RECV_OUTPUT"	},
920#endif
921#if defined(PACKET_RX_RING)
922	{ PACKET_RX_RING,		"PACKET_RX_RING"	},
923#endif
924#if defined(PACKET_STATISTICS)
925	{ PACKET_STATISTICS,		"PACKET_STATISTICS"	},
926#endif
927#if defined(PACKET_COPY_THRESH)
928	{ PACKET_COPY_THRESH,		"PACKET_COPY_THRESH"	},
929#endif
930#if defined(PACKET_AUXDATA)
931	{ PACKET_AUXDATA,		"PACKET_AUXDATA"	},
932#endif
933#if defined(PACKET_ORIGDEV)
934	{ PACKET_ORIGDEV,		"PACKET_ORIGDEV"	},
935#endif
936#if defined(PACKET_VERSION)
937	{ PACKET_VERSION,		"PACKET_VERSION"	},
938#endif
939#if defined(PACKET_HDRLEN)
940	{ PACKET_HDRLEN,		"PACKET_HDRLEN"	},
941#endif
942#if defined(PACKET_RESERVE)
943	{ PACKET_RESERVE,		"PACKET_RESERVE"	},
944#endif
945#if defined(PACKET_TX_RING)
946	{ PACKET_TX_RING,		"PACKET_TX_RING"	},
947#endif
948#if defined(PACKET_LOSS)
949	{ PACKET_LOSS,			"PACKET_LOSS"	},
950#endif
951	{ 0,				NULL			},
952};
953#endif /* SOL_PACKET */
954
955#ifdef SOL_SCTP
956static const struct xlat socksctpoptions[] = {
957#if defined(SCTP_RTOINFO)
958	{ SCTP_RTOINFO,			"SCTP_RTOINFO"	},
959#endif
960#if defined(SCTP_ASSOCINFO)
961	{ SCTP_ASSOCINFO,		"SCTP_ASSOCINFO"},
962#endif
963#if defined(SCTP_INITMSG)
964	{ SCTP_INITMSG,			"SCTP_INITMSG"	},
965#endif
966#if defined(SCTP_NODELAY)
967	{ SCTP_NODELAY,			"SCTP_NODELAY"	},
968#endif
969#if defined(SCTP_AUTOCLOSE)
970	{ SCTP_AUTOCLOSE,		"SCTP_AUTOCLOSE"},
971#endif
972#if defined(SCTP_SET_PEER_PRIMARY_ADDR)
973	{ SCTP_SET_PEER_PRIMARY_ADDR,	"SCTP_SET_PEER_PRIMARY_ADDR"},
974#endif
975#if defined(SCTP_PRIMARY_ADDR)
976	{ SCTP_PRIMARY_ADDR,		"SCTP_PRIMARY_ADDR"	},
977#endif
978#if defined(SCTP_ADAPTATION_LAYER)
979	{ SCTP_ADAPTATION_LAYER,	"SCTP_ADAPTATION_LAYER"	},
980#endif
981#if defined(SCTP_DISABLE_FRAGMENTS)
982	{ SCTP_DISABLE_FRAGMENTS,	"SCTP_DISABLE_FRAGMENTS"},
983#endif
984#if defined(SCTP_PEER_ADDR_PARAMS)
985	{ SCTP_PEER_ADDR_PARAMS,	"SCTP_PEER_ADDR_PARAMS"	},
986#endif
987#if defined(SCTP_DEFAULT_SEND_PARAM)
988	{ SCTP_DEFAULT_SEND_PARAM,	"SCTP_DEFAULT_SEND_PARAM"},
989#endif
990#if defined(SCTP_EVENTS)
991	{ SCTP_EVENTS,			"SCTP_EVENTS"		},
992#endif
993#if defined(SCTP_I_WANT_MAPPED_V4_ADDR)
994	{ SCTP_I_WANT_MAPPED_V4_ADDR,	"SCTP_I_WANT_MAPPED_V4_ADDR"},
995#endif
996#if defined(SCTP_MAXSEG)
997	{ SCTP_MAXSEG,			"SCTP_MAXSEG"		},
998#endif
999#if defined(SCTP_STATUS)
1000	{ SCTP_STATUS,			"SCTP_STATUS"		},
1001#endif
1002#if defined(SCTP_GET_PEER_ADDR_INFO)
1003	{ SCTP_GET_PEER_ADDR_INFO,	"SCTP_GET_PEER_ADDR_INFO"},
1004#endif
1005#if defined(SCTP_DELAYED_ACK)
1006	{ SCTP_DELAYED_ACK,		"SCTP_DELAYED_ACK"	},
1007#endif
1008#if defined(SCTP_CONTEXT)
1009	{ SCTP_CONTEXT,			"SCTP_CONTEXT"		},
1010#endif
1011#if defined(SCTP_FRAGMENT_INTERLEAVE)
1012	{ SCTP_FRAGMENT_INTERLEAVE,	"SCTP_FRAGMENT_INTERLEAVE"},
1013#endif
1014#if defined(SCTP_PARTIAL_DELIVERY_POINT)
1015	{ SCTP_PARTIAL_DELIVERY_POINT,	"SCTP_PARTIAL_DELIVERY_POINT"},
1016#endif
1017#if defined(SCTP_MAX_BURST)
1018	{ SCTP_MAX_BURST,		"SCTP_MAX_BURST"	},
1019#endif
1020#if defined(SCTP_AUTH_CHUNK)
1021	{ SCTP_AUTH_CHUNK,		"SCTP_AUTH_CHUNK"	},
1022#endif
1023#if defined(SCTP_HMAC_IDENT)
1024	{ SCTP_HMAC_IDENT,		"SCTP_HMAC_IDENT"	},
1025#endif
1026#if defined(SCTP_AUTH_KEY)
1027	{ SCTP_AUTH_KEY,		"SCTP_AUTH_KEY"		},
1028#endif
1029#if defined(SCTP_AUTH_ACTIVE_KEY)
1030	{ SCTP_AUTH_ACTIVE_KEY,		"SCTP_AUTH_ACTIVE_KEY"	},
1031#endif
1032#if defined(SCTP_AUTH_DELETE_KEY)
1033	{ SCTP_AUTH_DELETE_KEY,		"SCTP_AUTH_DELETE_KEY"	},
1034#endif
1035#if defined(SCTP_PEER_AUTH_CHUNKS)
1036	{ SCTP_PEER_AUTH_CHUNKS,	"SCTP_PEER_AUTH_CHUNKS"	},
1037#endif
1038#if defined(SCTP_LOCAL_AUTH_CHUNKS)
1039	{ SCTP_LOCAL_AUTH_CHUNKS,	"SCTP_LOCAL_AUTH_CHUNKS"},
1040#endif
1041#if defined(SCTP_GET_ASSOC_NUMBER)
1042	{ SCTP_GET_ASSOC_NUMBER,	"SCTP_GET_ASSOC_NUMBER"	},
1043#endif
1044
1045	/* linux specific things */
1046#if defined(SCTP_SOCKOPT_BINDX_ADD)
1047	{ SCTP_SOCKOPT_BINDX_ADD,	"SCTP_SOCKOPT_BINDX_ADD"	},
1048#endif
1049#if defined(SCTP_SOCKOPT_BINDX_REM)
1050	{ SCTP_SOCKOPT_BINDX_REM,	"SCTP_SOCKOPT_BINDX_REM"	},
1051#endif
1052#if defined(SCTP_SOCKOPT_PEELOFF)
1053	{ SCTP_SOCKOPT_PEELOFF,		"SCTP_SOCKOPT_PEELOFF"		},
1054#endif
1055#if defined(SCTP_GET_PEER_ADDRS_NUM_OLD)
1056	{ SCTP_GET_PEER_ADDRS_NUM_OLD,	"SCTP_GET_PEER_ADDRS_NUM_OLD"	},
1057#endif
1058#if defined(SCTP_GET_PEER_ADDRS_OLD)
1059	{ SCTP_GET_PEER_ADDRS_OLD,	"SCTP_GET_PEER_ADDRS_OLD"	},
1060#endif
1061#if defined(SCTP_GET_LOCAL_ADDRS_NUM_OLD)
1062	{ SCTP_GET_LOCAL_ADDRS_NUM_OLD,	"SCTP_GET_LOCAL_ADDRS_NUM_OLD"	},
1063#endif
1064#if defined(SCTP_GET_LOCAL_ADDRS_OLD)
1065	{ SCTP_GET_LOCAL_ADDRS_OLD,	"SCTP_GET_LOCAL_ADDRS_OLD"	},
1066#endif
1067#if defined(SCTP_SOCKOPT_CONNECTX_OLD)
1068	{ SCTP_SOCKOPT_CONNECTX_OLD,	"SCTP_SOCKOPT_CONNECTX_OLD"	},
1069#endif
1070#if defined(SCTP_GET_PEER_ADDRS)
1071	{ SCTP_GET_PEER_ADDRS,		"SCTP_GET_PEER_ADDRS"		},
1072#endif
1073#if defined(SCTP_GET_LOCAL_ADDRS)
1074	{ SCTP_GET_LOCAL_ADDRS,		"SCTP_GET_LOCAL_ADDRS"		},
1075#endif
1076
1077	{ 0,	NULL	},
1078};
1079#endif
1080
1081#if  !defined (SOL_TCP) && defined (IPPROTO_TCP)
1082#define SOL_TCP IPPROTO_TCP
1083#endif
1084
1085#ifdef SOL_TCP
1086static const struct xlat socktcpoptions[] = {
1087	{ TCP_NODELAY,		"TCP_NODELAY"	},
1088	{ TCP_MAXSEG,		"TCP_MAXSEG"	},
1089#if defined(TCP_CORK)
1090	{ TCP_CORK,		"TCP_CORK"	},
1091#endif
1092#if defined(TCP_KEEPIDLE)
1093	{ TCP_KEEPIDLE,		"TCP_KEEPIDLE" },
1094#endif
1095#if defined(TCP_KEEPINTVL)
1096	{ TCP_KEEPINTVL,	"TCP_KEEPINTVL" },
1097#endif
1098#if defined(TCP_KEEPCNT)
1099	{ TCP_KEEPCNT,		"TCP_KEEPCNT" },
1100#endif
1101#if defined(TCP_NKEEP)
1102	{ TCP_NKEEP,		"TCP_NKEEP"	},
1103#endif
1104#if defined(TCP_SYNCNT)
1105	{ TCP_SYNCNT,		"TCP_SYNCNT" },
1106#endif
1107#if defined(TCP_LINGER2)
1108	{ TCP_LINGER2,		"TCP_LINGER2" },
1109#endif
1110#if defined(TCP_DEFER_ACCEPT)
1111	{ TCP_DEFER_ACCEPT,	"TCP_DEFER_ACCEPT" },
1112#endif
1113#if defined(TCP_WINDOW_CLAMP)
1114	{ TCP_WINDOW_CLAMP,	"TCP_WINDOW_CLAMP" },
1115#endif
1116#if defined(TCP_INFO)
1117	{ TCP_INFO,		"TCP_INFO" },
1118#endif
1119#if defined(TCP_QUICKACK)
1120	{ TCP_QUICKACK,		"TCP_QUICKACK" },
1121#endif
1122#if defined(TCP_CONGESTION)
1123	{ TCP_CONGESTION,	"TCP_CONGESTION" },
1124#endif
1125#if defined(TCP_MD5SIG)
1126	{ TCP_MD5SIG,		"TCP_MD5SIG" },
1127#endif
1128#if defined(TCP_COOKIE_TRANSACTIONS)
1129	{ TCP_COOKIE_TRANSACTIONS,	"TCP_COOKIE_TRANSACTIONS" },
1130#endif
1131#if defined(TCP_THIN_LINEAR_TIMEOUTS)
1132	{ TCP_THIN_LINEAR_TIMEOUTS,	"TCP_THIN_LINEAR_TIMEOUTS" },
1133#endif
1134#if defined(TCP_THIN_DUPACK)
1135	{ TCP_THIN_DUPACK,	"TCP_THIN_DUPACK" },
1136#endif
1137#if defined(TCP_USER_TIMEOUT)
1138	{ TCP_USER_TIMEOUT,	"TCP_USER_TIMEOUT" },
1139#endif
1140	{ 0,			NULL		},
1141};
1142#endif /* SOL_TCP */
1143
1144#ifdef SOL_RAW
1145static const struct xlat icmpfilterflags[] = {
1146#if defined(ICMP_ECHOREPLY)
1147	{ (1<<ICMP_ECHOREPLY),		"ICMP_ECHOREPLY"	},
1148#endif
1149#if defined(ICMP_DEST_UNREACH)
1150	{ (1<<ICMP_DEST_UNREACH),	"ICMP_DEST_UNREACH"	},
1151#endif
1152#if defined(ICMP_SOURCE_QUENCH)
1153	{ (1<<ICMP_SOURCE_QUENCH),	"ICMP_SOURCE_QUENCH"	},
1154#endif
1155#if defined(ICMP_REDIRECT)
1156	{ (1<<ICMP_REDIRECT),		"ICMP_REDIRECT"		},
1157#endif
1158#if defined(ICMP_ECHO)
1159	{ (1<<ICMP_ECHO),		"ICMP_ECHO"		},
1160#endif
1161#if defined(ICMP_TIME_EXCEEDED)
1162	{ (1<<ICMP_TIME_EXCEEDED),	"ICMP_TIME_EXCEEDED"	},
1163#endif
1164#if defined(ICMP_PARAMETERPROB)
1165	{ (1<<ICMP_PARAMETERPROB),	"ICMP_PARAMETERPROB"	},
1166#endif
1167#if defined(ICMP_TIMESTAMP)
1168	{ (1<<ICMP_TIMESTAMP),		"ICMP_TIMESTAMP"	},
1169#endif
1170#if defined(ICMP_TIMESTAMPREPLY)
1171	{ (1<<ICMP_TIMESTAMPREPLY),	"ICMP_TIMESTAMPREPLY"	},
1172#endif
1173#if defined(ICMP_INFO_REQUEST)
1174	{ (1<<ICMP_INFO_REQUEST),	"ICMP_INFO_REQUEST"	},
1175#endif
1176#if defined(ICMP_INFO_REPLY)
1177	{ (1<<ICMP_INFO_REPLY),		"ICMP_INFO_REPLY"	},
1178#endif
1179#if defined(ICMP_ADDRESS)
1180	{ (1<<ICMP_ADDRESS),		"ICMP_ADDRESS"		},
1181#endif
1182#if defined(ICMP_ADDRESSREPLY)
1183	{ (1<<ICMP_ADDRESSREPLY),	"ICMP_ADDRESSREPLY"	},
1184#endif
1185	{ 0,				NULL			},
1186};
1187#endif /* SOL_RAW */
1188
1189#if defined(AF_PACKET) /* from e.g. linux/if_packet.h */
1190static const struct xlat af_packet_types[] = {
1191#if defined(PACKET_HOST)
1192	{ PACKET_HOST,			"PACKET_HOST"		},
1193#endif
1194#if defined(PACKET_BROADCAST)
1195	{ PACKET_BROADCAST,		"PACKET_BROADCAST"	},
1196#endif
1197#if defined(PACKET_MULTICAST)
1198	{ PACKET_MULTICAST,		"PACKET_MULTICAST"	},
1199#endif
1200#if defined(PACKET_OTHERHOST)
1201	{ PACKET_OTHERHOST,		"PACKET_OTHERHOST"	},
1202#endif
1203#if defined(PACKET_OUTGOING)
1204	{ PACKET_OUTGOING,		"PACKET_OUTGOING"	},
1205#endif
1206#if defined(PACKET_LOOPBACK)
1207	{ PACKET_LOOPBACK,		"PACKET_LOOPBACK"	},
1208#endif
1209#if defined(PACKET_FASTROUTE)
1210	{ PACKET_FASTROUTE,		"PACKET_FASTROUTE"	},
1211#endif
1212	{ 0,				NULL			},
1213};
1214#endif /* defined(AF_PACKET) */
1215
1216
1217void
1218printsock(struct tcb *tcp, long addr, int addrlen)
1219{
1220	union {
1221		char pad[128];
1222		struct sockaddr sa;
1223		struct sockaddr_in sin;
1224		struct sockaddr_un sau;
1225#ifdef HAVE_INET_NTOP
1226		struct sockaddr_in6 sa6;
1227#endif
1228#if defined(LINUX) && defined(AF_IPX)
1229		struct sockaddr_ipx sipx;
1230#endif
1231#ifdef AF_PACKET
1232		struct sockaddr_ll ll;
1233#endif
1234#ifdef AF_NETLINK
1235		struct sockaddr_nl nl;
1236#endif
1237	} addrbuf;
1238	char string_addr[100];
1239
1240	if (addr == 0) {
1241		tprints("NULL");
1242		return;
1243	}
1244	if (!verbose(tcp)) {
1245		tprintf("%#lx", addr);
1246		return;
1247	}
1248
1249	if (addrlen < 2 || addrlen > sizeof(addrbuf))
1250		addrlen = sizeof(addrbuf);
1251
1252	memset(&addrbuf, 0, sizeof(addrbuf));
1253	if (umoven(tcp, addr, addrlen, addrbuf.pad) < 0) {
1254		tprints("{...}");
1255		return;
1256	}
1257	addrbuf.pad[sizeof(addrbuf.pad) - 1] = '\0';
1258
1259	tprints("{sa_family=");
1260	printxval(addrfams, addrbuf.sa.sa_family, "AF_???");
1261	tprints(", ");
1262
1263	switch (addrbuf.sa.sa_family) {
1264	case AF_UNIX:
1265		if (addrlen == 2) {
1266			tprints("NULL");
1267		} else if (addrbuf.sau.sun_path[0]) {
1268			tprints("path=");
1269			printpathn(tcp, addr + 2, strlen(addrbuf.sau.sun_path));
1270		} else {
1271			tprints("path=@");
1272			printpathn(tcp, addr + 3, strlen(addrbuf.sau.sun_path + 1));
1273		}
1274		break;
1275	case AF_INET:
1276		tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")",
1277			ntohs(addrbuf.sin.sin_port), inet_ntoa(addrbuf.sin.sin_addr));
1278		break;
1279#ifdef HAVE_INET_NTOP
1280	case AF_INET6:
1281		inet_ntop(AF_INET6, &addrbuf.sa6.sin6_addr, string_addr, sizeof(string_addr));
1282		tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=%u",
1283				ntohs(addrbuf.sa6.sin6_port), string_addr,
1284				addrbuf.sa6.sin6_flowinfo);
1285#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
1286		{
1287#if defined(HAVE_IF_INDEXTONAME) && defined(IN6_IS_ADDR_LINKLOCAL) && defined(IN6_IS_ADDR_MC_LINKLOCAL)
1288			int numericscope = 0;
1289			if (IN6_IS_ADDR_LINKLOCAL(&addrbuf.sa6.sin6_addr)
1290			    || IN6_IS_ADDR_MC_LINKLOCAL(&addrbuf.sa6.sin6_addr)) {
1291				char scopebuf[IFNAMSIZ + 1];
1292
1293				if (if_indextoname(addrbuf.sa6.sin6_scope_id, scopebuf) == NULL)
1294					numericscope++;
1295				else
1296					tprintf(", sin6_scope_id=if_nametoindex(\"%s\")", scopebuf);
1297			} else
1298				numericscope++;
1299
1300			if (numericscope)
1301#endif
1302				tprintf(", sin6_scope_id=%u", addrbuf.sa6.sin6_scope_id);
1303		}
1304#endif
1305		break;
1306#endif
1307#if defined(AF_IPX) && defined(linux)
1308	case AF_IPX:
1309		{
1310			int i;
1311			tprintf("sipx_port=htons(%u), ",
1312					ntohs(addrbuf.sipx.sipx_port));
1313			/* Yes, I know, this does not look too
1314			 * strace-ish, but otherwise the IPX
1315			 * addresses just look monstrous...
1316			 * Anyways, feel free if you don't like
1317			 * this way.. :)
1318			 */
1319			tprintf("%08lx:", (unsigned long)ntohl(addrbuf.sipx.sipx_network));
1320			for (i = 0; i < IPX_NODE_LEN; i++)
1321				tprintf("%02x", addrbuf.sipx.sipx_node[i]);
1322			tprintf("/[%02x]", addrbuf.sipx.sipx_type);
1323		}
1324		break;
1325#endif /* AF_IPX && linux */
1326#ifdef AF_PACKET
1327	case AF_PACKET:
1328		{
1329			int i;
1330			tprintf("proto=%#04x, if%d, pkttype=",
1331					ntohs(addrbuf.ll.sll_protocol),
1332					addrbuf.ll.sll_ifindex);
1333			printxval(af_packet_types, addrbuf.ll.sll_pkttype, "?");
1334			tprintf(", addr(%d)={%d, ",
1335					addrbuf.ll.sll_halen,
1336					addrbuf.ll.sll_hatype);
1337			for (i = 0; i < addrbuf.ll.sll_halen; i++)
1338				tprintf("%02x", addrbuf.ll.sll_addr[i]);
1339		}
1340		break;
1341
1342#endif /* AF_APACKET */
1343#ifdef AF_NETLINK
1344	case AF_NETLINK:
1345		tprintf("pid=%d, groups=%08x", addrbuf.nl.nl_pid, addrbuf.nl.nl_groups);
1346		break;
1347#endif /* AF_NETLINK */
1348	/* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
1349	AF_X25 AF_ROSE etc. still need to be done */
1350
1351	default:
1352		tprints("sa_data=");
1353		printstr(tcp, (long) &((struct sockaddr *) addr)->sa_data,
1354			sizeof addrbuf.sa.sa_data);
1355		break;
1356	}
1357	tprints("}");
1358}
1359
1360#if HAVE_SENDMSG
1361static const struct xlat scmvals[] = {
1362#ifdef SCM_RIGHTS
1363	{ SCM_RIGHTS,		"SCM_RIGHTS"		},
1364#endif
1365#ifdef SCM_CREDENTIALS
1366	{ SCM_CREDENTIALS,	"SCM_CREDENTIALS"	},
1367#endif
1368	{ 0,			NULL			}
1369};
1370
1371static void
1372printcmsghdr(struct tcb *tcp, unsigned long addr, unsigned long len)
1373{
1374	struct cmsghdr *cmsg = len < sizeof(struct cmsghdr) ?
1375			       NULL : malloc(len);
1376	if (cmsg == NULL || umoven(tcp, addr, len, (char *) cmsg) < 0) {
1377		tprintf(", msg_control=%#lx", addr);
1378		free(cmsg);
1379		return;
1380	}
1381
1382	tprintf(", {cmsg_len=%u, cmsg_level=", (unsigned) cmsg->cmsg_len);
1383	printxval(socketlayers, cmsg->cmsg_level, "SOL_???");
1384	tprints(", cmsg_type=");
1385
1386	if (cmsg->cmsg_level == SOL_SOCKET) {
1387		unsigned long cmsg_len;
1388
1389		printxval(scmvals, cmsg->cmsg_type, "SCM_???");
1390		cmsg_len = (len < cmsg->cmsg_len) ? len : cmsg->cmsg_len;
1391
1392		if (cmsg->cmsg_type == SCM_RIGHTS
1393		    && CMSG_LEN(sizeof(int)) <= cmsg_len) {
1394			int *fds = (int *) CMSG_DATA(cmsg);
1395			int first = 1;
1396
1397			tprints(", {");
1398			while ((char *) fds < ((char *) cmsg + cmsg_len)) {
1399				if (!first)
1400					tprints(", ");
1401				tprintf("%d", *fds++);
1402				first = 0;
1403			}
1404			tprints("}}");
1405			free(cmsg);
1406			return;
1407		}
1408		if (cmsg->cmsg_type == SCM_CREDENTIALS
1409		    && CMSG_LEN(sizeof(struct ucred)) <= cmsg_len) {
1410			struct ucred *uc = (struct ucred *) CMSG_DATA(cmsg);
1411
1412			tprintf("{pid=%ld, uid=%ld, gid=%ld}}",
1413				(long)uc->pid, (long)uc->uid, (long)uc->gid);
1414			free(cmsg);
1415			return;
1416		}
1417	}
1418	free(cmsg);
1419	tprints(", ...}");
1420}
1421
1422static void
1423do_msghdr(struct tcb *tcp, struct msghdr *msg)
1424{
1425	tprintf("{msg_name(%d)=", msg->msg_namelen);
1426	printsock(tcp, (long)msg->msg_name, msg->msg_namelen);
1427
1428	tprintf(", msg_iov(%lu)=", (unsigned long)msg->msg_iovlen);
1429	tprint_iov(tcp, (unsigned long)msg->msg_iovlen,
1430		   (unsigned long)msg->msg_iov, 1);
1431
1432#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
1433	tprintf(", msg_controllen=%lu", (unsigned long)msg->msg_controllen);
1434	if (msg->msg_controllen)
1435		printcmsghdr(tcp, (unsigned long) msg->msg_control,
1436			     msg->msg_controllen);
1437	tprints(", msg_flags=");
1438	printflags(msg_flags, msg->msg_flags, "MSG_???");
1439#else /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
1440	tprintf("msg_accrights=%#lx, msg_accrightslen=%u",
1441		(unsigned long) msg->msg_accrights, msg->msg_accrightslen);
1442#endif /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
1443	tprints("}");
1444}
1445
1446static void
1447printmsghdr(struct tcb *tcp, long addr)
1448{
1449	struct msghdr msg;
1450
1451	if (umove(tcp, addr, &msg) < 0) {
1452		tprintf("%#lx", addr);
1453		return;
1454	}
1455	do_msghdr(tcp, &msg);
1456}
1457
1458#ifdef LINUX
1459static void
1460printmmsghdr(struct tcb *tcp, long addr)
1461{
1462	struct mmsghdr {
1463		struct msghdr msg_hdr;
1464		unsigned msg_len;
1465	} mmsg;
1466
1467	if (umove(tcp, addr, &mmsg) < 0) {
1468		tprintf("%#lx", addr);
1469		return;
1470	}
1471	tprints("{");
1472	do_msghdr(tcp, &mmsg.msg_hdr);
1473	tprintf(", %u}", mmsg.msg_len);
1474}
1475#endif
1476
1477#endif /* HAVE_SENDMSG */
1478
1479/*
1480 * low bits of the socket type define real socket type,
1481 * other bits are socket type flags.
1482 */
1483static void
1484tprint_sock_type(struct tcb *tcp, int flags)
1485{
1486	const char *str = xlookup(socktypes, flags & SOCK_TYPE_MASK);
1487
1488	if (str) {
1489		tprints(str);
1490		flags &= ~SOCK_TYPE_MASK;
1491		if (!flags)
1492			return;
1493		tprints("|");
1494	}
1495	printflags(sock_type_flags, flags, "SOCK_???");
1496}
1497
1498int
1499sys_socket(struct tcb *tcp)
1500{
1501	if (entering(tcp)) {
1502		printxval(domains, tcp->u_arg[0], "PF_???");
1503		tprints(", ");
1504		tprint_sock_type(tcp, tcp->u_arg[1]);
1505		tprints(", ");
1506		switch (tcp->u_arg[0]) {
1507		case PF_INET:
1508#ifdef PF_INET6
1509		case PF_INET6:
1510#endif
1511			printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
1512			break;
1513#ifdef PF_IPX
1514		case PF_IPX:
1515			/* BTW: I don't believe this.. */
1516			tprints("[");
1517			printxval(domains, tcp->u_arg[2], "PF_???");
1518			tprints("]");
1519			break;
1520#endif /* PF_IPX */
1521		default:
1522			tprintf("%lu", tcp->u_arg[2]);
1523			break;
1524		}
1525	}
1526	return 0;
1527}
1528
1529#ifdef SVR4
1530int
1531sys_so_socket(struct tcb *tcp)
1532{
1533	if (entering(tcp)) {
1534		/* not sure really what these args are... but this
1535		 * is how truss prints it
1536		 */
1537		tprintf("%ld, %ld, %ld, ",
1538		  tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
1539		printpath(tcp, tcp->u_arg[3]);
1540		tprintf(", %ld", tcp->u_arg[4]);
1541	}
1542	return 0;
1543}
1544
1545int
1546sys_so_socketpair(struct tcb *tcp)
1547{
1548	if (entering(tcp)) {
1549		/* not sure what this arg is */
1550		tprintf("0x%lx", tcp->u_arg[0]);
1551	}
1552	return 0;
1553}
1554#endif /* SVR4 */
1555
1556int
1557sys_bind(struct tcb *tcp)
1558{
1559	if (entering(tcp)) {
1560		tprintf("%ld, ", tcp->u_arg[0]);
1561		printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1562		tprintf(", %lu", tcp->u_arg[2]);
1563	}
1564	return 0;
1565}
1566
1567int
1568sys_connect(struct tcb *tcp)
1569{
1570	return sys_bind(tcp);
1571}
1572
1573int
1574sys_listen(struct tcb *tcp)
1575{
1576	if (entering(tcp)) {
1577		tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1578	}
1579	return 0;
1580}
1581
1582static int
1583do_accept(struct tcb *tcp, int flags_arg)
1584{
1585	if (entering(tcp)) {
1586		tprintf("%ld, ", tcp->u_arg[0]);
1587		return 0;
1588	}
1589	if (!tcp->u_arg[2])
1590		tprintf("%#lx, NULL", tcp->u_arg[1]);
1591	else {
1592		int len;
1593		if (tcp->u_arg[1] == 0 || syserror(tcp)
1594		    || umove(tcp, tcp->u_arg[2], &len) < 0) {
1595			tprintf("%#lx", tcp->u_arg[1]);
1596		} else {
1597			printsock(tcp, tcp->u_arg[1], len);
1598		}
1599		tprints(", ");
1600		printnum_int(tcp, tcp->u_arg[2], "%u");
1601	}
1602	if (flags_arg >= 0) {
1603		tprints(", ");
1604		printflags(sock_type_flags, tcp->u_arg[flags_arg],
1605			   "SOCK_???");
1606	}
1607	return 0;
1608}
1609
1610int
1611sys_accept(struct tcb *tcp)
1612{
1613	return do_accept(tcp, -1);
1614}
1615
1616#ifdef LINUX
1617int
1618sys_accept4(struct tcb *tcp)
1619{
1620	return do_accept(tcp, 3);
1621}
1622#endif
1623
1624int
1625sys_send(struct tcb *tcp)
1626{
1627	if (entering(tcp)) {
1628		tprintf("%ld, ", tcp->u_arg[0]);
1629		printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1630		tprintf(", %lu, ", tcp->u_arg[2]);
1631		/* flags */
1632		printflags(msg_flags, tcp->u_arg[3], "MSG_???");
1633	}
1634	return 0;
1635}
1636
1637int
1638sys_sendto(struct tcb *tcp)
1639{
1640	if (entering(tcp)) {
1641		tprintf("%ld, ", tcp->u_arg[0]);
1642		printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1643		tprintf(", %lu, ", tcp->u_arg[2]);
1644		/* flags */
1645		printflags(msg_flags, tcp->u_arg[3], "MSG_???");
1646		/* to address */
1647		tprints(", ");
1648		printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
1649		/* to length */
1650		tprintf(", %lu", tcp->u_arg[5]);
1651	}
1652	return 0;
1653}
1654
1655#ifdef HAVE_SENDMSG
1656
1657int
1658sys_sendmsg(struct tcb *tcp)
1659{
1660	if (entering(tcp)) {
1661		tprintf("%ld, ", tcp->u_arg[0]);
1662		printmsghdr(tcp, tcp->u_arg[1]);
1663		/* flags */
1664		tprints(", ");
1665		printflags(msg_flags, tcp->u_arg[2], "MSG_???");
1666	}
1667	return 0;
1668}
1669
1670#endif /* HAVE_SENDMSG */
1671
1672int
1673sys_recv(struct tcb *tcp)
1674{
1675	if (entering(tcp)) {
1676		tprintf("%ld, ", tcp->u_arg[0]);
1677	} else {
1678		if (syserror(tcp))
1679			tprintf("%#lx", tcp->u_arg[1]);
1680		else
1681			printstr(tcp, tcp->u_arg[1], tcp->u_rval);
1682
1683		tprintf(", %lu, ", tcp->u_arg[2]);
1684		printflags(msg_flags, tcp->u_arg[3], "MSG_???");
1685	}
1686	return 0;
1687}
1688
1689int
1690sys_recvfrom(struct tcb *tcp)
1691{
1692	int fromlen;
1693
1694	if (entering(tcp)) {
1695		tprintf("%ld, ", tcp->u_arg[0]);
1696	} else {
1697		if (syserror(tcp)) {
1698			tprintf("%#lx, %lu, %lu, %#lx, %#lx",
1699				tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3],
1700				tcp->u_arg[4], tcp->u_arg[5]);
1701			return 0;
1702		}
1703		/* buf */
1704		printstr(tcp, tcp->u_arg[1], tcp->u_rval);
1705		/* len */
1706		tprintf(", %lu, ", tcp->u_arg[2]);
1707		/* flags */
1708		printflags(msg_flags, tcp->u_arg[3], "MSG_???");
1709		/* from address, len */
1710		if (!tcp->u_arg[4] || !tcp->u_arg[5]) {
1711			if (tcp->u_arg[4] == 0)
1712				tprints(", NULL");
1713			else
1714				tprintf(", %#lx", tcp->u_arg[4]);
1715			if (tcp->u_arg[5] == 0)
1716				tprints(", NULL");
1717			else
1718				tprintf(", %#lx", tcp->u_arg[5]);
1719			return 0;
1720		}
1721		if (umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
1722			tprints(", {...}, [?]");
1723			return 0;
1724		}
1725		tprints(", ");
1726		printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
1727		/* from length */
1728		tprintf(", [%u]", fromlen);
1729	}
1730	return 0;
1731}
1732
1733#ifdef HAVE_SENDMSG
1734
1735int
1736sys_recvmsg(struct tcb *tcp)
1737{
1738	if (entering(tcp)) {
1739		tprintf("%ld, ", tcp->u_arg[0]);
1740	} else {
1741		if (syserror(tcp) || !verbose(tcp))
1742			tprintf("%#lx", tcp->u_arg[1]);
1743		else
1744			printmsghdr(tcp, tcp->u_arg[1]);
1745		/* flags */
1746		tprints(", ");
1747		printflags(msg_flags, tcp->u_arg[2], "MSG_???");
1748	}
1749	return 0;
1750}
1751
1752#ifdef LINUX
1753int
1754sys_recvmmsg(struct tcb *tcp)
1755{
1756	static char str[128];
1757	if (entering(tcp)) {
1758
1759		tprintf("%ld, ", tcp->u_arg[0]);
1760		if (verbose(tcp)) {
1761			sprint_timespec(str, tcp, tcp->u_arg[4]);
1762			tcp->auxstr = strdup(str);
1763		} else {
1764			tprintf("%#lx, %ld, ", tcp->u_arg[1], tcp->u_arg[2]);
1765			printflags(msg_flags, tcp->u_arg[3], "MSG_???");
1766			tprints(", ");
1767			print_timespec(tcp, tcp->u_arg[4]);
1768		}
1769		return 0;
1770	} else {
1771		if (verbose(tcp)) {
1772			if (syserror(tcp))
1773				tprintf("%#lx", tcp->u_arg[1]);
1774			else
1775				printmmsghdr(tcp, tcp->u_arg[1]);
1776			tprintf(", %ld, ", tcp->u_arg[2]);
1777			/* flags */
1778			printflags(msg_flags, tcp->u_arg[3], "MSG_???");
1779			/* timeout on entrance */
1780			tprintf(", %s", tcp->auxstr ? tcp->auxstr : "{...}");
1781			free((void *) tcp->auxstr);
1782			tcp->auxstr = NULL;
1783		}
1784		if (syserror(tcp))
1785			return 0;
1786		if (tcp->u_rval == 0) {
1787			tcp->auxstr = "Timeout";
1788			return RVAL_STR;
1789		}
1790		if (!verbose(tcp))
1791			return 0;
1792		/* timeout on exit */
1793		strcpy(str, "left ");
1794		sprint_timespec(str + strlen(str), tcp, tcp->u_arg[4]);
1795		tcp->auxstr = str;
1796		return RVAL_STR;
1797	}
1798}
1799#endif
1800
1801#endif /* HAVE_SENDMSG */
1802
1803static const struct xlat shutdown_modes[] = {
1804	{ 0,	"SHUT_RD"	},
1805	{ 1,	"SHUT_WR"	},
1806	{ 2,	"SHUT_RDWR"	},
1807	{ 0,	NULL		}
1808};
1809
1810int
1811sys_shutdown(struct tcb *tcp)
1812{
1813	if (entering(tcp)) {
1814		tprintf("%ld, ", tcp->u_arg[0]);
1815		printxval(shutdown_modes, tcp->u_arg[1], "SHUT_???");
1816	}
1817	return 0;
1818}
1819
1820int
1821sys_getsockname(struct tcb *tcp)
1822{
1823	return sys_accept(tcp);
1824}
1825
1826int
1827sys_getpeername(struct tcb *tcp)
1828{
1829	return sys_accept(tcp);
1830}
1831
1832static int
1833do_pipe(struct tcb *tcp, int flags_arg)
1834{
1835	if (exiting(tcp)) {
1836		if (syserror(tcp)) {
1837			tprintf("%#lx", tcp->u_arg[0]);
1838		} else {
1839#if defined(LINUX) && !defined(SPARC) && !defined(SPARC64) && !defined(SH) && !defined(IA64)
1840			int fds[2];
1841
1842			if (umoven(tcp, tcp->u_arg[0], sizeof fds, (char *) fds) < 0)
1843				tprints("[...]");
1844			else
1845				tprintf("[%u, %u]", fds[0], fds[1]);
1846#elif defined(SPARC) || defined(SPARC64) || defined(SH) || defined(SVR4) || defined(FREEBSD) || defined(IA64)
1847			tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
1848#else
1849			tprintf("%#lx", tcp->u_arg[0]);
1850#endif
1851		}
1852		if (flags_arg >= 0) {
1853			tprints(", ");
1854			printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
1855		}
1856	}
1857	return 0;
1858}
1859
1860int
1861sys_pipe(struct tcb *tcp)
1862{
1863	return do_pipe(tcp, -1);
1864}
1865
1866#ifdef LINUX
1867int
1868sys_pipe2(struct tcb *tcp)
1869{
1870	return do_pipe(tcp, 1);
1871}
1872#endif
1873
1874int
1875sys_socketpair(struct tcb *tcp)
1876{
1877#ifdef LINUX
1878	int fds[2];
1879#endif
1880
1881	if (entering(tcp)) {
1882		printxval(domains, tcp->u_arg[0], "PF_???");
1883		tprints(", ");
1884		tprint_sock_type(tcp, tcp->u_arg[1]);
1885		tprints(", ");
1886		switch (tcp->u_arg[0]) {
1887		case PF_INET:
1888			printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
1889			break;
1890#ifdef PF_IPX
1891		case PF_IPX:
1892			/* BTW: I don't believe this.. */
1893			tprints("[");
1894			printxval(domains, tcp->u_arg[2], "PF_???");
1895			tprints("]");
1896			break;
1897#endif /* PF_IPX */
1898		default:
1899			tprintf("%lu", tcp->u_arg[2]);
1900			break;
1901		}
1902	} else {
1903		if (syserror(tcp)) {
1904			tprintf(", %#lx", tcp->u_arg[3]);
1905			return 0;
1906		}
1907#ifdef LINUX
1908		if (umoven(tcp, tcp->u_arg[3], sizeof fds, (char *) fds) < 0)
1909			tprints(", [...]");
1910		else
1911			tprintf(", [%u, %u]", fds[0], fds[1]);
1912#endif /* LINUX */
1913#if defined(SUNOS4) || defined(SVR4) || defined(FREEBSD)
1914		tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
1915#endif /* SUNOS4 || SVR4 || FREEBSD */
1916	}
1917	return 0;
1918}
1919
1920int
1921sys_getsockopt(struct tcb *tcp)
1922{
1923	if (entering(tcp)) {
1924		tprintf("%ld, ", tcp->u_arg[0]);
1925		printxval(socketlayers, tcp->u_arg[1], "SOL_???");
1926		tprints(", ");
1927		switch (tcp->u_arg[1]) {
1928		case SOL_SOCKET:
1929			printxval(sockoptions, tcp->u_arg[2], "SO_???");
1930			break;
1931#ifdef SOL_IP
1932		case SOL_IP:
1933			printxval(sockipoptions, tcp->u_arg[2], "IP_???");
1934			break;
1935#endif
1936#ifdef SOL_IPV6
1937		case SOL_IPV6:
1938			printxval(sockipv6options, tcp->u_arg[2], "IPV6_???");
1939			break;
1940#endif
1941#ifdef SOL_IPX
1942		case SOL_IPX:
1943			printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
1944			break;
1945#endif
1946#ifdef SOL_PACKET
1947		case SOL_PACKET:
1948			printxval(sockpacketoptions, tcp->u_arg[2], "PACKET_???");
1949			break;
1950#endif
1951#ifdef SOL_TCP
1952		case SOL_TCP:
1953			printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
1954			break;
1955#endif
1956#ifdef SOL_SCTP
1957		case SOL_SCTP:
1958			printxval(socksctpoptions, tcp->u_arg[2], "SCTP_???");
1959			break;
1960#endif
1961
1962		/* SOL_AX25 SOL_ROSE SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
1963		 * etc. still need work */
1964		default:
1965			tprintf("%lu", tcp->u_arg[2]);
1966			break;
1967		}
1968		tprints(", ");
1969	} else {
1970		int len;
1971		if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &len) < 0) {
1972			tprintf("%#lx, %#lx",
1973				tcp->u_arg[3], tcp->u_arg[4]);
1974			return 0;
1975		}
1976
1977		switch (tcp->u_arg[1]) {
1978		case SOL_SOCKET:
1979			switch (tcp->u_arg[2]) {
1980#ifdef SO_LINGER
1981			case SO_LINGER:
1982				if (len == sizeof(struct linger)) {
1983					struct linger linger;
1984					if (umove(tcp,
1985						   tcp->u_arg[3],
1986						   &linger) < 0)
1987						break;
1988					tprintf("{onoff=%d, linger=%d}, "
1989						"[%d]",
1990						linger.l_onoff,
1991						linger.l_linger,
1992						len);
1993					return 0;
1994				}
1995				break;
1996#endif
1997#ifdef SO_PEERCRED
1998			case SO_PEERCRED:
1999				if (len == sizeof(struct ucred)) {
2000					struct ucred uc;
2001					if (umove(tcp,
2002						   tcp->u_arg[3],
2003						   &uc) < 0)
2004						break;
2005					tprintf("{pid=%ld, uid=%ld, gid=%ld}, "
2006						"[%d]",
2007						(long)uc.pid,
2008						(long)uc.uid,
2009						(long)uc.gid,
2010						len);
2011					return 0;
2012				}
2013				break;
2014#endif
2015			}
2016			break;
2017		case SOL_PACKET:
2018			switch (tcp->u_arg[2]) {
2019#ifdef PACKET_STATISTICS
2020			case PACKET_STATISTICS:
2021				if (len == sizeof(struct tpacket_stats)) {
2022					struct tpacket_stats stats;
2023					if (umove(tcp,
2024						   tcp->u_arg[3],
2025						   &stats) < 0)
2026						break;
2027					tprintf("{packets=%u, drops=%u}, "
2028						"[%d]",
2029						stats.tp_packets,
2030						stats.tp_drops,
2031						len);
2032					return 0;
2033				}
2034				break;
2035#endif
2036			}
2037			break;
2038		}
2039
2040		if (len == sizeof(int)) {
2041			printnum_int(tcp, tcp->u_arg[3], "%d");
2042		}
2043		else {
2044			printstr(tcp, tcp->u_arg[3], len);
2045		}
2046		tprintf(", [%d]", len);
2047	}
2048	return 0;
2049}
2050
2051#if defined(ICMP_FILTER)
2052static void printicmpfilter(struct tcb *tcp, long addr)
2053{
2054	struct icmp_filter	filter;
2055
2056	if (!addr) {
2057		tprints("NULL");
2058		return;
2059	}
2060	if (syserror(tcp) || !verbose(tcp)) {
2061		tprintf("%#lx", addr);
2062		return;
2063	}
2064	if (umove(tcp, addr, &filter) < 0) {
2065		tprints("{...}");
2066		return;
2067	}
2068
2069	tprints("~(");
2070	printflags(icmpfilterflags, ~filter.data, "ICMP_???");
2071	tprints(")");
2072}
2073#endif /* ICMP_FILTER */
2074
2075static int
2076printsockopt(struct tcb *tcp, int level, int name, long addr, int len)
2077{
2078	printxval(socketlayers, level, "SOL_??");
2079	tprints(", ");
2080	switch (level) {
2081	    case SOL_SOCKET:
2082		printxval(sockoptions, name, "SO_???");
2083		switch (name) {
2084#if defined(SO_LINGER)
2085		    case SO_LINGER:
2086			if (len == sizeof(struct linger)) {
2087				struct linger linger;
2088				if (umove(tcp, addr, &linger) < 0)
2089					break;
2090				tprintf(", {onoff=%d, linger=%d}",
2091					linger.l_onoff,
2092					linger.l_linger);
2093				return 0;
2094			}
2095			break;
2096#endif
2097		}
2098		break;
2099#ifdef SOL_IP
2100	    case SOL_IP:
2101		printxval(sockipoptions, name, "IP_???");
2102		break;
2103#endif
2104#ifdef SOL_IPV6
2105	    case SOL_IPV6:
2106		printxval(sockipv6options, name, "IPV6_???");
2107		break;
2108#endif
2109#ifdef SOL_IPX
2110	    case SOL_IPX:
2111		printxval(sockipxoptions, name, "IPX_???");
2112		break;
2113#endif
2114#ifdef SOL_PACKET
2115	    case SOL_PACKET:
2116		printxval(sockpacketoptions, name, "PACKET_???");
2117		/* TODO: decode packate_mreq for PACKET_*_MEMBERSHIP */
2118		switch (name) {
2119#ifdef PACKET_RX_RING
2120		    case PACKET_RX_RING:
2121#endif
2122#ifdef PACKET_TX_RING
2123		    case PACKET_TX_RING:
2124#endif
2125#if defined(PACKET_RX_RING) || defined(PACKET_TX_RING)
2126			if (len == sizeof(struct tpacket_req)) {
2127				struct tpacket_req req;
2128				if (umove(tcp, addr, &req) < 0)
2129					break;
2130				tprintf(", {block_size=%u, block_nr=%u, frame_size=%u, frame_nr=%u}",
2131					req.tp_block_size,
2132					req.tp_block_nr,
2133					req.tp_frame_size,
2134					req.tp_frame_nr);
2135				return 0;
2136			}
2137			break;
2138#endif /* PACKET_RX_RING || PACKET_TX_RING */
2139		}
2140		break;
2141#endif
2142#ifdef SOL_TCP
2143	    case SOL_TCP:
2144		printxval(socktcpoptions, name, "TCP_???");
2145		break;
2146#endif
2147#ifdef SOL_SCTP
2148	   case SOL_SCTP:
2149		printxval(socksctpoptions, name, "SCTP_???");
2150		break;
2151#endif
2152#ifdef SOL_RAW
2153	    case SOL_RAW:
2154		printxval(sockrawoptions, name, "RAW_???");
2155		switch (name) {
2156#if defined(ICMP_FILTER)
2157		    case ICMP_FILTER:
2158			tprints(", ");
2159			printicmpfilter(tcp, addr);
2160			return 0;
2161#endif
2162		}
2163		break;
2164#endif
2165
2166		/* SOL_AX25 SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
2167		 * etc. still need work  */
2168
2169	    default:
2170		tprintf("%u", name);
2171	}
2172
2173	/* default arg printing */
2174
2175	tprints(", ");
2176
2177	if (len == sizeof(int)) {
2178		printnum_int(tcp, addr, "%d");
2179	}
2180	else {
2181		printstr(tcp, addr, len);
2182	}
2183	return 0;
2184}
2185
2186
2187#ifdef HAVE_STRUCT_OPTHDR
2188
2189void
2190print_sock_optmgmt(struct tcb *tcp, long addr, int len)
2191{
2192	int c = 0;
2193	struct opthdr hdr;
2194
2195	while (len >= (int) sizeof hdr) {
2196		if (umove(tcp, addr, &hdr) < 0) break;
2197		if (c++) {
2198			tprints(", ");
2199		}
2200		else if (len > hdr.len + sizeof hdr) {
2201			tprints("[");
2202		}
2203		tprints("{");
2204		addr += sizeof hdr;
2205		len -= sizeof hdr;
2206		printsockopt(tcp, hdr.level, hdr.name, addr, hdr.len);
2207		if (hdr.len > 0) {
2208			addr += hdr.len;
2209			len -= hdr.len;
2210		}
2211		tprints("}");
2212	}
2213	if (len > 0) {
2214		if (c++) tprints(", ");
2215		printstr(tcp, addr, len);
2216	}
2217	if (c > 1) tprints("]");
2218}
2219
2220#endif
2221
2222int
2223sys_setsockopt(struct tcb *tcp)
2224{
2225	if (entering(tcp)) {
2226		tprintf("%ld, ", tcp->u_arg[0]);
2227		printsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
2228			      tcp->u_arg[3], tcp->u_arg[4]);
2229		tprintf(", %lu", tcp->u_arg[4]);
2230	}
2231	return 0;
2232}
2233
2234#if UNIXWARE >= 7
2235
2236static const struct xlat sock_version[] = {
2237	{ __NETLIB_UW211_SVR4,	"UW211_SVR4" },
2238	{ __NETLIB_UW211_XPG4,	"UW211_XPG4" },
2239	{ __NETLIB_GEMINI_SVR4,	"GEMINI_SVR4" },
2240	{ __NETLIB_GEMINI_XPG4,	"GEMINI_XPG4" },
2241	{ __NETLIB_FP1_SVR4,	"FP1_SVR4" },
2242	{ __NETLIB_FP1_XPG4,	"FP1_XPG4" },
2243	{ 0,			NULL },
2244};
2245
2246
2247int
2248netlib_call(struct tcb *tcp, int (*func)())
2249{
2250	if (entering(tcp)) {
2251		int i;
2252		printxval(sock_version, tcp->u_arg[0], "__NETLIB_???");
2253		tprints(", ");
2254		--tcp->u_nargs;
2255		for (i = 0; i < tcp->u_nargs; i++)
2256			tcp->u_arg[i] = tcp->u_arg[i + 1];
2257		return func(tcp);
2258	}
2259
2260	return func(tcp);
2261}
2262
2263int
2264sys_xsocket(struct tcb *tcp)
2265{
2266	return netlib_call(tcp, sys_socket);
2267}
2268
2269int
2270sys_xsocketpair(struct tcb *tcp)
2271{
2272	return netlib_call(tcp, sys_socketpair);
2273}
2274
2275int
2276sys_xbind(struct tcb *tcp)
2277{
2278	return netlib_call(tcp, sys_bind);
2279}
2280
2281int
2282sys_xconnect(struct tcb *tcp)
2283{
2284	return netlib_call(tcp, sys_connect);
2285}
2286
2287int
2288sys_xlisten(struct tcb *tcp)
2289{
2290	return netlib_call(tcp, sys_listen);
2291}
2292
2293int
2294sys_xaccept(struct tcb *tcp)
2295{
2296	return netlib_call(tcp, sys_accept);
2297}
2298
2299int
2300sys_xsendmsg(struct tcb *tcp)
2301{
2302	return netlib_call(tcp, sys_sendmsg);
2303}
2304
2305int
2306sys_xrecvmsg(struct tcb *tcp)
2307{
2308	return netlib_call(tcp, sys_recvmsg);
2309}
2310
2311int
2312sys_xgetsockaddr(struct tcb *tcp)
2313{
2314	if (entering(tcp)) {
2315		printxval(sock_version, tcp->u_arg[0], "__NETLIB_???");
2316		tprints(", ");
2317		if (tcp->u_arg[1] == 0) {
2318			tprints("LOCALNAME, ");
2319		}
2320		else if (tcp->u_arg[1] == 1) {
2321			tprints("REMOTENAME, ");
2322		}
2323		else {
2324			tprintf("%ld, ", tcp->u_arg[1]);
2325		}
2326		tprintf("%ld, ", tcp->u_arg[2]);
2327	}
2328	else {
2329		if (tcp->u_arg[3] == 0 || syserror(tcp)) {
2330			tprintf("%#lx", tcp->u_arg[3]);
2331		} else {
2332			printsock(tcp, tcp->u_arg[3], tcp->u_arg[4]);
2333		}
2334		tprints(", ");
2335		printnum(tcp, tcp->u_arg[4], "%lu");
2336	}
2337
2338	return 0;
2339
2340}
2341
2342int
2343sys_xgetsockopt(struct tcb *tcp)
2344{
2345	return netlib_call(tcp, sys_getsockopt);
2346}
2347
2348int
2349sys_xsetsockopt(struct tcb *tcp)
2350{
2351	return netlib_call(tcp, sys_setsockopt);
2352}
2353
2354int
2355sys_xshutdown(struct tcb *tcp)
2356{
2357	return netlib_call(tcp, sys_shutdown);
2358}
2359
2360#endif /* UNIXWARE */
2361