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