net.c revision b6c32f4598b84364472bc3febcb80ff3e475def8
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_SEQPACKET
324	{ SOCK_SEQPACKET,"SOCK_SEQPACKET"},
325#endif
326#ifdef SOCK_RDM
327	{ SOCK_RDM,	"SOCK_RDM"	},
328#endif
329#ifdef SOCK_PACKET
330	{ SOCK_PACKET,	"SOCK_PACKET"	},
331#endif
332	{ 0,		NULL		},
333};
334static const struct xlat socketlayers[] = {
335#if defined(SOL_IP)
336	{ SOL_IP,	"SOL_IP"	},
337#endif
338#if defined(SOL_ICMP)
339	{ SOL_ICMP,	"SOL_ICMP"	},
340#endif
341#if defined(SOL_TCP)
342	{ SOL_TCP,	"SOL_TCP"	},
343#endif
344#if defined(SOL_UDP)
345	{ SOL_UDP,	"SOL_UDP"	},
346#endif
347#if defined(SOL_IPV6)
348	{ SOL_IPV6,	"SOL_IPV6"	},
349#endif
350#if defined(SOL_ICMPV6)
351	{ SOL_ICMPV6,	"SOL_ICMPV6"	},
352#endif
353#if defined(SOL_RAW)
354	{ SOL_RAW,	"SOL_RAW"	},
355#endif
356#if defined(SOL_IPX)
357	{ SOL_IPX,	"SOL_IPX"	},
358#endif
359#if defined(SOL_IPX)
360	{ SOL_IPX,	"SOL_IPX"	},
361#endif
362#if defined(SOL_AX25)
363	{ SOL_AX25,	"SOL_AX25"	},
364#endif
365#if defined(SOL_ATALK)
366	{ SOL_ATALK,	"SOL_ATALK"	},
367#endif
368#if defined(SOL_NETROM)
369	{ SOL_NETROM,	"SOL_NETROM"	},
370#endif
371#if defined(SOL_ROSE)
372	{ SOL_ROSE,	"SOL_ROSE"	},
373#endif
374#if defined(SOL_DECNET)
375	{ SOL_DECNET,	"SOL_DECNET"	},
376#endif
377#if defined(SOL_X25)
378	{ SOL_X25,	"SOL_X25"	},
379#endif
380#if defined(SOL_PACKET)
381	{ SOL_PACKET,	"SOL_PACKET"	},
382#endif
383#if defined(SOL_ATM)
384	{ SOL_ATM,	"SOL_ATM"	},
385#endif
386#if defined(SOL_AAL)
387	{ SOL_AAL,	"SOL_AAL"	},
388#endif
389#if defined(SOL_IRDA)
390	{ SOL_IRDA,	"SOL_IRDA"	},
391#endif
392	{ SOL_SOCKET,	"SOL_SOCKET"	},	/* Never used! */
393};
394/*** WARNING: DANGER WILL ROBINSON: NOTE "socketlayers" array above
395     falls into "protocols" array below!!!!   This is intended!!! ***/
396static const struct xlat protocols[] = {
397	{ IPPROTO_IP,	"IPPROTO_IP"	},
398	{ IPPROTO_ICMP,	"IPPROTO_ICMP"	},
399	{ IPPROTO_TCP,	"IPPROTO_TCP"	},
400	{ IPPROTO_UDP,	"IPPROTO_UDP"	},
401#ifdef IPPROTO_GGP
402	{ IPPROTO_GGP,	"IPPROTO_GGP"	},
403#endif
404#ifdef IPPROTO_EGP
405	{ IPPROTO_EGP,	"IPPROTO_EGP"	},
406#endif
407#ifdef IPPROTO_PUP
408	{ IPPROTO_PUP,	"IPPROTO_PUP"	},
409#endif
410#ifdef IPPROTO_IDP
411	{ IPPROTO_IDP,	"IPPROTO_IDP"	},
412#endif
413#ifdef IPPROTO_IPV6
414	{ IPPROTO_IPV6,	"IPPROTO_IPV6"	},
415#endif
416#ifdef IPPROTO_ICMPV6
417	{ IPPROTO_ICMPV6,"IPPROTO_ICMPV6"},
418#endif
419#ifdef IPPROTO_IGMP
420	{ IPPROTO_IGMP,	"IPPROTO_IGMP"	},
421#endif
422#ifdef IPPROTO_HELLO
423	{ IPPROTO_HELLO,"IPPROTO_HELLO"	},
424#endif
425#ifdef IPPROTO_ND
426	{ IPPROTO_ND,	"IPPROTO_ND"	},
427#endif
428#ifdef IPPROTO_RAW
429	{ IPPROTO_RAW,	"IPPROTO_RAW"	},
430#endif
431#ifdef IPPROTO_MAX
432	{ IPPROTO_MAX,	"IPPROTO_MAX"	},
433#endif
434#ifdef IPPROTO_IPIP
435	{ IPPROTO_IPIP,	"IPPROTO_IPIP"	},
436#endif
437	{ 0,		NULL		},
438};
439static const struct xlat msg_flags[] = {
440	{ MSG_OOB,		"MSG_OOB"		},
441#ifdef MSG_DONTROUTE
442	{ MSG_DONTROUTE,	"MSG_DONTROUTE"		},
443#endif
444#ifdef MSG_PEEK
445	{ MSG_PEEK,		"MSG_PEEK"		},
446#endif
447#ifdef MSG_CTRUNC
448	{ MSG_CTRUNC,		"MSG_CTRUNC"		},
449#endif
450#ifdef MSG_PROXY
451	{ MSG_PROXY,		"MSG_PROXY"		},
452#endif
453#ifdef MSG_EOR
454	{ MSG_EOR,		"MSG_EOR"		},
455#endif
456#ifdef MSG_WAITALL
457	{ MSG_WAITALL,		"MSG_WAITALL"		},
458#endif
459#ifdef MSG_TRUNC
460	{ MSG_TRUNC,		"MSG_TRUNC"		},
461#endif
462#ifdef MSG_CTRUNC
463	{ MSG_CTRUNC,		"MSG_CTRUNC"		},
464#endif
465#ifdef MSG_ERRQUEUE
466	{ MSG_ERRQUEUE,		"MSG_ERRQUEUE"		},
467#endif
468#ifdef MSG_DONTWAIT
469	{ MSG_DONTWAIT,		"MSG_DONTWAIT"		},
470#endif
471#ifdef MSG_CONFIRM
472	{ MSG_CONFIRM,		"MSG_CONFIRM"		},
473#endif
474#ifdef MSG_PROBE
475	{ MSG_PROBE,		"MSG_PROBE"		},
476#endif
477#ifdef MSG_FIN
478	{ MSG_FIN,		"MSG_FIN"		},
479#endif
480#ifdef MSG_SYN
481	{ MSG_SYN,		"MSG_SYN"		},
482#endif
483#ifdef MSG_RST
484	{ MSG_RST,		"MSG_RST"		},
485#endif
486#ifdef MSG_NOSIGNAL
487	{ MSG_NOSIGNAL,		"MSG_NOSIGNAL"		},
488#endif
489#ifdef MSG_MORE
490	{ MSG_MORE,		"MSG_MORE"		},
491#endif
492#ifdef MSG_CMSG_CLOEXEC
493	{ MSG_CMSG_CLOEXEC,	"MSG_CMSG_CLOEXEC"	},
494#endif
495	{ 0,			NULL			},
496};
497
498static const struct xlat sockoptions[] = {
499#ifdef SO_ACCEPTCONN
500	{ SO_ACCEPTCONN,	"SO_ACCEPTCONN"	},
501#endif
502#ifdef SO_ALLRAW
503	{ SO_ALLRAW,	"SO_ALLRAW"	},
504#endif
505#ifdef SO_ATTACH_FILTER
506	{ SO_ATTACH_FILTER,	"SO_ATTACH_FILTER"	},
507#endif
508#ifdef SO_BINDTODEVICE
509	{ SO_BINDTODEVICE,	"SO_BINDTODEVICE"	},
510#endif
511#ifdef SO_BROADCAST
512	{ SO_BROADCAST,	"SO_BROADCAST"	},
513#endif
514#ifdef SO_BSDCOMPAT
515	{ SO_BSDCOMPAT,	"SO_BSDCOMPAT"	},
516#endif
517#ifdef SO_DEBUG
518	{ SO_DEBUG,	"SO_DEBUG"	},
519#endif
520#ifdef SO_DETACH_FILTER
521	{ SO_DETACH_FILTER,	"SO_DETACH_FILTER"	},
522#endif
523#ifdef SO_DONTROUTE
524	{ SO_DONTROUTE,	"SO_DONTROUTE"	},
525#endif
526#ifdef SO_ERROR
527	{ SO_ERROR,	"SO_ERROR"	},
528#endif
529#ifdef SO_ICS
530	{ SO_ICS,	"SO_ICS"	},
531#endif
532#ifdef SO_IMASOCKET
533	{ SO_IMASOCKET,	"SO_IMASOCKET"	},
534#endif
535#ifdef SO_KEEPALIVE
536	{ SO_KEEPALIVE,	"SO_KEEPALIVE"	},
537#endif
538#ifdef SO_LINGER
539	{ SO_LINGER,	"SO_LINGER"	},
540#endif
541#ifdef SO_LISTENING
542	{ SO_LISTENING,	"SO_LISTENING"	},
543#endif
544#ifdef SO_MGMT
545	{ SO_MGMT,	"SO_MGMT"	},
546#endif
547#ifdef SO_NO_CHECK
548	{ SO_NO_CHECK,	"SO_NO_CHECK"	},
549#endif
550#ifdef SO_OOBINLINE
551	{ SO_OOBINLINE,	"SO_OOBINLINE"	},
552#endif
553#ifdef SO_ORDREL
554	{ SO_ORDREL,	"SO_ORDREL"	},
555#endif
556#ifdef SO_PARALLELSVR
557	{ SO_PARALLELSVR,	"SO_PARALLELSVR"	},
558#endif
559#ifdef SO_PASSCRED
560	{ SO_PASSCRED,	"SO_PASSCRED"	},
561#endif
562#ifdef SO_PEERCRED
563	{ SO_PEERCRED,	"SO_PEERCRED"	},
564#endif
565#ifdef SO_PEERNAME
566	{ SO_PEERNAME,	"SO_PEERNAME"	},
567#endif
568#ifdef SO_PEERSEC
569	{ SO_PEERSEC,	"SO_PEERSEC"	},
570#endif
571#ifdef SO_PRIORITY
572	{ SO_PRIORITY,	"SO_PRIORITY"	},
573#endif
574#ifdef SO_PROTOTYPE
575	{ SO_PROTOTYPE,	"SO_PROTOTYPE"	},
576#endif
577#ifdef SO_RCVBUF
578	{ SO_RCVBUF,	"SO_RCVBUF"	},
579#endif
580#ifdef SO_RCVLOWAT
581	{ SO_RCVLOWAT,	"SO_RCVLOWAT"	},
582#endif
583#ifdef SO_RCVTIMEO
584	{ SO_RCVTIMEO,	"SO_RCVTIMEO"	},
585#endif
586#ifdef SO_RDWR
587	{ SO_RDWR,	"SO_RDWR"	},
588#endif
589#ifdef SO_REUSEADDR
590	{ SO_REUSEADDR,	"SO_REUSEADDR"	},
591#endif
592#ifdef SO_REUSEPORT
593	{ SO_REUSEPORT,	"SO_REUSEPORT"	},
594#endif
595#ifdef SO_SECURITY_AUTHENTICATION
596	{ SO_SECURITY_AUTHENTICATION,"SO_SECURITY_AUTHENTICATION"},
597#endif
598#ifdef SO_SECURITY_ENCRYPTION_NETWORK
599	{ SO_SECURITY_ENCRYPTION_NETWORK,"SO_SECURITY_ENCRYPTION_NETWORK"},
600#endif
601#ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
602	{ SO_SECURITY_ENCRYPTION_TRANSPORT,"SO_SECURITY_ENCRYPTION_TRANSPORT"},
603#endif
604#ifdef SO_SEMA
605	{ SO_SEMA,	"SO_SEMA"	},
606#endif
607#ifdef SO_SNDBUF
608	{ SO_SNDBUF,	"SO_SNDBUF"	},
609#endif
610#ifdef SO_SNDLOWAT
611	{ SO_SNDLOWAT,	"SO_SNDLOWAT"	},
612#endif
613#ifdef SO_SNDTIMEO
614	{ SO_SNDTIMEO,	"SO_SNDTIMEO"	},
615#endif
616#ifdef SO_TIMESTAMP
617	{ SO_TIMESTAMP,	"SO_TIMESTAMP"	},
618#endif
619#ifdef SO_TYPE
620	{ SO_TYPE,	"SO_TYPE"	},
621#endif
622#ifdef SO_USELOOPBACK
623	{ SO_USELOOPBACK,	"SO_USELOOPBACK"	},
624#endif
625	{ 0,		NULL		},
626};
627
628#if !defined (SOL_IP) && defined (IPPROTO_IP)
629#define SOL_IP IPPROTO_IP
630#endif
631
632#ifdef SOL_IP
633static const struct xlat sockipoptions[] = {
634#ifdef IP_TOS
635	{ IP_TOS,		"IP_TOS"		},
636#endif
637#ifdef IP_TTL
638	{ IP_TTL,		"IP_TTL"		},
639#endif
640#ifdef IP_HDRINCL
641	{ IP_HDRINCL,		"IP_HDRINCL"		},
642#endif
643#ifdef IP_OPTIONS
644	{ IP_OPTIONS,		"IP_OPTIONS"		},
645#endif
646#ifdef IP_ROUTER_ALERT
647	{ IP_ROUTER_ALERT,	"IP_ROUTER_ALERT"	},
648#endif
649#ifdef IP_RECVOPTIONS
650	{ IP_RECVOPTIONS,	"IP_RECVOPTIONS"	},
651#endif
652#ifdef IP_RECVOPTS
653	{ IP_RECVOPTS,		"IP_RECVOPTS"		},
654#endif
655#ifdef IP_RECVRETOPTS
656	{ IP_RECVRETOPTS,	"IP_RECVRETOPTS"	},
657#endif
658#ifdef IP_RECVDSTADDR
659	{ IP_RECVDSTADDR,	"IP_RECVDSTADDR"	},
660#endif
661#ifdef IP_RETOPTS
662	{ IP_RETOPTS,		"IP_RETOPTS"		},
663#endif
664#ifdef IP_PKTINFO
665	{ IP_PKTINFO,		"IP_PKTINFO"		},
666#endif
667#ifdef IP_PKTOPTIONS
668	{ IP_PKTOPTIONS,	"IP_PKTOPTIONS"		},
669#endif
670#ifdef IP_MTU_DISCOVER
671	{ IP_MTU_DISCOVER,	"IP_MTU_DISCOVER"	},
672#endif
673#ifdef IP_RECVERR
674	{ IP_RECVERR,		"IP_RECVERR"		},
675#endif
676#ifdef IP_RECVTTL
677	{ IP_RECVTTL,		"IP_RECVTTL"		},
678#endif
679#ifdef IP_RECVTOS
680	{ IP_RECVTOS,		"IP_RECVTOS"		},
681#endif
682#ifdef IP_MTU
683	{ IP_MTU,		"IP_MTU"		},
684#endif
685#ifdef IP_MULTICAST_IF
686	{ IP_MULTICAST_IF,	"IP_MULTICAST_IF"	},
687#endif
688#ifdef IP_MULTICAST_TTL
689	{ IP_MULTICAST_TTL,	"IP_MULTICAST_TTL"	},
690#endif
691#ifdef IP_MULTICAST_LOOP
692	{ IP_MULTICAST_LOOP,	"IP_MULTICAST_LOOP"	},
693#endif
694#ifdef IP_ADD_MEMBERSHIP
695	{ IP_ADD_MEMBERSHIP,	"IP_ADD_MEMBERSHIP"	},
696#endif
697#ifdef IP_DROP_MEMBERSHIP
698	{ IP_DROP_MEMBERSHIP,	"IP_DROP_MEMBERSHIP"	},
699#endif
700#ifdef IP_BROADCAST_IF
701	{ IP_BROADCAST_IF,	"IP_BROADCAST_IF"	},
702#endif
703#ifdef IP_RECVIFINDEX
704	{ IP_RECVIFINDEX,	"IP_RECVIFINDEX"	},
705#endif
706#ifdef IP_MSFILTER
707	{ IP_MSFILTER,		"IP_MSFILTER"		},
708#endif
709#ifdef MCAST_MSFILTER
710	{ MCAST_MSFILTER,	"MCAST_MSFILTER"	},
711#endif
712#ifdef IP_FREEBIND
713	{ IP_FREEBIND,		"IP_FREEBIND"		},
714#endif
715	{ 0,			NULL			},
716};
717#endif /* SOL_IP */
718
719#ifdef SOL_IPV6
720static const struct xlat sockipv6options[] = {
721#ifdef IPV6_ADDRFORM
722	{ IPV6_ADDRFORM,	"IPV6_ADDRFORM"		},
723#endif
724#ifdef MCAST_FILTER
725	{ MCAST_FILTER,		"MCAST_FILTER"		},
726#endif
727#ifdef IPV6_PKTOPTIONS
728	{ IPV6_PKTOPTIONS,	"IPV6_PKTOPTIONS"	},
729#endif
730#ifdef IPV6_MTU
731	{ IPV6_MTU,		"IPV6_MTU"		},
732#endif
733#ifdef IPV6_V6ONLY
734	{ IPV6_V6ONLY,		"IPV6_V6ONLY"		},
735#endif
736#ifdef IPV6_PKTINFO
737	{ IPV6_PKTINFO,		"IPV6_PKTINFO"		},
738#endif
739#ifdef IPV6_HOPLIMIT
740	{ IPV6_HOPLIMIT,	"IPV6_HOPLIMIT"		},
741#endif
742#ifdef IPV6_RTHDR
743	{ IPV6_RTHDR,		"IPV6_RTHDR"		},
744#endif
745#ifdef IPV6_HOPOPTS
746	{ IPV6_HOPOPTS,		"IPV6_HOPOPTS"		},
747#endif
748#ifdef IPV6_DSTOPTS
749	{ IPV6_DSTOPTS,		"IPV6_DSTOPTS"		},
750#endif
751#ifdef IPV6_FLOWINFO
752	{ IPV6_FLOWINFO,	"IPV6_FLOWINFO"		},
753#endif
754#ifdef IPV6_UNICAST_HOPS
755	{ IPV6_UNICAST_HOPS,	"IPV6_UNICAST_HOPS"	},
756#endif
757#ifdef IPV6_MULTICAST_HOPS
758	{ IPV6_MULTICAST_HOPS,	"IPV6_MULTICAST_HOPS"	},
759#endif
760#ifdef IPV6_MULTICAST_LOOP
761	{ IPV6_MULTICAST_LOOP,	"IPV6_MULTICAST_LOOP"	},
762#endif
763#ifdef IPV6_MULTICAST_IF
764	{ IPV6_MULTICAST_IF,	"IPV6_MULTICAST_IF"	},
765#endif
766#ifdef IPV6_MTU_DISCOVER
767	{ IPV6_MTU_DISCOVER,	"IPV6_MTU_DISCOVER"	},
768#endif
769#ifdef IPV6_RECVERR
770	{ IPV6_RECVERR,		"IPV6_RECVERR"		},
771#endif
772#ifdef IPV6_FLOWINFO_SEND
773	{ IPV6_FLOWINFO_SEND,	"IPV6_FLOWINFO_SEND"	},
774#endif
775#ifdef IPV6_ADD_MEMBERSHIP
776	{ IPV6_ADD_MEMBERSHIP,	"IPV6_ADD_MEMBERSHIP"	},
777#endif
778#ifdef IPV6_DROP_MEMBERSHIP
779	{ IPV6_DROP_MEMBERSHIP,	"IPV6_DROP_MEMBERSHIP"	},
780#endif
781#ifdef IPV6_ROUTER_ALERT
782	{ IPV6_ROUTER_ALERT,	"IPV6_ROUTER_ALERT"	},
783#endif
784	{ 0,			NULL			},
785};
786#endif /* SOL_IPV6 */
787
788#ifdef SOL_IPX
789static const struct xlat sockipxoptions[] = {
790	{ IPX_TYPE,     "IPX_TYPE"      },
791	{ 0,            NULL            },
792};
793#endif /* SOL_IPX */
794
795#ifdef SOL_RAW
796static const struct xlat sockrawoptions[] = {
797#if defined(ICMP_FILTER)
798	{ ICMP_FILTER,		"ICMP_FILTER"	},
799#endif
800	{ 0,			NULL		},
801};
802#endif /* SOL_RAW */
803
804#ifdef SOL_PACKET
805static const struct xlat sockpacketoptions[] = {
806	{ PACKET_ADD_MEMBERSHIP,	"PACKET_ADD_MEMBERSHIP"	},
807	{ PACKET_DROP_MEMBERSHIP,	"PACKET_DROP_MEMBERSHIP"},
808#if defined(PACKET_RECV_OUTPUT)
809	{ PACKET_RECV_OUTPUT,		"PACKET_RECV_OUTPUT"	},
810#endif
811#if defined(PACKET_RX_RING)
812	{ PACKET_RX_RING,		"PACKET_RX_RING"	},
813#endif
814#if defined(PACKET_STATISTICS)
815	{ PACKET_STATISTICS,		"PACKET_STATISTICS"	},
816#endif
817	{ 0,				NULL			},
818};
819#endif /* SOL_PACKET */
820
821#if  !defined (SOL_TCP) && defined (IPPROTO_TCP)
822#define SOL_TCP IPPROTO_TCP
823#endif
824
825#ifdef SOL_TCP
826static const struct xlat socktcpoptions[] = {
827	{ TCP_NODELAY,		"TCP_NODELAY"	},
828	{ TCP_MAXSEG,		"TCP_MAXSEG"	},
829#if defined(TCP_CORK)
830	{ TCP_CORK,		"TCP_CORK"	},
831#endif
832#if defined(TCP_KEEPIDLE)
833	{ TCP_KEEPIDLE,		"TCP_KEEPIDLE" },
834#endif
835#if defined(TCP_KEEPINTVL)
836	{ TCP_KEEPINTVL,	"TCP_KEEPINTVL" },
837#endif
838#if defined(TCP_KEEPCNT)
839	{ TCP_KEEPCNT,		"TCP_KEEPCNT" },
840#endif
841#if defined(TCP_NKEEP)
842	{ TCP_NKEEP,		"TCP_NKEEP"	},
843#endif
844#if defined(TCP_SYNCNT)
845	{ TCP_SYNCNT,		"TCP_SYNCNT" },
846#endif
847#if defined(TCP_LINGER2)
848	{ TCP_LINGER2,		"TCP_LINGER2" },
849#endif
850#if defined(TCP_DEFER_ACCEPT)
851	{ TCP_DEFER_ACCEPT,	"TCP_DEFER_ACCEPT" },
852#endif
853#if defined(TCP_WINDOW_CLAMP)
854	{ TCP_WINDOW_CLAMP,	"TCP_WINDOW_CLAMP" },
855#endif
856#if defined(TCP_INFO)
857	{ TCP_INFO,		"TCP_INFO" },
858#endif
859#if defined(TCP_QUICKACK)
860	{ TCP_QUICKACK,		"TCP_QUICKACK" },
861#endif
862	{ 0,			NULL		},
863};
864#endif /* SOL_TCP */
865
866#ifdef SOL_RAW
867static const struct xlat icmpfilterflags[] = {
868#if defined(ICMP_ECHOREPLY)
869	{ (1<<ICMP_ECHOREPLY),		"ICMP_ECHOREPLY"	},
870#endif
871#if defined(ICMP_DEST_UNREACH)
872	{ (1<<ICMP_DEST_UNREACH),	"ICMP_DEST_UNREACH"	},
873#endif
874#if defined(ICMP_SOURCE_QUENCH)
875	{ (1<<ICMP_SOURCE_QUENCH),	"ICMP_SOURCE_QUENCH"	},
876#endif
877#if defined(ICMP_REDIRECT)
878	{ (1<<ICMP_REDIRECT),		"ICMP_REDIRECT"		},
879#endif
880#if defined(ICMP_ECHO)
881	{ (1<<ICMP_ECHO),		"ICMP_ECHO"		},
882#endif
883#if defined(ICMP_TIME_EXCEEDED)
884	{ (1<<ICMP_TIME_EXCEEDED),	"ICMP_TIME_EXCEEDED"	},
885#endif
886#if defined(ICMP_PARAMETERPROB)
887	{ (1<<ICMP_PARAMETERPROB),	"ICMP_PARAMETERPROB"	},
888#endif
889#if defined(ICMP_TIMESTAMP)
890	{ (1<<ICMP_TIMESTAMP),		"ICMP_TIMESTAMP"	},
891#endif
892#if defined(ICMP_TIMESTAMPREPLY)
893	{ (1<<ICMP_TIMESTAMPREPLY),	"ICMP_TIMESTAMPREPLY"	},
894#endif
895#if defined(ICMP_INFO_REQUEST)
896	{ (1<<ICMP_INFO_REQUEST),	"ICMP_INFO_REQUEST"	},
897#endif
898#if defined(ICMP_INFO_REPLY)
899	{ (1<<ICMP_INFO_REPLY),		"ICMP_INFO_REPLY"	},
900#endif
901#if defined(ICMP_ADDRESS)
902	{ (1<<ICMP_ADDRESS),		"ICMP_ADDRESS"		},
903#endif
904#if defined(ICMP_ADDRESSREPLY)
905	{ (1<<ICMP_ADDRESSREPLY),	"ICMP_ADDRESSREPLY"	},
906#endif
907	{ 0,				NULL			},
908};
909#endif /* SOL_RAW */
910
911#if defined(AF_PACKET) /* from e.g. linux/if_packet.h */
912static const struct xlat af_packet_types[] = {
913#if defined(PACKET_HOST)
914	{ PACKET_HOST,			"PACKET_HOST"		},
915#endif
916#if defined(PACKET_BROADCAST)
917	{ PACKET_BROADCAST,		"PACKET_BROADCAST"	},
918#endif
919#if defined(PACKET_MULTICAST)
920	{ PACKET_MULTICAST,		"PACKET_MULTICAST"	},
921#endif
922#if defined(PACKET_OTHERHOST)
923	{ PACKET_OTHERHOST,		"PACKET_OTHERHOST"	},
924#endif
925#if defined(PACKET_OUTGOING)
926	{ PACKET_OUTGOING,		"PACKET_OUTGOING"	},
927#endif
928#if defined(PACKET_LOOPBACK)
929	{ PACKET_LOOPBACK,		"PACKET_LOOPBACK"	},
930#endif
931#if defined(PACKET_FASTROUTE)
932	{ PACKET_FASTROUTE,		"PACKET_FASTROUTE"	},
933#endif
934	{ 0,				NULL			},
935};
936#endif /* defined(AF_PACKET) */
937
938
939void
940printsock(struct tcb *tcp, long addr, int addrlen)
941{
942	union {
943		char pad[128];
944		struct sockaddr sa;
945		struct sockaddr_in sin;
946		struct sockaddr_un sau;
947#ifdef HAVE_INET_NTOP
948		struct sockaddr_in6 sa6;
949#endif
950#if defined(LINUX) && defined(AF_IPX)
951		struct sockaddr_ipx sipx;
952#endif
953#ifdef AF_PACKET
954		struct sockaddr_ll ll;
955#endif
956#ifdef AF_NETLINK
957		struct sockaddr_nl nl;
958#endif
959	} addrbuf;
960	char string_addr[100];
961
962	if (addr == 0) {
963		tprintf("NULL");
964		return;
965	}
966	if (!verbose(tcp)) {
967		tprintf("%#lx", addr);
968		return;
969	}
970
971	if (addrlen < 2 || addrlen > sizeof(addrbuf))
972		addrlen = sizeof(addrbuf);
973
974	memset(&addrbuf, 0, sizeof(addrbuf));
975	if (umoven(tcp, addr, addrlen, addrbuf.pad) < 0) {
976		tprintf("{...}");
977		return;
978	}
979	addrbuf.pad[sizeof(addrbuf.pad) - 1] = '\0';
980
981	tprintf("{sa_family=");
982	printxval(addrfams, addrbuf.sa.sa_family, "AF_???");
983	tprintf(", ");
984
985	switch (addrbuf.sa.sa_family) {
986	case AF_UNIX:
987		if (addrlen == 2) {
988			tprintf("NULL");
989		} else if (addrbuf.sau.sun_path[0]) {
990			tprintf("path=");
991			printstr(tcp, addr + 2, strlen(addrbuf.sau.sun_path));
992		} else {
993			tprintf("path=@");
994			printstr(tcp, addr + 3, strlen(addrbuf.sau.sun_path + 1));
995		}
996		break;
997	case AF_INET:
998		tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")",
999			ntohs(addrbuf.sin.sin_port), inet_ntoa(addrbuf.sin.sin_addr));
1000		break;
1001#ifdef HAVE_INET_NTOP
1002	case AF_INET6:
1003		inet_ntop(AF_INET6, &addrbuf.sa6.sin6_addr, string_addr, sizeof(string_addr));
1004		tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=%u",
1005				ntohs(addrbuf.sa6.sin6_port), string_addr,
1006				addrbuf.sa6.sin6_flowinfo);
1007#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
1008		{
1009#if defined(HAVE_IF_INDEXTONAME) && defined(IN6_IS_ADDR_LINKLOCAL) && defined(IN6_IS_ADDR_MC_LINKLOCAL)
1010		    int numericscope = 0;
1011		    if (IN6_IS_ADDR_LINKLOCAL (&addrbuf.sa6.sin6_addr)
1012			    || IN6_IS_ADDR_MC_LINKLOCAL (&addrbuf.sa6.sin6_addr)) {
1013			char scopebuf[IFNAMSIZ + 1];
1014
1015			if (if_indextoname (addrbuf.sa6.sin6_scope_id, scopebuf) == NULL)
1016			    numericscope++;
1017			else
1018			    tprintf(", sin6_scope_id=if_nametoindex(\"%s\")", scopebuf);
1019		    } else
1020			numericscope++;
1021
1022		    if (numericscope)
1023#endif
1024			tprintf(", sin6_scope_id=%u", addrbuf.sa6.sin6_scope_id);
1025		}
1026#endif
1027		    break;
1028#endif
1029#if defined(AF_IPX) && defined(linux)
1030	case AF_IPX:
1031		{
1032			int i;
1033			tprintf("sipx_port=htons(%u), ",
1034					ntohs(addrbuf.sipx.sipx_port));
1035			/* Yes, I know, this does not look too
1036			 * strace-ish, but otherwise the IPX
1037			 * addresses just look monstrous...
1038			 * Anyways, feel free if you don't like
1039			 * this way.. :)
1040			 */
1041			tprintf("%08lx:", (unsigned long)ntohl(addrbuf.sipx.sipx_network));
1042			for (i = 0; i<IPX_NODE_LEN; i++)
1043				tprintf("%02x", addrbuf.sipx.sipx_node[i]);
1044			tprintf("/[%02x]", addrbuf.sipx.sipx_type);
1045		}
1046		break;
1047#endif /* AF_IPX && linux */
1048#ifdef AF_PACKET
1049	case AF_PACKET:
1050		{
1051			int i;
1052			tprintf("proto=%#04x, if%d, pkttype=",
1053					ntohs(addrbuf.ll.sll_protocol),
1054					addrbuf.ll.sll_ifindex);
1055			printxval(af_packet_types, addrbuf.ll.sll_pkttype, "?");
1056			tprintf(", addr(%d)={%d, ",
1057					addrbuf.ll.sll_halen,
1058					addrbuf.ll.sll_hatype);
1059			for (i=0; i<addrbuf.ll.sll_halen; i++)
1060				tprintf("%02x", addrbuf.ll.sll_addr[i]);
1061		}
1062		break;
1063
1064#endif /* AF_APACKET */
1065#ifdef AF_NETLINK
1066	case AF_NETLINK:
1067		tprintf("pid=%d, groups=%08x", addrbuf.nl.nl_pid, addrbuf.nl.nl_groups);
1068		break;
1069#endif /* AF_NETLINK */
1070	/* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
1071	AF_X25 AF_ROSE etc. still need to be done */
1072
1073	default:
1074		tprintf("sa_data=");
1075		printstr(tcp, (long) &((struct sockaddr *) addr)->sa_data,
1076			sizeof addrbuf.sa.sa_data);
1077		break;
1078	}
1079	tprintf("}");
1080}
1081
1082#if HAVE_SENDMSG
1083static const struct xlat scmvals[] = {
1084#ifdef SCM_RIGHTS
1085	{ SCM_RIGHTS,		"SCM_RIGHTS"		},
1086#endif
1087#ifdef SCM_CREDENTIALS
1088	{ SCM_CREDENTIALS,	"SCM_CREDENTIALS"	},
1089#endif
1090	{ 0,			NULL			}
1091};
1092
1093static void
1094printcmsghdr(tcp, addr, len)
1095struct tcb *tcp;
1096unsigned long addr;
1097unsigned long len;
1098{
1099	struct cmsghdr *cmsg = len < sizeof(struct cmsghdr) ?
1100			       NULL : malloc(len);
1101	if (cmsg == NULL || umoven(tcp, addr, len, (char *) cmsg) < 0) {
1102		tprintf(", msg_control=%#lx", addr);
1103		free(cmsg);
1104		return;
1105	}
1106
1107	tprintf(", {cmsg_len=%zu, cmsg_level=", cmsg->cmsg_len);
1108	printxval(socketlayers, cmsg->cmsg_level, "SOL_???");
1109	tprintf(", cmsg_type=");
1110
1111	if (cmsg->cmsg_level == SOL_SOCKET) {
1112		unsigned long cmsg_len;
1113
1114		printxval(scmvals, cmsg->cmsg_type, "SCM_???");
1115		cmsg_len = (len < cmsg->cmsg_len) ? len : cmsg->cmsg_len;
1116
1117		if (cmsg->cmsg_type == SCM_RIGHTS
1118		    && CMSG_LEN(sizeof(int)) <= cmsg_len) {
1119			int *fds = (int *) CMSG_DATA (cmsg);
1120			int first = 1;
1121
1122			tprintf(", {");
1123			while ((char *) fds < ((char *) cmsg + cmsg_len)) {
1124				if (!first)
1125					tprintf(", ");
1126				tprintf("%d", *fds++);
1127				first = 0;
1128			}
1129			tprintf("}}");
1130			free(cmsg);
1131			return;
1132		}
1133		if (cmsg->cmsg_type == SCM_CREDENTIALS
1134		    && CMSG_LEN(sizeof(struct ucred)) <= cmsg_len) {
1135			struct ucred *uc = (struct ucred *) CMSG_DATA (cmsg);
1136
1137			tprintf("{pid=%ld, uid=%ld, gid=%ld}}",
1138				(long)uc->pid, (long)uc->uid, (long)uc->gid);
1139			free(cmsg);
1140			return;
1141		}
1142	}
1143	free(cmsg);
1144	tprintf(", ...}");
1145}
1146
1147static void
1148printmsghdr(tcp, addr)
1149struct tcb *tcp;
1150long addr;
1151{
1152	struct msghdr msg;
1153
1154	if (umove(tcp, addr, &msg) < 0) {
1155		tprintf("%#lx", addr);
1156		return;
1157	}
1158	tprintf("{msg_name(%d)=", msg.msg_namelen);
1159	printsock(tcp, (long)msg.msg_name, msg.msg_namelen);
1160
1161	tprintf(", msg_iov(%lu)=", (unsigned long)msg.msg_iovlen);
1162	tprint_iov(tcp, (unsigned long)msg.msg_iovlen,
1163		   (unsigned long)msg.msg_iov);
1164
1165#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
1166	tprintf(", msg_controllen=%lu", (unsigned long)msg.msg_controllen);
1167	if (msg.msg_controllen)
1168		printcmsghdr(tcp, (unsigned long) msg.msg_control,
1169			     msg.msg_controllen);
1170	tprintf(", msg_flags=");
1171	printflags(msg_flags, msg.msg_flags, "MSG_???");
1172#else /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
1173	tprintf("msg_accrights=%#lx, msg_accrightslen=%u",
1174		(unsigned long) msg.msg_accrights, msg.msg_accrightslen);
1175#endif /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
1176	tprintf("}");
1177}
1178
1179#endif /* HAVE_SENDMSG */
1180
1181int
1182sys_socket(tcp)
1183struct tcb *tcp;
1184{
1185	if (entering(tcp)) {
1186		printxval(domains, tcp->u_arg[0], "PF_???");
1187		tprintf(", ");
1188		printxval(socktypes, tcp->u_arg[1], "SOCK_???");
1189		tprintf(", ");
1190		switch (tcp->u_arg[0]) {
1191		case PF_INET:
1192#ifdef PF_INET6
1193		case PF_INET6:
1194#endif
1195			printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
1196			break;
1197#ifdef PF_IPX
1198		case PF_IPX:
1199			/* BTW: I don't believe this.. */
1200			tprintf("[");
1201			printxval(domains, tcp->u_arg[2], "PF_???");
1202			tprintf("]");
1203			break;
1204#endif /* PF_IPX */
1205		default:
1206			tprintf("%lu", tcp->u_arg[2]);
1207			break;
1208		}
1209	}
1210	return 0;
1211}
1212
1213#ifdef SVR4
1214int
1215sys_so_socket(tcp)
1216struct tcb *tcp;
1217{
1218	if (entering(tcp)) {
1219		/* not sure really what these args are... but this
1220		 * is how truss prints it
1221		 */
1222		tprintf("%ld, %ld, %ld, ",
1223		  tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
1224		printpath(tcp, tcp->u_arg[3]);
1225		tprintf(", %ld", tcp->u_arg[4]);
1226	}
1227	return 0;
1228}
1229
1230int
1231sys_so_socketpair(tcp)
1232struct tcb *tcp;
1233{
1234	if (entering(tcp)) {
1235	  	/* not sure what this arg is */
1236		tprintf("0x%lx", tcp->u_arg[0]);
1237	}
1238	return 0;
1239}
1240#endif /* SVR4 */
1241
1242int
1243sys_bind(tcp)
1244struct tcb *tcp;
1245{
1246	if (entering(tcp)) {
1247		tprintf("%ld, ", tcp->u_arg[0]);
1248		printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1249		tprintf(", %lu", tcp->u_arg[2]);
1250	}
1251	return 0;
1252}
1253
1254int
1255sys_connect(tcp)
1256struct tcb *tcp;
1257{
1258	return sys_bind(tcp);
1259}
1260
1261int
1262sys_listen(tcp)
1263struct tcb *tcp;
1264{
1265	if (entering(tcp)) {
1266		tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1267	}
1268	return 0;
1269}
1270
1271int
1272sys_accept(tcp)
1273struct tcb *tcp;
1274{
1275	if (entering(tcp)) {
1276		tprintf("%ld, ", tcp->u_arg[0]);
1277	} else if (!tcp->u_arg[2])
1278		tprintf("%#lx, NULL", tcp->u_arg[1]);
1279	else {
1280		if (tcp->u_arg[1] == 0 || syserror(tcp)) {
1281			tprintf("%#lx", tcp->u_arg[1]);
1282		} else {
1283			printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1284		}
1285		tprintf(", ");
1286		printnum(tcp, tcp->u_arg[2], "%lu");
1287	}
1288	return 0;
1289}
1290
1291int
1292sys_send(tcp)
1293struct tcb *tcp;
1294{
1295	if (entering(tcp)) {
1296		tprintf("%ld, ", tcp->u_arg[0]);
1297		printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1298		tprintf(", %lu, ", tcp->u_arg[2]);
1299		/* flags */
1300		printflags(msg_flags, tcp->u_arg[3], "MSG_???");
1301	}
1302	return 0;
1303}
1304
1305int
1306sys_sendto(tcp)
1307struct tcb *tcp;
1308{
1309	if (entering(tcp)) {
1310		tprintf("%ld, ", tcp->u_arg[0]);
1311		printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1312		tprintf(", %lu, ", tcp->u_arg[2]);
1313		/* flags */
1314		printflags(msg_flags, tcp->u_arg[3], "MSG_???");
1315		/* to address */
1316		tprintf(", ");
1317		printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
1318		/* to length */
1319		tprintf(", %lu", tcp->u_arg[5]);
1320	}
1321	return 0;
1322}
1323
1324#ifdef HAVE_SENDMSG
1325
1326int
1327sys_sendmsg(tcp)
1328struct tcb *tcp;
1329{
1330	if (entering(tcp)) {
1331		tprintf("%ld, ", tcp->u_arg[0]);
1332		printmsghdr(tcp, tcp->u_arg[1]);
1333		/* flags */
1334		tprintf(", ");
1335		printflags(msg_flags, tcp->u_arg[2], "MSG_???");
1336	}
1337	return 0;
1338}
1339
1340#endif /* HAVE_SENDMSG */
1341
1342int
1343sys_recv(tcp)
1344struct tcb *tcp;
1345{
1346	if (entering(tcp)) {
1347		tprintf("%ld, ", tcp->u_arg[0]);
1348	} else {
1349		if (syserror(tcp))
1350			tprintf("%#lx", tcp->u_arg[1]);
1351		else
1352			printstr(tcp, tcp->u_arg[1], tcp->u_rval);
1353
1354		tprintf(", %lu, ", tcp->u_arg[2]);
1355		printflags(msg_flags, tcp->u_arg[3], "MSG_???");
1356	}
1357	return 0;
1358}
1359
1360int
1361sys_recvfrom(tcp)
1362struct tcb *tcp;
1363{
1364	int fromlen;
1365
1366	if (entering(tcp)) {
1367		tprintf("%ld, ", tcp->u_arg[0]);
1368	} else {
1369		if (syserror(tcp)) {
1370			tprintf("%#lx, %lu, %lu, %#lx, %#lx",
1371				tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3],
1372				tcp->u_arg[4], tcp->u_arg[5]);
1373			return 0;
1374		}
1375		/* buf */
1376		printstr(tcp, tcp->u_arg[1], tcp->u_rval);
1377		/* len */
1378		tprintf(", %lu, ", tcp->u_arg[2]);
1379		/* flags */
1380		printflags(msg_flags, tcp->u_arg[3], "MSG_???");
1381		/* from address, len */
1382		if (!tcp->u_arg[4] || !tcp->u_arg[5]) {
1383			if (tcp->u_arg[4] == 0)
1384				tprintf(", NULL");
1385			else
1386				tprintf(", %#lx", tcp->u_arg[4]);
1387			if (tcp->u_arg[5] == 0)
1388				tprintf(", NULL");
1389			else
1390				tprintf(", %#lx", tcp->u_arg[5]);
1391			return 0;
1392		}
1393		if (umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
1394			tprintf(", {...}, [?]");
1395			return 0;
1396		}
1397		tprintf(", ");
1398		printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
1399		/* from length */
1400		tprintf(", [%u]", fromlen);
1401	}
1402	return 0;
1403}
1404
1405#ifdef HAVE_SENDMSG
1406
1407int
1408sys_recvmsg(tcp)
1409struct tcb *tcp;
1410{
1411	if (entering(tcp)) {
1412		tprintf("%ld, ", tcp->u_arg[0]);
1413	} else {
1414		if (syserror(tcp) || !verbose(tcp))
1415			tprintf("%#lx", tcp->u_arg[1]);
1416		else
1417			printmsghdr(tcp, tcp->u_arg[1]);
1418		/* flags */
1419		tprintf(", ");
1420		printflags(msg_flags, tcp->u_arg[2], "MSG_???");
1421	}
1422	return 0;
1423}
1424
1425#endif /* HAVE_SENDMSG */
1426
1427int
1428sys_shutdown(tcp)
1429struct tcb *tcp;
1430{
1431	if (entering(tcp)) {
1432		tprintf("%ld, %ld", tcp->u_arg[0], tcp->u_arg[1]);
1433		switch (tcp->u_arg[1]) {
1434		case 0:
1435			tprintf("%s", " /* receive */");
1436			break;
1437		case 1:
1438			tprintf("%s", " /* send */");
1439			break;
1440		case 2:
1441			tprintf("%s", " /* send and receive */");
1442			break;
1443		}
1444	}
1445	return 0;
1446}
1447
1448int
1449sys_getsockname(tcp)
1450struct tcb *tcp;
1451{
1452	return sys_accept(tcp);
1453}
1454
1455int
1456sys_getpeername(tcp)
1457struct tcb *tcp;
1458{
1459	return sys_accept(tcp);
1460}
1461
1462int
1463sys_pipe(tcp)
1464struct tcb *tcp;
1465{
1466
1467#if defined(LINUX) && !defined(SPARC) && !defined(SPARC64) && !defined(SH) && !defined(IA64)
1468	int fds[2];
1469
1470	if (exiting(tcp)) {
1471		if (syserror(tcp)) {
1472			tprintf("%#lx", tcp->u_arg[0]);
1473			return 0;
1474		}
1475		if (umoven(tcp, tcp->u_arg[0], sizeof fds, (char *) fds) < 0)
1476			tprintf("[...]");
1477		else
1478			tprintf("[%u, %u]", fds[0], fds[1]);
1479	}
1480#elif defined(SPARC) || defined(SPARC64) || defined(SH) || defined(SVR4) || defined(FREEBSD) || defined(IA64)
1481	if (exiting(tcp))
1482		tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
1483#endif
1484	return 0;
1485}
1486
1487int
1488sys_socketpair(tcp)
1489struct tcb *tcp;
1490{
1491#ifdef LINUX
1492	int fds[2];
1493#endif
1494
1495	if (entering(tcp)) {
1496		printxval(domains, tcp->u_arg[0], "PF_???");
1497		tprintf(", ");
1498		printxval(socktypes, tcp->u_arg[1], "SOCK_???");
1499		tprintf(", ");
1500		switch (tcp->u_arg[0]) {
1501		case PF_INET:
1502			printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
1503			break;
1504#ifdef PF_IPX
1505		case PF_IPX:
1506			/* BTW: I don't believe this.. */
1507			tprintf("[");
1508			printxval(domains, tcp->u_arg[2], "PF_???");
1509			tprintf("]");
1510			break;
1511#endif /* PF_IPX */
1512		default:
1513			tprintf("%lu", tcp->u_arg[2]);
1514			break;
1515		}
1516	} else {
1517		if (syserror(tcp)) {
1518			tprintf(", %#lx", tcp->u_arg[3]);
1519			return 0;
1520		}
1521#ifdef LINUX
1522		if (umoven(tcp, tcp->u_arg[3], sizeof fds, (char *) fds) < 0)
1523			tprintf(", [...]");
1524		else
1525			tprintf(", [%u, %u]", fds[0], fds[1]);
1526#endif /* LINUX */
1527#if defined(SUNOS4) || defined(SVR4) || defined(FREEBSD)
1528		tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
1529#endif /* SUNOS4 || SVR4 || FREEBSD */
1530	}
1531	return 0;
1532}
1533
1534int
1535sys_getsockopt(tcp)
1536struct tcb *tcp;
1537{
1538	if (entering(tcp)) {
1539		tprintf("%ld, ", tcp->u_arg[0]);
1540		printxval(socketlayers, tcp->u_arg[1], "SOL_???");
1541		tprintf (", ");
1542		switch (tcp->u_arg[1]) {
1543		case SOL_SOCKET:
1544			printxval(sockoptions, tcp->u_arg[2], "SO_???");
1545			break;
1546#ifdef SOL_IP
1547		case SOL_IP:
1548			printxval(sockipoptions, tcp->u_arg[2], "IP_???");
1549			break;
1550#endif
1551#ifdef SOL_IPV6
1552		case SOL_IPV6:
1553			printxval(sockipv6options, tcp->u_arg[2], "IPV6_???");
1554			break;
1555#endif
1556#ifdef SOL_IPX
1557		case SOL_IPX:
1558			printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
1559			break;
1560#endif
1561#ifdef SOL_PACKET
1562		case SOL_PACKET:
1563			printxval(sockpacketoptions, tcp->u_arg[2], "PACKET_???");
1564			break;
1565#endif
1566#ifdef SOL_TCP
1567		case SOL_TCP:
1568			printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
1569			break;
1570#endif
1571
1572		/* SOL_AX25 SOL_ROSE SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
1573		 * etc. still need work */
1574		default:
1575			tprintf("%lu", tcp->u_arg[2]);
1576			break;
1577		}
1578	} else {
1579		int len;
1580		if (syserror(tcp) || umove (tcp, tcp->u_arg[4], &len) < 0) {
1581			tprintf(", %#lx, %#lx",
1582				tcp->u_arg[3], tcp->u_arg[4]);
1583			return 0;
1584		}
1585
1586		switch (tcp->u_arg[1]) {
1587		case SOL_SOCKET:
1588			switch (tcp->u_arg[2]) {
1589#ifdef SO_LINGER
1590			case SO_LINGER:
1591			        if (len == sizeof (struct linger)) {
1592					struct linger linger;
1593					if (umove (tcp,
1594						   tcp->u_arg[3],
1595						   &linger) < 0)
1596						break;
1597					tprintf(", {onoff=%d, linger=%d}, "
1598						"[%d]",
1599						linger.l_onoff,
1600						linger.l_linger,
1601						len);
1602					return 0;
1603				}
1604				break;
1605#endif
1606			}
1607			break;
1608		}
1609
1610		tprintf (", ");
1611		if (len == sizeof (int)) {
1612			printnum(tcp, tcp->u_arg[3], "%ld");
1613		}
1614		else {
1615			printstr (tcp, tcp->u_arg[3], len);
1616		}
1617		tprintf(", [%d]", len);
1618	}
1619	return 0;
1620}
1621
1622#if defined(ICMP_FILTER)
1623static void printicmpfilter(tcp, addr)
1624struct tcb *tcp;
1625long addr;
1626{
1627	struct icmp_filter	filter;
1628
1629	if (!addr) {
1630		tprintf("NULL");
1631		return;
1632	}
1633	if (syserror(tcp) || !verbose(tcp)) {
1634		tprintf("%#lx", addr);
1635		return;
1636	}
1637	if (umove(tcp, addr, &filter) < 0) {
1638		tprintf("{...}");
1639		return;
1640	}
1641
1642	tprintf("~(");
1643	printflags(icmpfilterflags, ~filter.data, "ICMP_???");
1644	tprintf(")");
1645}
1646#endif /* ICMP_FILTER */
1647
1648static int
1649printsockopt (tcp, level, name, addr, len)
1650struct tcb *tcp;
1651int level;
1652int name;
1653long addr;
1654int len;
1655{
1656	printxval(socketlayers, level, "SOL_??");
1657	tprintf (", ");
1658	switch (level) {
1659	    case SOL_SOCKET:
1660		printxval(sockoptions, name, "SO_???");
1661		switch (name) {
1662#if defined(SO_LINGER)
1663		    case SO_LINGER:
1664			if (len == sizeof (struct linger)) {
1665				struct linger linger;
1666				if (umove (tcp, addr, &linger) < 0)
1667					break;
1668				tprintf(", {onoff=%d, linger=%d}",
1669					linger.l_onoff,
1670					linger.l_linger);
1671				return 0;
1672			}
1673			break;
1674#endif
1675		}
1676		break;
1677#ifdef SOL_IP
1678	    case SOL_IP:
1679		printxval(sockipoptions, name, "IP_???");
1680		break;
1681#endif
1682#ifdef SOL_IPV6
1683	    case SOL_IPV6:
1684		printxval(sockipv6options, name, "IPV6_???");
1685		break;
1686#endif
1687#ifdef SOL_IPX
1688	    case SOL_IPX:
1689		printxval(sockipxoptions, name, "IPX_???");
1690		break;
1691#endif
1692#ifdef SOL_PACKET
1693	    case SOL_PACKET:
1694		printxval(sockpacketoptions, name, "PACKET_???");
1695		/* TODO: decode packate_mreq for PACKET_*_MEMBERSHIP */
1696		break;
1697#endif
1698#ifdef SOL_TCP
1699	    case SOL_TCP:
1700		printxval(socktcpoptions, name, "TCP_???");
1701		break;
1702#endif
1703#ifdef SOL_RAW
1704	    case SOL_RAW:
1705		printxval(sockrawoptions, name, "RAW_???");
1706		switch (name) {
1707#if defined(ICMP_FILTER)
1708		    case ICMP_FILTER:
1709			tprintf(", ");
1710			printicmpfilter(tcp, addr);
1711			return 0;
1712#endif
1713		}
1714		break;
1715#endif
1716
1717		/* SOL_AX25 SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
1718		 * etc. still need work  */
1719
1720	    default:
1721		tprintf("%u", name);
1722	}
1723
1724	/* default arg printing */
1725
1726	tprintf (", ");
1727
1728	if (len == sizeof (int)) {
1729		printnum_int (tcp, addr, "%d");
1730	}
1731	else {
1732		printstr (tcp, addr, len);
1733	}
1734	return 0;
1735}
1736
1737
1738#ifdef HAVE_STRUCT_OPTHDR
1739
1740void
1741print_sock_optmgmt (tcp, addr, len)
1742struct tcb *tcp;
1743long addr;
1744int len;
1745{
1746	int c = 0;
1747	struct opthdr hdr;
1748
1749	while (len >= (int) sizeof hdr) {
1750		if (umove(tcp, addr, &hdr) < 0) break;
1751		if (c++) {
1752			tprintf (", ");
1753		}
1754		else if (len > hdr.len + sizeof hdr) {
1755			tprintf ("[");
1756		}
1757		tprintf ("{");
1758		addr += sizeof hdr;
1759		len -= sizeof hdr;
1760		printsockopt (tcp, hdr.level, hdr.name, addr, hdr.len);
1761		if (hdr.len > 0) {
1762			addr += hdr.len;
1763			len -= hdr.len;
1764		}
1765		tprintf ("}");
1766	}
1767	if (len > 0) {
1768		if (c++) tprintf (", ");
1769		printstr (tcp, addr, len);
1770	}
1771	if (c > 1) tprintf ("]");
1772}
1773
1774#endif
1775
1776int
1777sys_setsockopt(tcp)
1778struct tcb *tcp;
1779{
1780	if (entering(tcp)) {
1781		tprintf("%ld, ", tcp->u_arg[0]);
1782		printsockopt (tcp, tcp->u_arg[1], tcp->u_arg[2],
1783			      tcp->u_arg[3], tcp->u_arg[4]);
1784		tprintf(", %lu", tcp->u_arg[4]);
1785	}
1786	return 0;
1787}
1788
1789#if UNIXWARE >= 7
1790
1791static const struct xlat sock_version[] = {
1792	{ __NETLIB_UW211_SVR4,	"UW211_SVR4" },
1793	{ __NETLIB_UW211_XPG4,	"UW211_XPG4" },
1794	{ __NETLIB_GEMINI_SVR4,	"GEMINI_SVR4" },
1795	{ __NETLIB_GEMINI_XPG4,	"GEMINI_XPG4" },
1796	{ __NETLIB_FP1_SVR4,	"FP1_SVR4" },
1797	{ __NETLIB_FP1_XPG4,	"FP1_XPG4" },
1798	{ 0,            NULL            },
1799};
1800
1801
1802int
1803netlib_call(tcp, func)
1804struct tcb *tcp;
1805int (*func) ();
1806{
1807	if (entering(tcp)) {
1808		int i;
1809		printxval (sock_version, tcp->u_arg[0], "__NETLIB_???");
1810		tprintf(", ");
1811		--tcp->u_nargs;
1812		for (i = 0; i < tcp->u_nargs; i++)
1813			tcp->u_arg[i] = tcp->u_arg[i + 1];
1814		return func (tcp);
1815
1816	}
1817
1818	return func (tcp);
1819}
1820
1821int
1822sys_xsocket(tcp)
1823struct tcb *tcp;
1824{
1825	return netlib_call (tcp, sys_socket);
1826}
1827
1828int
1829sys_xsocketpair(tcp)
1830struct tcb *tcp;
1831{
1832	return netlib_call (tcp, sys_socketpair);
1833}
1834
1835int
1836sys_xbind(tcp)
1837struct tcb *tcp;
1838{
1839	return netlib_call (tcp, sys_bind);
1840}
1841
1842int
1843sys_xconnect(tcp)
1844struct tcb *tcp;
1845{
1846	return netlib_call (tcp, sys_connect);
1847}
1848
1849int
1850sys_xlisten(tcp)
1851struct tcb *tcp;
1852{
1853	return netlib_call (tcp, sys_listen);
1854}
1855
1856int
1857sys_xaccept(tcp)
1858struct tcb *tcp;
1859{
1860	return netlib_call (tcp, sys_accept);
1861}
1862
1863int
1864sys_xsendmsg(tcp)
1865struct tcb *tcp;
1866{
1867	return netlib_call (tcp, sys_sendmsg);
1868}
1869
1870int
1871sys_xrecvmsg(tcp)
1872struct tcb *tcp;
1873{
1874	return netlib_call (tcp, sys_recvmsg);
1875}
1876
1877int
1878sys_xgetsockaddr(tcp)
1879struct tcb *tcp;
1880{
1881	if (entering(tcp)) {
1882		printxval (sock_version, tcp->u_arg[0], "__NETLIB_???");
1883		tprintf(", ");
1884		if (tcp->u_arg[1] == 0) {
1885			tprintf ("LOCALNAME, ");
1886		}
1887		else if (tcp->u_arg[1] == 1) {
1888			tprintf ("REMOTENAME, ");
1889		}
1890		else {
1891			tprintf ("%ld, ", tcp->u_arg [1]);
1892		}
1893		tprintf ("%ld, ", tcp->u_arg [2]);
1894	}
1895	else {
1896		if (tcp->u_arg[3] == 0 || syserror(tcp)) {
1897			tprintf("%#lx", tcp->u_arg[3]);
1898		} else {
1899			printsock(tcp, tcp->u_arg[3], tcp->u_arg[4]);
1900		}
1901		tprintf(", ");
1902		printnum(tcp, tcp->u_arg[4], "%lu");
1903	}
1904
1905	return 0;
1906
1907}
1908
1909#if 0
1910
1911int
1912sys_xsetsockaddr(tcp)
1913struct tcb *tcp;
1914{
1915	return netlib_call (tcp, sys_setsockaddr);
1916}
1917
1918#endif
1919
1920int
1921sys_xgetsockopt(tcp)
1922struct tcb *tcp;
1923{
1924	return netlib_call (tcp, sys_getsockopt);
1925}
1926
1927int
1928sys_xsetsockopt(tcp)
1929struct tcb *tcp;
1930{
1931	return netlib_call (tcp, sys_setsockopt);
1932}
1933
1934int
1935sys_xshutdown(tcp)
1936struct tcb *tcp;
1937{
1938	return netlib_call (tcp, sys_shutdown);
1939}
1940
1941#endif
1942