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