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