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