]> granicus.if.org Git - strace/blob - net.c
Bunch of stuff
[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  * Copyright (c) 1996-1999 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 #include <netinet/in.h>
39 #include <arpa/inet.h>
40 #if defined(LINUX)
41 #include <asm/types.h>
42 #if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC__ + __GLIBC_MINOR__ >= 3)
43 #  include <netipx/ipx.h>
44 #else
45 #  include <linux/ipx.h>
46 #endif
47 #endif /* LINUX */
48
49 #if defined (__GLIBC__) && ((__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1))
50 #if defined(HAVE_LINUX_IN6_H)
51 #include <linux/in6.h>
52 #endif
53 #endif
54
55 #if defined(HAVE_SYS_UIO_H)
56 #include <sys/uio.h>
57 #endif
58
59 #if defined(HAVE_LINUX_NETLINK_H)
60 #include <linux/netlink.h>
61 #endif
62
63 #if defined(HAVE_LINUX_IF_PACKET_H)
64 #include <linux/if_packet.h>
65 #endif
66
67 #ifndef PF_UNSPEC
68 #define PF_UNSPEC AF_UNSPEC
69 #endif
70
71 #ifdef LINUX
72 /* Under Linux these are enums so we can't test for them with ifdef. */
73 #define IPPROTO_EGP IPPROTO_EGP
74 #define IPPROTO_PUP IPPROTO_PUP
75 #define IPPROTO_IDP IPPROTO_IDP
76 #define IPPROTO_IGMP IPPROTO_IGMP
77 #define IPPROTO_RAW IPPROTO_RAW
78 #define IPPROTO_MAX IPPROTO_MAX
79 #endif
80
81 static struct xlat domains[] = {
82         { PF_UNSPEC,    "PF_UNSPEC"     },
83         { PF_UNIX,      "PF_UNIX"       },
84         { PF_INET,      "PF_INET"       },
85 #ifdef PF_NETLINK
86         { PF_NETLINK,   "PF_NETLINK"    },
87 #endif
88 #ifdef PF_PACKET
89         { PF_PACKET,    "PF_PACKET"     },
90 #endif
91 #ifdef PF_INET6
92         { PF_INET6,     "PF_INET6"      },
93 #endif
94 #ifdef PF_ATMSVC
95         { PF_ATMSVC,    "PF_INET6"      },
96 #endif
97 #ifdef PF_INET6
98         { PF_INET6,     "PF_INET6"      },
99 #endif
100 #ifdef PF_LOCAL
101         { PF_LOCAL,     "PS_LOCAL"      },
102 #endif
103 #ifdef PF_ISO
104         { PF_ISO,       "PF_ISO"        },
105 #endif
106 #ifdef PF_AX25
107         { PF_AX25,      "PF_AX25"       },
108 #endif
109 #ifdef PF_IPX
110         { PF_IPX,       "PF_IPX"        },
111 #endif
112 #ifdef PF_APPLETALK
113         { PF_APPLETALK, "PF_APPLETALK"  },
114 #endif
115 #ifdef PF_NETROM
116         { PF_NETROM,    "PF_NETROM"     },
117 #endif
118 #ifdef PF_BRIDGE
119         { PF_BRIDGE,    "PF_BRIDGE"     },
120 #endif
121 #ifdef PF_AAL5
122         { PF_AAL5,      "PF_AAL5"       },
123 #endif
124 #ifdef PF_X25
125         { PF_X25,       "PF_X25"        },
126 #endif
127 #ifdef PF_ROSE
128         { PF_ROSE,      "PF_ROSE"       },
129 #endif
130 #ifdef PF_DECNET
131         { PF_DECNET,    "PF_DECNET"     },
132 #endif
133 #ifdef PF_NETBEUI
134         { PF_NETBEUI,   "PF_NETBEUI"    },
135 #endif
136 #ifdef PF_IMPLINK
137         { PF_IMPLINK,   "PF_IMPLINK"    },
138 #endif
139         { 0,            NULL            },
140 };
141 static struct xlat addrfams[] = {
142         { AF_UNSPEC,    "AF_UNSPEC"     },
143         { AF_UNIX,      "AF_UNIX"       },
144         { AF_INET,      "AF_INET"       },
145 #ifdef AF_INET6
146         { AF_INET6,     "AF_INET6"      },
147 #endif
148         { AF_DECnet,    "AF_DECnet"     },
149 #ifdef PF_ATMSVC
150         { AF_ATMSVC,    "AF_ATMSVC"     },
151 #endif
152 #ifdef AF_PACKET
153         { AF_PACKET,    "AF_PACKET"     },
154 #endif
155 #ifdef AF_NETLINK
156         { AF_NETLINK,   "AF_NETLINK"    },
157 #endif
158 #ifdef AF_ISO
159         { AF_ISO,       "AF_ISO"        },
160 #endif
161 #ifdef AF_IMPLINK
162         { AF_IMPLINK,   "AF_IMPLINK"    },
163 #endif
164         { 0,            NULL            },
165 };
166 static struct xlat socktypes[] = {
167         { SOCK_STREAM,  "SOCK_STREAM"   },
168         { SOCK_DGRAM,   "SOCK_DGRAM"    },
169 #ifdef SOCK_RAW
170         { SOCK_RAW,     "SOCK_RAW"      },
171 #endif
172 #ifdef SOCK_SEQPACKET
173         { SOCK_SEQPACKET,"SOCK_SEQPACKET"},
174 #endif
175 #ifdef SOCK_RDM
176         { SOCK_RDM,     "SOCK_RDM"      },
177 #endif
178 #ifdef SOCK_PACKET
179         { SOCK_PACKET,  "SOCK_PACKET"   },
180 #endif
181         { 0,            NULL            },
182 };
183 static struct xlat protocols[] = {
184         { IPPROTO_IP,   "IPPROTO_IP"    },
185         { IPPROTO_ICMP, "IPPROTO_ICMP"  },
186         { IPPROTO_TCP,  "IPPROTO_TCP"   },
187         { IPPROTO_UDP,  "IPPROTO_UDP"   },
188 #ifdef IPPROTO_GGP
189         { IPPROTO_GGP,  "IPPROTO_GGP"   },
190 #endif
191 #ifdef IPPROTO_EGP
192         { IPPROTO_EGP,  "IPPROTO_EGP"   },
193 #endif
194 #ifdef IPPROTO_PUP
195         { IPPROTO_PUP,  "IPPROTO_PUP"   },
196 #endif
197 #ifdef IPPROTO_IDP
198         { IPPROTO_IDP,  "IPPROTO_IDP"   },
199 #endif
200 #ifdef IPPROTO_IPV6
201         { IPPROTO_IPV6, "IPPROTO_IPV6"  },
202 #endif
203 #ifdef IPPROTO_ICMPV6
204         { IPPROTO_ICMPV6,"IPPROTO_ICMPV6"},
205 #endif
206 #ifdef IPPROTO_IGMP
207         { IPPROTO_IGMP, "IPPROTO_IGMP"  },
208 #endif
209 #ifdef IPPROTO_HELLO
210         { IPPROTO_HELLO,"IPPROTO_HELLO" },
211 #endif
212 #ifdef IPPROTO_ND
213         { IPPROTO_ND,   "IPPROTO_ND"    },
214 #endif
215 #ifdef IPPROTO_RAW
216         { IPPROTO_RAW,  "IPPROTO_RAW"   },
217 #endif
218 #ifdef IPPROTO_MAX
219         { IPPROTO_MAX,  "IPPROTO_MAX"   },
220 #endif
221 #ifdef IPPROTO_IPIP
222         { IPPROTO_IPIP, "IPPROTO_IPIP"  },
223 #endif
224         { 0,            NULL            },
225 };
226 static struct xlat msg_flags[] = {
227         { MSG_OOB,      "MSG_OOB"       },
228 #ifdef MSG_DONTROUTE
229         { MSG_DONTROUTE,"MSG_DONTROUTE" },
230 #endif
231 #ifdef MSG_PEEK
232         { MSG_PEEK,     "MSG_PEEK"      },
233 #endif
234 #ifdef MSG_CTRUNC
235         { MSG_CTRUNC,   "MSG_CTRUNC"    },
236 #endif
237 #ifdef MSG_PROXY
238         { MSG_PROXY,    "MSG_PROXY"     },
239 #endif
240 #ifdef MSG_EOR
241         { MSG_EOR,      "MSG_EOR"       },
242 #endif
243 #ifdef MSG_WAITALL
244         { MSG_WAITALL,  "MSG_WAITALL"   },
245 #endif
246 #ifdef MSG_TRUNC
247         { MSG_TRUNC,    "MSG_TRUNC"     },
248 #endif
249 #ifdef MSG_CTRUNC
250         { MSG_CTRUNC,   "MSG_CTRUNC"    },
251 #endif
252 #ifdef MSG_ERRQUEUE
253         { MSG_ERRQUEUE, "MSG_ERRQUEUE"  },
254 #endif
255 #ifdef MSG_DONTWAIT
256         { MSG_DONTWAIT, "MSG_DONTWAIT"  },
257 #endif
258 #ifdef MSG_CONFIRM
259         { MSG_CONFIRM,  "MSG_CONFIRM"   },
260 #endif
261 #ifdef MSG_PROBE
262         { MSG_PROBE,    "MSG_PROBE"     },
263 #endif
264         { 0,            NULL            },
265 };
266
267 static struct xlat sockoptions[] = {
268 #ifdef SO_PEERCRED
269         { SO_PEERCRED,  "SO_PEERCRED"   },
270 #endif
271 #ifdef SO_PASSCRED
272         { SO_PASSCRED,  "SO_PASSCRED"   },
273 #endif
274 #ifdef SO_DEBUG
275         { SO_DEBUG,     "SO_DEBUG"      },
276 #endif
277 #ifdef SO_REUSEADDR
278         { SO_REUSEADDR, "SO_REUSEADDR"  },
279 #endif
280 #ifdef SO_KEEPALIVE
281         { SO_KEEPALIVE, "SO_KEEPALIVE"  },
282 #endif
283 #ifdef SO_DONTROUTE
284         { SO_DONTROUTE, "SO_DONTROUTE"  },
285 #endif
286 #ifdef SO_BROADCAST
287         { SO_BROADCAST, "SO_BROADCAST"  },
288 #endif
289 #ifdef SO_LINGER
290         { SO_LINGER,    "SO_LINGER"     },
291 #endif
292 #ifdef SO_OOBINLINE
293         { SO_OOBINLINE, "SO_OOBINLINE"  },
294 #endif
295 #ifdef SO_TYPE
296         { SO_TYPE,      "SO_TYPE"       },
297 #endif
298 #ifdef SO_ERROR
299         { SO_ERROR,     "SO_ERROR"      },
300 #endif
301 #ifdef SO_SNDBUF
302         { SO_SNDBUF,    "SO_SNDBUF"     },
303 #endif
304 #ifdef SO_RCVBUF
305         { SO_RCVBUF,    "SO_RCVBUF"     },
306 #endif
307 #ifdef SO_NO_CHECK
308         { SO_NO_CHECK,  "SO_NO_CHECK"   },
309 #endif
310 #ifdef SO_PRIORITY
311         { SO_PRIORITY,  "SO_PRIORITY"   },
312 #endif
313 #ifdef SO_ACCEPTCONN
314         { SO_ACCEPTCONN,"SO_ACCEPTCONN" },
315 #endif
316 #ifdef SO_USELOOPBACK
317         { SO_USELOOPBACK,"SO_USELOOPBACK"},
318 #endif
319 #ifdef SO_SNDLOWAT
320         { SO_SNDLOWAT,  "SO_SNDLOWAT"   },
321 #endif
322 #ifdef SO_RCVLOWAT
323         { SO_RCVLOWAT,  "SO_RCVLOWAT"   },
324 #endif
325 #ifdef SO_SNDTIMEO
326         { SO_SNDTIMEO,  "SO_SNDTIMEO"   },
327 #endif
328 #ifdef SO_RCVTIMEO
329         { SO_RCVTIMEO,  "SO_RCVTIMEO"   },
330 #endif
331 #ifdef SO_BSDCOMPAT
332         { SO_BSDCOMPAT, "SO_BSDCOMPAT"  },
333 #endif
334 #ifdef SO_REUSEPORT
335         { SO_REUSEPORT, "SO_REUSEPORT"  },
336 #endif
337 #ifdef SO_RCVLOWAT
338         { SO_RCVLOWAT, "SO_RCVLOWAT"    },
339 #endif
340 #ifdef SO_SNDLOWAT
341         { SO_SNDLOWAT, "SO_SNDLOWAT"    },
342 #endif
343 #ifdef SO_RCVTIMEO
344         { SO_RCVTIMEO, "SO_RCVTIMEO"    },
345 #endif
346 #ifdef SO_SNDTIMEO
347         { SO_SNDTIMEO, "SO_SNDTIMEO"    },
348 #endif
349         { 0,            NULL            },
350 };
351
352 #ifdef SOL_IP
353 static struct xlat sockipoptions[] = {
354         { IP_TOS,       "IP_TOS"        },
355         { IP_TTL,       "IP_TTL"        },
356 #if defined(IP_HDRINCL)
357         { IP_HDRINCL,   "IP_HDRINCL"    },
358 #endif
359 #if defined(IP_OPTIONS)
360         { IP_OPTIONS,   "IP_OPTIONS"    },
361 #endif
362         { IP_MULTICAST_IF,      "IP_MULTICAST_IF"       },
363         { IP_MULTICAST_TTL,     "IP_MULTICAST_TTL"      },
364         { IP_MULTICAST_LOOP,    "IP_MULTICAST_LOOP"     },
365         { IP_ADD_MEMBERSHIP,    "IP_ADD_MEMBERSHIP"     },
366         { IP_DROP_MEMBERSHIP,   "IP_DROP_MEMBERSHIP"    },
367         { 0,            NULL            },
368 };
369 #endif /* SOL_IP */
370
371 #ifdef SOL_IPX
372 static struct xlat sockipxoptions[] = {
373         { IPX_TYPE,     "IPX_TYPE"      },
374         { 0,            NULL            },
375 };
376 #endif /* SOL_IPX */
377
378 #ifdef SOL_TCP
379 static struct xlat socktcpoptions[] = {
380         { TCP_NODELAY,  "TCP_NODELAY"   },
381         { TCP_MAXSEG,   "TCP_MAXSEG"    },
382         { 0,            NULL            },
383 };
384 #endif /* SOL_TCP */
385
386 void
387 printsock(tcp, addr, addrlen)
388 struct tcb *tcp;
389 long addr;
390 int addrlen;
391 {
392         union {
393                 char pad[128];
394                 struct sockaddr sa;
395                 struct sockaddr_in sin;
396                 struct sockaddr_un sau;
397 #ifdef HAVE_INET_NTOP
398                 struct sockaddr_in6 sa6;
399 #endif
400 #if defined(LINUX) && defined(AF_IPX)
401                 struct sockaddr_ipx sipx;
402 #endif
403 #ifdef AF_PACKET
404                 struct sockaddr_ll ll;
405 #endif
406 #ifdef AF_NETLINK
407                 struct sockaddr_nl nl;
408 #endif
409         } addrbuf;
410         char string_addr[100];
411
412         if (addr == 0) {
413                 tprintf("NULL");
414                 return;
415         }
416         if (!verbose(tcp)) {
417                 tprintf("%#lx", addr);
418                 return;
419         }
420         if ((addrlen<2) || (addrlen>sizeof(addrbuf)))
421                 addrlen=sizeof(addrbuf);
422
423         if (umoven(tcp, addr, addrlen, (char*)&addrbuf) < 0) {
424                 tprintf("{...}");
425                 return;
426         }
427
428         tprintf("{sin_family=");
429         printxval(addrfams, addrbuf.sa.sa_family, "AF_???");
430         tprintf(", ");
431
432         switch (addrbuf.sa.sa_family) {
433         case AF_UNIX:
434                 if (addrlen==2) {
435                         tprintf("<nil>");
436                 } else if (addrbuf.sau.sun_path[0]) {
437                         tprintf("path=\"%*.*s\"", addrlen-2, addrlen-2, addrbuf.sau.sun_path);
438                 } else {
439                         tprintf("path=@%*.*s", addrlen-3, addrlen-3, addrbuf.sau.sun_path+1);
440                 }
441                 break;
442         case AF_INET:
443                 tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")}",
444                         ntohs(addrbuf.sin.sin_port), inet_ntoa(addrbuf.sin.sin_addr));
445                 break;
446 #ifdef HAVE_INET_NTOP
447         case AF_INET6:
448                 inet_ntop(AF_INET6, &addrbuf.sa6.sin6_addr, string_addr, sizeof(string_addr));
449                 tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=htonl(%u)}",
450                         ntohs(addrbuf.sa6.sin6_port), string_addr, ntohl(addrbuf.sa6.sin6_flowinfo));
451                 break;  
452 #endif
453 #if defined(AF_IPX) && defined(linux)
454         case AF_IPX:
455                 {
456                         int i;
457                         tprintf("{sipx_port=htons(%u), ",
458                                         ntohs(addrbuf.sipx.sipx_port));
459                         /* Yes, I know, this does not look too
460                          * strace-ish, but otherwise the IPX
461                          * addresses just look monstrous...
462                          * Anyways, feel free if you don't like
463                          * this way.. :) 
464                          */
465                         tprintf("%08lx:", (unsigned long)ntohl(addrbuf.sipx.sipx_network));
466                         for (i = 0; i<IPX_NODE_LEN; i++)
467                                 tprintf("%02x", addrbuf.sipx.sipx_node[i]);
468                         tprintf("/[%02x]", addrbuf.sipx.sipx_type);
469                 }
470                 break;
471 #endif /* AF_IPX && linux */
472 #ifdef AF_PACKET
473         case AF_PACKET:
474                 {
475                         int i;
476                         tprintf("proto=%#04x, if%d, pkttype=%d, addr(%d)={%d, ",
477                                         ntohs(addrbuf.ll.sll_protocol),
478                                         addrbuf.ll.sll_ifindex,
479                                         addrbuf.ll.sll_pkttype,
480                                         addrbuf.ll.sll_halen,
481                                         addrbuf.ll.sll_hatype);
482                         for (i=0; i<addrbuf.ll.sll_addr[i]; i++) 
483                                 tprintf("%02x", addrbuf.ll.sll_addr[i]);
484                 }
485                 break;
486
487 #endif /* AF_APACKET */
488 #ifdef AF_NETLINLK
489         case AF_NETLINK:
490                 tprintf("pid=%d, groups=%08x", addrbuf.nl.nl_pid, addrbuf.nl.nl_groups);
491                 break;
492 #endif /* AF_NETLINK */
493         /* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
494         AF_X25 AF_ROSE etc. still need to be done */
495
496         default:
497                 tprintf("{sa_family=%u, sa_data=", addrbuf.sa.sa_family);
498                 printstr(tcp, (long) &((struct sockaddr *) addr)->sa_data,
499                         sizeof addrbuf.sa.sa_data);
500                 break;
501         }
502         tprintf("}");
503 }
504
505 #if HAVE_SENDMSG
506
507 static void
508 printiovec(tcp, iovec, len)
509 struct tcb *tcp;
510 struct iovec *iovec;
511 long   len;
512 {
513         struct iovec *iov;
514         int i;
515
516         iov = (struct iovec *) malloc(len * sizeof *iov);
517         if (iov == NULL) {
518                 fprintf(stderr, "No memory");
519                 return;
520         }
521         if (umoven(tcp, (long)iovec,
522                                 len * sizeof *iov, (char *) iov) < 0) {
523                 tprintf("%#lx", (unsigned long)iovec);
524         } else {
525                 tprintf("[");
526                 for (i = 0; i < len; i++) {
527                         if (i)
528                                 tprintf(", ");
529                         tprintf("{");
530                         printstr(tcp, (long) iov[i].iov_base,
531                                         iov[i].iov_len);
532                         tprintf(", %lu}", (unsigned long)iov[i].iov_len);
533                 }
534                 tprintf("]");
535         }
536         free((char *) iov);
537 }
538
539 static void
540 printmsghdr(tcp, addr)
541 struct tcb *tcp;
542 long addr;
543 {
544         struct msghdr msg;
545
546         if (umove(tcp, addr, &msg) < 0) {
547                 tprintf("%#lx", addr);
548                 return;
549         }
550         tprintf("{msg_name(%d)=", msg.msg_namelen);
551         printsock(tcp, (long)msg.msg_name, msg.msg_namelen);
552
553         tprintf(", msg_iov(%lu)=", (unsigned long)msg.msg_iovlen);
554         printiovec(tcp, msg.msg_iov, msg.msg_iovlen);
555
556 #ifdef HAVE_MSG_CONTROL
557         tprintf(", msg_controllen=%lu", (unsigned long)msg.msg_controllen);
558         if (msg.msg_controllen) 
559                 tprintf(", msg_control=%#lx, ", (unsigned long) msg.msg_control);
560         tprintf(", msg_flags=");
561         if (printflags(msg_flags, msg.msg_flags)==0)
562                 tprintf("0");
563 #else /* !HAVE_MSG_CONTROL */
564         tprintf("msg_accrights=%#lx, msg_accrightslen=%u",
565                 (unsigned long) msg.msg_accrights, msg.msg_accrightslen);
566 #endif /* !HAVE_MSG_CONTROL */
567         tprintf("}");
568 }
569
570 #endif /* HAVE_SENDMSG */
571
572 int
573 sys_socket(tcp)
574 struct tcb *tcp;
575 {
576         if (entering(tcp)) {
577                 printxval(domains, tcp->u_arg[0], "PF_???");
578                 tprintf(", ");
579                 printxval(socktypes, tcp->u_arg[1], "SOCK_???");
580                 tprintf(", ");
581                 switch (tcp->u_arg[0]) {
582                 case PF_INET:
583                         printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
584                         break;
585 #ifdef PF_IPX
586                 case PF_IPX:
587                         /* BTW: I don't believe this.. */
588                         tprintf("[");
589                         printxval(domains, tcp->u_arg[2], "PF_???");
590                         tprintf("]");
591                         break;
592 #endif /* PF_IPX */
593                 default:
594                         tprintf("%lu", tcp->u_arg[2]);
595                         break;
596                 }
597         }
598         return 0;
599 }
600
601 int
602 sys_bind(tcp)
603 struct tcb *tcp;
604 {
605         if (entering(tcp)) {
606                 tprintf("%ld, ", tcp->u_arg[0]);
607                 printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
608                 tprintf(", %lu", tcp->u_arg[2]);
609         }
610         return 0;
611 }
612
613 int
614 sys_connect(tcp)
615 struct tcb *tcp;
616 {
617         return sys_bind(tcp);
618 }
619
620 int
621 sys_listen(tcp)
622 struct tcb *tcp;
623 {
624         if (entering(tcp)) {
625                 tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]);
626         }
627         return 0;
628 }
629
630 int
631 sys_accept(tcp)
632 struct tcb *tcp;
633 {
634         if (entering(tcp)) {
635                 tprintf("%ld, ", tcp->u_arg[0]);
636         } else if (!tcp->u_arg[2])
637                 tprintf("%#lx, NULL", tcp->u_arg[1]);
638         else {
639                 if (tcp->u_arg[1] == 0 || syserror(tcp)) {
640                         tprintf("%#lx", tcp->u_arg[1]);
641                 } else {
642                         printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
643                 }
644                 tprintf(", ");
645                 printnum(tcp, tcp->u_arg[2], "%lu");
646         }
647         return 0;
648 }
649
650 int
651 sys_send(tcp)
652 struct tcb *tcp;
653 {
654         if (entering(tcp)) {
655                 tprintf("%ld, ", tcp->u_arg[0]);
656                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
657                 tprintf(", %lu, ", tcp->u_arg[2]);
658                 /* flags */
659                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
660                         tprintf("0");
661         }
662         return 0;
663 }
664
665 int
666 sys_sendto(tcp)
667 struct tcb *tcp;
668 {
669         if (entering(tcp)) {
670                 tprintf("%ld, ", tcp->u_arg[0]);
671                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
672                 tprintf(", %lu, ", tcp->u_arg[2]);
673                 /* flags */
674                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
675                         tprintf("0");
676                 /* to address */
677                 tprintf(", ");
678                 printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
679                 /* to length */
680                 tprintf(", %lu", tcp->u_arg[5]);
681         }
682         return 0;
683 }
684
685 #ifdef HAVE_SENDMSG
686
687 int
688 sys_sendmsg(tcp)
689 struct tcb *tcp;
690 {
691         if (entering(tcp)) {
692                 tprintf("%ld, ", tcp->u_arg[0]);
693                 printmsghdr(tcp, tcp->u_arg[1]);
694                 /* flags */
695                 tprintf(", ");
696                 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
697                         tprintf("0");
698         }
699         return 0;
700 }
701
702 #endif /* HAVE_SENDMSG */
703
704 int
705 sys_recv(tcp)
706 struct tcb *tcp;
707 {
708         if (entering(tcp)) {
709                 tprintf("%ld, ", tcp->u_arg[0]);
710         } else {
711                 if (syserror(tcp))
712                         tprintf("%#lx", tcp->u_arg[1]);
713                 else
714                         printstr(tcp, tcp->u_arg[1], tcp->u_rval);
715
716                 tprintf(", %lu, ", tcp->u_arg[2]);
717                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
718                         tprintf("0");
719         }
720         return 0;
721 }
722
723 int
724 sys_recvfrom(tcp)
725 struct tcb *tcp;
726 {
727         int fromlen;
728
729         if (entering(tcp)) {
730                 tprintf("%ld, ", tcp->u_arg[0]);
731         } else {
732                 if (syserror(tcp)) {
733                         tprintf("%#lx, %lu, %lu, %#lx, %#lx",
734                                 tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3],
735                                 tcp->u_arg[4], tcp->u_arg[5]);
736                         return 0;
737                 }
738                 /* buf */
739                 printstr(tcp, tcp->u_arg[1], tcp->u_rval);
740                 /* len */
741                 tprintf(", %lu, ", tcp->u_arg[2]);
742                 /* flags */
743                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
744                         tprintf("0");
745                 /* from address, len */
746                 if (!tcp->u_arg[4] || !tcp->u_arg[5]) {
747                         if (tcp->u_arg[4] == 0)
748                                 tprintf(", NULL");
749                         else
750                                 tprintf(", %#lx", tcp->u_arg[4]);
751                         if (tcp->u_arg[5] == 0)
752                                 tprintf(", NULL");
753                         else
754                                 tprintf(", %#lx", tcp->u_arg[5]);
755                         return 0;
756                 }
757                 if (umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
758                         tprintf(", {...}, [?]");
759                         return 0;
760                 }
761                 tprintf(", ");
762                 printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
763                 /* from length */
764                 tprintf(", [%u]", fromlen);
765         }
766         return 0;
767 }
768
769 #ifdef HAVE_SENDMSG
770
771 int
772 sys_recvmsg(tcp)
773 struct tcb *tcp;
774 {
775         if (entering(tcp)) {
776                 tprintf("%ld, ", tcp->u_arg[0]);
777         } else {
778                 if (syserror(tcp) || !verbose(tcp))
779                         tprintf("%#lx", tcp->u_arg[1]);
780                 else
781                         printmsghdr(tcp, tcp->u_arg[1]);
782                 /* flags */
783                 tprintf(", ");
784                 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
785                         tprintf("0");
786         }
787         return 0;
788 }
789
790 #endif /* HAVE_SENDMSG */
791
792 int
793 sys_shutdown(tcp)
794 struct tcb *tcp;
795 {
796         if (entering(tcp)) {
797                 tprintf("%ld, %ld", tcp->u_arg[0], tcp->u_arg[1]);
798                 switch (tcp->u_arg[1]) {
799                 case 0:
800                         tprintf("%s", " /* receive */");
801                         break;
802                 case 1:
803                         tprintf("%s", " /* send */");
804                         break;
805                 case 2:
806                         tprintf("%s", " /* send and receive */");
807                         break;
808                 }
809         }
810         return 0;
811 }
812
813 int
814 sys_getsockname(tcp)
815 struct tcb *tcp;
816 {
817         return sys_accept(tcp);
818 }
819
820 int
821 sys_getpeername(tcp)
822 struct tcb *tcp;
823 {
824         return sys_accept(tcp);
825 }
826
827 int
828 sys_pipe(tcp)
829 struct tcb *tcp;
830 {
831
832 #if defined(LINUX) && !defined(SPARC)
833         int fds[2];
834
835         if (exiting(tcp)) {
836                 if (syserror(tcp)) {
837                         tprintf("%#lx", tcp->u_arg[0]);
838                         return 0;
839                 }
840                 if (umoven(tcp, tcp->u_arg[0], sizeof fds, (char *) fds) < 0)
841                         tprintf("[...]");
842                 else
843                         tprintf("[%u, %u]", fds[0], fds[1]);
844         }
845 #elif defined(SPARC) || defined(SVR4)
846         if (exiting(tcp))
847                 tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
848 #endif
849         return 0;
850 }
851
852 int
853 sys_socketpair(tcp)
854 struct tcb *tcp;
855 {
856 #ifdef LINUX
857         int fds[2];
858 #endif
859
860         if (entering(tcp)) {
861                 printxval(domains, tcp->u_arg[0], "PF_???");
862                 tprintf(", ");
863                 printxval(socktypes, tcp->u_arg[1], "SOCK_???");
864                 tprintf(", ");
865                 switch (tcp->u_arg[0]) {
866                 case PF_INET:
867                         printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
868                         break;
869 #ifdef PF_IPX
870                 case PF_IPX:
871                         /* BTW: I don't believe this.. */
872                         tprintf("[");
873                         printxval(domains, tcp->u_arg[2], "PF_???");
874                         tprintf("]");
875                         break;
876 #endif /* PF_IPX */
877                 default:        
878                         tprintf("%lu", tcp->u_arg[2]);
879                         break;
880                 }
881         } else {
882                 if (syserror(tcp)) {
883                         tprintf(", %#lx", tcp->u_arg[3]);
884                         return 0;
885                 }
886 #ifdef LINUX
887                 if (umoven(tcp, tcp->u_arg[3], sizeof fds, (char *) fds) < 0)
888                         tprintf(", [...]");
889                 else
890                         tprintf(", [%u, %u]", fds[0], fds[1]);
891 #endif /* LINUX */
892 #ifdef SUNOS4
893                 tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
894 #endif /* SUNOS4 */
895 #ifdef SVR4
896                 tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
897 #endif /* SVR4 */
898         }
899         return 0;
900 }
901
902 int
903 sys_getsockopt(tcp)
904 struct tcb *tcp;
905 {
906         if (entering(tcp)) {
907                 tprintf("%ld, ", tcp->u_arg[0]);
908                 switch (tcp->u_arg[1]) {
909                 case SOL_SOCKET:
910                         tprintf("SOL_SOCKET, ");
911                         printxval(sockoptions, tcp->u_arg[2], "SO_???");
912                         tprintf(", ");
913                         break;
914 #ifdef SOL_IP
915                 case SOL_IP:
916                         tprintf("SOL_IP, ");
917                         printxval(sockipoptions, tcp->u_arg[2], "IP_???");
918                         tprintf(", ");
919                         break;
920 #endif
921 #ifdef SOL_IPX
922                 case SOL_IPX:
923                         tprintf("SOL_IPX, ");
924                         printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
925                         tprintf(", ");
926                         break;
927 #endif
928 #ifdef SOL_TCP
929                 case SOL_TCP:
930                         tprintf("SOL_TCP, ");
931                         printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
932                         tprintf(", ");
933                         break;
934 #endif
935
936                 /* SOL_AX25 SOL_ROSE SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
937                  * etc. still need work */
938                 default: 
939                         /* XXX - should know socket family here */
940                         printxval(protocols, tcp->u_arg[1], "IPPROTO_???");
941                         tprintf(", %lu, ", tcp->u_arg[2]);
942                         break;
943                 }
944         } else {
945                 if (syserror(tcp)) {
946                         tprintf("%#lx, %#lx",
947                                 tcp->u_arg[3], tcp->u_arg[4]);
948                         return 0;
949                 }
950                 printnum(tcp, tcp->u_arg[3], "%ld");
951                 tprintf(", ");
952                 printnum(tcp, tcp->u_arg[4], "%ld");
953         }
954         return 0;
955 }
956
957 int
958 sys_setsockopt(tcp)
959 struct tcb *tcp;
960 {
961         if (entering(tcp)) {
962                 tprintf("%ld, ", tcp->u_arg[0]);
963                 switch (tcp->u_arg[1]) {
964                 case SOL_SOCKET:
965                         tprintf("SOL_SOCKET, ");
966                         printxval(sockoptions, tcp->u_arg[2], "SO_???");
967                         tprintf(", ");
968                         break;
969 #ifdef SOL_IP
970                 case SOL_IP:
971                         tprintf("SOL_IP, ");
972                         printxval(sockipoptions, tcp->u_arg[2], "IP_???");
973                         tprintf(", ");
974                         break;
975 #endif
976 #ifdef SOL_IPX
977                 case SOL_IPX:
978                         tprintf("SOL_IPX, ");
979                         printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
980                         tprintf(", ");
981                         break;
982 #endif
983 #ifdef SOL_TCP
984                 case SOL_TCP:
985                         tprintf("SOL_TCP, ");
986                         printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
987                         tprintf(", ");
988                         break;
989 #endif
990
991                 /* SOL_AX25 SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25 
992                  * etc. still need work  */
993                 default:
994                         /* XXX - should know socket family here */
995                         printxval(protocols, tcp->u_arg[1], "IPPROTO_???");
996                         tprintf("%lu, ", tcp->u_arg[2]);
997                         break;
998                 }
999                 printnum(tcp, tcp->u_arg[3], "%ld");
1000                 tprintf(", %lu", tcp->u_arg[4]);
1001         }
1002         return 0;
1003 }