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