]> granicus.if.org Git - strace/blob - net.c
d8e4b15dd8150776d2454c5c28152b46e69e3b2c
[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 HAVE_INET_NTOP
315         struct sockaddr_in6 sa6;
316         char string_addr[100];
317 #endif
318 #ifdef LINUX
319         struct sockaddr_ipx sipx;
320 #endif
321
322         if (addr == 0) {
323                 tprintf("NULL");
324                 return;
325         }
326         if (!verbose(tcp)) {
327                 tprintf("%#lx", addr);
328                 return;
329         }
330         if (umove(tcp, addr, &sa) < 0) {
331                 tprintf("{...}");
332                 return;
333         }
334         switch (sa.sa_family) {
335         case AF_UNIX:
336                 if (umove(tcp, addr, &sau) < 0)
337                         tprintf("{sun_family=AF_UNIX, ...}");
338                 else
339                         tprintf("{sun_family=AF_UNIX, sun_path=\"%s\"}",
340                                 sau.sun_path);
341                 break;
342         case AF_INET:
343                 tprintf("{sin_family=AF_INET, ");
344                 tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")}",
345                         ntohs(sin->sin_port), inet_ntoa(sin->sin_addr));
346                 break;
347 #ifdef HAVE_INET_NTOP
348         case AF_INET6:
349                 if (umove(tcp, addr, &sa6) < 0)
350                         tprintf("{sin6_family=AF_INET6, ...}");
351                 else
352                 {
353                         tprintf("{sin6_family=AF_INET6, ");
354                         inet_ntop(AF_INET6, &sa6.sin6_addr, string_addr, sizeof(string_addr));
355                         tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=htonl(%u)",
356                                 ntohs(sa6.sin6_port), string_addr, ntohl(sa6.sin6_flowinfo));
357                 }
358                 break;  
359 #endif
360 #if defined(AF_IPX) && defined(linux)
361         case AF_IPX:
362                 if (umove(tcp, addr, &sipx)<0)
363                         tprintf("{sipx_family=AF_IPX, ...}");
364                 else {
365                         int i;
366                         tprintf("{sipx_family=AF_IPX, ");
367                         tprintf("{sipx_port=htons(%u), ",
368                                 ntohs(sipx.sipx_port));
369                         /* Yes, I know, this does not look too
370                          * strace-ish, but otherwise the IPX
371                          * addresses just look monstrous...
372                          * Anyways, feel free if you don't like
373                          * this way.. :) 
374                          */
375                         tprintf("%08lx:", (unsigned long)ntohl(sipx.sipx_network));
376                         for (i = 0; i<IPX_NODE_LEN; i++)
377                                 tprintf("%02x", sipx.sipx_node[i]);
378                         tprintf("/[%02x]", sipx.sipx_type);
379                         tprintf("}");
380                 }
381                 break;
382 #endif /* AF_IPX  && linux */
383         /* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
384         AF_X25 AF_INET6 AF_ROSE still need to be done */
385
386         default:
387                 tprintf("{sa_family=%u, sa_data=", sa.sa_family);
388                 printstr(tcp, (long) &((struct sockaddr *) addr)->sa_data,
389                         sizeof sa.sa_data);
390                 tprintf("}");
391                 break;
392         }
393 }
394
395 #if HAVE_SENDMSG
396
397 static void
398 printmsghdr(tcp, addr)
399 struct tcb *tcp;
400 long addr;
401 {
402         struct msghdr msg;
403
404         if (umove(tcp, addr, &msg) < 0) {
405                 tprintf("%#lx", addr);
406                 return;
407         }
408         tprintf("{msg_name=");
409         printstr(tcp, (long) msg.msg_name, msg.msg_namelen);
410         tprintf(", msg_namelen=%u, msg_iov=%#lx, msg_iovlen=%u, ",
411                 msg.msg_namelen,
412                 (unsigned long) msg.msg_iov, msg.msg_iovlen);
413 #ifdef HAVE_MSG_CONTROL
414         tprintf("msg_control=%#lx, msg_controllen=%u, msg_flags=%#x}",
415                 (unsigned long) msg.msg_control, msg.msg_controllen,
416                 msg.msg_flags);
417 #else /* !HAVE_MSG_CONTROL */
418         tprintf("msg_accrights=%#lx, msg_accrightslen=%u}",
419                 (unsigned long) msg.msg_accrights, msg.msg_accrightslen);
420 #endif /* !HAVE_MSG_CONTROL */
421 }
422
423 #endif /* HAVE_SENDMSG */
424
425 int
426 sys_socket(tcp)
427 struct tcb *tcp;
428 {
429         if (entering(tcp)) {
430                 printxval(domains, tcp->u_arg[0], "PF_???");
431                 tprintf(", ");
432                 printxval(socktypes, tcp->u_arg[1], "SOCK_???");
433                 tprintf(", ");
434                 switch (tcp->u_arg[0]) {
435                 case PF_INET:
436                         printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
437                         break;
438 #ifdef PF_IPX
439                 case PF_IPX:
440                         /* BTW: I don't believe this.. */
441                         tprintf("[");
442                         printxval(domains, tcp->u_arg[2], "PF_???");
443                         tprintf("]");
444                         break;
445 #endif /* PF_IPX */
446                 default:
447                         tprintf("%lu", tcp->u_arg[2]);
448                         break;
449                 }
450         }
451         return 0;
452 }
453
454 int
455 sys_bind(tcp)
456 struct tcb *tcp;
457 {
458         if (entering(tcp)) {
459                 tprintf("%ld, ", tcp->u_arg[0]);
460                 printsock(tcp, tcp->u_arg[1]);
461                 tprintf(", %lu", tcp->u_arg[2]);
462         }
463         return 0;
464 }
465
466 int
467 sys_connect(tcp)
468 struct tcb *tcp;
469 {
470         return sys_bind(tcp);
471 }
472
473 int
474 sys_listen(tcp)
475 struct tcb *tcp;
476 {
477         if (entering(tcp)) {
478                 tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]);
479         }
480         return 0;
481 }
482
483 int
484 sys_accept(tcp)
485 struct tcb *tcp;
486 {
487         if (entering(tcp)) {
488                 tprintf("%ld, ", tcp->u_arg[0]);
489         } else if (!tcp->u_arg[2])
490                 tprintf("%#lx, NULL", tcp->u_arg[1]);
491         else {
492                 if (tcp->u_arg[1] == 0 || syserror(tcp)) {
493                         tprintf("%#lx", tcp->u_arg[1]);
494                 } else {
495                         printsock(tcp, tcp->u_arg[1]);
496                 }
497                 tprintf(", ");
498                 printnum(tcp, tcp->u_arg[2], "%lu");
499         }
500         return 0;
501 }
502
503 int
504 sys_send(tcp)
505 struct tcb *tcp;
506 {
507         if (entering(tcp)) {
508                 tprintf("%ld, ", tcp->u_arg[0]);
509                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
510                 tprintf(", %lu, ", tcp->u_arg[2]);
511                 /* flags */
512                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
513                         tprintf("0");
514         }
515         return 0;
516 }
517
518 int
519 sys_sendto(tcp)
520 struct tcb *tcp;
521 {
522         if (entering(tcp)) {
523                 tprintf("%ld, ", tcp->u_arg[0]);
524                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
525                 tprintf(", %lu, ", tcp->u_arg[2]);
526                 /* flags */
527                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
528                         tprintf("0");
529                 /* to address */
530                 tprintf(", ");
531                 printsock(tcp, tcp->u_arg[4]);
532                 /* to length */
533                 tprintf(", %lu", tcp->u_arg[5]);
534         }
535         return 0;
536 }
537
538 #ifdef HAVE_SENDMSG
539
540 int
541 sys_sendmsg(tcp)
542 struct tcb *tcp;
543 {
544         if (entering(tcp)) {
545                 tprintf("%ld, ", tcp->u_arg[0]);
546                 printmsghdr(tcp, tcp->u_arg[1]);
547                 /* flags */
548                 tprintf(", ");
549                 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
550                         tprintf("0");
551         }
552         return 0;
553 }
554
555 #endif /* HAVE_SENDMSG */
556
557 int
558 sys_recv(tcp)
559 struct tcb *tcp;
560 {
561         if (entering(tcp)) {
562                 tprintf("%ld, ", tcp->u_arg[0]);
563         } else {
564                 if (syserror(tcp))
565                         tprintf("%#lx", tcp->u_arg[1]);
566                 else
567                         printstr(tcp, tcp->u_arg[1], tcp->u_rval);
568
569                 tprintf(", %lu, ", tcp->u_arg[2]);
570                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
571                         tprintf("0");
572         }
573         return 0;
574 }
575
576 int
577 sys_recvfrom(tcp)
578 struct tcb *tcp;
579 {
580         int fromlen;
581
582         if (entering(tcp)) {
583                 tprintf("%ld, ", tcp->u_arg[0]);
584         } else {
585                 if (syserror(tcp)) {
586                         tprintf("%#lx, %lu, %lu, %#lx, %#lx",
587                                 tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3],
588                                 tcp->u_arg[4], tcp->u_arg[5]);
589                         return 0;
590                 }
591                 /* buf */
592                 printstr(tcp, tcp->u_arg[1], tcp->u_rval);
593                 /* len */
594                 tprintf(", %lu, ", tcp->u_arg[2]);
595                 /* flags */
596                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
597                         tprintf("0");
598                 /* from address, len */
599                 if (!tcp->u_arg[4] || !tcp->u_arg[5]) {
600                         if (tcp->u_arg[4] == 0)
601                                 tprintf(", NULL");
602                         else
603                                 tprintf(", %#lx", tcp->u_arg[4]);
604                         if (tcp->u_arg[5] == 0)
605                                 tprintf(", NULL");
606                         else
607                                 tprintf(", %#lx", tcp->u_arg[5]);
608                         return 0;
609                 }
610                 if (umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
611                         tprintf(", {...}, [?]");
612                         return 0;
613                 }
614                 tprintf(", ");
615                 printsock(tcp, tcp->u_arg[4]);
616                 /* from length */
617                 tprintf(", [%u]", fromlen);
618         }
619         return 0;
620 }
621
622 #ifdef HAVE_SENDMSG
623
624 int
625 sys_recvmsg(tcp)
626 struct tcb *tcp;
627 {
628         if (entering(tcp)) {
629                 tprintf("%ld, ", tcp->u_arg[0]);
630         } else {
631                 if (syserror(tcp) || !verbose(tcp))
632                         tprintf("%#lx", tcp->u_arg[1]);
633                 else
634                         printmsghdr(tcp, tcp->u_arg[1]);
635                 /* flags */
636                 tprintf(", ");
637                 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
638                         tprintf("0");
639         }
640         return 0;
641 }
642
643 #endif /* HAVE_SENDMSG */
644
645 int
646 sys_shutdown(tcp)
647 struct tcb *tcp;
648 {
649         if (entering(tcp)) {
650                 tprintf("%ld, %ld", tcp->u_arg[0], tcp->u_arg[1]);
651                 switch (tcp->u_arg[1]) {
652                 case 0:
653                         tprintf("%s", " /* receive */");
654                         break;
655                 case 1:
656                         tprintf("%s", " /* send */");
657                         break;
658                 case 2:
659                         tprintf("%s", " /* send and receive */");
660                         break;
661                 }
662         }
663         return 0;
664 }
665
666 int
667 sys_getsockname(tcp)
668 struct tcb *tcp;
669 {
670         return sys_accept(tcp);
671 }
672
673 int
674 sys_getpeername(tcp)
675 struct tcb *tcp;
676 {
677         return sys_accept(tcp);
678 }
679
680 int
681 sys_pipe(tcp)
682 struct tcb *tcp;
683 {
684
685 #if defined(LINUX) && !defined(SPARC)
686         int fds[2];
687
688         if (exiting(tcp)) {
689                 if (syserror(tcp)) {
690                         tprintf("%#lx", tcp->u_arg[0]);
691                         return 0;
692                 }
693                 if (umoven(tcp, tcp->u_arg[0], sizeof fds, (char *) fds) < 0)
694                         tprintf("[...]");
695                 else
696                         tprintf("[%u, %u]", fds[0], fds[1]);
697         }
698 #elif defined(SPARC) || defined(SVR4)
699         if (exiting(tcp))
700                 tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
701 #endif
702         return 0;
703 }
704
705 int
706 sys_socketpair(tcp)
707 struct tcb *tcp;
708 {
709 #ifdef LINUX
710         int fds[2];
711 #endif
712
713         if (entering(tcp)) {
714                 printxval(domains, tcp->u_arg[0], "PF_???");
715                 tprintf(", ");
716                 printxval(socktypes, tcp->u_arg[1], "SOCK_???");
717                 tprintf(", ");
718                 switch (tcp->u_arg[0]) {
719                 case PF_INET:
720                         printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
721                         break;
722 #ifdef PF_IPX
723                 case PF_IPX:
724                         /* BTW: I don't believe this.. */
725                         tprintf("[");
726                         printxval(domains, tcp->u_arg[2], "PF_???");
727                         tprintf("]");
728                         break;
729 #endif /* PF_IPX */
730                 default:        
731                         tprintf("%lu", tcp->u_arg[2]);
732                         break;
733                 }
734         } else {
735                 if (syserror(tcp)) {
736                         tprintf(", %#lx", tcp->u_arg[3]);
737                         return 0;
738                 }
739 #ifdef LINUX
740                 if (umoven(tcp, tcp->u_arg[3], sizeof fds, (char *) fds) < 0)
741                         tprintf(", [...]");
742                 else
743                         tprintf(", [%u, %u]", fds[0], fds[1]);
744 #endif /* LINUX */
745 #ifdef SUNOS4
746                 tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
747 #endif /* SUNOS4 */
748 #ifdef SVR4
749                 tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
750 #endif /* SVR4 */
751         }
752         return 0;
753 }
754
755 int
756 sys_getsockopt(tcp)
757 struct tcb *tcp;
758 {
759         if (entering(tcp)) {
760                 tprintf("%ld, ", tcp->u_arg[0]);
761                 switch (tcp->u_arg[1]) {
762                 case SOL_SOCKET:
763                         tprintf("SOL_SOCKET, ");
764                         printxval(sockoptions, tcp->u_arg[2], "SO_???");
765                         tprintf(", ");
766                         break;
767 #ifdef SOL_IP
768                 case SOL_IP:
769                         tprintf("SOL_IP, ");
770                         printxval(sockipoptions, tcp->u_arg[2], "IP_???");
771                         tprintf(", ");
772                         break;
773 #endif
774 #ifdef SOL_IPX
775                 case SOL_IPX:
776                         tprintf("SOL_IPX, ");
777                         printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
778                         tprintf(", ");
779                         break;
780 #endif
781 #ifdef SOL_TCP
782                 case SOL_TCP:
783                         tprintf("SOL_TCP, ");
784                         printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
785                         tprintf(", ");
786                         break;
787 #endif
788
789                 /* SOL_AX25 SOL_ROSE SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
790                  * etc. still need work */
791                 default: 
792                         /* XXX - should know socket family here */
793                         printxval(protocols, tcp->u_arg[1], "IPPROTO_???");
794                         tprintf("%lu, ", tcp->u_arg[2]);
795                         break;
796                 }
797         } else {
798                 if (syserror(tcp)) {
799                         tprintf("%#lx, %#lx",
800                                 tcp->u_arg[3], tcp->u_arg[4]);
801                         return 0;
802                 }
803                 printnum(tcp, tcp->u_arg[3], "%ld");
804                 tprintf(", ");
805                 printnum(tcp, tcp->u_arg[4], "%ld");
806         }
807         return 0;
808 }
809
810 int
811 sys_setsockopt(tcp)
812 struct tcb *tcp;
813 {
814         if (entering(tcp)) {
815                 tprintf("%ld, ", tcp->u_arg[0]);
816                 switch (tcp->u_arg[1]) {
817                 case SOL_SOCKET:
818                         tprintf("SOL_SOCKET, ");
819                         printxval(sockoptions, tcp->u_arg[2], "SO_???");
820                         tprintf(", ");
821                         break;
822 #ifdef SOL_IP
823                 case SOL_IP:
824                         tprintf("SOL_IP, ");
825                         printxval(sockipoptions, tcp->u_arg[2], "IP_???");
826                         tprintf(", ");
827                         break;
828 #endif
829 #ifdef SOL_IPX
830                 case SOL_IPX:
831                         tprintf("SOL_IPX, ");
832                         printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
833                         tprintf(", ");
834                         break;
835 #endif
836 #ifdef SOL_TCP
837                 case SOL_TCP:
838                         tprintf("SOL_TCP, ");
839                         printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
840                         tprintf(", ");
841                         break;
842 #endif
843
844                 /* SOL_AX25 SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25 
845                  * etc. still need work  */
846                 default:
847                         /* XXX - should know socket family here */
848                         printxval(protocols, tcp->u_arg[1], "IPPROTO_???");
849                         tprintf("%lu, ", tcp->u_arg[2]);
850                         break;
851                 }
852                 printnum(tcp, tcp->u_arg[3], "%ld");
853                 tprintf(", %lu", tcp->u_arg[4]);
854         }
855         return 0;
856 }