net.c revision f185065a405794eaf6abc0dcf8345d9e6aa882f7
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	{ PF_UNSPEC,	"PF_UNSPEC"	},
121	{ PF_UNIX,	"PF_UNIX"	},
122	{ PF_INET,	"PF_INET"	},
123#ifdef PF_NETLINK
124	{ PF_NETLINK,	"PF_NETLINK"	},
125#endif
126#ifdef PF_PACKET
127	{ PF_PACKET,	"PF_PACKET"	},
128#endif
129#ifdef PF_INET6
130	{ PF_INET6,	"PF_INET6"	},
131#endif
132#ifdef PF_ATMSVC
133	{ PF_ATMSVC,	"PF_INET6"	},
134#endif
135#ifdef PF_INET6
136	{ PF_INET6,	"PF_INET6"	},
137#endif
138#ifdef PF_LOCAL
139	{ PF_LOCAL,	"PS_LOCAL"	},
140#endif
141#ifdef PF_ISO
142	{ PF_ISO,	"PF_ISO"	},
143#endif
144#ifdef PF_AX25
145	{ PF_AX25,	"PF_AX25"	},
146#endif
147#ifdef PF_IPX
148	{ PF_IPX,	"PF_IPX"	},
149#endif
150#ifdef PF_APPLETALK
151	{ PF_APPLETALK,	"PF_APPLETALK"	},
152#endif
153#ifdef PF_NETROM
154	{ PF_NETROM,	"PF_NETROM"	},
155#endif
156#ifdef PF_BRIDGE
157	{ PF_BRIDGE,	"PF_BRIDGE"	},
158#endif
159#ifdef PF_AAL5
160	{ PF_AAL5,	"PF_AAL5"	},
161#endif
162#ifdef PF_X25
163	{ PF_X25,	"PF_X25"	},
164#endif
165#ifdef PF_ROSE
166	{ PF_ROSE,	"PF_ROSE"	},
167#endif
168#ifdef PF_DECNET
169	{ PF_DECNET,	"PF_DECNET"	},
170#endif
171#ifdef PF_NETBEUI
172	{ PF_NETBEUI,	"PF_NETBEUI"	},
173#endif
174#ifdef PF_IMPLINK
175	{ PF_IMPLINK,	"PF_IMPLINK"	},
176#endif
177	{ 0,		NULL		},
178};
179static struct xlat addrfams[] = {
180	{ AF_UNSPEC,	"AF_UNSPEC"	},
181	{ AF_UNIX,	"AF_UNIX"	},
182	{ AF_INET,	"AF_INET"	},
183#ifdef AF_INET6
184	{ AF_INET6,	"AF_INET6"	},
185#endif
186	{ AF_DECnet,	"AF_DECnet"	},
187#ifdef PF_ATMSVC
188	{ AF_ATMSVC,	"AF_ATMSVC"	},
189#endif
190#ifdef AF_PACKET
191	{ AF_PACKET,	"AF_PACKET"	},
192#endif
193#ifdef AF_NETLINK
194	{ AF_NETLINK,	"AF_NETLINK"	},
195#endif
196#ifdef AF_ISO
197	{ AF_ISO,	"AF_ISO"	},
198#endif
199#ifdef AF_IMPLINK
200	{ AF_IMPLINK,	"AF_IMPLINK"	},
201#endif
202	{ 0,		NULL		},
203};
204static struct xlat socktypes[] = {
205	{ SOCK_STREAM,	"SOCK_STREAM"	},
206	{ SOCK_DGRAM,	"SOCK_DGRAM"	},
207#ifdef SOCK_RAW
208	{ SOCK_RAW,	"SOCK_RAW"	},
209#endif
210#ifdef SOCK_SEQPACKET
211	{ SOCK_SEQPACKET,"SOCK_SEQPACKET"},
212#endif
213#ifdef SOCK_RDM
214	{ SOCK_RDM,	"SOCK_RDM"	},
215#endif
216#ifdef SOCK_PACKET
217	{ SOCK_PACKET,	"SOCK_PACKET"	},
218#endif
219	{ 0,		NULL		},
220};
221static struct xlat socketlayers[] = {
222	{ SOL_IP,	"SOL_IP"	},
223#if defined(SOL_ICMP)
224	{ SOL_ICMP,	"SOL_ICMP"	},
225#endif
226	{ SOL_TCP,	"SOL_TCP"	},
227	{ SOL_UDP,	"SOL_UDP"	},
228#if defined(SOL_IPV6)
229	{ SOL_IPV6,	"SOL_IPV6"	},
230#endif
231#if defined(SOL_ICMPV6)
232	{ SOL_ICMPV6,	"SOL_ICMPV6"	},
233#endif
234#if defined(SOL_RAW)
235	{ SOL_RAW,	"SOL_RAW"	},
236#endif
237#if defined(SOL_IPX)
238	{ SOL_IPX,	"SOL_IPX"	},
239#endif
240#if defined(SOL_IPX)
241	{ SOL_IPX,	"SOL_IPX"	},
242#endif
243#if defined(SOL_AX25)
244	{ SOL_AX25,	"SOL_AX25"	},
245#endif
246#if defined(SOL_ATALK)
247	{ SOL_ATALK,	"SOL_ATALK"	},
248#endif
249#if defined(SOL_NETROM)
250	{ SOL_NETROM,	"SOL_NETROM"	},
251#endif
252#if defined(SOL_ROSE)
253	{ SOL_ROSE,	"SOL_ROSE"	},
254#endif
255#if defined(SOL_DECNET)
256	{ SOL_DECNET,	"SOL_DECNET"	},
257#endif
258#if defined(SOL_X25)
259	{ SOL_X25,	"SOL_X25"	},
260#endif
261#if defined(SOL_PACKET)
262	{ SOL_PACKET,	"SOL_PACKET"	},
263#endif
264#if defined(SOL_ATM)
265	{ SOL_ATM,	"SOL_ATM"	},
266#endif
267#if defined(SOL_AAL)
268	{ SOL_AAL,	"SOL_AAL"	},
269#endif
270#if defined(SOL_IRDA)
271	{ SOL_IRDA,	"SOL_IRDA"	},
272#endif
273};
274static struct xlat protocols[] = {
275	{ IPPROTO_IP,	"IPPROTO_IP"	},
276	{ IPPROTO_ICMP,	"IPPROTO_ICMP"	},
277	{ IPPROTO_TCP,	"IPPROTO_TCP"	},
278	{ IPPROTO_UDP,	"IPPROTO_UDP"	},
279#ifdef IPPROTO_GGP
280	{ IPPROTO_GGP,	"IPPROTO_GGP"	},
281#endif
282#ifdef IPPROTO_EGP
283	{ IPPROTO_EGP,	"IPPROTO_EGP"	},
284#endif
285#ifdef IPPROTO_PUP
286	{ IPPROTO_PUP,	"IPPROTO_PUP"	},
287#endif
288#ifdef IPPROTO_IDP
289	{ IPPROTO_IDP,	"IPPROTO_IDP"	},
290#endif
291#ifdef IPPROTO_IPV6
292	{ IPPROTO_IPV6,	"IPPROTO_IPV6"	},
293#endif
294#ifdef IPPROTO_ICMPV6
295	{ IPPROTO_ICMPV6,"IPPROTO_ICMPV6"},
296#endif
297#ifdef IPPROTO_IGMP
298	{ IPPROTO_IGMP,	"IPPROTO_IGMP"	},
299#endif
300#ifdef IPPROTO_HELLO
301	{ IPPROTO_HELLO,"IPPROTO_HELLO"	},
302#endif
303#ifdef IPPROTO_ND
304	{ IPPROTO_ND,	"IPPROTO_ND"	},
305#endif
306#ifdef IPPROTO_RAW
307	{ IPPROTO_RAW,	"IPPROTO_RAW"	},
308#endif
309#ifdef IPPROTO_MAX
310	{ IPPROTO_MAX,	"IPPROTO_MAX"	},
311#endif
312#ifdef IPPROTO_IPIP
313	{ IPPROTO_IPIP,	"IPPROTO_IPIP"	},
314#endif
315	{ 0,		NULL		},
316};
317static struct xlat msg_flags[] = {
318	{ MSG_OOB,	"MSG_OOB"	},
319#ifdef MSG_DONTROUTE
320	{ MSG_DONTROUTE,"MSG_DONTROUTE"	},
321#endif
322#ifdef MSG_PEEK
323	{ MSG_PEEK,	"MSG_PEEK"	},
324#endif
325#ifdef MSG_CTRUNC
326	{ MSG_CTRUNC,	"MSG_CTRUNC"	},
327#endif
328#ifdef MSG_PROXY
329	{ MSG_PROXY,	"MSG_PROXY"	},
330#endif
331#ifdef MSG_EOR
332	{ MSG_EOR,	"MSG_EOR"	},
333#endif
334#ifdef MSG_WAITALL
335	{ MSG_WAITALL,	"MSG_WAITALL"	},
336#endif
337#ifdef MSG_TRUNC
338	{ MSG_TRUNC,	"MSG_TRUNC"	},
339#endif
340#ifdef MSG_CTRUNC
341	{ MSG_CTRUNC,	"MSG_CTRUNC"	},
342#endif
343#ifdef MSG_ERRQUEUE
344	{ MSG_ERRQUEUE,	"MSG_ERRQUEUE"	},
345#endif
346#ifdef MSG_DONTWAIT
347	{ MSG_DONTWAIT,	"MSG_DONTWAIT"	},
348#endif
349#ifdef MSG_CONFIRM
350	{ MSG_CONFIRM,	"MSG_CONFIRM"	},
351#endif
352#ifdef MSG_PROBE
353	{ MSG_PROBE,	"MSG_PROBE"	},
354#endif
355	{ 0,		NULL		},
356};
357
358static struct xlat sockoptions[] = {
359#ifdef SO_PEERCRED
360	{ SO_PEERCRED,	"SO_PEERCRED"	},
361#endif
362#ifdef SO_PASSCRED
363	{ SO_PASSCRED,	"SO_PASSCRED"	},
364#endif
365#ifdef SO_DEBUG
366	{ SO_DEBUG,	"SO_DEBUG"	},
367#endif
368#ifdef SO_REUSEADDR
369	{ SO_REUSEADDR,	"SO_REUSEADDR"	},
370#endif
371#ifdef SO_KEEPALIVE
372	{ SO_KEEPALIVE,	"SO_KEEPALIVE"	},
373#endif
374#ifdef SO_DONTROUTE
375	{ SO_DONTROUTE,	"SO_DONTROUTE"	},
376#endif
377#ifdef SO_BROADCAST
378	{ SO_BROADCAST,	"SO_BROADCAST"	},
379#endif
380#ifdef SO_LINGER
381	{ SO_LINGER,	"SO_LINGER"	},
382#endif
383#ifdef SO_OOBINLINE
384	{ SO_OOBINLINE,	"SO_OOBINLINE"	},
385#endif
386#ifdef SO_TYPE
387	{ SO_TYPE,	"SO_TYPE"	},
388#endif
389#ifdef SO_ERROR
390	{ SO_ERROR,	"SO_ERROR"	},
391#endif
392#ifdef SO_SNDBUF
393	{ SO_SNDBUF,	"SO_SNDBUF"	},
394#endif
395#ifdef SO_RCVBUF
396	{ SO_RCVBUF,	"SO_RCVBUF"	},
397#endif
398#ifdef SO_NO_CHECK
399	{ SO_NO_CHECK,	"SO_NO_CHECK"	},
400#endif
401#ifdef SO_PRIORITY
402	{ SO_PRIORITY,	"SO_PRIORITY"	},
403#endif
404#ifdef SO_ACCEPTCONN
405	{ SO_ACCEPTCONN,"SO_ACCEPTCONN"	},
406#endif
407#ifdef SO_USELOOPBACK
408	{ SO_USELOOPBACK,"SO_USELOOPBACK"},
409#endif
410#ifdef SO_SNDLOWAT
411	{ SO_SNDLOWAT,	"SO_SNDLOWAT"	},
412#endif
413#ifdef SO_RCVLOWAT
414	{ SO_RCVLOWAT,	"SO_RCVLOWAT"	},
415#endif
416#ifdef SO_SNDTIMEO
417	{ SO_SNDTIMEO,	"SO_SNDTIMEO"	},
418#endif
419#ifdef SO_RCVTIMEO
420	{ SO_RCVTIMEO,	"SO_RCVTIMEO"	},
421#endif
422#ifdef SO_BSDCOMPAT
423	{ SO_BSDCOMPAT,	"SO_BSDCOMPAT"	},
424#endif
425#ifdef SO_REUSEPORT
426	{ SO_REUSEPORT,	"SO_REUSEPORT"	},
427#endif
428#ifdef SO_RCVLOWAT
429	{ SO_RCVLOWAT, "SO_RCVLOWAT"	},
430#endif
431#ifdef SO_SNDLOWAT
432	{ SO_SNDLOWAT, "SO_SNDLOWAT"	},
433#endif
434#ifdef SO_RCVTIMEO
435	{ SO_RCVTIMEO, "SO_RCVTIMEO"	},
436#endif
437#ifdef SO_SNDTIMEO
438	{ SO_SNDTIMEO, "SO_SNDTIMEO"	},
439#endif
440	{ 0,		NULL		},
441};
442
443#ifdef SOL_IP
444static struct xlat sockipoptions[] = {
445	{ IP_TOS,		"IP_TOS"		},
446	{ IP_TTL,		"IP_TTL"		},
447#if defined(IP_HDRINCL)
448	{ IP_HDRINCL,		"IP_HDRINCL"		},
449#endif
450#if defined(IP_OPTIONS)
451	{ IP_OPTIONS,		"IP_OPTIONS"		},
452#endif
453	{ IP_ROUTER_ALERT,	"IP_ROUTER_ALERT"	},
454#if defined(IP_RECVOPTIONS)
455	{ IP_RECVOPTIONS,	"IP_RECVOPTIONS"	},
456#endif
457	{ IP_RETOPTS,		"IP_RETOPTS"		},
458	{ IP_PKTINFO,		"IP_PKTINFO"		},
459	{ IP_PKTOPTIONS,	"IP_PKTOPTIONS"	},
460	{ IP_MTU_DISCOVER,	"IP_MTU_DISCOVER"	},
461	{ IP_MTU_DISCOVER,	"IP_MTU_DISCOVER"	},
462	{ IP_RECVERR,		"IP_RECVERR"		},
463	{ IP_RECVTTL,		"IP_RECRECVTTL"		},
464	{ IP_RECVTOS,		"IP_RECRECVTOS"		},
465#if defined(IP_MTU)
466	{ IP_MTU,		"IP_MTU"		},
467#endif
468	{ IP_MULTICAST_IF,	"IP_MULTICAST_IF"	},
469	{ IP_MULTICAST_TTL,	"IP_MULTICAST_TTL"	},
470	{ IP_MULTICAST_LOOP,	"IP_MULTICAST_LOOP"	},
471	{ IP_ADD_MEMBERSHIP,	"IP_ADD_MEMBERSHIP"	},
472	{ IP_DROP_MEMBERSHIP,	"IP_DROP_MEMBERSHIP"	},
473	{ 0,			NULL			},
474};
475#endif /* SOL_IP */
476
477#ifdef SOL_IPX
478static struct xlat sockipxoptions[] = {
479	{ IPX_TYPE,     "IPX_TYPE"      },
480	{ 0,            NULL            },
481};
482#endif /* SOL_IPX */
483
484#ifdef SOL_RAW
485static struct xlat sockrawoptions[] = {
486#if defined(ICMP_FILTER)
487	{ ICMP_FILTER,		"ICMP_FILTER"	},
488#endif
489	{ 0,			NULL		},
490};
491#endif /* SOL_RAW */
492
493#ifdef SOL_PACKET
494static struct xlat sockpacketoptions[] = {
495	{ PACKET_ADD_MEMBERSHIP,	"PACKET_ADD_MEMBERSHIP"	},
496	{ PACKET_DROP_MEMBERSHIP,	"PACKET_DROP_MEMBERSHIP"},
497#if defined(PACKET_RECV_OUTPUT)
498	{ PACKET_RECV_OUTPUT,		"PACKET_RECV_OUTPUT"	},
499#endif
500#if defined(PACKET_RX_RING)
501	{ PACKET_RX_RING,		"PACKET_RX_RING"	},
502#endif
503#if defined(PACKET_STATISTICS)
504	{ PACKET_STATISTICS,		"PACKET_STATISTICS"	},
505#endif
506	{ 0,				NULL			},
507};
508#endif /* SOL_PACKET */
509
510#ifdef SOL_TCP
511static struct xlat socktcpoptions[] = {
512	{ TCP_NODELAY,	"TCP_NODELAY"	},
513	{ TCP_MAXSEG,	"TCP_MAXSEG"	},
514#if defined(TCP_CORK)
515	{ TCP_CORK,	"TCP_CORK"	},
516#endif
517	{ 0,		NULL		},
518};
519#endif /* SOL_TCP */
520
521#ifdef SOL_RAW
522static struct xlat icmpfilterflags[] = {
523#if defined(ICMP_ECHOREPLY)
524	{ (1<<ICMP_ECHOREPLY),		"ICMP_ECHOREPLY"	},
525#endif
526#if defined(ICMP_DEST_UNREACH)
527	{ (1<<ICMP_DEST_UNREACH),	"ICMP_DEST_UNREACH"	},
528#endif
529#if defined(ICMP_SOURCE_QUENCH)
530	{ (1<<ICMP_SOURCE_QUENCH),	"ICMP_SOURCE_QUENCH"	},
531#endif
532#if defined(ICMP_REDIRECT)
533	{ (1<<ICMP_REDIRECT),		"ICMP_REDIRECT"		},
534#endif
535#if defined(ICMP_ECHO)
536	{ (1<<ICMP_ECHO),		"ICMP_ECHO"		},
537#endif
538#if defined(ICMP_TIME_EXCEEDED)
539	{ (1<<ICMP_TIME_EXCEEDED),	"ICMP_TIME_EXCEEDED"	},
540#endif
541#if defined(ICMP_PARAMETERPROB)
542	{ (1<<ICMP_PARAMETERPROB),	"ICMP_PARAMETERPROB"	},
543#endif
544#if defined(ICMP_TIMESTAMP)
545	{ (1<<ICMP_TIMESTAMP),		"ICMP_TIMESTAMP"	},
546#endif
547#if defined(ICMP_TIMESTAMPREPLY)
548	{ (1<<ICMP_TIMESTAMPREPLY),	"ICMP_TIMESTAMPREPLY"	},
549#endif
550#if defined(ICMP_INFO_REQUEST)
551	{ (1<<ICMP_INFO_REQUEST),	"ICMP_INFO_REQUEST"	},
552#endif
553#if defined(ICMP_INFO_REPLY)
554	{ (1<<ICMP_INFO_REPLY),		"ICMP_INFO_REPLY"	},
555#endif
556#if defined(ICMP_ADDRESS)
557	{ (1<<ICMP_ADDRESS),		"ICMP_ADDRESS"		},
558#endif
559#if defined(ICMP_ADDRESSREPLY)
560	{ (1<<ICMP_ADDRESSREPLY),	"ICMP_ADDRESSREPLY"	},
561#endif
562	{ 0,				NULL			},
563};
564#endif /* SOL_RAW */
565
566
567void
568printsock(tcp, addr, addrlen)
569struct tcb *tcp;
570long addr;
571int addrlen;
572{
573	union {
574		char pad[128];
575		struct sockaddr sa;
576		struct sockaddr_in sin;
577		struct sockaddr_un sau;
578#ifdef HAVE_INET_NTOP
579		struct sockaddr_in6 sa6;
580#endif
581#if defined(LINUX) && defined(AF_IPX)
582		struct sockaddr_ipx sipx;
583#endif
584#ifdef AF_PACKET
585		struct sockaddr_ll ll;
586#endif
587#ifdef AF_NETLINK
588		struct sockaddr_nl nl;
589#endif
590	} addrbuf;
591	char string_addr[100];
592
593	if (addr == 0) {
594		tprintf("NULL");
595		return;
596	}
597	if (!verbose(tcp)) {
598		tprintf("%#lx", addr);
599		return;
600	}
601	if ((addrlen<2) || (addrlen>sizeof(addrbuf)))
602		addrlen=sizeof(addrbuf);
603
604	if (umoven(tcp, addr, addrlen, (char*)&addrbuf) < 0) {
605		tprintf("{...}");
606		return;
607	}
608
609	tprintf("{sin_family=");
610	printxval(addrfams, addrbuf.sa.sa_family, "AF_???");
611	tprintf(", ");
612
613	switch (addrbuf.sa.sa_family) {
614	case AF_UNIX:
615		if (addrlen==2) {
616			tprintf("<nil>");
617		} else if (addrbuf.sau.sun_path[0]) {
618			tprintf("path=\"%*.*s\"", addrlen-2, addrlen-2, addrbuf.sau.sun_path);
619		} else {
620			tprintf("path=@%*.*s", addrlen-3, addrlen-3, addrbuf.sau.sun_path+1);
621		}
622		break;
623	case AF_INET:
624		tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")}",
625			ntohs(addrbuf.sin.sin_port), inet_ntoa(addrbuf.sin.sin_addr));
626		break;
627#ifdef HAVE_INET_NTOP
628	case AF_INET6:
629		inet_ntop(AF_INET6, &addrbuf.sa6.sin6_addr, string_addr, sizeof(string_addr));
630		tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=%u",
631				ntohs(addrbuf.sa6.sin6_port), string_addr,
632				addrbuf.sa6.sin6_flowinfo);
633#ifdef HAVE_SIN6_SCOPE_ID
634		{
635#if defined(HAVE_IF_INDEXTONAME) && defined(IN6_IS_ADDR_LINKLOCAL) && defined(IN6_IS_ADDR_MC_LINKLOCAL)
636		    int numericscope = 0;
637		    if (IN6_IS_ADDR_LINKLOCAL (&addrbuf.sa6.sin6_addr)
638			    || IN6_IS_ADDR_MC_LINKLOCAL (&addrbuf.sa6.sin6_addr)) {
639			char scopebuf[IFNAMSIZ + 1];
640
641			if (if_indextoname (addrbuf.sa6.sin6_scope_id, scopebuf) == NULL)
642			    numericscope++;
643			else
644			    tprintf(", sin6_scope_id=if_nametoindex(\"%s\")", scopebuf);
645		    } else
646			numericscope++;
647
648		    if (numericscope)
649#endif
650			tprintf(", sin6_scope_id=%u", addrbuf.sa6.sin6_scope_id);
651		}
652#endif
653		    break;
654#endif
655#if defined(AF_IPX) && defined(linux)
656	case AF_IPX:
657		{
658			int i;
659			tprintf("{sipx_port=htons(%u), ",
660					ntohs(addrbuf.sipx.sipx_port));
661			/* Yes, I know, this does not look too
662			 * strace-ish, but otherwise the IPX
663			 * addresses just look monstrous...
664			 * Anyways, feel free if you don't like
665			 * this way.. :)
666			 */
667			tprintf("%08lx:", (unsigned long)ntohl(addrbuf.sipx.sipx_network));
668			for (i = 0; i<IPX_NODE_LEN; i++)
669				tprintf("%02x", addrbuf.sipx.sipx_node[i]);
670			tprintf("/[%02x]", addrbuf.sipx.sipx_type);
671		}
672		break;
673#endif /* AF_IPX && linux */
674#ifdef AF_PACKET
675	case AF_PACKET:
676		{
677			int i;
678			tprintf("proto=%#04x, if%d, pkttype=%d, addr(%d)={%d, ",
679					ntohs(addrbuf.ll.sll_protocol),
680					addrbuf.ll.sll_ifindex,
681					addrbuf.ll.sll_pkttype,
682					addrbuf.ll.sll_halen,
683					addrbuf.ll.sll_hatype);
684			for (i=0; i<addrbuf.ll.sll_addr[i]; i++)
685				tprintf("%02x", addrbuf.ll.sll_addr[i]);
686		}
687		break;
688
689#endif /* AF_APACKET */
690#ifdef AF_NETLINLK
691	case AF_NETLINK:
692		tprintf("pid=%d, groups=%08x", addrbuf.nl.nl_pid, addrbuf.nl.nl_groups);
693		break;
694#endif /* AF_NETLINK */
695	/* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
696	AF_X25 AF_ROSE etc. still need to be done */
697
698	default:
699		tprintf("{sa_family=%u, sa_data=", addrbuf.sa.sa_family);
700		printstr(tcp, (long) &((struct sockaddr *) addr)->sa_data,
701			sizeof addrbuf.sa.sa_data);
702		break;
703	}
704	tprintf("}");
705}
706
707#if HAVE_SENDMSG
708
709static void
710printiovec(tcp, iovec, len)
711struct tcb *tcp;
712struct iovec *iovec;
713long   len;
714{
715	struct iovec *iov;
716	int i;
717
718	iov = (struct iovec *) malloc(len * sizeof *iov);
719	if (iov == NULL) {
720		fprintf(stderr, "No memory");
721		return;
722	}
723	if (umoven(tcp, (long)iovec,
724				len * sizeof *iov, (char *) iov) < 0) {
725		tprintf("%#lx", (unsigned long)iovec);
726	} else {
727		tprintf("[");
728		for (i = 0; i < len; i++) {
729			if (i)
730				tprintf(", ");
731			tprintf("{");
732			printstr(tcp, (long) iov[i].iov_base,
733					iov[i].iov_len);
734			tprintf(", %lu}", (unsigned long)iov[i].iov_len);
735		}
736		tprintf("]");
737	}
738	free((char *) iov);
739}
740
741static void
742printmsghdr(tcp, addr)
743struct tcb *tcp;
744long addr;
745{
746	struct msghdr msg;
747
748	if (umove(tcp, addr, &msg) < 0) {
749		tprintf("%#lx", addr);
750		return;
751	}
752	tprintf("{msg_name(%d)=", msg.msg_namelen);
753	printsock(tcp, (long)msg.msg_name, msg.msg_namelen);
754
755	tprintf(", msg_iov(%lu)=", (unsigned long)msg.msg_iovlen);
756	printiovec(tcp, msg.msg_iov, msg.msg_iovlen);
757
758#ifdef HAVE_MSG_CONTROL
759	tprintf(", msg_controllen=%lu", (unsigned long)msg.msg_controllen);
760	if (msg.msg_controllen)
761		tprintf(", msg_control=%#lx, ", (unsigned long) msg.msg_control);
762	tprintf(", msg_flags=");
763	if (printflags(msg_flags, msg.msg_flags)==0)
764		tprintf("0");
765#else /* !HAVE_MSG_CONTROL */
766	tprintf("msg_accrights=%#lx, msg_accrightslen=%u",
767		(unsigned long) msg.msg_accrights, msg.msg_accrightslen);
768#endif /* !HAVE_MSG_CONTROL */
769	tprintf("}");
770}
771
772#endif /* HAVE_SENDMSG */
773
774int
775sys_socket(tcp)
776struct tcb *tcp;
777{
778	if (entering(tcp)) {
779		printxval(domains, tcp->u_arg[0], "PF_???");
780		tprintf(", ");
781		printxval(socktypes, tcp->u_arg[1], "SOCK_???");
782		tprintf(", ");
783		switch (tcp->u_arg[0]) {
784		case PF_INET:
785			printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
786			break;
787#ifdef PF_IPX
788		case PF_IPX:
789			/* BTW: I don't believe this.. */
790			tprintf("[");
791			printxval(domains, tcp->u_arg[2], "PF_???");
792			tprintf("]");
793			break;
794#endif /* PF_IPX */
795		default:
796			tprintf("%lu", tcp->u_arg[2]);
797			break;
798		}
799	}
800	return 0;
801}
802
803int
804sys_bind(tcp)
805struct tcb *tcp;
806{
807	if (entering(tcp)) {
808		tprintf("%ld, ", tcp->u_arg[0]);
809		printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
810		tprintf(", %lu", tcp->u_arg[2]);
811	}
812	return 0;
813}
814
815int
816sys_connect(tcp)
817struct tcb *tcp;
818{
819	return sys_bind(tcp);
820}
821
822int
823sys_listen(tcp)
824struct tcb *tcp;
825{
826	if (entering(tcp)) {
827		tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]);
828	}
829	return 0;
830}
831
832int
833sys_accept(tcp)
834struct tcb *tcp;
835{
836	if (entering(tcp)) {
837		tprintf("%ld, ", tcp->u_arg[0]);
838	} else if (!tcp->u_arg[2])
839		tprintf("%#lx, NULL", tcp->u_arg[1]);
840	else {
841		if (tcp->u_arg[1] == 0 || syserror(tcp)) {
842			tprintf("%#lx", tcp->u_arg[1]);
843		} else {
844			printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
845		}
846		tprintf(", ");
847		printnum(tcp, tcp->u_arg[2], "%lu");
848	}
849	return 0;
850}
851
852int
853sys_send(tcp)
854struct tcb *tcp;
855{
856	if (entering(tcp)) {
857		tprintf("%ld, ", tcp->u_arg[0]);
858		printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
859		tprintf(", %lu, ", tcp->u_arg[2]);
860		/* flags */
861		if (printflags(msg_flags, tcp->u_arg[3]) == 0)
862			tprintf("0");
863	}
864	return 0;
865}
866
867int
868sys_sendto(tcp)
869struct tcb *tcp;
870{
871	if (entering(tcp)) {
872		tprintf("%ld, ", tcp->u_arg[0]);
873		printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
874		tprintf(", %lu, ", tcp->u_arg[2]);
875		/* flags */
876		if (printflags(msg_flags, tcp->u_arg[3]) == 0)
877			tprintf("0");
878		/* to address */
879		tprintf(", ");
880		printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
881		/* to length */
882		tprintf(", %lu", tcp->u_arg[5]);
883	}
884	return 0;
885}
886
887#ifdef HAVE_SENDMSG
888
889int
890sys_sendmsg(tcp)
891struct tcb *tcp;
892{
893	if (entering(tcp)) {
894		tprintf("%ld, ", tcp->u_arg[0]);
895		printmsghdr(tcp, tcp->u_arg[1]);
896		/* flags */
897		tprintf(", ");
898		if (printflags(msg_flags, tcp->u_arg[2]) == 0)
899			tprintf("0");
900	}
901	return 0;
902}
903
904#endif /* HAVE_SENDMSG */
905
906int
907sys_recv(tcp)
908struct tcb *tcp;
909{
910	if (entering(tcp)) {
911		tprintf("%ld, ", tcp->u_arg[0]);
912	} else {
913		if (syserror(tcp))
914			tprintf("%#lx", tcp->u_arg[1]);
915		else
916			printstr(tcp, tcp->u_arg[1], tcp->u_rval);
917
918		tprintf(", %lu, ", tcp->u_arg[2]);
919		if (printflags(msg_flags, tcp->u_arg[3]) == 0)
920			tprintf("0");
921	}
922	return 0;
923}
924
925int
926sys_recvfrom(tcp)
927struct tcb *tcp;
928{
929	int fromlen;
930
931	if (entering(tcp)) {
932		tprintf("%ld, ", tcp->u_arg[0]);
933	} else {
934		if (syserror(tcp)) {
935			tprintf("%#lx, %lu, %lu, %#lx, %#lx",
936				tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3],
937				tcp->u_arg[4], tcp->u_arg[5]);
938			return 0;
939		}
940		/* buf */
941		printstr(tcp, tcp->u_arg[1], tcp->u_rval);
942		/* len */
943		tprintf(", %lu, ", tcp->u_arg[2]);
944		/* flags */
945		if (printflags(msg_flags, tcp->u_arg[3]) == 0)
946			tprintf("0");
947		/* from address, len */
948		if (!tcp->u_arg[4] || !tcp->u_arg[5]) {
949			if (tcp->u_arg[4] == 0)
950				tprintf(", NULL");
951			else
952				tprintf(", %#lx", tcp->u_arg[4]);
953			if (tcp->u_arg[5] == 0)
954				tprintf(", NULL");
955			else
956				tprintf(", %#lx", tcp->u_arg[5]);
957			return 0;
958		}
959		if (umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
960			tprintf(", {...}, [?]");
961			return 0;
962		}
963		tprintf(", ");
964		printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
965		/* from length */
966		tprintf(", [%u]", fromlen);
967	}
968	return 0;
969}
970
971#ifdef HAVE_SENDMSG
972
973int
974sys_recvmsg(tcp)
975struct tcb *tcp;
976{
977	if (entering(tcp)) {
978		tprintf("%ld, ", tcp->u_arg[0]);
979	} else {
980		if (syserror(tcp) || !verbose(tcp))
981			tprintf("%#lx", tcp->u_arg[1]);
982		else
983			printmsghdr(tcp, tcp->u_arg[1]);
984		/* flags */
985		tprintf(", ");
986		if (printflags(msg_flags, tcp->u_arg[2]) == 0)
987			tprintf("0");
988	}
989	return 0;
990}
991
992#endif /* HAVE_SENDMSG */
993
994int
995sys_shutdown(tcp)
996struct tcb *tcp;
997{
998	if (entering(tcp)) {
999		tprintf("%ld, %ld", tcp->u_arg[0], tcp->u_arg[1]);
1000		switch (tcp->u_arg[1]) {
1001		case 0:
1002			tprintf("%s", " /* receive */");
1003			break;
1004		case 1:
1005			tprintf("%s", " /* send */");
1006			break;
1007		case 2:
1008			tprintf("%s", " /* send and receive */");
1009			break;
1010		}
1011	}
1012	return 0;
1013}
1014
1015int
1016sys_getsockname(tcp)
1017struct tcb *tcp;
1018{
1019	return sys_accept(tcp);
1020}
1021
1022int
1023sys_getpeername(tcp)
1024struct tcb *tcp;
1025{
1026	return sys_accept(tcp);
1027}
1028
1029int
1030sys_pipe(tcp)
1031struct tcb *tcp;
1032{
1033
1034#if defined(LINUX) && !defined(SPARC)
1035	int fds[2];
1036
1037	if (exiting(tcp)) {
1038		if (syserror(tcp)) {
1039			tprintf("%#lx", tcp->u_arg[0]);
1040			return 0;
1041		}
1042		if (umoven(tcp, tcp->u_arg[0], sizeof fds, (char *) fds) < 0)
1043			tprintf("[...]");
1044		else
1045			tprintf("[%u, %u]", fds[0], fds[1]);
1046	}
1047#elif defined(SPARC) || defined(SVR4) || defined(FREEBSD)
1048	if (exiting(tcp))
1049		tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
1050#endif
1051	return 0;
1052}
1053
1054int
1055sys_socketpair(tcp)
1056struct tcb *tcp;
1057{
1058#ifdef LINUX
1059	int fds[2];
1060#endif
1061
1062	if (entering(tcp)) {
1063		printxval(domains, tcp->u_arg[0], "PF_???");
1064		tprintf(", ");
1065		printxval(socktypes, tcp->u_arg[1], "SOCK_???");
1066		tprintf(", ");
1067		switch (tcp->u_arg[0]) {
1068		case PF_INET:
1069			printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
1070			break;
1071#ifdef PF_IPX
1072		case PF_IPX:
1073			/* BTW: I don't believe this.. */
1074			tprintf("[");
1075			printxval(domains, tcp->u_arg[2], "PF_???");
1076			tprintf("]");
1077			break;
1078#endif /* PF_IPX */
1079		default:
1080			tprintf("%lu", tcp->u_arg[2]);
1081			break;
1082		}
1083	} else {
1084		if (syserror(tcp)) {
1085			tprintf(", %#lx", tcp->u_arg[3]);
1086			return 0;
1087		}
1088#ifdef LINUX
1089		if (umoven(tcp, tcp->u_arg[3], sizeof fds, (char *) fds) < 0)
1090			tprintf(", [...]");
1091		else
1092			tprintf(", [%u, %u]", fds[0], fds[1]);
1093#endif /* LINUX */
1094#if defined(SUNOS4) || defined(SVR4) || defined(FREEBSD)
1095		tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
1096#endif /* SUNOS4 || SVR4 || FREEBSD */
1097	}
1098	return 0;
1099}
1100
1101int
1102sys_getsockopt(tcp)
1103struct tcb *tcp;
1104{
1105	if (entering(tcp)) {
1106		tprintf("%ld, ", tcp->u_arg[0]);
1107		switch (tcp->u_arg[1]) {
1108		case SOL_SOCKET:
1109			tprintf("SOL_SOCKET, ");
1110			printxval(sockoptions, tcp->u_arg[2], "SO_???");
1111			tprintf(", ");
1112			break;
1113#ifdef SOL_IP
1114		case SOL_IP:
1115			tprintf("SOL_IP, ");
1116			printxval(sockipoptions, tcp->u_arg[2], "IP_???");
1117			tprintf(", ");
1118			break;
1119#endif
1120#ifdef SOL_IPX
1121		case SOL_IPX:
1122			tprintf("SOL_IPX, ");
1123			printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
1124			tprintf(", ");
1125			break;
1126#endif
1127#ifdef SOL_PACKET
1128		case SOL_PACKET:
1129			tprintf("SOL_PACKET, ");
1130			printxval(sockpacketoptions, tcp->u_arg[2], "PACKET_???");
1131			tprintf(", ");
1132			break;
1133#endif
1134#ifdef SOL_TCP
1135		case SOL_TCP:
1136			tprintf("SOL_TCP, ");
1137			printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
1138			tprintf(", ");
1139			break;
1140#endif
1141
1142		/* SOL_AX25 SOL_ROSE SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
1143		 * etc. still need work */
1144		default:
1145			/* XXX - should know socket family here */
1146			printxval(socketlayers, tcp->u_arg[1], "SOL_???");
1147			tprintf(", %lu, ", tcp->u_arg[2]);
1148			break;
1149		}
1150	} else {
1151		if (syserror(tcp)) {
1152			tprintf("%#lx, %#lx",
1153				tcp->u_arg[3], tcp->u_arg[4]);
1154			return 0;
1155		}
1156		printnum(tcp, tcp->u_arg[3], "%ld");
1157		tprintf(", ");
1158		printnum(tcp, tcp->u_arg[4], "%ld");
1159	}
1160	return 0;
1161}
1162
1163#if defined(ICMP_FILTER)
1164static void printicmpfilter(tcp, addr)
1165struct tcb *tcp;
1166long addr;
1167{
1168	struct icmp_filter	filter;
1169
1170	if (!addr) {
1171		tprintf("NULL");
1172		return;
1173	}
1174	if (syserror(tcp) || !verbose(tcp)) {
1175		tprintf("%#lx", addr);
1176		return;
1177	}
1178	if (umove(tcp, addr, &filter) < 0) {
1179		tprintf("{...}");
1180		return;
1181	}
1182
1183	tprintf("~(");
1184	if (printflags(icmpfilterflags, ~filter.data) == 0)
1185		tprintf("0");
1186	tprintf(")");
1187}
1188#endif /* ICMP_FILTER */
1189
1190int
1191sys_setsockopt(tcp)
1192struct tcb *tcp;
1193{
1194	if (entering(tcp)) {
1195		tprintf("%ld, ", tcp->u_arg[0]);
1196		switch (tcp->u_arg[1]) {
1197		case SOL_SOCKET:
1198			tprintf("SOL_SOCKET, ");
1199			printxval(sockoptions, tcp->u_arg[2], "SO_???");
1200			tprintf(", ");
1201			printnum(tcp, tcp->u_arg[3], "%ld");
1202			tprintf(", %lu", tcp->u_arg[4]);
1203			break;
1204#ifdef SOL_IP
1205		case SOL_IP:
1206			tprintf("SOL_IP, ");
1207			printxval(sockipoptions, tcp->u_arg[2], "IP_???");
1208			tprintf(", ");
1209			printnum(tcp, tcp->u_arg[3], "%ld");
1210			tprintf(", %lu", tcp->u_arg[4]);
1211			break;
1212#endif
1213#ifdef SOL_IPX
1214		case SOL_IPX:
1215			tprintf("SOL_IPX, ");
1216			printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
1217			tprintf(", ");
1218			printnum(tcp, tcp->u_arg[3], "%ld");
1219			tprintf(", %lu", tcp->u_arg[4]);
1220			break;
1221#endif
1222#ifdef SOL_PACKET
1223		case SOL_PACKET:
1224			tprintf("SOL_PACKET, ");
1225			printxval(sockpacketoptions, tcp->u_arg[2], "PACKET_???");
1226			tprintf(", ");
1227			/* TODO: decode packate_mreq for PACKET_*_MEMBERSHIP */
1228			printnum(tcp, tcp->u_arg[3], "%ld");
1229			tprintf(", %lu", tcp->u_arg[4]);
1230			break;
1231#endif
1232#ifdef SOL_TCP
1233		case SOL_TCP:
1234			tprintf("SOL_TCP, ");
1235			printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
1236			tprintf(", ");
1237			printnum(tcp, tcp->u_arg[3], "%ld");
1238			tprintf(", %lu", tcp->u_arg[4]);
1239			break;
1240#endif
1241#ifdef SOL_RAW
1242		case SOL_RAW:
1243			tprintf("SOL_RAW, ");
1244			printxval(sockrawoptions, tcp->u_arg[2], "RAW_???");
1245			tprintf(", ");
1246			switch (tcp->u_arg[2]) {
1247#if defined(ICMP_FILTER)
1248				case ICMP_FILTER:
1249					printicmpfilter(tcp, tcp->u_arg[3]);
1250					break;
1251#endif
1252				default:
1253					printnum(tcp, tcp->u_arg[3], "%ld");
1254					break;
1255			}
1256			tprintf(", %lu", tcp->u_arg[4]);
1257			break;
1258#endif
1259
1260		/* SOL_AX25 SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
1261		 * etc. still need work  */
1262		default:
1263			/* XXX - should know socket family here */
1264			printxval(socketlayers, tcp->u_arg[1], "IPPROTO_???");
1265			tprintf(", %lu, ", tcp->u_arg[2]);
1266			printnum(tcp, tcp->u_arg[3], "%ld");
1267			tprintf(", %lu", tcp->u_arg[4]);
1268			break;
1269		}
1270	}
1271	return 0;
1272}
1273
1274#if UNIXWARE >= 7
1275
1276static struct xlat sock_version[] = {
1277	{ __NETLIB_UW211_SVR4,	"UW211_SVR4" },
1278	{ __NETLIB_UW211_XPG4,	"UW211_XPG4" },
1279	{ __NETLIB_GEMINI_SVR4,	"GEMINI_SVR4" },
1280	{ __NETLIB_GEMINI_XPG4,	"GEMINI_XPG4" },
1281	{ __NETLIB_FP1_SVR4,	"FP1_SVR4" },
1282	{ __NETLIB_FP1_XPG4,	"FP1_XPG4" },
1283	{ 0,            NULL            },
1284};
1285
1286
1287int
1288netlib_call(tcp, func)
1289struct tcb *tcp;
1290int (*func) ();
1291{
1292	if (entering(tcp)) {
1293		int i;
1294		printxval (sock_version, tcp->u_arg[0], "__NETLIB_???");
1295		tprintf(", ");
1296		--tcp->u_nargs;
1297		for (i = 0; i < tcp->u_nargs; i++)
1298			tcp->u_arg[i] = tcp->u_arg[i + 1];
1299		return func (tcp);
1300
1301	}
1302
1303	return func (tcp);
1304}
1305
1306int
1307sys_xsocket(tcp)
1308struct tcb *tcp;
1309{
1310	return netlib_call (tcp, sys_socket);
1311}
1312
1313int
1314sys_xsocketpair(tcp)
1315struct tcb *tcp;
1316{
1317	return netlib_call (tcp, sys_socketpair);
1318}
1319
1320int
1321sys_xbind(tcp)
1322struct tcb *tcp;
1323{
1324	return netlib_call (tcp, sys_bind);
1325}
1326
1327int
1328sys_xconnect(tcp)
1329struct tcb *tcp;
1330{
1331	return netlib_call (tcp, sys_connect);
1332}
1333
1334int
1335sys_xlisten(tcp)
1336struct tcb *tcp;
1337{
1338	return netlib_call (tcp, sys_listen);
1339}
1340
1341int
1342sys_xaccept(tcp)
1343struct tcb *tcp;
1344{
1345	return netlib_call (tcp, sys_accept);
1346}
1347
1348int
1349sys_xsendmsg(tcp)
1350struct tcb *tcp;
1351{
1352	return netlib_call (tcp, sys_sendmsg);
1353}
1354
1355int
1356sys_xrecvmsg(tcp)
1357struct tcb *tcp;
1358{
1359	return netlib_call (tcp, sys_recvmsg);
1360}
1361
1362int
1363sys_xgetsockaddr(tcp)
1364struct tcb *tcp;
1365{
1366	if (entering(tcp)) {
1367		printxval (sock_version, tcp->u_arg[0], "__NETLIB_???");
1368		tprintf(", ");
1369		if (tcp->u_arg[1] == 0) {
1370			tprintf ("LOCALNAME, ");
1371		}
1372		else if (tcp->u_arg[1] == 1) {
1373			tprintf ("REMOTENAME, ");
1374		}
1375		else {
1376			tprintf ("%ld, ", tcp->u_arg [1]);
1377		}
1378		tprintf ("%ld, ", tcp->u_arg [2]);
1379	}
1380	else {
1381		if (tcp->u_arg[3] == 0 || syserror(tcp)) {
1382			tprintf("%#lx", tcp->u_arg[3]);
1383		} else {
1384			printsock(tcp, tcp->u_arg[3], tcp->u_arg[4]);
1385		}
1386		tprintf(", ");
1387		printnum(tcp, tcp->u_arg[4], "%lu");
1388	}
1389
1390	return 0;
1391
1392}
1393
1394#if 0
1395
1396int
1397sys_xsetsockaddr(tcp)
1398struct tcb *tcp;
1399{
1400	return netlib_call (tcp, sys_setsockaddr);
1401}
1402
1403#endif
1404
1405int
1406sys_xgetsockopt(tcp)
1407struct tcb *tcp;
1408{
1409	return netlib_call (tcp, sys_getsockopt);
1410}
1411
1412int
1413sys_xsetsockopt(tcp)
1414struct tcb *tcp;
1415{
1416	return netlib_call (tcp, sys_setsockopt);
1417}
1418
1419int
1420sys_xshutdown(tcp)
1421struct tcb *tcp;
1422{
1423	return netlib_call (tcp, sys_shutdown);
1424}
1425
1426#endif
1427