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