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