]> granicus.if.org Git - strace/blob - net.c
maint: update for linux v5.3-rc8
[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  * Copyright (c) 1999-2019 The strace developers.
7  * All rights reserved.
8  *
9  * SPDX-License-Identifier: LGPL-2.1-or-later
10  */
11
12 #include "defs.h"
13 #include "print_fields.h"
14
15 #include <sys/stat.h>
16 #include <sys/socket.h>
17 #include <sys/uio.h>
18 #include <sys/un.h>
19 #include <netinet/in.h>
20 #ifdef HAVE_NETINET_TCP_H
21 # include <netinet/tcp.h>
22 #endif
23 #ifdef HAVE_NETINET_UDP_H
24 # include <netinet/udp.h>
25 #endif
26 #ifdef HAVE_NETINET_SCTP_H
27 # include <netinet/sctp.h>
28 #endif
29 #include <arpa/inet.h>
30 #include <net/if.h>
31 #include <asm/types.h>
32 #ifdef HAVE_NETIPX_IPX_H
33 # include <netipx/ipx.h>
34 #else
35 # include <linux/ipx.h>
36 #endif
37
38 #if defined(HAVE_LINUX_IP_VS_H)
39 # include <linux/ip_vs.h>
40 #endif
41 #include "netlink.h"
42 #if defined(HAVE_LINUX_NETFILTER_ARP_ARP_TABLES_H)
43 # include <linux/netfilter_arp/arp_tables.h>
44 #endif
45 #if defined(HAVE_LINUX_NETFILTER_BRIDGE_EBTABLES_H)
46 # include <linux/netfilter_bridge/ebtables.h>
47 #endif
48 #if defined(HAVE_LINUX_NETFILTER_IPV4_IP_TABLES_H)
49 # include <linux/netfilter_ipv4/ip_tables.h>
50 #endif
51 #if defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H)
52 # include <linux/netfilter_ipv6/ip6_tables.h>
53 #endif
54 #include <linux/if_packet.h>
55 #include <linux/icmp.h>
56
57 #include "xlat/socktypes.h"
58 #include "xlat/sock_type_flags.h"
59 #ifndef SOCK_TYPE_MASK
60 # define SOCK_TYPE_MASK 0xf
61 #endif
62
63 #include "xlat/socketlayers.h"
64
65 #include "xlat/inet_protocols.h"
66
67 #define XLAT_MACROS_ONLY
68 #include "xlat/addrfams.h"
69 #include "xlat/ethernet_protocols.h"
70 #undef XLAT_MACROS_ONLY
71 #include "xlat/ax25_protocols.h"
72 #include "xlat/irda_protocols.h"
73 #include "xlat/can_protocols.h"
74 #include "xlat/bt_protocols.h"
75 #include "xlat/isdn_protocols.h"
76 #include "xlat/phonet_protocols.h"
77 #include "xlat/caif_protocols.h"
78 #include "xlat/nfc_protocols.h"
79 #include "xlat/kcm_protocols.h"
80 #include "xlat/smc_protocols.h"
81
82 const size_t inet_protocols_size = ARRAY_SIZE(inet_protocols) - 1;
83
84 static void
85 decode_sockbuf(struct tcb *const tcp, const int fd, const kernel_ulong_t addr,
86                const kernel_ulong_t addrlen)
87 {
88
89         switch (verbose(tcp) ? getfdproto(tcp, fd) : SOCK_PROTO_UNKNOWN) {
90         case SOCK_PROTO_NETLINK:
91                 decode_netlink(tcp, fd, addr, addrlen);
92                 break;
93         default:
94                 printstrn(tcp, addr, addrlen);
95         }
96 }
97
98 /*
99  * low bits of the socket type define real socket type,
100  * other bits are socket type flags.
101  */
102 static void
103 tprint_sock_type(unsigned int flags)
104 {
105         const char *str = xlookup(socktypes, flags & SOCK_TYPE_MASK);
106
107         if (str) {
108                 print_xlat_ex(flags & SOCK_TYPE_MASK, str, XLAT_STYLE_DEFAULT);
109                 flags &= ~SOCK_TYPE_MASK;
110                 if (!flags)
111                         return;
112                 tprints("|");
113         }
114         printflags(sock_type_flags, flags, "SOCK_???");
115 }
116
117 SYS_FUNC(socket)
118 {
119         printxval(addrfams, tcp->u_arg[0], "AF_???");
120         tprints(", ");
121         tprint_sock_type(tcp->u_arg[1]);
122         tprints(", ");
123         switch (tcp->u_arg[0]) {
124         case AF_INET:
125         case AF_INET6:
126                 printxval(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
127                 break;
128
129         case AF_AX25:
130                 /* Those are not available in public headers.  */
131                 printxval_ex(ax25_protocols, tcp->u_arg[2], "AX25_P_???",
132                              XLAT_STYLE_VERBOSE);
133                 break;
134
135         case AF_NETLINK:
136                 printxval(netlink_protocols, tcp->u_arg[2], "NETLINK_???");
137                 break;
138
139         case AF_PACKET:
140                 tprints("htons(");
141                 printxval(ethernet_protocols, ntohs(tcp->u_arg[2]),
142                           "ETH_P_???");
143                 tprints(")");
144                 break;
145
146         case AF_IRDA:
147                 printxval(can_protocols, tcp->u_arg[2], "IRDAPROTO_???");
148                 break;
149
150         case AF_CAN:
151                 printxval(can_protocols, tcp->u_arg[2], "CAN_???");
152                 break;
153
154         case AF_BLUETOOTH:
155                 printxval(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
156                 break;
157
158         case AF_RXRPC:
159                 printxval(addrfams, tcp->u_arg[2], "AF_???");
160                 break;
161
162         case AF_ISDN:
163                 printxval(isdn_protocols, tcp->u_arg[2], "ISDN_P_???");
164                 break;
165
166         case AF_PHONET:
167                 printxval(phonet_protocols, tcp->u_arg[2], "PN_PROTO_???");
168                 break;
169
170         case AF_CAIF:
171                 printxval(caif_protocols, tcp->u_arg[2], "CAIFPROTO_???");
172                 break;
173
174         case AF_NFC:
175                 printxval(nfc_protocols, tcp->u_arg[2], "NFC_SOCKPROTO_???");
176                 break;
177
178         case AF_KCM:
179                 printxval(kcm_protocols, tcp->u_arg[2], "KCMPROTO_???");
180                 break;
181
182         case AF_SMC:
183                 printxval(smc_protocols, tcp->u_arg[2], "SMCPROTO_???");
184                 break;
185
186         default:
187                 tprintf("%" PRI_klu, tcp->u_arg[2]);
188                 break;
189         }
190
191         return RVAL_DECODED | RVAL_FD;
192 }
193
194 static bool
195 fetch_socklen(struct tcb *const tcp, int *const plen,
196               const kernel_ulong_t sockaddr, const kernel_ulong_t socklen)
197 {
198         return verbose(tcp) && sockaddr && socklen
199                && umove(tcp, socklen, plen) == 0;
200 }
201
202 static int
203 decode_sockname(struct tcb *tcp)
204 {
205         int ulen, rlen;
206
207         if (entering(tcp)) {
208                 printfd(tcp, tcp->u_arg[0]);
209                 tprints(", ");
210                 if (fetch_socklen(tcp, &ulen, tcp->u_arg[1], tcp->u_arg[2])) {
211                         set_tcb_priv_ulong(tcp, ulen);
212                         return 0;
213                 } else {
214                         printaddr(tcp->u_arg[1]);
215                         tprints(", ");
216                         printaddr(tcp->u_arg[2]);
217                         return RVAL_DECODED;
218                 }
219         }
220
221         ulen = get_tcb_priv_ulong(tcp);
222
223         if (syserror(tcp) || umove(tcp, tcp->u_arg[2], &rlen) < 0) {
224                 printaddr(tcp->u_arg[1]);
225                 tprintf(", [%d]", ulen);
226         } else {
227                 decode_sockaddr(tcp, tcp->u_arg[1], ulen > rlen ? rlen : ulen);
228                 if (ulen != rlen)
229                         tprintf(", [%d->%d]", ulen, rlen);
230                 else
231                         tprintf(", [%d]", rlen);
232         }
233
234         return RVAL_DECODED;
235 }
236
237 SYS_FUNC(accept)
238 {
239         return decode_sockname(tcp) | RVAL_FD;
240 }
241
242 SYS_FUNC(accept4)
243 {
244         int rc = decode_sockname(tcp);
245
246         if (rc & RVAL_DECODED) {
247                 tprints(", ");
248                 printflags(sock_type_flags, tcp->u_arg[3], "SOCK_???");
249         }
250
251         return rc | RVAL_FD;
252 }
253
254 SYS_FUNC(send)
255 {
256         printfd(tcp, tcp->u_arg[0]);
257         tprints(", ");
258         decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
259         tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
260         /* flags */
261         printflags(msg_flags, tcp->u_arg[3], "MSG_???");
262
263         return RVAL_DECODED;
264 }
265
266 SYS_FUNC(sendto)
267 {
268         printfd(tcp, tcp->u_arg[0]);
269         tprints(", ");
270         decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
271         tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
272         /* flags */
273         printflags(msg_flags, tcp->u_arg[3], "MSG_???");
274         /* to address */
275         const int addrlen = tcp->u_arg[5];
276         tprints(", ");
277         decode_sockaddr(tcp, tcp->u_arg[4], addrlen);
278         /* to length */
279         tprintf(", %d", addrlen);
280
281         return RVAL_DECODED;
282 }
283
284 SYS_FUNC(recv)
285 {
286         if (entering(tcp)) {
287                 printfd(tcp, tcp->u_arg[0]);
288                 tprints(", ");
289         } else {
290                 if (syserror(tcp)) {
291                         printaddr(tcp->u_arg[1]);
292                 } else {
293                         decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
294                                        MIN((kernel_ulong_t) tcp->u_rval,
295                                            tcp->u_arg[2]));
296                 }
297
298                 tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
299                 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
300         }
301         return 0;
302 }
303
304 SYS_FUNC(recvfrom)
305 {
306         int ulen, rlen;
307
308         if (entering(tcp)) {
309                 printfd(tcp, tcp->u_arg[0]);
310                 tprints(", ");
311                 if (fetch_socklen(tcp, &ulen, tcp->u_arg[4], tcp->u_arg[5])) {
312                         set_tcb_priv_ulong(tcp, ulen);
313                 }
314         } else {
315                 /* buf */
316                 if (syserror(tcp)) {
317                         printaddr(tcp->u_arg[1]);
318                 } else {
319                         decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
320                                        MIN((kernel_ulong_t) tcp->u_rval,
321                                            tcp->u_arg[2]));
322                 }
323                 /* size */
324                 tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
325                 /* flags */
326                 printflags(msg_flags, tcp->u_arg[3], "MSG_???");
327                 tprints(", ");
328
329                 ulen = get_tcb_priv_ulong(tcp);
330
331                 if (!fetch_socklen(tcp, &rlen, tcp->u_arg[4], tcp->u_arg[5])) {
332                         /* from address */
333                         printaddr(tcp->u_arg[4]);
334                         tprints(", ");
335                         /* from length */
336                         printaddr(tcp->u_arg[5]);
337                         return 0;
338                 }
339                 if (syserror(tcp)) {
340                         /* from address */
341                         printaddr(tcp->u_arg[4]);
342                         /* from length */
343                         tprintf(", [%d]", ulen);
344                         return 0;
345                 }
346                 /* from address */
347                 decode_sockaddr(tcp, tcp->u_arg[4], ulen > rlen ? rlen : ulen);
348                 /* from length */
349                 if (ulen != rlen)
350                         tprintf(", [%d->%d]", ulen, rlen);
351                 else
352                         tprintf(", [%d]", rlen);
353         }
354         return 0;
355 }
356
357 SYS_FUNC(getsockname)
358 {
359         return decode_sockname(tcp);
360 }
361
362 static void
363 printpair_fd(struct tcb *tcp, const int i0, const int i1)
364 {
365         tprints("[");
366         printfd(tcp, i0);
367         tprints(", ");
368         printfd(tcp, i1);
369         tprints("]");
370 }
371
372 static void
373 decode_pair_fd(struct tcb *const tcp, const kernel_ulong_t addr)
374 {
375         int pair[2];
376
377         if (umove_or_printaddr(tcp, addr, &pair))
378                 return;
379
380         printpair_fd(tcp, pair[0], pair[1]);
381 }
382
383 static int
384 do_pipe(struct tcb *tcp, int flags_arg)
385 {
386         if (exiting(tcp)) {
387                 decode_pair_fd(tcp, tcp->u_arg[0]);
388                 if (flags_arg >= 0) {
389                         tprints(", ");
390                         printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
391                 }
392         }
393         return 0;
394 }
395
396 SYS_FUNC(pipe)
397 {
398 #if HAVE_ARCH_GETRVAL2
399         if (exiting(tcp) && !syserror(tcp))
400                 printpair_fd(tcp, tcp->u_rval, getrval2(tcp));
401         return 0;
402 #else
403         return do_pipe(tcp, -1);
404 #endif
405 }
406
407 SYS_FUNC(pipe2)
408 {
409         return do_pipe(tcp, 1);
410 }
411
412 SYS_FUNC(socketpair)
413 {
414         if (entering(tcp)) {
415                 printxval(addrfams, tcp->u_arg[0], "AF_???");
416                 tprints(", ");
417                 tprint_sock_type(tcp->u_arg[1]);
418                 tprintf(", %" PRI_klu, tcp->u_arg[2]);
419         } else {
420                 tprints(", ");
421                 decode_pair_fd(tcp, tcp->u_arg[3]);
422         }
423         return 0;
424 }
425
426 #include "xlat/sock_options.h"
427 #include "xlat/getsock_options.h"
428 #include "xlat/setsock_options.h"
429 #include "xlat/sock_ip_options.h"
430 #include "xlat/getsock_ip_options.h"
431 #include "xlat/setsock_ip_options.h"
432 #include "xlat/sock_ipv6_options.h"
433 #include "xlat/getsock_ipv6_options.h"
434 #include "xlat/setsock_ipv6_options.h"
435 #include "xlat/sock_ipx_options.h"
436 #include "xlat/sock_ax25_options.h"
437 #include "xlat/sock_netlink_options.h"
438 #include "xlat/sock_packet_options.h"
439 #include "xlat/sock_raw_options.h"
440 #include "xlat/sock_sctp_options.h"
441 #include "xlat/sock_tcp_options.h"
442 #include "xlat/sock_udp_options.h"
443 #include "xlat/sock_irda_options.h"
444 #include "xlat/sock_llc_options.h"
445 #include "xlat/sock_dccp_options.h"
446 #include "xlat/sock_tipc_options.h"
447 #include "xlat/sock_rxrpc_options.h"
448 #include "xlat/sock_pppol2tp_options.h"
449 #include "xlat/sock_bluetooth_options.h"
450 #include "xlat/sock_pnp_options.h"
451 #include "xlat/sock_rds_options.h"
452 #include "xlat/sock_iucv_options.h"
453 #include "xlat/sock_caif_options.h"
454 #include "xlat/sock_alg_options.h"
455 #include "xlat/sock_nfcllcp_options.h"
456 #include "xlat/sock_kcm_options.h"
457 #include "xlat/sock_tls_options.h"
458 #include "xlat/sock_xdp_options.h"
459
460 static void
461 print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
462                             unsigned int name, bool is_getsockopt)
463 {
464         printfd(tcp, fd);
465         tprints(", ");
466         printxval(socketlayers, level, "SOL_??");
467         tprints(", ");
468
469         switch (level) {
470         case SOL_SOCKET:
471                 printxvals(name, "SO_???", sock_options,
472                            is_getsockopt ? getsock_options :
473                                            setsock_options, NULL);
474                 break;
475         case SOL_IP:
476                 printxvals(name, "IP_???", sock_ip_options,
477                            is_getsockopt ? getsock_ip_options :
478                                            setsock_ip_options, NULL);
479                 break;
480         case SOL_IPV6:
481                 printxvals(name, "IPV6_???", sock_ipv6_options,
482                            is_getsockopt ? getsock_ipv6_options :
483                                            setsock_ipv6_options, NULL);
484                 break;
485         case SOL_IPX:
486                 printxval(sock_ipx_options, name, "IPX_???");
487                 break;
488         case SOL_AX25:
489                 printxval(sock_ax25_options, name, "AX25_???");
490                 break;
491         case SOL_PACKET:
492                 printxval(sock_packet_options, name, "PACKET_???");
493                 break;
494         case SOL_TCP:
495                 printxval(sock_tcp_options, name, "TCP_???");
496                 break;
497         case SOL_SCTP:
498                 printxval(sock_sctp_options, name, "SCTP_???");
499                 break;
500         case SOL_RAW:
501                 printxval(sock_raw_options, name, "RAW_???");
502                 break;
503         case SOL_NETLINK:
504                 printxval(sock_netlink_options, name, "NETLINK_???");
505                 break;
506         case SOL_UDP:
507                 printxval(sock_udp_options, name, "UDP_???");
508                 break;
509         case SOL_IRDA:
510                 printxval(sock_irda_options, name, "IRLMP_???");
511                 break;
512         case SOL_LLC:
513                 printxval(sock_llc_options, name, "LLC_OPT_???");
514                 break;
515         case SOL_DCCP:
516                 printxval(sock_dccp_options, name, "DCCP_SOCKOPT_???");
517                 break;
518         case SOL_TIPC:
519                 printxval(sock_tipc_options, name, "TIPC_???");
520                 break;
521         case SOL_RXRPC:
522                 printxval(sock_rxrpc_options, name, "RXRPC_???");
523                 break;
524         case SOL_PPPOL2TP:
525                 printxval(sock_pppol2tp_options, name, "PPPOL2TP_SO_???");
526                 break;
527         case SOL_BLUETOOTH:
528                 printxval(sock_bluetooth_options, name, "BT_???");
529                 break;
530         case SOL_PNPIPE:
531                 printxval(sock_pnp_options, name, "PNPIPE_???");
532                 break;
533         case SOL_RDS:
534                 printxval(sock_rds_options, name, "RDS_???");
535                 break;
536         case SOL_IUCV:
537                 printxval(sock_iucv_options, name, "SO_???");
538                 break;
539         case SOL_CAIF:
540                 printxval(sock_caif_options, name, "CAIFSO_???");
541                 break;
542         case SOL_ALG:
543                 printxval(sock_alg_options, name, "ALG_???");
544                 break;
545         case SOL_NFC:
546                 printxval(sock_nfcllcp_options, name, "NFC_LLCP_???");
547                 break;
548         case SOL_KCM:
549                 printxval(sock_kcm_options, name, "KCM_???");
550                 break;
551         case SOL_TLS:
552                 printxval(sock_tls_options, name, "TLS_???");
553                 break;
554         case SOL_XDP:
555                 printxval(sock_xdp_options, name, "XDP_???");
556                 break;
557
558                 /* Other SOL_* protocol levels still need work. */
559
560         default:
561                 tprintf("%u", name);
562         }
563
564         tprints(", ");
565 }
566
567 static void
568 print_get_linger(struct tcb *const tcp, const kernel_ulong_t addr,
569                  unsigned int len)
570 {
571         struct linger linger;
572
573         /*
574          * The kernel cannot return len > sizeof(linger) because struct linger
575          * cannot change, but extra safety won't harm either.
576          */
577         if (len > sizeof(linger))
578                 len = sizeof(linger);
579         if (umoven_or_printaddr(tcp, addr, len, &linger))
580                 return;
581
582         if (len < sizeof(linger.l_onoff)) {
583                 tprints("{l_onoff=");
584                 print_quoted_string((void *) &linger.l_onoff,
585                                     len, QUOTE_FORCE_HEX);
586         } else {
587                 PRINT_FIELD_D("{", linger, l_onoff);
588
589                 if (len > offsetof(struct linger, l_linger)) {
590                         len -= offsetof(struct linger, l_linger);
591                         if (len < sizeof(linger.l_linger)) {
592                                 tprints(", l_linger=");
593                                 print_quoted_string((void *) &linger.l_linger,
594                                                     len, QUOTE_FORCE_HEX);
595                         } else {
596                                 PRINT_FIELD_D(", ", linger, l_linger);
597                         }
598                 }
599         }
600         tprints("}");
601 }
602
603 static void
604 print_get_ucred(struct tcb *const tcp, const kernel_ulong_t addr,
605                 unsigned int len)
606 {
607         struct ucred uc;
608
609         /*
610          * The kernel is very unlikely to return len > sizeof(uc)
611          * because struct ucred is very unlikely to change,
612          * but extra safety won't harm either.
613          */
614         if (len > sizeof(uc))
615                 len = sizeof(uc);
616
617         if (umoven_or_printaddr(tcp, addr, len, &uc))
618                 return;
619
620         if (len < sizeof(uc.pid)) {
621                 tprints("{pid=");
622                 print_quoted_string((void *) &uc.pid,
623                                     len, QUOTE_FORCE_HEX);
624         } else {
625                 PRINT_FIELD_D("{", uc, pid);
626
627                 if (len > offsetof(struct ucred, uid)) {
628                         len -= offsetof(struct ucred, uid);
629                         if (len < sizeof(uc.uid)) {
630                                 tprints(", uid=");
631                                 print_quoted_string((void *) &uc.uid,
632                                                     len, QUOTE_FORCE_HEX);
633                         } else {
634                                 PRINT_FIELD_UID(", ", uc, uid);
635
636                                 if (len > offsetof(struct ucred, gid) -
637                                           offsetof(struct ucred, uid)) {
638                                         len -= offsetof(struct ucred, gid) -
639                                                offsetof(struct ucred, uid);
640                                         if (len < sizeof(uc.gid)) {
641                                                 tprints(", gid=");
642                                                 print_quoted_string((void *) &uc.gid,
643                                                                     len,
644                                                                     QUOTE_FORCE_HEX);
645                                         } else {
646                                                 PRINT_FIELD_UID(", ", uc, gid);
647                                         }
648                                 }
649                         }
650                 }
651         }
652         tprints("}");
653 }
654
655 static void
656 print_get_error(struct tcb *const tcp, const kernel_ulong_t addr,
657                 unsigned int len)
658 {
659         unsigned int err;
660
661         if (len > sizeof(err))
662                 err = sizeof(err);
663
664         if (umoven_or_printaddr(tcp, addr, len, &err))
665                 return;
666
667         tprints("[");
668         print_err(err, false);
669         tprints("]");
670 }
671
672 #ifdef PACKET_STATISTICS
673 static void
674 print_tpacket_stats(struct tcb *const tcp, const kernel_ulong_t addr,
675                     unsigned int len)
676 {
677         struct tp_stats {
678                 unsigned int tp_packets, tp_drops, tp_freeze_q_cnt;
679         } stats;
680
681         /*
682          * The kernel may return len > sizeof(stats) if the kernel structure
683          * grew as it happened when tpacket_stats_v3 was introduced.
684          */
685         if (len > sizeof(stats))
686                 len = sizeof(stats);
687
688         if (umoven_or_printaddr(tcp, addr, len, &stats))
689                 return;
690
691         if (len < sizeof(stats.tp_packets)) {
692                 tprints("{tp_packets=");
693                 print_quoted_string((void *) &stats.tp_packets,
694                                     len, QUOTE_FORCE_HEX);
695         } else {
696                 PRINT_FIELD_U("{", stats, tp_packets);
697
698                 if (len > offsetof(struct tp_stats, tp_drops)) {
699                         len -= offsetof(struct tp_stats, tp_drops);
700                         if (len < sizeof(stats.tp_drops)) {
701                                 tprints(", tp_drops=");
702                                 print_quoted_string((void *) &stats.tp_drops,
703                                                     len, QUOTE_FORCE_HEX);
704                         } else {
705                                 PRINT_FIELD_U(", ", stats, tp_drops);
706
707                                 if (len > offsetof(struct tp_stats, tp_freeze_q_cnt) -
708                                           offsetof(struct tp_stats, tp_drops)) {
709                                         len -= offsetof(struct tp_stats, tp_freeze_q_cnt) -
710                                                offsetof(struct tp_stats, tp_drops);
711                                         if (len < sizeof(stats.tp_freeze_q_cnt)) {
712                                                 tprints(", tp_freeze_q_cnt=");
713                                                 print_quoted_string((void *) &stats.tp_freeze_q_cnt,
714                                                                     len,
715                                                                     QUOTE_FORCE_HEX);
716                                         } else {
717                                                 PRINT_FIELD_U(", ", stats, tp_freeze_q_cnt);
718                                         }
719                                 }
720                         }
721                 }
722         }
723         tprints("}");
724 }
725 #endif /* PACKET_STATISTICS */
726
727 #include "xlat/icmpfilterflags.h"
728
729 static void
730 print_icmp_filter(struct tcb *const tcp, const kernel_ulong_t addr, int len)
731 {
732         struct icmp_filter filter = {};
733
734         if (len > (int) sizeof(filter))
735                 len = sizeof(filter);
736         else if (len <= 0) {
737                 printaddr(addr);
738                 return;
739         }
740
741         if (umoven_or_printaddr(tcp, addr, len, &filter))
742                 return;
743
744         tprints("~(");
745         printflags(icmpfilterflags, ~filter.data, "ICMP_???");
746         tprints(")");
747 }
748
749 static void
750 print_getsockopt(struct tcb *const tcp, const unsigned int level,
751                  const unsigned int name, const kernel_ulong_t addr,
752                  const int ulen, const int rlen)
753 {
754         if (ulen <= 0 || rlen <= 0) {
755                 /*
756                  * As the kernel neither accepts nor returns a negative
757                  * length in case of successful getsockopt syscall
758                  * invocation, negative values must have been forged
759                  * by userspace.
760                  */
761                 printaddr(addr);
762                 return;
763         }
764
765         if (addr && verbose(tcp))
766         switch (level) {
767         case SOL_SOCKET:
768                 switch (name) {
769                 case SO_LINGER:
770                         print_get_linger(tcp, addr, rlen);
771                         return;
772                 case SO_PEERCRED:
773                         print_get_ucred(tcp, addr, rlen);
774                         return;
775                 case SO_ATTACH_FILTER:
776                         /*
777                          * The length returned by the kernel in case of
778                          * successful getsockopt syscall invocation is struct
779                          * sock_fprog.len that has type unsigned short,
780                          * anything else must have been forged by userspace.
781                          */
782                         if ((unsigned short) rlen == (unsigned int) rlen)
783                                 print_sock_fprog(tcp, addr, rlen);
784                         else
785                                 printaddr(addr);
786                         return;
787                 case SO_ERROR:
788                         print_get_error(tcp, addr, rlen);
789                         return;
790                 }
791                 break;
792
793         case SOL_PACKET:
794                 switch (name) {
795 #ifdef PACKET_STATISTICS
796                 case PACKET_STATISTICS:
797                         print_tpacket_stats(tcp, addr, rlen);
798                         return;
799 #endif
800                 }
801                 break;
802
803         case SOL_RAW:
804                 switch (name) {
805                 case ICMP_FILTER:
806                         print_icmp_filter(tcp, addr, rlen);
807                         return;
808                 }
809                 break;
810
811         case SOL_NETLINK:
812                 switch (name) {
813                 case NETLINK_LIST_MEMBERSHIPS: {
814                         uint32_t buf;
815                         print_array(tcp, addr, MIN(ulen, rlen) / sizeof(buf),
816                                     &buf, sizeof(buf),
817                                     tfetch_mem, print_uint32_array_member, 0);
818                         break;
819                         }
820                 default:
821                         printnum_int(tcp, addr, "%d");
822                         break;
823                 }
824                 return;
825         }
826
827         /* default arg printing */
828
829         if (verbose(tcp)) {
830                 if (rlen == sizeof(int)) {
831                         printnum_int(tcp, addr, "%d");
832                 } else {
833                         printstrn(tcp, addr, rlen);
834                 }
835         } else {
836                 printaddr(addr);
837         }
838 }
839
840 SYS_FUNC(getsockopt)
841 {
842         int ulen, rlen;
843
844         if (entering(tcp)) {
845                 print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
846                                             tcp->u_arg[1], tcp->u_arg[2], true);
847
848                 if (verbose(tcp) && tcp->u_arg[4]
849                     && umove(tcp, tcp->u_arg[4], &ulen) == 0) {
850                         set_tcb_priv_ulong(tcp, ulen);
851                         return 0;
852                 } else {
853                         printaddr(tcp->u_arg[3]);
854                         tprints(", ");
855                         printaddr(tcp->u_arg[4]);
856                         return RVAL_DECODED;
857                 }
858         } else {
859                 ulen = get_tcb_priv_ulong(tcp);
860
861                 if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &rlen) < 0) {
862                         printaddr(tcp->u_arg[3]);
863                         tprintf(", [%d]", ulen);
864                 } else {
865                         print_getsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
866                                          tcp->u_arg[3], ulen, rlen);
867                         if (ulen != rlen)
868                                 tprintf(", [%d->%d]", ulen, rlen);
869                         else
870                                 tprintf(", [%d]", rlen);
871                 }
872         }
873         return 0;
874 }
875
876 static void
877 print_set_linger(struct tcb *const tcp, const kernel_ulong_t addr,
878                  const int len)
879 {
880         struct linger linger;
881
882         if (len < (int) sizeof(linger)) {
883                 printaddr(addr);
884         } else if (!umove_or_printaddr(tcp, addr, &linger)) {
885                 PRINT_FIELD_D("{", linger, l_onoff);
886                 PRINT_FIELD_D(", ", linger, l_linger);
887                 tprints("}");
888         }
889 }
890
891 #ifdef IP_ADD_MEMBERSHIP
892 static void
893 print_mreq(struct tcb *const tcp, const kernel_ulong_t addr,
894            const int len)
895 {
896         struct ip_mreq mreq;
897
898         if (len < (int) sizeof(mreq)) {
899                 printaddr(addr);
900         } else if (!umove_or_printaddr(tcp, addr, &mreq)) {
901                 PRINT_FIELD_INET_ADDR("{", mreq, imr_multiaddr, AF_INET);
902                 PRINT_FIELD_INET_ADDR(", ", mreq, imr_interface, AF_INET);
903                 tprints("}");
904         }
905 }
906 #endif /* IP_ADD_MEMBERSHIP */
907
908 #ifdef IPV6_ADD_MEMBERSHIP
909 static void
910 print_mreq6(struct tcb *const tcp, const kernel_ulong_t addr,
911             const int len)
912 {
913         struct ipv6_mreq mreq;
914
915         if (len < (int) sizeof(mreq)) {
916                 printaddr(addr);
917         } else if (!umove_or_printaddr(tcp, addr, &mreq)) {
918                 PRINT_FIELD_INET_ADDR("{", mreq, ipv6mr_multiaddr, AF_INET6);
919                 PRINT_FIELD_IFINDEX(", ", mreq, ipv6mr_interface);
920                 tprints("}");
921         }
922 }
923 #endif /* IPV6_ADD_MEMBERSHIP */
924
925 #ifdef PACKET_RX_RING
926 static void
927 print_tpacket_req(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
928 {
929         struct tpacket_req req;
930
931         if (len != sizeof(req) ||
932             umove(tcp, addr, &req) < 0) {
933                 printaddr(addr);
934         } else {
935                 PRINT_FIELD_U("{", req, tp_block_size);
936                 PRINT_FIELD_U(", ", req, tp_block_nr);
937                 PRINT_FIELD_U(", ", req, tp_frame_size);
938                 PRINT_FIELD_U(", ", req, tp_frame_nr);
939                 tprints("}");
940         }
941 }
942 #endif /* PACKET_RX_RING */
943
944 #ifdef PACKET_ADD_MEMBERSHIP
945 # include "xlat/packet_mreq_type.h"
946
947 static void
948 print_packet_mreq(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
949 {
950         struct packet_mreq mreq;
951
952         if (len != sizeof(mreq) ||
953             umove(tcp, addr, &mreq) < 0) {
954                 printaddr(addr);
955         } else {
956                 PRINT_FIELD_IFINDEX("{", mreq, mr_ifindex);
957                 PRINT_FIELD_XVAL(", ", mreq, mr_type, packet_mreq_type,
958                                  "PACKET_MR_???");
959                 PRINT_FIELD_U(", ", mreq, mr_alen);
960                 PRINT_FIELD_MAC_SZ(", ", mreq, mr_address,
961                                    (mreq.mr_alen > sizeof(mreq.mr_address)
962                                     ? sizeof(mreq.mr_address) : mreq.mr_alen));
963                 tprints("}");
964         }
965 }
966 #endif /* PACKET_ADD_MEMBERSHIP */
967
968 static void
969 print_setsockopt(struct tcb *const tcp, const unsigned int level,
970                  const unsigned int name, const kernel_ulong_t addr,
971                  const int len)
972 {
973         if (addr && verbose(tcp))
974         switch (level) {
975         case SOL_SOCKET:
976                 switch (name) {
977                 case SO_LINGER:
978                         print_set_linger(tcp, addr, len);
979                         return;
980                 case SO_ATTACH_FILTER:
981                 case SO_ATTACH_REUSEPORT_CBPF:
982                         if ((unsigned int) len == get_sock_fprog_size())
983                                 decode_sock_fprog(tcp, addr);
984                         else
985                                 printaddr(addr);
986                         return;
987                 }
988                 break;
989
990         case SOL_IP:
991                 switch (name) {
992 #ifdef IP_ADD_MEMBERSHIP
993                 case IP_ADD_MEMBERSHIP:
994                 case IP_DROP_MEMBERSHIP:
995                         print_mreq(tcp, addr, len);
996                         return;
997 #endif /* IP_ADD_MEMBERSHIP */
998 #ifdef MCAST_JOIN_GROUP
999                 case MCAST_JOIN_GROUP:
1000                 case MCAST_LEAVE_GROUP:
1001                         print_group_req(tcp, addr, len);
1002                         return;
1003 #endif /* MCAST_JOIN_GROUP */
1004                 }
1005                 break;
1006
1007         case SOL_IPV6:
1008                 switch (name) {
1009 #ifdef IPV6_ADD_MEMBERSHIP
1010                 case IPV6_ADD_MEMBERSHIP:
1011                 case IPV6_DROP_MEMBERSHIP:
1012 # ifdef IPV6_JOIN_ANYCAST
1013                 case IPV6_JOIN_ANYCAST:
1014 # endif
1015 # ifdef IPV6_LEAVE_ANYCAST
1016                 case IPV6_LEAVE_ANYCAST:
1017 # endif
1018                         print_mreq6(tcp, addr, len);
1019                         return;
1020 #endif /* IPV6_ADD_MEMBERSHIP */
1021 #ifdef MCAST_JOIN_GROUP
1022                 case MCAST_JOIN_GROUP:
1023                 case MCAST_LEAVE_GROUP:
1024                         print_group_req(tcp, addr, len);
1025                         return;
1026 #endif /* MCAST_JOIN_GROUP */
1027                 }
1028                 break;
1029
1030         case SOL_PACKET:
1031                 switch (name) {
1032 #ifdef PACKET_RX_RING
1033                 case PACKET_RX_RING:
1034 # ifdef PACKET_TX_RING
1035                 case PACKET_TX_RING:
1036 # endif
1037                         print_tpacket_req(tcp, addr, len);
1038                         return;
1039 #endif /* PACKET_RX_RING */
1040 #ifdef PACKET_ADD_MEMBERSHIP
1041                 case PACKET_ADD_MEMBERSHIP:
1042                 case PACKET_DROP_MEMBERSHIP:
1043                         print_packet_mreq(tcp, addr, len);
1044                         return;
1045 #endif /* PACKET_ADD_MEMBERSHIP */
1046                 }
1047                 break;
1048
1049         case SOL_RAW:
1050                 switch (name) {
1051                 case ICMP_FILTER:
1052                         print_icmp_filter(tcp, addr, len);
1053                         return;
1054                 }
1055                 break;
1056
1057         case SOL_NETLINK:
1058                 if (len < (int) sizeof(int))
1059                         printaddr(addr);
1060                 else
1061                         printnum_int(tcp, addr, "%d");
1062                 return;
1063         }
1064
1065         /* default arg printing */
1066
1067         if (verbose(tcp)) {
1068                 if (len == sizeof(int)) {
1069                         printnum_int(tcp, addr, "%d");
1070                 } else {
1071                         printstrn(tcp, addr, len);
1072                 }
1073         } else {
1074                 printaddr(addr);
1075         }
1076 }
1077
1078 SYS_FUNC(setsockopt)
1079 {
1080         print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
1081                                     tcp->u_arg[1], tcp->u_arg[2], false);
1082         print_setsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
1083                          tcp->u_arg[3], tcp->u_arg[4]);
1084         tprintf(", %d", (int) tcp->u_arg[4]);
1085
1086         return RVAL_DECODED;
1087 }