]> granicus.if.org Git - strace/blob - net.c
Only compile IPX-support in net.c for Linux
[strace] / net.c
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  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  *      $Id$
30  */
31
32 #include "defs.h"
33
34 #include <sys/stat.h>
35 #include <sys/socket.h>
36 #include <sys/un.h>
37 #include <netinet/in.h>
38 #include <arpa/inet.h>
39 #if defined(LINUX)
40 #include <asm/types.h>
41 #if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC__ + __GLIBC_MINOR__ >= 3)
42 #  include <netipx/ipx.h>
43 #else
44 #  include <linux/ipx.h>
45 #endif
46 #endif /* LINUX */
47
48 #ifndef PF_UNSPEC
49 #define PF_UNSPEC AF_UNSPEC
50 #endif
51
52 #ifdef LINUX
53 /* Under Linux these are enums so we can't test for them with ifdef. */
54 #define IPPROTO_EGP IPPROTO_EGP
55 #define IPPROTO_PUP IPPROTO_PUP
56 #define IPPROTO_IDP IPPROTO_IDP
57 #define IPPROTO_IGMP IPPROTO_IGMP
58 #define IPPROTO_RAW IPPROTO_RAW
59 #define IPPROTO_MAX IPPROTO_MAX
60 #endif
61
62 static struct xlat domains[] = {
63         { PF_UNSPEC,    "PF_UNSPEC"     },
64         { PF_UNIX,      "PF_UNIX"       },
65         { PF_INET,      "PF_INET"       },
66 #ifdef PF_LOCAL
67         { PF_LOCAL,     "PS_LOCAL"      },
68 #endif
69 #ifdef PF_ISO
70         { PF_ISO,       "PF_ISO"        },
71 #endif
72 #ifdef PF_AX25
73         { PF_AX25,      "PF_AX25"       },
74 #endif
75 #ifdef PF_IPX
76         { PF_IPX,       "PF_IPX"        },
77 #endif
78 #ifdef PF_APPLETALK
79         { PF_APPLETALK, "PF_APPLETALK"  },
80 #endif
81 #ifdef PF_NETROM
82         { PF_NETROM,    "PF_NETROM"     },
83 #endif
84 #ifdef PF_BRIDGE
85         { PF_BRIDGE,    "PF_BRIDGE"     },
86 #endif
87 #ifdef PF_AAL5
88         { PF_AAL5,      "PF_AAL5"       },
89 #endif
90 #ifdef PF_X25
91         { PF_X25,       "PF_X25"        },
92 #endif
93 #ifdef PF_INET6
94         { PF_INET6,     "PF_INET6"      },
95 #endif
96 #ifdef PF_ROSE
97         { PF_ROSE,      "PF_ROSE"       },
98 #endif
99 #ifdef PF_DECNET
100         { PF_DECNET,    "PF_DECNET"     },
101 #endif
102 #ifdef PF_NETBEUI
103         { PF_NETBEUI,   "PF_NETBEUI"    },
104 #endif
105 #ifdef PF_IMPLINK
106         { PF_IMPLINK,   "PF_IMPLINK"    },
107 #endif
108         { 0,            NULL            },
109 };
110 static struct xlat socktypes[] = {
111         { SOCK_STREAM,  "SOCK_STREAM"   },
112         { SOCK_DGRAM,   "SOCK_DGRAM"    },
113 #ifdef SOCK_RAW
114         { SOCK_RAW,     "SOCK_RAW"      },
115 #endif
116 #ifdef SOCK_SEQPACKET
117         { SOCK_SEQPACKET,"SOCK_SEQPACKET"},
118 #endif
119 #ifdef SOCK_RDM
120         { SOCK_RDM,     "SOCK_RDM"      },
121 #endif
122 #ifdef SOCK_PACKET
123         { SOCK_PACKET,  "SOCK_PACKET"   },
124 #endif
125         { 0,            NULL            },
126 };
127 static struct xlat protocols[] = {
128         { IPPROTO_IP,   "IPPROTO_IP"    },
129         { IPPROTO_ICMP, "IPPROTO_ICMP"  },
130         { IPPROTO_TCP,  "IPPROTO_TCP"   },
131         { IPPROTO_UDP,  "IPPROTO_UDP"   },
132 #ifdef IPPROTO_GGP
133         { IPPROTO_GGP,  "IPPROTO_GGP"   },
134 #endif
135 #ifdef IPPROTO_EGP
136         { IPPROTO_EGP,  "IPPROTO_EGP"   },
137 #endif
138 #ifdef IPPROTO_PUP
139         { IPPROTO_PUP,  "IPPROTO_PUP"   },
140 #endif
141 #ifdef IPPROTO_IDP
142         { IPPROTO_IDP,  "IPPROTO_IDP"   },
143 #endif
144 #ifdef IPPROTO_IPV6
145         { IPPROTO_IPV6, "IPPROTO_IPV6"  },
146 #endif
147 #ifdef IPPROTO_ICMPV6
148         { IPPROTO_ICMPV6,"IPPROTO_ICMPV6"},
149 #endif
150 #ifdef IPPROTO_IGMP
151         { IPPROTO_IGMP, "IPPROTO_IGMP"  },
152 #endif
153 #ifdef IPPROTO_HELLO
154         { IPPROTO_HELLO,"IPPROTO_HELLO" },
155 #endif
156 #ifdef IPPROTO_ND
157         { IPPROTO_ND,   "IPPROTO_ND"    },
158 #endif
159 #ifdef IPPROTO_RAW
160         { IPPROTO_RAW,  "IPPROTO_RAW"   },
161 #endif
162 #ifdef IPPROTO_MAX
163         { IPPROTO_MAX,  "IPPROTO_MAX"   },
164 #endif
165 #ifdef IPPROTO_IPIP
166         { IPPROTO_IPIP, "IPPROTO_IPIP"  },
167 #endif
168         { 0,            NULL            },
169 };
170 static struct xlat msg_flags[] = {
171         { MSG_OOB,      "MSG_OOB"       },
172 #ifdef MSG_DONTROUTE
173         { MSG_DONTROUTE,"MSG_DONTROUTE" },
174 #endif
175 #ifdef MSG_PEEK
176         { MSG_PEEK,     "MSG_PEEK"      },
177 #endif
178 #ifdef MSG_CTRUNC
179         { MSG_CTRUNC,   "MSG_CTRUNC"    },
180 #endif
181 #ifdef MSG_PROXY
182         { MSG_PROXY,    "MSG_PROXY"     },
183 #endif
184 #ifdef MSG_EOR
185         { MSG_EOR,      "MSG_EOR"       },
186 #endif
187 #ifdef MSG_WAITALL
188         { MSG_WAITALL,  "MSG_WAITALL"   },
189 #endif
190         { 0,            NULL            },
191 };
192
193 static struct xlat sockoptions[] = {
194 #ifdef SO_DEBUG
195         { SO_DEBUG,     "SO_DEBUG"      },
196 #endif
197 #ifdef SO_REUSEADDR
198         { SO_REUSEADDR, "SO_REUSEADDR"  },
199 #endif
200 #ifdef SO_KEEPALIVE
201         { SO_KEEPALIVE, "SO_KEEPALIVE"  },
202 #endif
203 #ifdef SO_DONTROUTE
204         { SO_DONTROUTE, "SO_DONTROUTE"  },
205 #endif
206 #ifdef SO_BROADCAST
207         { SO_BROADCAST, "SO_BROADCAST"  },
208 #endif
209 #ifdef SO_LINGER
210         { SO_LINGER,    "SO_LINGER"     },
211 #endif
212 #ifdef SO_OOBINLINE
213         { SO_OOBINLINE, "SO_OOBINLINE"  },
214 #endif
215 #ifdef SO_TYPE
216         { SO_TYPE,      "SO_TYPE"       },
217 #endif
218 #ifdef SO_ERROR
219         { SO_ERROR,     "SO_ERROR"      },
220 #endif
221 #ifdef SO_SNDBUF
222         { SO_SNDBUF,    "SO_SNDBUF"     },
223 #endif
224 #ifdef SO_RCVBUF
225         { SO_RCVBUF,    "SO_RCVBUF"     },
226 #endif
227 #ifdef SO_NO_CHECK
228         { SO_NO_CHECK,  "SO_NO_CHECK"   },
229 #endif
230 #ifdef SO_PRIORITY
231         { SO_PRIORITY,  "SO_PRIORITY"   },
232 #endif
233 #ifdef SO_ACCEPTCONN
234         { SO_ACCEPTCONN,"SO_ACCEPTCONN" },
235 #endif
236 #ifdef SO_USELOOPBACK
237         { SO_USELOOPBACK,"SO_USELOOPBACK"},
238 #endif
239 #ifdef SO_SNDLOWAT
240         { SO_SNDLOWAT,  "SO_SNDLOWAT"   },
241 #endif
242 #ifdef SO_RCVLOWAT
243         { SO_RCVLOWAT,  "SO_RCVLOWAT"   },
244 #endif
245 #ifdef SO_SNDTIMEO
246         { SO_SNDTIMEO,  "SO_SNDTIMEO"   },
247 #endif
248 #ifdef SO_RCVTIMEO
249         { SO_RCVTIMEO,  "SO_RCVTIMEO"   },
250 #endif
251 #ifdef SO_BSDCOMPAT
252         { SO_BSDCOMPAT, "SO_BSDCOMPAT"  },
253 #endif
254 #ifdef SO_REUSEPORT
255         { SO_REUSEPORT, "SO_REUSEPORT"  },
256 #endif
257 #ifdef SO_RCVLOWAT
258         { SO_RCVLOWAT, "SO_RCVLOWAT"    },
259 #endif
260 #ifdef SO_SNDLOWAT
261         { SO_SNDLOWAT, "SO_SNDLOWAT"    },
262 #endif
263 #ifdef SO_RCVTIMEO
264         { SO_RCVTIMEO, "SO_RCVTIMEO"    },
265 #endif
266 #ifdef SO_SNDTIMEO
267         { SO_SNDTIMEO, "SO_SNDTIMEO"    },
268 #endif
269         { 0,            NULL            },
270 };
271
272 #ifdef SOL_IP
273 static struct xlat sockipoptions[] = {
274         { IP_TOS,       "IP_TOS"        },
275         { IP_TTL,       "IP_TTL"        },
276 #if defined(IP_HDRINCL)
277         { IP_HDRINCL,   "IP_HDRINCL"    },
278 #endif
279 #if defined(IP_OPTIONS)
280         { IP_OPTIONS,   "IP_OPTIONS"    },
281 #endif
282         { IP_MULTICAST_IF,      "IP_MULTICAST_IF"       },
283         { IP_MULTICAST_TTL,     "IP_MULTICAST_TTL"      },
284         { IP_MULTICAST_LOOP,    "IP_MULTICAST_LOOP"     },
285         { IP_ADD_MEMBERSHIP,    "IP_ADD_MEMBERSHIP"     },
286         { IP_DROP_MEMBERSHIP,   "IP_DROP_MEMBERSHIP"    },
287         { 0,            NULL            },
288 };
289 #endif /* SOL_IP */
290
291 #ifdef SOL_IPX
292 static struct xlat sockipxoptions[] = {
293         { IPX_TYPE,     "IPX_TYPE"      },
294         { 0,            NULL            },
295 };
296 #endif /* SOL_IPX */
297
298 #ifdef SOL_TCP
299 static struct xlat socktcpoptions[] = {
300         { TCP_NODELAY,  "TCP_NODELAY"   },
301         { TCP_MAXSEG,   "TCP_MAXSEG"    },
302         { 0,            NULL            },
303 };
304 #endif /* SOL_TCP */
305
306 void
307 printsock(tcp, addr)
308 struct tcb *tcp;
309 long addr;
310 {
311         struct sockaddr sa;
312         struct sockaddr_in *sin = (struct sockaddr_in *) &sa;
313         struct sockaddr_un sau;
314 #ifdef LINUX
315         struct sockaddr_ipx sipx;
316 #endif
317
318         if (addr == 0) {
319                 tprintf("NULL");
320                 return;
321         }
322         if (!verbose(tcp)) {
323                 tprintf("%#lx", addr);
324                 return;
325         }
326         if (umove(tcp, addr, &sa) < 0) {
327                 tprintf("{...}");
328                 return;
329         }
330         switch (sa.sa_family) {
331         case AF_UNIX:
332                 if (umove(tcp, addr, &sau) < 0)
333                         tprintf("{sun_family=AF_UNIX, ...}");
334                 else
335                         tprintf("{sun_family=AF_UNIX, sun_path=\"%s\"}",
336                                 sau.sun_path);
337                 break;
338         case AF_INET:
339                 tprintf("{sin_family=AF_INET, ");
340                 tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")}",
341                         ntohs(sin->sin_port), inet_ntoa(sin->sin_addr));
342                 break;
343 #if defined(AF_IPX) && defined(linux)
344         case AF_IPX:
345                 if (umove(tcp, addr, &sipx)<0)
346                         tprintf("{sipx_family=AF_IPX, ...}");
347                 else {
348                         int i;
349                         tprintf("{sipx_family=AF_IPX, ");
350                         tprintf("{sipx_port=htons(%u), ",
351                                 ntohs(sipx.sipx_port));
352                         /* Yes, I know, this does not look too
353                          * strace-ish, but otherwise the IPX
354                          * addresses just look monstrous...
355                          * Anyways, feel free if you don't like
356                          * this way.. :) 
357                          */
358                         tprintf("%08lx:", (unsigned long)ntohl(sipx.sipx_network));
359                         for (i = 0; i<IPX_NODE_LEN; i++)
360                                 tprintf("%02x", sipx.sipx_node[i]);
361                         tprintf("/[%02x]", sipx.sipx_type);
362                         tprintf("}");
363                 }
364                 break;
365 #endif /* AF_IPX  && linux */
366         /* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
367         AF_X25 AF_INET6 AF_ROSE still need to be done */
368
369         default:
370                 tprintf("{sa_family=%u, sa_data=", sa.sa_family);
371                 printstr(tcp, (long) &((struct sockaddr *) addr)->sa_data,
372                         sizeof sa.sa_data);
373                 tprintf("}");
374                 break;
375         }
376 }
377
378 #if HAVE_SENDMSG
379
380 static void
381 printmsghdr(tcp, addr)
382 struct tcb *tcp;
383 long addr;
384 {
385         struct msghdr msg;
386
387         if (umove(tcp, addr, &msg) < 0) {
388                 tprintf("%#lx", addr);
389                 return;
390         }
391         tprintf("{msg_name=");
392         printstr(tcp, (long) msg.msg_name, msg.msg_namelen);
393         tprintf(", msg_namelen=%u, msg_iov=%#lx, msg_iovlen=%u, ",
394                 msg.msg_namelen,
395                 (unsigned long) msg.msg_iov, msg.msg_iovlen);
396 #ifdef HAVE_MSG_CONTROL
397         tprintf("msg_control=%#lx, msg_controllen=%u, msg_flags=%#x}",
398                 (unsigned long) msg.msg_control, msg.msg_controllen,
399                 msg.msg_flags);
400 #else /* !HAVE_MSG_CONTROL */
401         tprintf("msg_accrights=%#lx, msg_accrightslen=%u}",
402                 (unsigned long) msg.msg_accrights, msg.msg_accrightslen);
403 #endif /* !HAVE_MSG_CONTROL */
404 }
405
406 #endif /* HAVE_SENDMSG */
407
408 int
409 sys_socket(tcp)
410 struct tcb *tcp;
411 {
412         if (entering(tcp)) {
413                 printxval(domains, tcp->u_arg[0], "PF_???");
414                 tprintf(", ");
415                 printxval(socktypes, tcp->u_arg[1], "SOCK_???");
416                 tprintf(", ");
417                 switch (tcp->u_arg[0]) {
418                 case PF_INET:
419                         printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
420                         break;
421 #ifdef PF_IPX
422                 case PF_IPX:
423                         /* BTW: I don't believe this.. */
424                         tprintf("[");
425                         printxval(domains, tcp->u_arg[2], "PF_???");
426                         tprintf("]");
427                         break;
428 #endif /* PF_IPX */
429                 default:
430                         tprintf("%lu", tcp->u_arg[2]);
431                         break;
432                 }
433         }
434         return 0;
435 }
436
437 int
438 sys_bind(tcp)
439 struct tcb *tcp;
440 {
441         if (entering(tcp)) {
442                 tprintf("%ld, ", tcp->u_arg[0]);
443                 printsock(tcp, tcp->u_arg[1]);
444                 tprintf(", %lu", tcp->u_arg[2]);
445         }
446         return 0;
447 }
448
449 int
450 sys_connect(tcp)
451 struct tcb *tcp;
452 {
453         return sys_bind(tcp);
454 }
455
456 int
457 sys_listen(tcp)
458 struct tcb *tcp;
459 {
460         if (entering(tcp)) {
461                 tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]);
462         }
463         return 0;
464 }
465
466 int
467 sys_accept(tcp)
468 struct tcb *tcp;
469 {
470         if (entering(tcp)) {
471                 tprintf("%ld, ", tcp->u_arg[0]);
472         } else if (!tcp->u_arg[2])
473                 tprintf("%#lx, NULL", tcp->u_arg[1]);
474         else {
475                 if (tcp->u_arg[1] == 0 || syserror(tcp)) {
476                         tprintf("%#lx", tcp->u_arg[1]);
477                 } else {
478                         printsock(tcp, tcp->u_arg[1]);
479                 }
480                 tprintf(", ");
481                 printnum(tcp, tcp->u_arg[2], "%lu");
482         }
483         return 0;
484 }
485
486 int
487 sys_send(tcp)
488 struct tcb *tcp;
489 {
490         if (entering(tcp)) {
491                 tprintf("%ld, ", tcp->u_arg[0]);
492                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
493                 tprintf(", %lu, ", tcp->u_arg[2]);
494                 /* flags */
495                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
496                         tprintf("0");
497         }
498         return 0;
499 }
500
501 int
502 sys_sendto(tcp)
503 struct tcb *tcp;
504 {
505         if (entering(tcp)) {
506                 tprintf("%ld, ", tcp->u_arg[0]);
507                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
508                 tprintf(", %lu, ", tcp->u_arg[2]);
509                 /* flags */
510                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
511                         tprintf("0");
512                 /* to address */
513                 tprintf(", ");
514                 printsock(tcp, tcp->u_arg[4]);
515                 /* to length */
516                 tprintf(", %lu", tcp->u_arg[5]);
517         }
518         return 0;
519 }
520
521 #ifdef HAVE_SENDMSG
522
523 int
524 sys_sendmsg(tcp)
525 struct tcb *tcp;
526 {
527         if (entering(tcp)) {
528                 tprintf("%ld, ", tcp->u_arg[0]);
529                 printmsghdr(tcp, tcp->u_arg[1]);
530                 /* flags */
531                 tprintf(", ");
532                 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
533                         tprintf("0");
534         }
535         return 0;
536 }
537
538 #endif /* HAVE_SENDMSG */
539
540 int
541 sys_recv(tcp)
542 struct tcb *tcp;
543 {
544         if (entering(tcp)) {
545                 tprintf("%ld, ", tcp->u_arg[0]);
546         } else {
547                 if (syserror(tcp))
548                         tprintf("%#lx", tcp->u_arg[1]);
549                 else
550                         printstr(tcp, tcp->u_arg[1], tcp->u_rval);
551
552                 tprintf(", %lu, ", tcp->u_arg[2]);
553                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
554                         tprintf("0");
555         }
556         return 0;
557 }
558
559 int
560 sys_recvfrom(tcp)
561 struct tcb *tcp;
562 {
563         int fromlen;
564
565         if (entering(tcp)) {
566                 tprintf("%ld, ", tcp->u_arg[0]);
567         } else {
568                 if (syserror(tcp)) {
569                         tprintf("%#lx, %lu, %lu, %#lx, %#lx",
570                                 tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3],
571                                 tcp->u_arg[4], tcp->u_arg[5]);
572                         return 0;
573                 }
574                 /* buf */
575                 printstr(tcp, tcp->u_arg[1], tcp->u_rval);
576                 /* len */
577                 tprintf(", %lu, ", tcp->u_arg[2]);
578                 /* flags */
579                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
580                         tprintf("0");
581                 /* from address, len */
582                 if (!tcp->u_arg[4] || !tcp->u_arg[5]) {
583                         if (tcp->u_arg[4] == 0)
584                                 tprintf(", NULL");
585                         else
586                                 tprintf(", %#lx", tcp->u_arg[4]);
587                         if (tcp->u_arg[5] == 0)
588                                 tprintf(", NULL");
589                         else
590                                 tprintf(", %#lx", tcp->u_arg[5]);
591                         return 0;
592                 }
593                 if (umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
594                         tprintf(", {...}, [?]");
595                         return 0;
596                 }
597                 tprintf(", ");
598                 printsock(tcp, tcp->u_arg[4]);
599                 /* from length */
600                 tprintf(", [%u]", fromlen);
601         }
602         return 0;
603 }
604
605 #ifdef HAVE_SENDMSG
606
607 int
608 sys_recvmsg(tcp)
609 struct tcb *tcp;
610 {
611         if (entering(tcp)) {
612                 tprintf("%ld, ", tcp->u_arg[0]);
613         } else {
614                 if (syserror(tcp) || !verbose(tcp))
615                         tprintf("%#lx", tcp->u_arg[1]);
616                 else
617                         printmsghdr(tcp, tcp->u_arg[1]);
618                 /* flags */
619                 tprintf(", ");
620                 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
621                         tprintf("0");
622         }
623         return 0;
624 }
625
626 #endif /* HAVE_SENDMSG */
627
628 int
629 sys_shutdown(tcp)
630 struct tcb *tcp;
631 {
632         if (entering(tcp)) {
633                 tprintf("%ld, %ld", tcp->u_arg[0], tcp->u_arg[1]);
634                 switch (tcp->u_arg[1]) {
635                 case 0:
636                         tprintf("%s", " /* receive */");
637                         break;
638                 case 1:
639                         tprintf("%s", " /* send */");
640                         break;
641                 case 2:
642                         tprintf("%s", " /* send and receive */");
643                         break;
644                 }
645         }
646         return 0;
647 }
648
649 int
650 sys_getsockname(tcp)
651 struct tcb *tcp;
652 {
653         return sys_accept(tcp);
654 }
655
656 int
657 sys_getpeername(tcp)
658 struct tcb *tcp;
659 {
660         return sys_accept(tcp);
661 }
662
663 int
664 sys_pipe(tcp)
665 struct tcb *tcp;
666 {
667
668 #if defined(LINUX) && !defined(SPARC)
669         int fds[2];
670
671         if (exiting(tcp)) {
672                 if (syserror(tcp)) {
673                         tprintf("%#lx", tcp->u_arg[0]);
674                         return 0;
675                 }
676                 if (umoven(tcp, tcp->u_arg[0], sizeof fds, (char *) fds) < 0)
677                         tprintf("[...]");
678                 else
679                         tprintf("[%u, %u]", fds[0], fds[1]);
680         }
681 #elif defined(SPARC) || defined(SVR4)
682         if (exiting(tcp))
683                 tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
684 #endif
685         return 0;
686 }
687
688 int
689 sys_socketpair(tcp)
690 struct tcb *tcp;
691 {
692 #ifdef LINUX
693         int fds[2];
694 #endif
695
696         if (entering(tcp)) {
697                 printxval(domains, tcp->u_arg[0], "PF_???");
698                 tprintf(", ");
699                 printxval(socktypes, tcp->u_arg[1], "SOCK_???");
700                 tprintf(", ");
701                 switch (tcp->u_arg[0]) {
702                 case PF_INET:
703                         printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
704                         break;
705 #ifdef PF_IPX
706                 case PF_IPX:
707                         /* BTW: I don't believe this.. */
708                         tprintf("[");
709                         printxval(domains, tcp->u_arg[2], "PF_???");
710                         tprintf("]");
711                         break;
712 #endif /* PF_IPX */
713                 default:        
714                         tprintf("%lu", tcp->u_arg[2]);
715                         break;
716                 }
717         } else {
718                 if (syserror(tcp)) {
719                         tprintf(", %#lx", tcp->u_arg[3]);
720                         return 0;
721                 }
722 #ifdef LINUX
723                 if (umoven(tcp, tcp->u_arg[3], sizeof fds, (char *) fds) < 0)
724                         tprintf(", [...]");
725                 else
726                         tprintf(", [%u, %u]", fds[0], fds[1]);
727 #endif /* LINUX */
728 #ifdef SUNOS4
729                 tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
730 #endif /* SUNOS4 */
731 #ifdef SVR4
732                 tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
733 #endif /* SVR4 */
734         }
735         return 0;
736 }
737
738 int
739 sys_getsockopt(tcp)
740 struct tcb *tcp;
741 {
742         if (entering(tcp)) {
743                 tprintf("%ld, ", tcp->u_arg[0]);
744                 switch (tcp->u_arg[1]) {
745                 case SOL_SOCKET:
746                         tprintf("SOL_SOCKET, ");
747                         printxval(sockoptions, tcp->u_arg[2], "SO_???");
748                         tprintf(", ");
749                         break;
750 #ifdef SOL_IP
751                 case SOL_IP:
752                         tprintf("SOL_IP, ");
753                         printxval(sockipoptions, tcp->u_arg[2], "IP_???");
754                         tprintf(", ");
755                         break;
756 #endif
757 #ifdef SOL_IPX
758                 case SOL_IPX:
759                         tprintf("SOL_IPX, ");
760                         printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
761                         tprintf(", ");
762                         break;
763 #endif
764 #ifdef SOL_TCP
765                 case SOL_TCP:
766                         tprintf("SOL_TCP, ");
767                         printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
768                         tprintf(", ");
769                         break;
770 #endif
771
772                 /* SOL_AX25 SOL_ROSE SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
773                  * etc. still need work */
774                 default: 
775                         /* XXX - should know socket family here */
776                         printxval(protocols, tcp->u_arg[1], "IPPROTO_???");
777                         tprintf("%lu, ", tcp->u_arg[2]);
778                         break;
779                 }
780         } else {
781                 if (syserror(tcp)) {
782                         tprintf("%#lx, %#lx",
783                                 tcp->u_arg[3], tcp->u_arg[4]);
784                         return 0;
785                 }
786                 printnum(tcp, tcp->u_arg[3], "%ld");
787                 tprintf(", ");
788                 printnum(tcp, tcp->u_arg[4], "%ld");
789         }
790         return 0;
791 }
792
793 int
794 sys_setsockopt(tcp)
795 struct tcb *tcp;
796 {
797         if (entering(tcp)) {
798                 tprintf("%ld, ", tcp->u_arg[0]);
799                 switch (tcp->u_arg[1]) {
800                 case SOL_SOCKET:
801                         tprintf("SOL_SOCKET, ");
802                         printxval(sockoptions, tcp->u_arg[2], "SO_???");
803                         tprintf(", ");
804                         break;
805 #ifdef SOL_IP
806                 case SOL_IP:
807                         tprintf("SOL_IP, ");
808                         printxval(sockipoptions, tcp->u_arg[2], "IP_???");
809                         tprintf(", ");
810                         break;
811 #endif
812 #ifdef SOL_IPX
813                 case SOL_IPX:
814                         tprintf("SOL_IPX, ");
815                         printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
816                         tprintf(", ");
817                         break;
818 #endif
819 #ifdef SOL_TCP
820                 case SOL_TCP:
821                         tprintf("SOL_TCP, ");
822                         printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
823                         tprintf(", ");
824                         break;
825 #endif
826
827                 /* SOL_AX25 SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25 
828                  * etc. still need work  */
829                 default:
830                         /* XXX - should know socket family here */
831                         printxval(protocols, tcp->u_arg[1], "IPPROTO_???");
832                         tprintf("%lu, ", tcp->u_arg[2]);
833                         break;
834                 }
835                 printnum(tcp, tcp->u_arg[3], "%ld");
836                 tprintf(", %lu", tcp->u_arg[4]);
837         }
838         return 0;
839 }