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