]> granicus.if.org Git - strace/blob - net.c
3a7f94036bb2f74379c0e1c3890fe0015a66f917
[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 "msghdr.h"
33 #include <sys/stat.h>
34 #include <sys/socket.h>
35 #include <sys/uio.h>
36 #include <sys/un.h>
37 #include <netinet/in.h>
38 #ifdef HAVE_NETINET_TCP_H
39 # include <netinet/tcp.h>
40 #endif
41 #ifdef HAVE_NETINET_UDP_H
42 # include <netinet/udp.h>
43 #endif
44 #ifdef HAVE_NETINET_SCTP_H
45 # include <netinet/sctp.h>
46 #endif
47 #include <arpa/inet.h>
48 #include <net/if.h>
49 #include <asm/types.h>
50 #ifdef HAVE_NETIPX_IPX_H
51 # include <netipx/ipx.h>
52 #else
53 # include <linux/ipx.h>
54 #endif
55
56 #if defined(HAVE_LINUX_IP_VS_H)
57 # include <linux/ip_vs.h>
58 #endif
59 #include <linux/netlink.h>
60 #if defined(HAVE_LINUX_NETFILTER_ARP_ARP_TABLES_H)
61 # include <linux/netfilter_arp/arp_tables.h>
62 #endif
63 #if defined(HAVE_LINUX_NETFILTER_BRIDGE_EBTABLES_H)
64 # include <linux/netfilter_bridge/ebtables.h>
65 #endif
66 #if defined(HAVE_LINUX_NETFILTER_IPV4_IP_TABLES_H)
67 # include <linux/netfilter_ipv4/ip_tables.h>
68 #endif
69 #if defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H)
70 # include <linux/netfilter_ipv6/ip6_tables.h>
71 #endif
72 #include <linux/if_packet.h>
73 #include <linux/icmp.h>
74
75 #include "xlat/socktypes.h"
76 #include "xlat/sock_type_flags.h"
77 #ifndef SOCK_TYPE_MASK
78 # define SOCK_TYPE_MASK 0xf
79 #endif
80
81 #include "xlat/socketlayers.h"
82
83 #include "xlat/inet_protocols.h"
84
85 #if !defined NETLINK_SOCK_DIAG && defined NETLINK_INET_DIAG
86 # define NETLINK_SOCK_DIAG NETLINK_INET_DIAG
87 #endif
88 #include "xlat/netlink_protocols.h"
89
90 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
91 # include <bluetooth/bluetooth.h>
92 # include "xlat/bt_protocols.h"
93 #endif
94
95 #include "xlat/msg_flags.h"
96
97 void
98 print_ifindex(unsigned int ifindex)
99 {
100 #ifdef HAVE_IF_INDEXTONAME
101         char buf[IFNAMSIZ + 1];
102
103         if (if_indextoname(ifindex, buf)) {
104                 tprints("if_nametoindex(");
105                 print_quoted_string(buf, sizeof(buf), QUOTE_0_TERMINATED);
106                 tprints(")");
107                 return;
108         }
109 #endif
110         tprintf("%u", ifindex);
111 }
112
113 #include "xlat/scmvals.h"
114 #include "xlat/ip_cmsg_types.h"
115
116 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
117 struct cmsghdr32 {
118         uint32_t cmsg_len;
119         int cmsg_level;
120         int cmsg_type;
121 };
122 #endif
123
124 typedef union {
125         char *ptr;
126         struct cmsghdr *cmsg;
127 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
128         struct cmsghdr32 *cmsg32;
129 #endif
130 } union_cmsghdr;
131
132 static void
133 print_scm_rights(struct tcb *tcp, const void *cmsg_data,
134                  const size_t data_len)
135 {
136         const int *fds = cmsg_data;
137         const char *end = (const char *) cmsg_data + data_len;
138         bool seen = false;
139
140         if (sizeof(*fds) > data_len)
141                 return;
142
143         tprints(", [");
144         while ((const char *) fds < end) {
145                 if (seen)
146                         tprints(", ");
147                 else
148                         seen = true;
149                 printfd(tcp, *fds++);
150         }
151         tprints("]");
152 }
153
154 static void
155 print_scm_creds(struct tcb *tcp, const void *cmsg_data,
156                 const size_t data_len)
157 {
158         const struct ucred *uc = cmsg_data;
159
160         if (sizeof(*uc) > data_len)
161                 return;
162
163         tprintf(", {pid=%u, uid=%u, gid=%u}",
164                 (unsigned) uc->pid, (unsigned) uc->uid, (unsigned) uc->gid);
165 }
166
167 static void
168 print_scm_security(struct tcb *tcp, const void *cmsg_data,
169                    const size_t data_len)
170 {
171         if (!data_len)
172                 return;
173
174         tprints(", ");
175         print_quoted_string(cmsg_data, data_len, 0);
176 }
177
178 static void
179 print_cmsg_ip_pktinfo(struct tcb *tcp, const void *cmsg_data,
180                       const size_t data_len)
181 {
182         const struct in_pktinfo *info = cmsg_data;
183
184         if (sizeof(*info) > data_len)
185                 return;
186
187         tprints(", {ipi_ifindex=");
188         print_ifindex(info->ipi_ifindex);
189         tprintf(", ipi_spec_dst=inet_addr(\"%s\"), ipi_addr=inet_addr(\"%s\")}",
190                 inet_ntoa(info->ipi_spec_dst), inet_ntoa(info->ipi_addr));
191 }
192
193 static void
194 print_cmsg_ip_ttl(struct tcb *tcp, const void *cmsg_data,
195                   const size_t data_len)
196 {
197         const unsigned int *ttl = cmsg_data;
198
199         if (sizeof(*ttl) > data_len)
200                 return;
201
202         tprintf(", {ttl=%u}", *ttl);
203 }
204
205 static void
206 print_cmsg_ip_tos(struct tcb *tcp, const void *cmsg_data,
207                   const size_t data_len)
208 {
209         const uint8_t *tos = cmsg_data;
210
211         if (sizeof(*tos) > data_len)
212                 return;
213
214         tprintf(", {tos=%x}", *tos);
215 }
216
217 static void
218 print_cmsg_ip_checksum(struct tcb *tcp, const void *cmsg_data,
219                        const size_t data_len)
220 {
221         const uint32_t *csum = cmsg_data;
222
223         if (sizeof(*csum) > data_len)
224                 return;
225
226         tprintf(", {csum=%u}", *csum);
227 }
228
229 static void
230 print_cmsg_ip_opts(struct tcb *tcp, const void *cmsg_data,
231                    const size_t data_len)
232 {
233         const unsigned char *opts = cmsg_data;
234         size_t i;
235
236         if (!data_len)
237                 return;
238
239         tprints(", {opts=0x");
240         for (i = 0; i < data_len; ++i)
241                 tprintf("%02x", opts[i]);
242         tprints("}");
243 }
244
245 static void
246 print_cmsg_ip_recverr(struct tcb *tcp, const void *cmsg_data,
247                       const size_t data_len)
248 {
249         const struct {
250                 uint32_t ee_errno;
251                 uint8_t  ee_origin;
252                 uint8_t  ee_type;
253                 uint8_t  ee_code;
254                 uint8_t  ee_pad;
255                 uint32_t ee_info;
256                 uint32_t ee_data;
257                 struct sockaddr_in offender;
258         } *err = cmsg_data;
259
260         if (sizeof(*err) > data_len)
261                 return;
262
263         tprintf(", {ee_errno=%u, ee_origin=%u, ee_type=%u, ee_code=%u"
264                 ", ee_info=%u, ee_data=%u, offender=",
265                 err->ee_errno, err->ee_origin, err->ee_type,
266                 err->ee_code, err->ee_info, err->ee_data);
267         print_sockaddr(tcp, &err->offender, sizeof(err->offender));
268         tprints("}");
269 }
270
271 static void
272 print_cmsg_ip_origdstaddr(struct tcb *tcp, const void *cmsg_data,
273                           const size_t data_len)
274 {
275         if (sizeof(struct sockaddr_in) > data_len)
276                 return;
277
278         tprints(", ");
279         print_sockaddr(tcp, cmsg_data, data_len);
280 }
281
282 static void
283 print_cmsg_type_data(struct tcb *tcp, const int cmsg_level, const int cmsg_type,
284                      const void *cmsg_data, const size_t data_len)
285 {
286         switch (cmsg_level) {
287         case SOL_SOCKET:
288                 printxval(scmvals, cmsg_type, "SCM_???");
289                 switch (cmsg_type) {
290                 case SCM_RIGHTS:
291                         print_scm_rights(tcp, cmsg_data, data_len);
292                         break;
293                 case SCM_CREDENTIALS:
294                         print_scm_creds(tcp, cmsg_data, data_len);
295                         break;
296                 case SCM_SECURITY:
297                         print_scm_security(tcp, cmsg_data, data_len);
298                         break;
299                 }
300                 break;
301         case SOL_IP:
302                 printxval(ip_cmsg_types, cmsg_type, "IP_???");
303                 switch (cmsg_type) {
304                 case IP_PKTINFO:
305                         print_cmsg_ip_pktinfo(tcp, cmsg_data, data_len);
306                         break;
307                 case IP_TTL:
308                         print_cmsg_ip_ttl(tcp, cmsg_data, data_len);
309                         break;
310                 case IP_TOS:
311                         print_cmsg_ip_tos(tcp, cmsg_data, data_len);
312                         break;
313                 case IP_RECVOPTS:
314                 case IP_RETOPTS:
315                         print_cmsg_ip_opts(tcp, cmsg_data, data_len);
316                         break;
317                 case IP_RECVERR:
318                         print_cmsg_ip_recverr(tcp, cmsg_data, data_len);
319                         break;
320                 case IP_ORIGDSTADDR:
321                         print_cmsg_ip_origdstaddr(tcp, cmsg_data, data_len);
322                         break;
323                 case IP_CHECKSUM:
324                         print_cmsg_ip_checksum(tcp, cmsg_data, data_len);
325                         break;
326                 case SCM_SECURITY:
327                         print_scm_security(tcp, cmsg_data, data_len);
328                         break;
329                 }
330                 break;
331         default:
332                 tprintf("%u", cmsg_type);
333         }
334 }
335
336 static void
337 decode_msg_control(struct tcb *tcp, unsigned long addr, size_t len)
338 {
339         const size_t cmsg_size =
340 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
341                 (current_wordsize < sizeof(long)) ? sizeof(struct cmsghdr32) :
342 #endif
343                         sizeof(struct cmsghdr);
344
345         if (!len)
346                 return;
347         tprints(", msg_control=");
348
349         char *buf = len < cmsg_size ? NULL : malloc(len);
350         if (!buf || umoven(tcp, addr, len, buf) < 0) {
351                 printaddr(addr);
352                 free(buf);
353                 return;
354         }
355
356         union_cmsghdr u = { .ptr = buf };
357
358         tprints("[");
359         while (len >= cmsg_size) {
360                 size_t cmsg_len =
361 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
362                         (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_len :
363 #endif
364                                 u.cmsg->cmsg_len;
365                 int cmsg_level =
366 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
367                         (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_level :
368 #endif
369                                 u.cmsg->cmsg_level;
370                 int cmsg_type =
371 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
372                         (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_type :
373 #endif
374                                 u.cmsg->cmsg_type;
375
376                 if (u.ptr != buf)
377                         tprints(", ");
378                 tprintf("{cmsg_len=%lu, cmsg_level=", (unsigned long) cmsg_len);
379                 printxval(socketlayers, cmsg_level, "SOL_???");
380                 tprints(", cmsg_type=");
381
382                 if (cmsg_len > len)
383                         cmsg_len = len;
384
385                 print_cmsg_type_data(tcp, cmsg_level, cmsg_type,
386                                      (const void *) (u.ptr + cmsg_size),
387                                      cmsg_len > cmsg_size ? cmsg_len - cmsg_size: 0);
388                 tprints("}");
389
390                 if (cmsg_len < cmsg_size) {
391                         len -= cmsg_size;
392                         break;
393                 }
394                 cmsg_len = (cmsg_len + current_wordsize - 1) &
395                         (size_t) ~(current_wordsize - 1);
396                 if (cmsg_len >= len) {
397                         len = 0;
398                         break;
399                 }
400                 u.ptr += cmsg_len;
401                 len -= cmsg_len;
402         }
403         if (len)
404                 tprints(", ...");
405         tprints("]");
406         free(buf);
407 }
408
409 static void
410 print_msghdr(struct tcb *tcp, struct msghdr *msg, unsigned long data_size)
411 {
412         tprints("{msg_name=");
413         decode_sockaddr(tcp, (long)msg->msg_name, msg->msg_namelen);
414         tprintf(", msg_namelen=%d", msg->msg_namelen);
415
416         tprints(", msg_iov=");
417         tprint_iov_upto(tcp, (unsigned long) msg->msg_iovlen,
418                         (unsigned long) msg->msg_iov, IOV_DECODE_STR, data_size);
419         tprintf(", msg_iovlen=%lu", (unsigned long) msg->msg_iovlen);
420
421         decode_msg_control(tcp, (unsigned long) msg->msg_control,
422                      msg->msg_controllen);
423         tprintf(", msg_controllen=%lu", (unsigned long) msg->msg_controllen);
424
425         tprints(", msg_flags=");
426         printflags(msg_flags, msg->msg_flags, "MSG_???");
427         tprints("}");
428 }
429
430 struct msghdr32 {
431         uint32_t /* void* */    msg_name;
432         uint32_t /* socklen_t */msg_namelen;
433         uint32_t /* iovec* */   msg_iov;
434         uint32_t /* size_t */   msg_iovlen;
435         uint32_t /* void* */    msg_control;
436         uint32_t /* size_t */   msg_controllen;
437         uint32_t /* int */      msg_flags;
438 };
439 struct mmsghdr32 {
440         struct msghdr32         msg_hdr;
441         uint32_t /* unsigned */ msg_len;
442 };
443
444 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
445 static void
446 copy_from_msghdr32(struct msghdr *to_msg, struct msghdr32 *from_msg32)
447 {
448         to_msg->msg_name       = (void*)(long)from_msg32->msg_name;
449         to_msg->msg_namelen    =              from_msg32->msg_namelen;
450         to_msg->msg_iov        = (void*)(long)from_msg32->msg_iov;
451         to_msg->msg_iovlen     =              from_msg32->msg_iovlen;
452         to_msg->msg_control    = (void*)(long)from_msg32->msg_control;
453         to_msg->msg_controllen =              from_msg32->msg_controllen;
454         to_msg->msg_flags      =              from_msg32->msg_flags;
455 }
456 #endif
457
458 static bool
459 fetch_msghdr(struct tcb *tcp, long addr, struct msghdr *msg)
460 {
461 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
462         if (current_wordsize == 4) {
463                 struct msghdr32 msg32;
464
465                 if (umove(tcp, addr, &msg32) < 0)
466                         return false;
467                 copy_from_msghdr32(msg, &msg32);
468         } else
469 #endif
470         if (umove(tcp, addr, msg) < 0)
471                 return false;
472         return true;
473 }
474
475 static bool
476 fetch_mmsghdr(struct tcb *tcp, long addr, unsigned int idx, struct mmsghdr *mmsg)
477 {
478 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
479         if (current_wordsize == 4) {
480                 struct mmsghdr32 mmsg32;
481
482                 addr += sizeof(struct mmsghdr32) * idx;
483                 if (umove(tcp, addr, &mmsg32) < 0)
484                         return false;
485
486                 copy_from_msghdr32(&mmsg->msg_hdr, &mmsg32.msg_hdr);
487                 mmsg->msg_len = mmsg32.msg_len;
488         } else
489 #endif
490         {
491                 addr += sizeof(*mmsg) * idx;
492                 if (umove(tcp, addr, mmsg) < 0)
493                         return false;
494         }
495         return true;
496 }
497
498 static void
499 decode_msghdr(struct tcb *tcp, long addr, unsigned long data_size)
500 {
501         struct msghdr msg;
502
503         if (verbose(tcp) && fetch_msghdr(tcp, addr, &msg))
504                 print_msghdr(tcp, &msg, data_size);
505         else
506                 printaddr(addr);
507 }
508
509 void
510 dumpiov_in_msghdr(struct tcb *tcp, long addr, unsigned long data_size)
511 {
512         struct msghdr msg;
513
514         if (fetch_msghdr(tcp, addr, &msg))
515                 dumpiov_upto(tcp, msg.msg_iovlen, (long)msg.msg_iov, data_size);
516 }
517
518 static void
519 decode_mmsghdr(struct tcb *tcp, long addr, unsigned int idx, unsigned long msg_len)
520 {
521         struct mmsghdr mmsg;
522
523         if (fetch_mmsghdr(tcp, addr, idx, &mmsg)) {
524                 tprints("{");
525                 print_msghdr(tcp, &mmsg.msg_hdr, msg_len ? msg_len : mmsg.msg_len);
526                 tprintf(", %u}", mmsg.msg_len);
527         }
528         else
529                 printaddr(addr);
530 }
531
532 static void
533 decode_mmsg(struct tcb *tcp, unsigned long msg_len)
534 {
535         /* mmsgvec */
536         if (syserror(tcp)) {
537                 printaddr(tcp->u_arg[1]);
538         } else {
539                 unsigned int len = tcp->u_rval;
540                 unsigned int i;
541
542                 tprints("{");
543                 for (i = 0; i < len; ++i) {
544                         if (i)
545                                 tprints(", ");
546                         decode_mmsghdr(tcp, tcp->u_arg[1], i, msg_len);
547                 }
548                 tprints("}");
549         }
550         /* vlen */
551         tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
552         /* flags */
553         printflags(msg_flags, tcp->u_arg[3], "MSG_???");
554 }
555
556 void
557 dumpiov_in_mmsghdr(struct tcb *tcp, long addr)
558 {
559         unsigned int len = tcp->u_rval;
560         unsigned int i;
561         struct mmsghdr mmsg;
562
563         for (i = 0; i < len; ++i) {
564                 if (fetch_mmsghdr(tcp, addr, i, &mmsg)) {
565                         tprintf(" = %lu buffers in vector %u\n",
566                                 (unsigned long)mmsg.msg_hdr.msg_iovlen, i);
567                         dumpiov_upto(tcp, mmsg.msg_hdr.msg_iovlen,
568                                 (long)mmsg.msg_hdr.msg_iov, mmsg.msg_len);
569                 }
570         }
571 }
572
573 /*
574  * low bits of the socket type define real socket type,
575  * other bits are socket type flags.
576  */
577 static void
578 tprint_sock_type(unsigned int flags)
579 {
580         const char *str = xlookup(socktypes, flags & SOCK_TYPE_MASK);
581
582         if (str) {
583                 tprints(str);
584                 flags &= ~SOCK_TYPE_MASK;
585                 if (!flags)
586                         return;
587                 tprints("|");
588         }
589         printflags(sock_type_flags, flags, "SOCK_???");
590 }
591
592 SYS_FUNC(socket)
593 {
594         printxval(addrfams, tcp->u_arg[0], "AF_???");
595         tprints(", ");
596         tprint_sock_type(tcp->u_arg[1]);
597         tprints(", ");
598         switch (tcp->u_arg[0]) {
599         case AF_INET:
600         case AF_INET6:
601                 printxval(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
602                 break;
603
604         case AF_NETLINK:
605                 printxval(netlink_protocols, tcp->u_arg[2], "NETLINK_???");
606                 break;
607
608 #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
609         case AF_BLUETOOTH:
610                 printxval(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
611                 break;
612 #endif
613
614         default:
615                 tprintf("%lu", tcp->u_arg[2]);
616                 break;
617         }
618
619         return RVAL_DECODED | RVAL_FD;
620 }
621
622 SYS_FUNC(bind)
623 {
624         printfd(tcp, tcp->u_arg[0]);
625         tprints(", ");
626         decode_sockaddr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
627         tprintf(", %lu", tcp->u_arg[2]);
628
629         return RVAL_DECODED;
630 }
631
632 SYS_FUNC(listen)
633 {
634         printfd(tcp, tcp->u_arg[0]);
635         tprints(", ");
636         tprintf("%lu", tcp->u_arg[1]);
637
638         return RVAL_DECODED;
639 }
640
641 static int
642 do_sockname(struct tcb *tcp, int flags_arg)
643 {
644         if (entering(tcp)) {
645                 printfd(tcp, tcp->u_arg[0]);
646                 tprints(", ");
647                 return 0;
648         }
649
650         int len;
651         if (!tcp->u_arg[2] || !verbose(tcp) || syserror(tcp) ||
652             umove(tcp, tcp->u_arg[2], &len) < 0) {
653                 printaddr(tcp->u_arg[1]);
654                 tprints(", ");
655                 printaddr(tcp->u_arg[2]);
656         } else {
657                 decode_sockaddr(tcp, tcp->u_arg[1], len);
658                 tprintf(", [%d]", len);
659         }
660
661         if (flags_arg >= 0) {
662                 tprints(", ");
663                 printflags(sock_type_flags, tcp->u_arg[flags_arg],
664                            "SOCK_???");
665         }
666         return 0;
667 }
668
669 SYS_FUNC(accept)
670 {
671         do_sockname(tcp, -1);
672         return RVAL_FD;
673 }
674
675 SYS_FUNC(accept4)
676 {
677         do_sockname(tcp, 3);
678         return RVAL_FD;
679 }
680
681 SYS_FUNC(send)
682 {
683         printfd(tcp, tcp->u_arg[0]);
684         tprints(", ");
685         printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
686         tprintf(", %lu, ", tcp->u_arg[2]);
687         /* flags */
688         printflags(msg_flags, tcp->u_arg[3], "MSG_???");
689
690         return RVAL_DECODED;
691 }
692
693 SYS_FUNC(sendto)
694 {
695         printfd(tcp, tcp->u_arg[0]);
696         tprints(", ");
697         printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
698         tprintf(", %lu, ", tcp->u_arg[2]);
699         /* flags */
700         printflags(msg_flags, tcp->u_arg[3], "MSG_???");
701         /* to address */
702         tprints(", ");
703         decode_sockaddr(tcp, tcp->u_arg[4], tcp->u_arg[5]);
704         /* to length */
705         tprintf(", %lu", tcp->u_arg[5]);
706
707         return RVAL_DECODED;
708 }
709
710 SYS_FUNC(sendmsg)
711 {
712         printfd(tcp, tcp->u_arg[0]);
713         tprints(", ");
714         decode_msghdr(tcp, tcp->u_arg[1], (unsigned long) -1L);
715         /* flags */
716         tprints(", ");
717         printflags(msg_flags, tcp->u_arg[2], "MSG_???");
718
719         return RVAL_DECODED;
720 }
721
722 SYS_FUNC(sendmmsg)
723 {
724         if (entering(tcp)) {
725                 /* sockfd */
726                 printfd(tcp, tcp->u_arg[0]);
727                 tprints(", ");
728                 if (!verbose(tcp)) {
729                         printaddr(tcp->u_arg[1]);
730                         tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
731                         printflags(msg_flags, tcp->u_arg[3], "MSG_???");
732                 }
733         } else {
734                 if (verbose(tcp))
735                         decode_mmsg(tcp, (unsigned long) -1L);
736         }
737         return 0;
738 }
739
740 SYS_FUNC(recv)
741 {
742         if (entering(tcp)) {
743                 printfd(tcp, tcp->u_arg[0]);
744                 tprints(", ");
745         } else {
746                 if (syserror(tcp))
747                         printaddr(tcp->u_arg[1]);
748                 else
749                         printstr(tcp, tcp->u_arg[1], tcp->u_rval);
750
751                 tprintf(", %lu, ", tcp->u_arg[2]);
752                 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
753         }
754         return 0;
755 }
756
757 SYS_FUNC(recvfrom)
758 {
759         int fromlen;
760
761         if (entering(tcp)) {
762                 printfd(tcp, tcp->u_arg[0]);
763                 tprints(", ");
764         } else {
765                 /* buf */
766                 if (syserror(tcp)) {
767                         printaddr(tcp->u_arg[1]);
768                 } else {
769                         printstr(tcp, tcp->u_arg[1], tcp->u_rval);
770                 }
771                 /* len */
772                 tprintf(", %lu, ", tcp->u_arg[2]);
773                 /* flags */
774                 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
775                 tprints(", ");
776                 if (syserror(tcp) || !tcp->u_arg[4] || !tcp->u_arg[5] ||
777                     umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
778                         /* from address, len */
779                         printaddr(tcp->u_arg[4]);
780                         tprints(", ");
781                         printaddr(tcp->u_arg[5]);
782                         return 0;
783                 }
784                 /* from address */
785                 decode_sockaddr(tcp, tcp->u_arg[4], fromlen);
786                 /* from length */
787                 tprintf(", [%u]", fromlen);
788         }
789         return 0;
790 }
791
792 SYS_FUNC(recvmsg)
793 {
794         if (entering(tcp)) {
795                 printfd(tcp, tcp->u_arg[0]);
796                 tprints(", ");
797         } else {
798                 if (syserror(tcp))
799                         printaddr(tcp->u_arg[1]);
800                 else
801                         decode_msghdr(tcp, tcp->u_arg[1], tcp->u_rval);
802                 /* flags */
803                 tprints(", ");
804                 printflags(msg_flags, tcp->u_arg[2], "MSG_???");
805         }
806         return 0;
807 }
808
809 SYS_FUNC(recvmmsg)
810 {
811         static char str[sizeof("left") + TIMESPEC_TEXT_BUFSIZE];
812
813         if (entering(tcp)) {
814                 printfd(tcp, tcp->u_arg[0]);
815                 tprints(", ");
816                 if (verbose(tcp)) {
817                         /* Abusing tcp->auxstr as temp storage.
818                          * Will be used and cleared on syscall exit.
819                          */
820                         tcp->auxstr = sprint_timespec(tcp, tcp->u_arg[4]);
821                 } else {
822                         printaddr(tcp->u_arg[1]);
823                         tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
824                         printflags(msg_flags, tcp->u_arg[3], "MSG_???");
825                         tprints(", ");
826                         print_timespec(tcp, tcp->u_arg[4]);
827                 }
828                 return 0;
829         } else {
830                 if (verbose(tcp)) {
831                         decode_mmsg(tcp, 0);
832                         tprints(", ");
833                         /* timeout on entrance */
834                         tprints(tcp->auxstr);
835                         tcp->auxstr = NULL;
836                 }
837                 if (syserror(tcp))
838                         return 0;
839                 if (tcp->u_rval == 0) {
840                         tcp->auxstr = "Timeout";
841                         return RVAL_STR;
842                 }
843                 if (!verbose(tcp))
844                         return 0;
845                 /* timeout on exit */
846                 snprintf(str, sizeof(str), "left %s",
847                          sprint_timespec(tcp, tcp->u_arg[4]));
848                 tcp->auxstr = str;
849                 return RVAL_STR;
850         }
851 }
852
853 #include "xlat/shutdown_modes.h"
854
855 SYS_FUNC(shutdown)
856 {
857         printfd(tcp, tcp->u_arg[0]);
858         tprints(", ");
859         printxval(shutdown_modes, tcp->u_arg[1], "SHUT_???");
860
861         return RVAL_DECODED;
862 }
863
864 SYS_FUNC(getsockname)
865 {
866         return do_sockname(tcp, -1);
867 }
868
869 static void
870 printpair_fd(struct tcb *tcp, const int i0, const int i1)
871 {
872         tprints("[");
873         printfd(tcp, i0);
874         tprints(", ");
875         printfd(tcp, i1);
876         tprints("]");
877 }
878
879 static void
880 decode_pair_fd(struct tcb *tcp, const long addr)
881 {
882         int pair[2];
883
884         if (umove_or_printaddr(tcp, addr, &pair))
885                 return;
886
887         printpair_fd(tcp, pair[0], pair[1]);
888 }
889
890 static int
891 do_pipe(struct tcb *tcp, int flags_arg)
892 {
893         if (exiting(tcp)) {
894                 decode_pair_fd(tcp, tcp->u_arg[0]);
895                 if (flags_arg >= 0) {
896                         tprints(", ");
897                         printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
898                 }
899         }
900         return 0;
901 }
902
903 SYS_FUNC(pipe)
904 {
905 #ifdef HAVE_GETRVAL2
906         if (exiting(tcp) && !syserror(tcp))
907                 printpair_fd(tcp, tcp->u_rval, getrval2(tcp));
908         return 0;
909 #else
910         return do_pipe(tcp, -1);
911 #endif
912 }
913
914 SYS_FUNC(pipe2)
915 {
916         return do_pipe(tcp, 1);
917 }
918
919 SYS_FUNC(socketpair)
920 {
921         if (entering(tcp)) {
922                 printxval(addrfams, tcp->u_arg[0], "AF_???");
923                 tprints(", ");
924                 tprint_sock_type(tcp->u_arg[1]);
925                 tprintf(", %lu", tcp->u_arg[2]);
926         } else {
927                 tprints(", ");
928                 decode_pair_fd(tcp, tcp->u_arg[3]);
929         }
930         return 0;
931 }
932
933 #include "xlat/sockoptions.h"
934 #include "xlat/sockipoptions.h"
935 #include "xlat/getsockipoptions.h"
936 #include "xlat/setsockipoptions.h"
937 #include "xlat/sockipv6options.h"
938 #include "xlat/getsockipv6options.h"
939 #include "xlat/setsockipv6options.h"
940 #include "xlat/sockipxoptions.h"
941 #include "xlat/sockrawoptions.h"
942 #include "xlat/sockpacketoptions.h"
943 #include "xlat/socksctpoptions.h"
944 #include "xlat/socktcpoptions.h"
945
946 static void
947 print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
948                             unsigned int name, bool is_getsockopt)
949 {
950         printfd(tcp, fd);
951         tprints(", ");
952         printxval(socketlayers, level, "SOL_??");
953         tprints(", ");
954
955         switch (level) {
956         case SOL_SOCKET:
957                 printxval(sockoptions, name, "SO_???");
958                 break;
959         case SOL_IP:
960                 printxvals(name, "IP_???", sockipoptions,
961                         is_getsockopt ? getsockipoptions : setsockipoptions, NULL);
962                 break;
963         case SOL_IPV6:
964                 printxvals(name, "IPV6_???", sockipv6options,
965                         is_getsockopt ? getsockipv6options : setsockipv6options, NULL);
966                 break;
967         case SOL_IPX:
968                 printxval(sockipxoptions, name, "IPX_???");
969                 break;
970         case SOL_PACKET:
971                 printxval(sockpacketoptions, name, "PACKET_???");
972                 break;
973         case SOL_TCP:
974                 printxval(socktcpoptions, name, "TCP_???");
975                 break;
976         case SOL_SCTP:
977                 printxval(socksctpoptions, name, "SCTP_???");
978                 break;
979         case SOL_RAW:
980                 printxval(sockrawoptions, name, "RAW_???");
981                 break;
982
983                 /* Other SOL_* protocol levels still need work. */
984
985         default:
986                 tprintf("%u", name);
987         }
988
989         tprints(", ");
990 }
991
992 static void
993 print_linger(struct tcb *tcp, long addr, int len)
994 {
995         struct linger linger;
996
997         if (len != sizeof(linger) ||
998             umove(tcp, addr, &linger) < 0) {
999                 printaddr(addr);
1000                 return;
1001         }
1002
1003         tprintf("{onoff=%d, linger=%d}",
1004                 linger.l_onoff,
1005                 linger.l_linger);
1006 }
1007
1008 #ifdef SO_PEERCRED
1009 static void
1010 print_ucred(struct tcb *tcp, long addr, int len)
1011 {
1012         struct ucred uc;
1013
1014         if (len != sizeof(uc) ||
1015             umove(tcp, addr, &uc) < 0) {
1016                 printaddr(addr);
1017         } else {
1018                 tprintf("{pid=%u, uid=%u, gid=%u}",
1019                         (unsigned) uc.pid,
1020                         (unsigned) uc.uid,
1021                         (unsigned) uc.gid);
1022         }
1023 }
1024 #endif /* SO_PEERCRED */
1025
1026 #ifdef PACKET_STATISTICS
1027 static void
1028 print_tpacket_stats(struct tcb *tcp, long addr, int len)
1029 {
1030         struct tpacket_stats stats;
1031
1032         if (len != sizeof(stats) ||
1033             umove(tcp, addr, &stats) < 0) {
1034                 printaddr(addr);
1035         } else {
1036                 tprintf("{packets=%u, drops=%u}",
1037                         stats.tp_packets,
1038                         stats.tp_drops);
1039         }
1040 }
1041 #endif /* PACKET_STATISTICS */
1042
1043 #include "xlat/icmpfilterflags.h"
1044
1045 static void
1046 print_icmp_filter(struct tcb *tcp, const long addr, int len)
1047 {
1048         struct icmp_filter filter = {};
1049
1050         if (len > (int) sizeof(filter))
1051                 len = sizeof(filter);
1052         else if (len <= 0) {
1053                 printaddr(addr);
1054                 return;
1055         }
1056
1057         if (umoven_or_printaddr(tcp, addr, len, &filter))
1058                 return;
1059
1060         tprints("~(");
1061         printflags(icmpfilterflags, ~filter.data, "ICMP_???");
1062         tprints(")");
1063 }
1064
1065 static void
1066 print_getsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
1067                  long addr, int len)
1068 {
1069         if (addr && verbose(tcp))
1070         switch (level) {
1071         case SOL_SOCKET:
1072                 switch (name) {
1073                 case SO_LINGER:
1074                         print_linger(tcp, addr, len);
1075                         goto done;
1076 #ifdef SO_PEERCRED
1077                 case SO_PEERCRED:
1078                         print_ucred(tcp, addr, len);
1079                         goto done;
1080 #endif
1081                 }
1082                 break;
1083
1084         case SOL_PACKET:
1085                 switch (name) {
1086 #ifdef PACKET_STATISTICS
1087                 case PACKET_STATISTICS:
1088                         print_tpacket_stats(tcp, addr, len);
1089                         goto done;
1090 #endif
1091                 }
1092                 break;
1093
1094         case SOL_RAW:
1095                 switch (name) {
1096                 case ICMP_FILTER:
1097                         print_icmp_filter(tcp, addr, len);
1098                         goto done;
1099                 }
1100                 break;
1101         }
1102
1103         /* default arg printing */
1104
1105         if (verbose(tcp)) {
1106                 if (len == sizeof(int)) {
1107                         printnum_int(tcp, addr, "%d");
1108                 } else {
1109                         printstr(tcp, addr, len);
1110                 }
1111         } else {
1112                 printaddr(addr);
1113         }
1114 done:
1115         tprintf(", [%d]", len);
1116 }
1117
1118 SYS_FUNC(getsockopt)
1119 {
1120         if (entering(tcp)) {
1121                 print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
1122                                             tcp->u_arg[1], tcp->u_arg[2], true);
1123         } else {
1124                 int len;
1125
1126                 if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &len) < 0) {
1127                         printaddr(tcp->u_arg[3]);
1128                         tprints(", ");
1129                         printaddr(tcp->u_arg[4]);
1130                 } else {
1131                         print_getsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
1132                                          tcp->u_arg[3], len);
1133                 }
1134         }
1135         return 0;
1136 }
1137
1138 #ifdef IP_ADD_MEMBERSHIP
1139 static void
1140 print_mreq(struct tcb *tcp, long addr, unsigned int len)
1141 {
1142         struct ip_mreq mreq;
1143
1144         if (len < sizeof(mreq)) {
1145                 printstr(tcp, addr, len);
1146                 return;
1147         }
1148         if (umove_or_printaddr(tcp, addr, &mreq))
1149                 return;
1150
1151         tprints("{imr_multiaddr=inet_addr(");
1152         print_quoted_string(inet_ntoa(mreq.imr_multiaddr),
1153                             16, QUOTE_0_TERMINATED);
1154         tprints("), imr_interface=inet_addr(");
1155         print_quoted_string(inet_ntoa(mreq.imr_interface),
1156                             16, QUOTE_0_TERMINATED);
1157         tprints(")}");
1158 }
1159 #endif /* IP_ADD_MEMBERSHIP */
1160
1161 #ifdef IPV6_ADD_MEMBERSHIP
1162 static void
1163 print_mreq6(struct tcb *tcp, long addr, unsigned int len)
1164 {
1165         struct ipv6_mreq mreq;
1166
1167         if (len < sizeof(mreq))
1168                 goto fail;
1169
1170         if (umove_or_printaddr(tcp, addr, &mreq))
1171                 return;
1172
1173         const struct in6_addr *in6 = &mreq.ipv6mr_multiaddr;
1174         char address[INET6_ADDRSTRLEN];
1175
1176         if (!inet_ntop(AF_INET6, in6, address, sizeof(address)))
1177                 goto fail;
1178
1179         tprints("{ipv6mr_multiaddr=inet_pton(");
1180         print_quoted_string(address, sizeof(address), QUOTE_0_TERMINATED);
1181         tprints("), ipv6mr_interface=");
1182         print_ifindex(mreq.ipv6mr_interface);
1183         tprints("}");
1184         return;
1185
1186 fail:
1187         printstr(tcp, addr, len);
1188 }
1189 #endif /* IPV6_ADD_MEMBERSHIP */
1190
1191 #ifdef MCAST_JOIN_GROUP
1192 static void
1193 print_group_req(struct tcb *tcp, long addr, int len)
1194 {
1195         struct group_req greq;
1196
1197         if (len != sizeof(greq) ||
1198             umove(tcp, addr, &greq) < 0) {
1199                 printaddr(addr);
1200                 return;
1201         }
1202
1203         tprintf("{gr_interface=%u, gr_group=", greq.gr_interface);
1204         print_sockaddr(tcp, &greq.gr_group, sizeof(greq.gr_group));
1205         tprintf("}");
1206
1207 }
1208 #endif /* MCAST_JOIN_GROUP */
1209
1210 #ifdef PACKET_RX_RING
1211 static void
1212 print_tpacket_req(struct tcb *tcp, long addr, int len)
1213 {
1214         struct tpacket_req req;
1215
1216         if (len != sizeof(req) ||
1217             umove(tcp, addr, &req) < 0) {
1218                 printaddr(addr);
1219         } else {
1220                 tprintf("{block_size=%u, block_nr=%u, "
1221                         "frame_size=%u, frame_nr=%u}",
1222                         req.tp_block_size,
1223                         req.tp_block_nr,
1224                         req.tp_frame_size,
1225                         req.tp_frame_nr);
1226         }
1227 }
1228 #endif /* PACKET_RX_RING */
1229
1230 #ifdef PACKET_ADD_MEMBERSHIP
1231 # include "xlat/packet_mreq_type.h"
1232
1233 static void
1234 print_packet_mreq(struct tcb *tcp, long addr, int len)
1235 {
1236         struct packet_mreq mreq;
1237
1238         if (len != sizeof(mreq) ||
1239             umove(tcp, addr, &mreq) < 0) {
1240                 printaddr(addr);
1241         } else {
1242                 unsigned int i;
1243
1244                 tprintf("{mr_ifindex=%u, mr_type=", mreq.mr_ifindex);
1245                 printxval(packet_mreq_type, mreq.mr_type, "PACKET_MR_???");
1246                 tprintf(", mr_alen=%u, mr_address=", mreq.mr_alen);
1247                 if (mreq.mr_alen > ARRAY_SIZE(mreq.mr_address))
1248                         mreq.mr_alen = ARRAY_SIZE(mreq.mr_address);
1249                 for (i = 0; i < mreq.mr_alen; ++i)
1250                         tprintf("%02x", mreq.mr_address[i]);
1251                 tprints("}");
1252         }
1253 }
1254 #endif /* PACKET_ADD_MEMBERSHIP */
1255
1256 static void
1257 print_setsockopt(struct tcb *tcp, unsigned int level, unsigned int name,
1258                  long addr, int len)
1259 {
1260         if (addr && verbose(tcp))
1261         switch (level) {
1262         case SOL_SOCKET:
1263                 switch (name) {
1264                 case SO_LINGER:
1265                         print_linger(tcp, addr, len);
1266                         goto done;
1267                 }
1268                 break;
1269
1270         case SOL_IP:
1271                 switch (name) {
1272 #ifdef IP_ADD_MEMBERSHIP
1273                 case IP_ADD_MEMBERSHIP:
1274                 case IP_DROP_MEMBERSHIP:
1275                         print_mreq(tcp, addr, len);
1276                         goto done;
1277 #endif /* IP_ADD_MEMBERSHIP */
1278 #ifdef MCAST_JOIN_GROUP
1279                 case MCAST_JOIN_GROUP:
1280                 case MCAST_LEAVE_GROUP:
1281                         print_group_req(tcp, addr, len);
1282                         goto done;
1283 #endif /* MCAST_JOIN_GROUP */
1284                 }
1285                 break;
1286
1287         case SOL_IPV6:
1288                 switch (name) {
1289 #ifdef IPV6_ADD_MEMBERSHIP
1290                 case IPV6_ADD_MEMBERSHIP:
1291                 case IPV6_DROP_MEMBERSHIP:
1292 # ifdef IPV6_JOIN_ANYCAST
1293                 case IPV6_JOIN_ANYCAST:
1294 # endif
1295 # ifdef IPV6_LEAVE_ANYCAST
1296                 case IPV6_LEAVE_ANYCAST:
1297 # endif
1298                         print_mreq6(tcp, addr, len);
1299                         goto done;
1300 #endif /* IPV6_ADD_MEMBERSHIP */
1301                 }
1302                 break;
1303
1304         case SOL_PACKET:
1305                 switch (name) {
1306 #ifdef PACKET_RX_RING
1307                 case PACKET_RX_RING:
1308 # ifdef PACKET_TX_RING
1309                 case PACKET_TX_RING:
1310 # endif
1311                         print_tpacket_req(tcp, addr, len);
1312                         goto done;
1313 #endif /* PACKET_RX_RING */
1314 #ifdef PACKET_ADD_MEMBERSHIP
1315                 case PACKET_ADD_MEMBERSHIP:
1316                 case PACKET_DROP_MEMBERSHIP:
1317                         print_packet_mreq(tcp, addr, len);
1318                         goto done;
1319 #endif /* PACKET_ADD_MEMBERSHIP */
1320                 }
1321                 break;
1322
1323         case SOL_RAW:
1324                 switch (name) {
1325                 case ICMP_FILTER:
1326                         print_icmp_filter(tcp, addr, len);
1327                         goto done;
1328                 }
1329                 break;
1330         }
1331
1332         /* default arg printing */
1333
1334         if (verbose(tcp)) {
1335                 if (len == sizeof(int)) {
1336                         printnum_int(tcp, addr, "%d");
1337                 } else {
1338                         printstr(tcp, addr, len);
1339                 }
1340         } else {
1341                 printaddr(addr);
1342         }
1343 done:
1344         tprintf(", %d", len);
1345 }
1346
1347 SYS_FUNC(setsockopt)
1348 {
1349         print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
1350                                     tcp->u_arg[1], tcp->u_arg[2], false);
1351         print_setsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
1352                          tcp->u_arg[3], tcp->u_arg[4]);
1353
1354         return RVAL_DECODED;
1355 }