]> granicus.if.org Git - strace/blob - net.c
process.c: move get*uid and set*uid parsers to a separate file
[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-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
31 #include "defs.h"
32 #include <sys/stat.h>
33 #include <sys/socket.h>
34 #include <sys/uio.h>
35 #include <sys/un.h>
36 #if defined(HAVE_SIN6_SCOPE_ID_LINUX)
37 # define in6_addr in6_addr_libc
38 # define ipv6_mreq ipv6_mreq_libc
39 # define sockaddr_in6 sockaddr_in6_libc
40 #endif
41 #include <netinet/in.h>
42 #ifdef HAVE_NETINET_TCP_H
43 # include <netinet/tcp.h>
44 #endif
45 #ifdef HAVE_NETINET_UDP_H
46 # include <netinet/udp.h>
47 #endif
48 #ifdef HAVE_NETINET_SCTP_H
49 # include <netinet/sctp.h>
50 #endif
51 #include <arpa/inet.h>
52 #include <net/if.h>
53 #include <asm/types.h>
54 #if defined(__GLIBC__)
55 # include <netipx/ipx.h>
56 #else
57 # include <linux/ipx.h>
58 #endif
59
60 #if defined(__GLIBC__) && defined(HAVE_SIN6_SCOPE_ID_LINUX)
61 # if defined(HAVE_LINUX_IN6_H)
62 #  if defined(HAVE_SIN6_SCOPE_ID_LINUX)
63 #   undef in6_addr
64 #   undef ipv6_mreq
65 #   undef sockaddr_in6
66 #   define in6_addr in6_addr_kernel
67 #   define ipv6_mreq ipv6_mreq_kernel
68 #   define sockaddr_in6 sockaddr_in6_kernel
69 #  endif
70 #  include <linux/in6.h>
71 #  if defined(HAVE_SIN6_SCOPE_ID_LINUX)
72 #   undef in6_addr
73 #   undef ipv6_mreq
74 #   undef sockaddr_in6
75 #   define in6_addr in6_addr_libc
76 #   define ipv6_mreq ipv6_mreq_libc
77 #   define sockaddr_in6 sockaddr_in6_kernel
78 #  endif
79 # endif
80 #endif
81
82 #if defined(HAVE_LINUX_NETLINK_H)
83 # include <linux/netlink.h>
84 #endif
85 #if defined(HAVE_LINUX_IF_PACKET_H)
86 # include <linux/if_packet.h>
87 #endif
88 #if defined(HAVE_LINUX_ICMP_H)
89 # include <linux/icmp.h>
90 #endif
91 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
92 # include <bluetooth/bluetooth.h>
93 # include <bluetooth/hci.h>
94 # include <bluetooth/l2cap.h>
95 # include <bluetooth/rfcomm.h>
96 # include <bluetooth/sco.h>
97 #endif
98 #ifndef PF_UNSPEC
99 # define PF_UNSPEC AF_UNSPEC
100 #endif
101
102 #include "xlat/domains.h"
103 #include "xlat/addrfams.h"
104 #include "xlat/socktypes.h"
105 #include "xlat/sock_type_flags.h"
106 #ifndef SOCK_TYPE_MASK
107 # define SOCK_TYPE_MASK 0xf
108 #endif
109 #include "xlat/socketlayers.h"
110 /*** WARNING: DANGER WILL ROBINSON: NOTE "socketlayers" array above
111      falls into "inet_protocols" array below!!!!   This is intended!!! ***/
112 #include "xlat/inet_protocols.h"
113
114 #ifdef PF_NETLINK
115 #include "xlat/netlink_protocols.h"
116 #endif
117
118 #if defined(HAVE_BLUETOOTH_BLUETOOTH_H)
119 # include "xlat/bt_protocols.h"
120 #endif
121
122 #include "xlat/msg_flags.h"
123 #include "xlat/sockoptions.h"
124
125 #if !defined(SOL_IP) && defined(IPPROTO_IP)
126 #define SOL_IP IPPROTO_IP
127 #endif
128
129 #ifdef SOL_IP
130 #include "xlat/sockipoptions.h"
131 #endif /* SOL_IP */
132
133 #ifdef SOL_IPV6
134 #include "xlat/sockipv6options.h"
135 #endif /* SOL_IPV6 */
136
137 #ifdef SOL_IPX
138 #include "xlat/sockipxoptions.h"
139 #endif /* SOL_IPX */
140
141 #ifdef SOL_RAW
142 #include "xlat/sockrawoptions.h"
143 #endif /* SOL_RAW */
144
145 #ifdef SOL_PACKET
146 #include "xlat/sockpacketoptions.h"
147 #endif /* SOL_PACKET */
148
149 #ifdef SOL_SCTP
150 #include "xlat/socksctpoptions.h"
151 #endif
152
153 #if !defined(SOL_TCP) && defined(IPPROTO_TCP)
154 #define SOL_TCP IPPROTO_TCP
155 #endif
156
157 #ifdef SOL_TCP
158 #include "xlat/socktcpoptions.h"
159 #endif /* SOL_TCP */
160
161 #ifdef SOL_RAW
162 #include "xlat/icmpfilterflags.h"
163 #endif /* SOL_RAW */
164
165 #if defined(AF_PACKET) /* from e.g. linux/if_packet.h */
166 #include "xlat/af_packet_types.h"
167 #endif /* defined(AF_PACKET) */
168
169 void
170 printsock(struct tcb *tcp, long addr, int addrlen)
171 {
172         union {
173                 char pad[128];
174                 struct sockaddr sa;
175                 struct sockaddr_in sin;
176                 struct sockaddr_un sau;
177 #ifdef HAVE_INET_NTOP
178                 struct sockaddr_in6 sa6;
179 #endif
180 #if defined(AF_IPX)
181                 struct sockaddr_ipx sipx;
182 #endif
183 #ifdef AF_PACKET
184                 struct sockaddr_ll ll;
185 #endif
186 #ifdef AF_NETLINK
187                 struct sockaddr_nl nl;
188 #endif
189 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
190                 struct sockaddr_hci hci;
191                 struct sockaddr_l2 l2;
192                 struct sockaddr_rc rc;
193                 struct sockaddr_sco sco;
194 #endif
195         } addrbuf;
196         char string_addr[100];
197
198         if (addr == 0) {
199                 tprints("NULL");
200                 return;
201         }
202         if (!verbose(tcp)) {
203                 tprintf("%#lx", addr);
204                 return;
205         }
206
207         if (addrlen < 2 || addrlen > (int) sizeof(addrbuf))
208                 addrlen = sizeof(addrbuf);
209
210         memset(&addrbuf, 0, sizeof(addrbuf));
211         if (umoven(tcp, addr, addrlen, addrbuf.pad) < 0) {
212                 tprints("{...}");
213                 return;
214         }
215         addrbuf.pad[sizeof(addrbuf.pad) - 1] = '\0';
216
217         tprints("{sa_family=");
218         printxval(addrfams, addrbuf.sa.sa_family, "AF_???");
219         tprints(", ");
220
221         switch (addrbuf.sa.sa_family) {
222         case AF_UNIX:
223                 if (addrlen == 2) {
224                         tprints("NULL");
225                 } else if (addrbuf.sau.sun_path[0]) {
226                         tprints("sun_path=");
227                         printpathn(tcp, addr + 2, strlen(addrbuf.sau.sun_path));
228                 } else {
229                         tprints("sun_path=@");
230                         printpathn(tcp, addr + 3, strlen(addrbuf.sau.sun_path + 1));
231                 }
232                 break;
233         case AF_INET:
234                 tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")",
235                         ntohs(addrbuf.sin.sin_port), inet_ntoa(addrbuf.sin.sin_addr));
236                 break;
237 #ifdef HAVE_INET_NTOP
238         case AF_INET6:
239                 inet_ntop(AF_INET6, &addrbuf.sa6.sin6_addr, string_addr, sizeof(string_addr));
240                 tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=%u",
241                                 ntohs(addrbuf.sa6.sin6_port), string_addr,
242                                 addrbuf.sa6.sin6_flowinfo);
243 #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
244                 {
245 #if defined(HAVE_IF_INDEXTONAME) && defined(IN6_IS_ADDR_LINKLOCAL) && defined(IN6_IS_ADDR_MC_LINKLOCAL)
246                         int numericscope = 0;
247                         if (IN6_IS_ADDR_LINKLOCAL(&addrbuf.sa6.sin6_addr)
248                             || IN6_IS_ADDR_MC_LINKLOCAL(&addrbuf.sa6.sin6_addr)) {
249                                 char scopebuf[IFNAMSIZ + 1];
250
251                                 if (if_indextoname(addrbuf.sa6.sin6_scope_id, scopebuf) == NULL)
252                                         numericscope++;
253                                 else
254                                         tprintf(", sin6_scope_id=if_nametoindex(\"%s\")", scopebuf);
255                         } else
256                                 numericscope++;
257
258                         if (numericscope)
259 #endif
260                                 tprintf(", sin6_scope_id=%u", addrbuf.sa6.sin6_scope_id);
261                 }
262 #endif
263                 break;
264 #endif
265 #if defined(AF_IPX)
266         case AF_IPX:
267                 {
268                         int i;
269                         tprintf("sipx_port=htons(%u), ",
270                                         ntohs(addrbuf.sipx.sipx_port));
271                         /* Yes, I know, this does not look too
272                          * strace-ish, but otherwise the IPX
273                          * addresses just look monstrous...
274                          * Anyways, feel free if you don't like
275                          * this way.. :)
276                          */
277                         tprintf("%08lx:", (unsigned long)ntohl(addrbuf.sipx.sipx_network));
278                         for (i = 0; i < IPX_NODE_LEN; i++)
279                                 tprintf("%02x", addrbuf.sipx.sipx_node[i]);
280                         tprintf("/[%02x]", addrbuf.sipx.sipx_type);
281                 }
282                 break;
283 #endif /* AF_IPX */
284 #ifdef AF_PACKET
285         case AF_PACKET:
286                 {
287                         int i;
288                         tprintf("proto=%#04x, if%d, pkttype=",
289                                         ntohs(addrbuf.ll.sll_protocol),
290                                         addrbuf.ll.sll_ifindex);
291                         printxval(af_packet_types, addrbuf.ll.sll_pkttype, "PACKET_???");
292                         tprintf(", addr(%d)={%d, ",
293                                         addrbuf.ll.sll_halen,
294                                         addrbuf.ll.sll_hatype);
295                         for (i = 0; i < addrbuf.ll.sll_halen; i++)
296                                 tprintf("%02x", addrbuf.ll.sll_addr[i]);
297                 }
298                 break;
299
300 #endif /* AF_PACKET */
301 #ifdef AF_NETLINK
302         case AF_NETLINK:
303                 tprintf("pid=%d, groups=%08x", addrbuf.nl.nl_pid, addrbuf.nl.nl_groups);
304                 break;
305 #endif /* AF_NETLINK */
306 #if defined(AF_BLUETOOTH) && defined(HAVE_BLUETOOTH_BLUETOOTH_H)
307         case AF_BLUETOOTH:
308                 tprintf("{sco_bdaddr=%02X:%02X:%02X:%02X:%02X:%02X} or "
309                         "{rc_bdaddr=%02X:%02X:%02X:%02X:%02X:%02X, rc_channel=%d} or "
310                         "{l2_psm=htobs(%d), l2_bdaddr=%02X:%02X:%02X:%02X:%02X:%02X, l2_cid=htobs(%d)} or "
311                         "{hci_dev=htobs(%d)}",
312                         addrbuf.sco.sco_bdaddr.b[0], addrbuf.sco.sco_bdaddr.b[1],
313                         addrbuf.sco.sco_bdaddr.b[2], addrbuf.sco.sco_bdaddr.b[3],
314                         addrbuf.sco.sco_bdaddr.b[4], addrbuf.sco.sco_bdaddr.b[5],
315                         addrbuf.rc.rc_bdaddr.b[0], addrbuf.rc.rc_bdaddr.b[1],
316                         addrbuf.rc.rc_bdaddr.b[2], addrbuf.rc.rc_bdaddr.b[3],
317                         addrbuf.rc.rc_bdaddr.b[4], addrbuf.rc.rc_bdaddr.b[5],
318                         addrbuf.rc.rc_channel,
319                         btohs(addrbuf.l2.l2_psm), addrbuf.l2.l2_bdaddr.b[0],
320                         addrbuf.l2.l2_bdaddr.b[1], addrbuf.l2.l2_bdaddr.b[2],
321                         addrbuf.l2.l2_bdaddr.b[3], addrbuf.l2.l2_bdaddr.b[4],
322                         addrbuf.l2.l2_bdaddr.b[5], btohs(addrbuf.l2.l2_cid),
323                         btohs(addrbuf.hci.hci_dev));
324                 break;
325 #endif /* AF_BLUETOOTH && HAVE_BLUETOOTH_BLUETOOTH_H */
326         /* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
327         AF_X25 AF_ROSE etc. still need to be done */
328
329         default:
330                 tprints("sa_data=");
331                 printstr(tcp, (long) &((struct sockaddr *) addr)->sa_data,
332                         sizeof addrbuf.sa.sa_data);
333                 break;
334         }
335         tprints("}");
336 }
337
338 #if HAVE_SENDMSG
339 #include "xlat/scmvals.h"
340
341 static void
342 printcmsghdr(struct tcb *tcp, unsigned long addr, unsigned long len)
343 {
344         struct cmsghdr *cmsg = len < sizeof(struct cmsghdr) ?
345                                NULL : malloc(len);
346         if (cmsg == NULL || umoven(tcp, addr, len, (char *) cmsg) < 0) {
347                 tprintf(", msg_control=%#lx", addr);
348                 free(cmsg);
349                 return;
350         }
351
352         tprintf(", {cmsg_len=%u, cmsg_level=", (unsigned) cmsg->cmsg_len);
353         printxval(socketlayers, cmsg->cmsg_level, "SOL_???");
354         tprints(", cmsg_type=");
355
356         if (cmsg->cmsg_level == SOL_SOCKET) {
357                 unsigned long cmsg_len;
358
359                 printxval(scmvals, cmsg->cmsg_type, "SCM_???");
360                 cmsg_len = (len < cmsg->cmsg_len) ? len : cmsg->cmsg_len;
361
362                 if (cmsg->cmsg_type == SCM_RIGHTS
363                     && CMSG_LEN(sizeof(int)) <= cmsg_len) {
364                         int *fds = (int *) CMSG_DATA(cmsg);
365                         int first = 1;
366
367                         tprints(", {");
368                         while ((char *) fds < ((char *) cmsg + cmsg_len)) {
369                                 if (!first)
370                                         tprints(", ");
371                                 printfd(tcp, *fds++);
372                                 first = 0;
373                         }
374                         tprints("}}");
375                         free(cmsg);
376                         return;
377                 }
378                 if (cmsg->cmsg_type == SCM_CREDENTIALS
379                     && CMSG_LEN(sizeof(struct ucred)) <= cmsg_len) {
380                         struct ucred *uc = (struct ucred *) CMSG_DATA(cmsg);
381
382                         tprintf("{pid=%ld, uid=%ld, gid=%ld}}",
383                                 (long)uc->pid, (long)uc->uid, (long)uc->gid);
384                         free(cmsg);
385                         return;
386                 }
387         }
388         free(cmsg);
389         tprints(", ...}");
390 }
391
392 static void
393 do_msghdr(struct tcb *tcp, struct msghdr *msg, unsigned long data_size)
394 {
395         tprintf("{msg_name(%d)=", msg->msg_namelen);
396         printsock(tcp, (long)msg->msg_name, msg->msg_namelen);
397
398         tprintf(", msg_iov(%lu)=", (unsigned long)msg->msg_iovlen);
399         tprint_iov_upto(tcp, (unsigned long)msg->msg_iovlen,
400                    (unsigned long)msg->msg_iov, 1, data_size);
401
402 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
403         tprintf(", msg_controllen=%lu", (unsigned long)msg->msg_controllen);
404         if (msg->msg_controllen)
405                 printcmsghdr(tcp, (unsigned long) msg->msg_control,
406                              msg->msg_controllen);
407         tprints(", msg_flags=");
408         printflags(msg_flags, msg->msg_flags, "MSG_???");
409 #else /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
410         tprintf("msg_accrights=%#lx, msg_accrightslen=%u",
411                 (unsigned long) msg->msg_accrights, msg->msg_accrightslen);
412 #endif /* !HAVE_STRUCT_MSGHDR_MSG_CONTROL */
413         tprints("}");
414 }
415
416 struct msghdr32 {
417         uint32_t /* void* */    msg_name;
418         uint32_t /* socklen_t */msg_namelen;
419         uint32_t /* iovec* */   msg_iov;
420         uint32_t /* size_t */   msg_iovlen;
421         uint32_t /* void* */    msg_control;
422         uint32_t /* size_t */   msg_controllen;
423         uint32_t /* int */      msg_flags;
424 };
425 struct mmsghdr32 {
426         struct msghdr32         msg_hdr;
427         uint32_t /* unsigned */ msg_len;
428 };
429
430 #ifndef HAVE_STRUCT_MMSGHDR
431 struct mmsghdr {
432         struct msghdr msg_hdr;
433         unsigned msg_len;
434 };
435 #endif
436
437 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
438 static void
439 copy_from_msghdr32(struct msghdr *to_msg, struct msghdr32 *from_msg32)
440 {
441         to_msg->msg_name       = (void*)(long)from_msg32->msg_name;
442         to_msg->msg_namelen    =              from_msg32->msg_namelen;
443         to_msg->msg_iov        = (void*)(long)from_msg32->msg_iov;
444         to_msg->msg_iovlen     =              from_msg32->msg_iovlen;
445         to_msg->msg_control    = (void*)(long)from_msg32->msg_control;
446         to_msg->msg_controllen =              from_msg32->msg_controllen;
447         to_msg->msg_flags      =              from_msg32->msg_flags;
448 }
449 #endif
450
451 static bool
452 extractmsghdr(struct tcb *tcp, long addr, struct msghdr *msg)
453 {
454 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
455         if (current_wordsize == 4) {
456                 struct msghdr32 msg32;
457
458                 if (umove(tcp, addr, &msg32) < 0)
459                         return false;
460                 copy_from_msghdr32(msg, &msg32);
461         } else
462 #endif
463         if (umove(tcp, addr, msg) < 0)
464                 return false;
465         return true;
466 }
467
468 static bool
469 extractmmsghdr(struct tcb *tcp, long addr, unsigned int idx, struct mmsghdr *mmsg)
470 {
471 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
472         if (current_wordsize == 4) {
473                 struct mmsghdr32 mmsg32;
474
475                 addr += sizeof(struct mmsghdr32) * idx;
476                 if (umove(tcp, addr, &mmsg32) < 0)
477                         return false;
478
479                 copy_from_msghdr32(&mmsg->msg_hdr, &mmsg32.msg_hdr);
480                 mmsg->msg_len = mmsg32.msg_len;
481         } else
482 #endif
483         {
484                 addr += sizeof(*mmsg) * idx;
485                 if (umove(tcp, addr, mmsg) < 0)
486                         return false;
487         }
488         return true;
489 }
490
491 static void
492 printmsghdr(struct tcb *tcp, long addr, unsigned long data_size)
493 {
494         struct msghdr msg;
495
496         if (extractmsghdr(tcp, addr, &msg))
497                 do_msghdr(tcp, &msg, data_size);
498         else
499                 tprintf("%#lx", addr);
500 }
501
502 void
503 dumpiov_in_msghdr(struct tcb *tcp, long addr)
504 {
505         struct msghdr msg;
506
507         if (extractmsghdr(tcp, addr, &msg))
508                 dumpiov(tcp, msg.msg_iovlen, (long)msg.msg_iov);
509 }
510
511 static void
512 printmmsghdr(struct tcb *tcp, long addr, unsigned int idx, unsigned long msg_len)
513 {
514         struct mmsghdr mmsg;
515
516         if (extractmmsghdr(tcp, addr, idx, &mmsg)) {
517                 tprints("{");
518                 do_msghdr(tcp, &mmsg.msg_hdr, msg_len ? msg_len : mmsg.msg_len);
519                 tprintf(", %u}", mmsg.msg_len);
520         }
521         else
522                 tprintf("%#lx", addr);
523 }
524
525 static void
526 decode_mmsg(struct tcb *tcp, unsigned long msg_len)
527 {
528         /* mmsgvec */
529         if (syserror(tcp)) {
530                 tprintf("%#lx", tcp->u_arg[1]);
531         } else {
532                 unsigned int len = tcp->u_rval;
533                 unsigned int i;
534
535                 tprints("{");
536                 for (i = 0; i < len; ++i) {
537                         if (i)
538                                 tprints(", ");
539                         printmmsghdr(tcp, tcp->u_arg[1], i, msg_len);
540                 }
541                 tprints("}");
542         }
543         /* vlen */
544         tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
545         /* flags */
546         printflags(msg_flags, tcp->u_arg[3], "MSG_???");
547 }
548
549 void
550 dumpiov_in_mmsghdr(struct tcb *tcp, long addr)
551 {
552         unsigned int len = tcp->u_rval;
553         unsigned int i;
554         struct mmsghdr mmsg;
555
556         for (i = 0; i < len; ++i) {
557                 if (extractmmsghdr(tcp, addr, i, &mmsg)) {
558                         tprintf(" = %lu buffers in vector %u\n",
559                                 (unsigned long)mmsg.msg_hdr.msg_iovlen, i);
560                         dumpiov(tcp, mmsg.msg_hdr.msg_iovlen,
561                                 (long)mmsg.msg_hdr.msg_iov);
562                 }
563         }
564 }
565 #endif /* HAVE_SENDMSG */
566
567 /*
568  * low bits of the socket type define real socket type,
569  * other bits are socket type flags.
570  */
571 static void
572 tprint_sock_type(int flags)
573 {
574         const char *str = xlookup(socktypes, flags & SOCK_TYPE_MASK);
575
576         if (str) {
577                 tprints(str);
578                 flags &= ~SOCK_TYPE_MASK;
579                 if (!flags)
580                         return;
581                 tprints("|");
582         }
583         printflags(sock_type_flags, flags, "SOCK_???");
584 }
585
586 int
587 sys_socket(struct tcb *tcp)
588 {
589         if (entering(tcp)) {
590                 printxval(domains, tcp->u_arg[0], "PF_???");
591                 tprints(", ");
592                 tprint_sock_type(tcp->u_arg[1]);
593                 tprints(", ");
594                 switch (tcp->u_arg[0]) {
595                 case PF_INET:
596 #ifdef PF_INET6
597                 case PF_INET6:
598 #endif
599                         printxval(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
600                         break;
601 #ifdef PF_IPX
602                 case PF_IPX:
603                         /* BTW: I don't believe this.. */
604                         tprints("[");
605                         printxval(domains, tcp->u_arg[2], "PF_???");
606                         tprints("]");
607                         break;
608 #endif /* PF_IPX */
609 #ifdef PF_NETLINK
610                 case PF_NETLINK:
611                         printxval(netlink_protocols, tcp->u_arg[2], "NETLINK_???");
612                         break;
613 #endif
614 #if defined(PF_BLUETOOTH) && defined(HAVE_BLUETOOTH_BLUETOOTH_H)
615                 case PF_BLUETOOTH:
616                         printxval(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
617                         break;
618 #endif
619                 default:
620                         tprintf("%lu", tcp->u_arg[2]);
621                         break;
622                 }
623         }
624         return 0;
625 }
626
627 int
628 sys_bind(struct tcb *tcp)
629 {
630         if (entering(tcp)) {
631                 printfd(tcp, tcp->u_arg[0]);
632                 tprints(", ");
633                 printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
634                 tprintf(", %lu", tcp->u_arg[2]);
635         }
636         return 0;
637 }
638
639 int
640 sys_connect(struct tcb *tcp)
641 {
642         return sys_bind(tcp);
643 }
644
645 int
646 sys_listen(struct tcb *tcp)
647 {
648         if (entering(tcp)) {
649                 printfd(tcp, tcp->u_arg[0]);
650                 tprints(", ");
651                 tprintf("%lu", tcp->u_arg[1]);
652         }
653         return 0;
654 }
655
656 static int
657 do_sockname(struct tcb *tcp, int flags_arg)
658 {
659         if (entering(tcp)) {
660                 printfd(tcp, tcp->u_arg[0]);
661                 tprints(", ");
662                 return 0;
663         }
664         if (!tcp->u_arg[2])
665                 tprintf("%#lx, NULL", tcp->u_arg[1]);
666         else {
667                 int len;
668                 if (tcp->u_arg[1] == 0 || syserror(tcp)
669                     || umove(tcp, tcp->u_arg[2], &len) < 0) {
670                         tprintf("%#lx", tcp->u_arg[1]);
671                 } else {
672                         printsock(tcp, tcp->u_arg[1], len);
673                 }
674                 tprints(", ");
675                 printnum_int(tcp, tcp->u_arg[2], "%u");
676         }
677         if (flags_arg >= 0) {
678                 tprints(", ");
679                 printflags(sock_type_flags, tcp->u_arg[flags_arg],
680                            "SOCK_???");
681         }
682         return 0;
683 }
684
685 int
686 sys_accept(struct tcb *tcp)
687 {
688         do_sockname(tcp, -1);
689         return RVAL_FD;
690 }
691
692 int
693 sys_accept4(struct tcb *tcp)
694 {
695         do_sockname(tcp, 3);
696         return RVAL_FD;
697 }
698
699 int
700 sys_send(struct tcb *tcp)
701 {
702         if (entering(tcp)) {
703                 printfd(tcp, tcp->u_arg[0]);
704                 tprints(", ");
705                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
706                 tprintf(", %lu, ", tcp->u_arg[2]);
707                 /* flags */
708                 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
709         }
710         return 0;
711 }
712
713 int
714 sys_sendto(struct tcb *tcp)
715 {
716         if (entering(tcp)) {
717                 printfd(tcp, tcp->u_arg[0]);
718                 tprints(", ");
719                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
720                 tprintf(", %lu, ", tcp->u_arg[2]);
721                 /* flags */
722                 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
723                 /* to address */
724                 tprints(", ");
725                 printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
726                 /* to length */
727                 tprintf(", %lu", tcp->u_arg[5]);
728         }
729         return 0;
730 }
731
732 #ifdef HAVE_SENDMSG
733
734 int
735 sys_sendmsg(struct tcb *tcp)
736 {
737         if (entering(tcp)) {
738                 printfd(tcp, tcp->u_arg[0]);
739                 tprints(", ");
740                 printmsghdr(tcp, tcp->u_arg[1], (unsigned long) -1L);
741                 /* flags */
742                 tprints(", ");
743                 printflags(msg_flags, tcp->u_arg[2], "MSG_???");
744         }
745         return 0;
746 }
747
748 int
749 sys_sendmmsg(struct tcb *tcp)
750 {
751         if (entering(tcp)) {
752                 /* sockfd */
753                 printfd(tcp, tcp->u_arg[0]);
754                 tprints(", ");
755                 if (!verbose(tcp)) {
756                         tprintf("%#lx, %u, ",
757                                 tcp->u_arg[1], (unsigned int) tcp->u_arg[2]);
758                         printflags(msg_flags, tcp->u_arg[3], "MSG_???");
759                 }
760         } else {
761                 if (verbose(tcp))
762                         decode_mmsg(tcp, (unsigned long) -1L);
763         }
764         return 0;
765 }
766
767 #endif /* HAVE_SENDMSG */
768
769 int
770 sys_recv(struct tcb *tcp)
771 {
772         if (entering(tcp)) {
773                 printfd(tcp, tcp->u_arg[0]);
774                 tprints(", ");
775         } else {
776                 if (syserror(tcp))
777                         tprintf("%#lx", tcp->u_arg[1]);
778                 else
779                         printstr(tcp, tcp->u_arg[1], tcp->u_rval);
780
781                 tprintf(", %lu, ", tcp->u_arg[2]);
782                 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
783         }
784         return 0;
785 }
786
787 int
788 sys_recvfrom(struct tcb *tcp)
789 {
790         int fromlen;
791
792         if (entering(tcp)) {
793                 printfd(tcp, tcp->u_arg[0]);
794                 tprints(", ");
795         } else {
796                 if (syserror(tcp)) {
797                         tprintf("%#lx, %lu, %lu, %#lx, %#lx",
798                                 tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3],
799                                 tcp->u_arg[4], tcp->u_arg[5]);
800                         return 0;
801                 }
802                 /* buf */
803                 printstr(tcp, tcp->u_arg[1], tcp->u_rval);
804                 /* len */
805                 tprintf(", %lu, ", tcp->u_arg[2]);
806                 /* flags */
807                 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
808                 /* from address, len */
809                 if (!tcp->u_arg[4] || !tcp->u_arg[5]) {
810                         if (tcp->u_arg[4] == 0)
811                                 tprints(", NULL");
812                         else
813                                 tprintf(", %#lx", tcp->u_arg[4]);
814                         if (tcp->u_arg[5] == 0)
815                                 tprints(", NULL");
816                         else
817                                 tprintf(", %#lx", tcp->u_arg[5]);
818                         return 0;
819                 }
820                 if (umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
821                         tprints(", {...}, [?]");
822                         return 0;
823                 }
824                 tprints(", ");
825                 printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
826                 /* from length */
827                 tprintf(", [%u]", fromlen);
828         }
829         return 0;
830 }
831
832 #ifdef HAVE_SENDMSG
833
834 int
835 sys_recvmsg(struct tcb *tcp)
836 {
837         if (entering(tcp)) {
838                 printfd(tcp, tcp->u_arg[0]);
839                 tprints(", ");
840         } else {
841                 if (syserror(tcp) || !verbose(tcp))
842                         tprintf("%#lx", tcp->u_arg[1]);
843                 else
844                         printmsghdr(tcp, tcp->u_arg[1], tcp->u_rval);
845                 /* flags */
846                 tprints(", ");
847                 printflags(msg_flags, tcp->u_arg[2], "MSG_???");
848         }
849         return 0;
850 }
851
852 int
853 sys_recvmmsg(struct tcb *tcp)
854 {
855         /* +5 chars are for "left " prefix */
856         static char str[5 + TIMESPEC_TEXT_BUFSIZE];
857
858         if (entering(tcp)) {
859                 printfd(tcp, tcp->u_arg[0]);
860                 tprints(", ");
861                 if (verbose(tcp)) {
862                         sprint_timespec(str, tcp, tcp->u_arg[4]);
863                         /* Abusing tcp->auxstr as temp storage.
864                          * Will be used and freed on syscall exit.
865                          */
866                         tcp->auxstr = strdup(str);
867                 } else {
868                         tprintf("%#lx, %ld, ", tcp->u_arg[1], tcp->u_arg[2]);
869                         printflags(msg_flags, tcp->u_arg[3], "MSG_???");
870                         tprints(", ");
871                         print_timespec(tcp, tcp->u_arg[4]);
872                 }
873                 return 0;
874         } else {
875                 if (verbose(tcp)) {
876                         decode_mmsg(tcp, 0);
877                         /* timeout on entrance */
878                         tprintf(", %s", tcp->auxstr ? tcp->auxstr : "{...}");
879                         free((void *) tcp->auxstr);
880                         tcp->auxstr = NULL;
881                 }
882                 if (syserror(tcp))
883                         return 0;
884                 if (tcp->u_rval == 0) {
885                         tcp->auxstr = "Timeout";
886                         return RVAL_STR;
887                 }
888                 if (!verbose(tcp))
889                         return 0;
890                 /* timeout on exit */
891                 sprint_timespec(stpcpy(str, "left "), tcp, tcp->u_arg[4]);
892                 tcp->auxstr = str;
893                 return RVAL_STR;
894         }
895 }
896
897 #endif /* HAVE_SENDMSG */
898
899 #include "xlat/shutdown_modes.h"
900
901 int
902 sys_shutdown(struct tcb *tcp)
903 {
904         if (entering(tcp)) {
905                 printfd(tcp, tcp->u_arg[0]);
906                 tprints(", ");
907                 printxval(shutdown_modes, tcp->u_arg[1], "SHUT_???");
908         }
909         return 0;
910 }
911
912 int
913 sys_getsockname(struct tcb *tcp)
914 {
915         return do_sockname(tcp, -1);
916 }
917
918 static int
919 do_pipe(struct tcb *tcp, int flags_arg)
920 {
921         if (exiting(tcp)) {
922                 if (syserror(tcp)) {
923                         tprintf("%#lx", tcp->u_arg[0]);
924                 } else {
925 #if !defined(SPARC) && !defined(SPARC64) && !defined(SH) && !defined(IA64)
926                         int fds[2];
927
928                         if (umoven(tcp, tcp->u_arg[0], sizeof fds, (char *) fds) < 0)
929                                 tprints("[...]");
930                         else
931                                 tprintf("[%u, %u]", fds[0], fds[1]);
932 #elif defined(SPARC) || defined(SPARC64) || defined(SH) || defined(IA64)
933                         tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
934 #else
935                         tprintf("%#lx", tcp->u_arg[0]);
936 #endif
937                 }
938                 if (flags_arg >= 0) {
939                         tprints(", ");
940                         printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
941                 }
942         }
943         return 0;
944 }
945
946 int
947 sys_pipe(struct tcb *tcp)
948 {
949         return do_pipe(tcp, -1);
950 }
951
952 int
953 sys_pipe2(struct tcb *tcp)
954 {
955         return do_pipe(tcp, 1);
956 }
957
958 int
959 sys_socketpair(struct tcb *tcp)
960 {
961         int fds[2];
962
963         if (entering(tcp)) {
964                 printxval(domains, tcp->u_arg[0], "PF_???");
965                 tprints(", ");
966                 tprint_sock_type(tcp->u_arg[1]);
967                 tprintf(", %lu", tcp->u_arg[2]);
968         } else {
969                 if (syserror(tcp)) {
970                         tprintf(", %#lx", tcp->u_arg[3]);
971                         return 0;
972                 }
973                 if (umoven(tcp, tcp->u_arg[3], sizeof fds, (char *) fds) < 0)
974                         tprints(", [...]");
975                 else
976                         tprintf(", [%u, %u]", fds[0], fds[1]);
977         }
978         return 0;
979 }
980
981 int
982 sys_getsockopt(struct tcb *tcp)
983 {
984         if (entering(tcp)) {
985                 printfd(tcp, tcp->u_arg[0]);
986                 tprints(", ");
987                 printxval(socketlayers, tcp->u_arg[1], "SOL_???");
988                 tprints(", ");
989                 switch (tcp->u_arg[1]) {
990                 case SOL_SOCKET:
991                         printxval(sockoptions, tcp->u_arg[2], "SO_???");
992                         break;
993 #ifdef SOL_IP
994                 case SOL_IP:
995                         printxval(sockipoptions, tcp->u_arg[2], "IP_???");
996                         break;
997 #endif
998 #ifdef SOL_IPV6
999                 case SOL_IPV6:
1000                         printxval(sockipv6options, tcp->u_arg[2], "IPV6_???");
1001                         break;
1002 #endif
1003 #ifdef SOL_IPX
1004                 case SOL_IPX:
1005                         printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
1006                         break;
1007 #endif
1008 #ifdef SOL_PACKET
1009                 case SOL_PACKET:
1010                         printxval(sockpacketoptions, tcp->u_arg[2], "PACKET_???");
1011                         break;
1012 #endif
1013 #ifdef SOL_TCP
1014                 case SOL_TCP:
1015                         printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
1016                         break;
1017 #endif
1018 #ifdef SOL_SCTP
1019                 case SOL_SCTP:
1020                         printxval(socksctpoptions, tcp->u_arg[2], "SCTP_???");
1021                         break;
1022 #endif
1023
1024                 /* SOL_AX25 SOL_ROSE SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
1025                  * etc. still need work */
1026                 default:
1027                         tprintf("%lu", tcp->u_arg[2]);
1028                         break;
1029                 }
1030                 tprints(", ");
1031         } else {
1032                 int len;
1033                 if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &len) < 0) {
1034                         tprintf("%#lx, %#lx",
1035                                 tcp->u_arg[3], tcp->u_arg[4]);
1036                         return 0;
1037                 }
1038
1039                 switch (tcp->u_arg[1]) {
1040                 case SOL_SOCKET:
1041                         switch (tcp->u_arg[2]) {
1042 #ifdef SO_LINGER
1043                         case SO_LINGER:
1044                                 if (len == sizeof(struct linger)) {
1045                                         struct linger linger;
1046                                         if (umove(tcp,
1047                                                    tcp->u_arg[3],
1048                                                    &linger) < 0)
1049                                                 break;
1050                                         tprintf("{onoff=%d, linger=%d}, "
1051                                                 "[%d]",
1052                                                 linger.l_onoff,
1053                                                 linger.l_linger,
1054                                                 len);
1055                                         return 0;
1056                                 }
1057                                 break;
1058 #endif
1059 #ifdef SO_PEERCRED
1060                         case SO_PEERCRED:
1061                                 if (len == sizeof(struct ucred)) {
1062                                         struct ucred uc;
1063                                         if (umove(tcp,
1064                                                    tcp->u_arg[3],
1065                                                    &uc) < 0)
1066                                                 break;
1067                                         tprintf("{pid=%ld, uid=%ld, gid=%ld}, "
1068                                                 "[%d]",
1069                                                 (long)uc.pid,
1070                                                 (long)uc.uid,
1071                                                 (long)uc.gid,
1072                                                 len);
1073                                         return 0;
1074                                 }
1075                                 break;
1076 #endif
1077                         }
1078                         break;
1079                 case SOL_PACKET:
1080                         switch (tcp->u_arg[2]) {
1081 #ifdef PACKET_STATISTICS
1082                         case PACKET_STATISTICS:
1083                                 if (len == sizeof(struct tpacket_stats)) {
1084                                         struct tpacket_stats stats;
1085                                         if (umove(tcp,
1086                                                    tcp->u_arg[3],
1087                                                    &stats) < 0)
1088                                                 break;
1089                                         tprintf("{packets=%u, drops=%u}, "
1090                                                 "[%d]",
1091                                                 stats.tp_packets,
1092                                                 stats.tp_drops,
1093                                                 len);
1094                                         return 0;
1095                                 }
1096                                 break;
1097 #endif
1098                         }
1099                         break;
1100                 }
1101
1102                 if (len == sizeof(int)) {
1103                         printnum_int(tcp, tcp->u_arg[3], "%d");
1104                 }
1105                 else {
1106                         printstr(tcp, tcp->u_arg[3], len);
1107                 }
1108                 tprintf(", [%d]", len);
1109         }
1110         return 0;
1111 }
1112
1113 #if defined(ICMP_FILTER)
1114 static void printicmpfilter(struct tcb *tcp, long addr)
1115 {
1116         struct icmp_filter      filter;
1117
1118         if (!addr) {
1119                 tprints("NULL");
1120                 return;
1121         }
1122         if (syserror(tcp) || !verbose(tcp)) {
1123                 tprintf("%#lx", addr);
1124                 return;
1125         }
1126         if (umove(tcp, addr, &filter) < 0) {
1127                 tprints("{...}");
1128                 return;
1129         }
1130
1131         tprints("~(");
1132         printflags(icmpfilterflags, ~filter.data, "ICMP_???");
1133         tprints(")");
1134 }
1135 #endif /* ICMP_FILTER */
1136
1137 static int
1138 printsockopt(struct tcb *tcp, int level, int name, long addr, int len)
1139 {
1140         printxval(socketlayers, level, "SOL_??");
1141         tprints(", ");
1142         switch (level) {
1143         case SOL_SOCKET:
1144                 printxval(sockoptions, name, "SO_???");
1145                 switch (name) {
1146 #if defined(SO_LINGER)
1147                 case SO_LINGER:
1148                         if (len == sizeof(struct linger)) {
1149                                 struct linger linger;
1150                                 if (umove(tcp, addr, &linger) < 0)
1151                                         break;
1152                                 tprintf(", {onoff=%d, linger=%d}",
1153                                         linger.l_onoff,
1154                                         linger.l_linger);
1155                                 return 0;
1156                         }
1157                         break;
1158 #endif
1159                 }
1160                 break;
1161 #ifdef SOL_IP
1162         case SOL_IP:
1163                 printxval(sockipoptions, name, "IP_???");
1164                 break;
1165 #endif
1166 #ifdef SOL_IPV6
1167         case SOL_IPV6:
1168                 printxval(sockipv6options, name, "IPV6_???");
1169                 break;
1170 #endif
1171 #ifdef SOL_IPX
1172         case SOL_IPX:
1173                 printxval(sockipxoptions, name, "IPX_???");
1174                 break;
1175 #endif
1176 #ifdef SOL_PACKET
1177         case SOL_PACKET:
1178                 printxval(sockpacketoptions, name, "PACKET_???");
1179                 /* TODO: decode packate_mreq for PACKET_*_MEMBERSHIP */
1180                 switch (name) {
1181 #ifdef PACKET_RX_RING
1182                 case PACKET_RX_RING:
1183 #endif
1184 #ifdef PACKET_TX_RING
1185                 case PACKET_TX_RING:
1186 #endif
1187 #if defined(PACKET_RX_RING) || defined(PACKET_TX_RING)
1188                         if (len == sizeof(struct tpacket_req)) {
1189                                 struct tpacket_req req;
1190                                 if (umove(tcp, addr, &req) < 0)
1191                                         break;
1192                                 tprintf(", {block_size=%u, block_nr=%u, frame_size=%u, frame_nr=%u}",
1193                                         req.tp_block_size,
1194                                         req.tp_block_nr,
1195                                         req.tp_frame_size,
1196                                         req.tp_frame_nr);
1197                                 return 0;
1198                         }
1199                         break;
1200 #endif /* PACKET_RX_RING || PACKET_TX_RING */
1201                 }
1202                 break;
1203 #endif
1204 #ifdef SOL_TCP
1205         case SOL_TCP:
1206                 printxval(socktcpoptions, name, "TCP_???");
1207                 break;
1208 #endif
1209 #ifdef SOL_SCTP
1210         case SOL_SCTP:
1211                 printxval(socksctpoptions, name, "SCTP_???");
1212                 break;
1213 #endif
1214 #ifdef SOL_RAW
1215         case SOL_RAW:
1216                 printxval(sockrawoptions, name, "RAW_???");
1217                 switch (name) {
1218 #if defined(ICMP_FILTER)
1219                         case ICMP_FILTER:
1220                                 tprints(", ");
1221                                 printicmpfilter(tcp, addr);
1222                                 return 0;
1223 #endif
1224                 }
1225                 break;
1226 #endif
1227
1228                 /* SOL_AX25 SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
1229                  * etc. still need work  */
1230
1231         default:
1232                 tprintf("%u", name);
1233         }
1234
1235         /* default arg printing */
1236
1237         tprints(", ");
1238
1239         if (len == sizeof(int)) {
1240                 printnum_int(tcp, addr, "%d");
1241         }
1242         else {
1243                 printstr(tcp, addr, len);
1244         }
1245         return 0;
1246 }
1247
1248 int
1249 sys_setsockopt(struct tcb *tcp)
1250 {
1251         if (entering(tcp)) {
1252                 printfd(tcp, tcp->u_arg[0]);
1253                 tprints(", ");
1254                 printsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
1255                               tcp->u_arg[3], tcp->u_arg[4]);
1256                 tprintf(", %lu", tcp->u_arg[4]);
1257         }
1258         return 0;
1259 }