Branch data Line data Source code
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 : :
74 : : #include "xlat/socktypes.h"
75 : : #include "xlat/sock_type_flags.h"
76 : : #ifndef SOCK_TYPE_MASK
77 : : # define SOCK_TYPE_MASK 0xf
78 : : #endif
79 : :
80 : : #include "xlat/socketlayers.h"
81 : :
82 : : #include "xlat/inet_protocols.h"
83 : : #include "xlat/netlink_protocols.h"
84 : :
85 : : #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
86 : : # include <bluetooth/bluetooth.h>
87 : : # include "xlat/bt_protocols.h"
88 : : #endif
89 : :
90 : : void
91 : 75 : print_ifindex(unsigned int ifindex)
92 : : {
93 : : #ifdef HAVE_IF_INDEXTONAME
94 : : char buf[IFNAMSIZ + 1];
95 : :
96 [ + + ]: 75 : if (if_indextoname(ifindex, buf)) {
97 : 50 : tprints("if_nametoindex(");
98 : 50 : print_quoted_string(buf, sizeof(buf), QUOTE_0_TERMINATED);
99 : 50 : tprints(")");
100 : 50 : return;
101 : : }
102 : : #endif
103 : 25 : tprintf("%u", ifindex);
104 : : }
105 : :
106 : : static void
107 : 164 : decode_sockbuf(struct tcb *const tcp, const int fd, const kernel_ulong_t addr,
108 : : const kernel_ulong_t addrlen)
109 : : {
110 : :
111 [ + - ][ + + ]: 164 : switch (verbose(tcp) ? getfdproto(tcp, fd) : SOCK_PROTO_UNKNOWN) {
112 : : case SOCK_PROTO_NETLINK:
113 : 70 : decode_netlink(tcp, addr, addrlen);
114 : 70 : break;
115 : : default:
116 : 94 : printstrn(tcp, addr, addrlen);
117 : : }
118 : 164 : }
119 : :
120 : : /*
121 : : * low bits of the socket type define real socket type,
122 : : * other bits are socket type flags.
123 : : */
124 : : static void
125 : 65 : tprint_sock_type(unsigned int flags)
126 : : {
127 : 65 : const char *str = xlookup(socktypes, flags & SOCK_TYPE_MASK);
128 : :
129 [ + - ]: 65 : if (str) {
130 : 65 : tprints(str);
131 : 65 : flags &= ~SOCK_TYPE_MASK;
132 [ + - ]: 65 : if (!flags)
133 : 65 : return;
134 : 0 : tprints("|");
135 : : }
136 : 0 : printflags(sock_type_flags, flags, "SOCK_???");
137 : : }
138 : :
139 : 60 : SYS_FUNC(socket)
140 : : {
141 : 60 : printxval(addrfams, tcp->u_arg[0], "AF_???");
142 : 60 : tprints(", ");
143 : 60 : tprint_sock_type(tcp->u_arg[1]);
144 : 60 : tprints(", ");
145 [ + + + ]: 60 : switch (tcp->u_arg[0]) {
146 : : case AF_INET:
147 : : case AF_INET6:
148 : 10 : printxval(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
149 : 10 : break;
150 : :
151 : : case AF_NETLINK:
152 : 10 : printxval(netlink_protocols, tcp->u_arg[2], "NETLINK_???");
153 : 10 : break;
154 : :
155 : : #ifdef HAVE_BLUETOOTH_BLUETOOTH_H
156 : : case AF_BLUETOOTH:
157 : : printxval(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
158 : : break;
159 : : #endif
160 : :
161 : : default:
162 : 40 : tprintf("%" PRI_klu, tcp->u_arg[2]);
163 : 40 : break;
164 : : }
165 : :
166 : 60 : return RVAL_DECODED | RVAL_FD;
167 : : }
168 : :
169 : 235 : SYS_FUNC(bind)
170 : : {
171 : 235 : printfd(tcp, tcp->u_arg[0]);
172 : 235 : tprints(", ");
173 : 235 : const int addrlen = tcp->u_arg[2];
174 : 235 : decode_sockaddr(tcp, tcp->u_arg[1], addrlen);
175 : 235 : tprintf(", %d", addrlen);
176 : :
177 : 235 : return RVAL_DECODED;
178 : : }
179 : :
180 : 20 : SYS_FUNC(listen)
181 : : {
182 : 20 : printfd(tcp, tcp->u_arg[0]);
183 : 20 : tprints(", ");
184 : 20 : tprintf("%" PRI_klu, tcp->u_arg[1]);
185 : :
186 : 20 : return RVAL_DECODED;
187 : : }
188 : :
189 : : static bool
190 : 425 : fetch_socklen(struct tcb *const tcp, int *const plen,
191 : : const kernel_ulong_t sockaddr, const kernel_ulong_t socklen)
192 : : {
193 [ + + ][ + + ]: 425 : return verbose(tcp) && sockaddr && socklen
194 [ + - ][ + + ]: 850 : && umove(tcp, socklen, plen) == 0;
195 : : }
196 : :
197 : : static int
198 : 470 : decode_sockname(struct tcb *tcp)
199 : : {
200 : : int ulen, rlen;
201 : :
202 [ + + ]: 470 : if (entering(tcp)) {
203 : 265 : printfd(tcp, tcp->u_arg[0]);
204 : 265 : tprints(", ");
205 [ + + ]: 265 : if (fetch_socklen(tcp, &ulen, tcp->u_arg[1], tcp->u_arg[2])) {
206 : 205 : set_tcb_priv_ulong(tcp, ulen);
207 : 205 : return 0;
208 : : } else {
209 : 60 : printaddr(tcp->u_arg[1]);
210 : 60 : tprints(", ");
211 : 60 : printaddr(tcp->u_arg[2]);
212 : 60 : return RVAL_DECODED;
213 : : }
214 : : }
215 : :
216 : 205 : ulen = get_tcb_priv_ulong(tcp);
217 : :
218 [ + + ][ - + ]: 205 : if (syserror(tcp) || umove(tcp, tcp->u_arg[2], &rlen) < 0) {
219 : 20 : printaddr(tcp->u_arg[1]);
220 : 20 : tprintf(", [%d]", ulen);
221 : : } else {
222 : 185 : decode_sockaddr(tcp, tcp->u_arg[1], ulen > rlen ? rlen : ulen);
223 [ + + ]: 185 : if (ulen != rlen)
224 : 135 : tprintf(", [%d->%d]", ulen, rlen);
225 : : else
226 : 50 : tprintf(", [%d]", rlen);
227 : : }
228 : :
229 : 470 : return RVAL_DECODED;
230 : : }
231 : :
232 : 125 : SYS_FUNC(accept)
233 : : {
234 : 125 : return decode_sockname(tcp) | RVAL_FD;
235 : : }
236 : :
237 : 65 : SYS_FUNC(accept4)
238 : : {
239 : 65 : int rc = decode_sockname(tcp);
240 : :
241 [ + + ]: 65 : if (rc & RVAL_DECODED) {
242 : 40 : tprints(", ");
243 : 40 : printflags(sock_type_flags, tcp->u_arg[3], "SOCK_???");
244 : : }
245 : :
246 : 65 : return rc | RVAL_FD;
247 : : }
248 : :
249 : 2 : SYS_FUNC(send)
250 : : {
251 : 2 : printfd(tcp, tcp->u_arg[0]);
252 : 2 : tprints(", ");
253 : 2 : decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
254 : 2 : tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
255 : : /* flags */
256 : 2 : printflags(msg_flags, tcp->u_arg[3], "MSG_???");
257 : :
258 : 2 : return RVAL_DECODED;
259 : : }
260 : :
261 : 100 : SYS_FUNC(sendto)
262 : : {
263 : 100 : printfd(tcp, tcp->u_arg[0]);
264 : 100 : tprints(", ");
265 : 100 : decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
266 : 100 : tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
267 : : /* flags */
268 : 100 : printflags(msg_flags, tcp->u_arg[3], "MSG_???");
269 : : /* to address */
270 : 100 : const int addrlen = tcp->u_arg[5];
271 : 100 : tprints(", ");
272 : 100 : decode_sockaddr(tcp, tcp->u_arg[4], addrlen);
273 : : /* to length */
274 : 100 : tprintf(", %d", addrlen);
275 : :
276 : 100 : return RVAL_DECODED;
277 : : }
278 : :
279 : 6 : SYS_FUNC(recv)
280 : : {
281 [ + + ]: 6 : if (entering(tcp)) {
282 : 3 : printfd(tcp, tcp->u_arg[0]);
283 : 3 : tprints(", ");
284 : : } else {
285 [ + + ]: 3 : if (syserror(tcp)) {
286 : 1 : printaddr(tcp->u_arg[1]);
287 : : } else {
288 : 2 : decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
289 : 2 : tcp->u_rval);
290 : : }
291 : :
292 : 3 : tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
293 : 3 : printflags(msg_flags, tcp->u_arg[3], "MSG_???");
294 : : }
295 : 6 : return 0;
296 : : }
297 : :
298 : 160 : SYS_FUNC(recvfrom)
299 : : {
300 : : int ulen, rlen;
301 : :
302 [ + + ]: 160 : if (entering(tcp)) {
303 : 80 : printfd(tcp, tcp->u_arg[0]);
304 : 80 : tprints(", ");
305 [ + + ]: 80 : if (fetch_socklen(tcp, &ulen, tcp->u_arg[4], tcp->u_arg[5])) {
306 : 80 : set_tcb_priv_ulong(tcp, ulen);
307 : : }
308 : : } else {
309 : : /* buf */
310 [ + + ]: 80 : if (syserror(tcp)) {
311 : 20 : printaddr(tcp->u_arg[1]);
312 : : } else {
313 : 60 : decode_sockbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
314 : 60 : tcp->u_rval);
315 : : }
316 : : /* size */
317 : 80 : tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
318 : : /* flags */
319 : 80 : printflags(msg_flags, tcp->u_arg[3], "MSG_???");
320 : 80 : tprints(", ");
321 : :
322 : 80 : ulen = get_tcb_priv_ulong(tcp);
323 : :
324 [ + + ]: 80 : if (!fetch_socklen(tcp, &rlen, tcp->u_arg[4], tcp->u_arg[5])) {
325 : : /* from address */
326 : 55 : printaddr(tcp->u_arg[4]);
327 : 55 : tprints(", ");
328 : : /* from length */
329 : 55 : printaddr(tcp->u_arg[5]);
330 : 55 : return 0;
331 : : }
332 [ + + ]: 25 : if (syserror(tcp)) {
333 : : /* from address */
334 : 5 : printaddr(tcp->u_arg[4]);
335 : : /* from length */
336 : 5 : tprintf(", [%d]", ulen);
337 : 5 : return 0;
338 : : }
339 : : /* from address */
340 : 20 : decode_sockaddr(tcp, tcp->u_arg[4], ulen > rlen ? rlen : ulen);
341 : : /* from length */
342 [ + + ]: 20 : if (ulen != rlen)
343 : 15 : tprintf(", [%d->%d]", ulen, rlen);
344 : : else
345 : 5 : tprintf(", [%d]", rlen);
346 : : }
347 : 160 : return 0;
348 : : }
349 : :
350 : : #include "xlat/shutdown_modes.h"
351 : :
352 : 5 : SYS_FUNC(shutdown)
353 : : {
354 : 5 : printfd(tcp, tcp->u_arg[0]);
355 : 5 : tprints(", ");
356 : 5 : printxval(shutdown_modes, tcp->u_arg[1], "SHUT_???");
357 : :
358 : 5 : return RVAL_DECODED;
359 : : }
360 : :
361 : 280 : SYS_FUNC(getsockname)
362 : : {
363 : 280 : return decode_sockname(tcp);
364 : : }
365 : :
366 : : static void
367 : 15 : printpair_fd(struct tcb *tcp, const int i0, const int i1)
368 : : {
369 : 15 : tprints("[");
370 : 15 : printfd(tcp, i0);
371 : 15 : tprints(", ");
372 : 15 : printfd(tcp, i1);
373 : 15 : tprints("]");
374 : 15 : }
375 : :
376 : : static void
377 : 20 : decode_pair_fd(struct tcb *const tcp, const kernel_ulong_t addr)
378 : : {
379 : : int pair[2];
380 : :
381 [ + + ]: 20 : if (umove_or_printaddr(tcp, addr, &pair))
382 : 5 : return;
383 : :
384 : 15 : printpair_fd(tcp, pair[0], pair[1]);
385 : : }
386 : :
387 : : static int
388 : 30 : do_pipe(struct tcb *tcp, int flags_arg)
389 : : {
390 [ + + ]: 30 : if (exiting(tcp)) {
391 : 15 : decode_pair_fd(tcp, tcp->u_arg[0]);
392 [ + + ]: 15 : if (flags_arg >= 0) {
393 : 10 : tprints(", ");
394 : 10 : printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
395 : : }
396 : : }
397 : 30 : return 0;
398 : : }
399 : :
400 : 10 : SYS_FUNC(pipe)
401 : : {
402 : : #ifdef HAVE_GETRVAL2
403 : : if (exiting(tcp) && !syserror(tcp))
404 : : printpair_fd(tcp, tcp->u_rval, getrval2(tcp));
405 : : return 0;
406 : : #else
407 : 10 : return do_pipe(tcp, -1);
408 : : #endif
409 : : }
410 : :
411 : 20 : SYS_FUNC(pipe2)
412 : : {
413 : 20 : return do_pipe(tcp, 1);
414 : : }
415 : :
416 : 10 : SYS_FUNC(socketpair)
417 : : {
418 [ + + ]: 10 : if (entering(tcp)) {
419 : 5 : printxval(addrfams, tcp->u_arg[0], "AF_???");
420 : 5 : tprints(", ");
421 : 5 : tprint_sock_type(tcp->u_arg[1]);
422 : 5 : tprintf(", %" PRI_klu, tcp->u_arg[2]);
423 : : } else {
424 : 5 : tprints(", ");
425 : 5 : decode_pair_fd(tcp, tcp->u_arg[3]);
426 : : }
427 : 10 : return 0;
428 : : }
429 : :
430 : : #include "xlat/sockoptions.h"
431 : : #include "xlat/sockipoptions.h"
432 : : #include "xlat/getsockipoptions.h"
433 : : #include "xlat/setsockipoptions.h"
434 : : #include "xlat/sockipv6options.h"
435 : : #include "xlat/getsockipv6options.h"
436 : : #include "xlat/setsockipv6options.h"
437 : : #include "xlat/sockipxoptions.h"
438 : : #include "xlat/sockrawoptions.h"
439 : : #include "xlat/sockpacketoptions.h"
440 : : #include "xlat/socksctpoptions.h"
441 : : #include "xlat/socktcpoptions.h"
442 : :
443 : : static void
444 : 160 : print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
445 : : unsigned int name, bool is_getsockopt)
446 : : {
447 : 160 : printfd(tcp, fd);
448 : 160 : tprints(", ");
449 : 160 : printxval(socketlayers, level, "SOL_??");
450 : 160 : tprints(", ");
451 : :
452 [ + + + - : 160 : switch (level) {
- + - +
- ]
453 : : case SOL_SOCKET:
454 : 25 : printxval(sockoptions, name, "SO_???");
455 : 25 : break;
456 : : case SOL_IP:
457 [ - + ]: 30 : printxvals(name, "IP_???", sockipoptions,
458 : : is_getsockopt ? getsockipoptions : setsockipoptions, NULL);
459 : 30 : break;
460 : : case SOL_IPV6:
461 [ - + ]: 60 : printxvals(name, "IPV6_???", sockipv6options,
462 : : is_getsockopt ? getsockipv6options : setsockipv6options, NULL);
463 : 60 : break;
464 : : case SOL_IPX:
465 : 0 : printxval(sockipxoptions, name, "IPX_???");
466 : 0 : break;
467 : : case SOL_PACKET:
468 : 0 : printxval(sockpacketoptions, name, "PACKET_???");
469 : 0 : break;
470 : : case SOL_TCP:
471 : 10 : printxval(socktcpoptions, name, "TCP_???");
472 : 10 : break;
473 : : case SOL_SCTP:
474 : 0 : printxval(socksctpoptions, name, "SCTP_???");
475 : 0 : break;
476 : : case SOL_RAW:
477 : 35 : printxval(sockrawoptions, name, "RAW_???");
478 : 35 : break;
479 : :
480 : : /* Other SOL_* protocol levels still need work. */
481 : :
482 : : default:
483 : 0 : tprintf("%u", name);
484 : : }
485 : :
486 : 160 : tprints(", ");
487 : 160 : }
488 : :
489 : : static void
490 : 0 : print_linger(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
491 : : {
492 : : struct linger linger;
493 : :
494 [ # # # # ]: 0 : if (len != sizeof(linger) ||
495 : 0 : umove(tcp, addr, &linger) < 0) {
496 : 0 : printaddr(addr);
497 : 0 : return;
498 : : }
499 : :
500 : 0 : tprintf("{onoff=%d, linger=%d}",
501 : : linger.l_onoff,
502 : : linger.l_linger);
503 : : }
504 : :
505 : : #ifdef SO_PEERCRED
506 : : static void
507 : 0 : print_ucred(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
508 : : {
509 : : struct ucred uc;
510 : :
511 [ # # # # ]: 0 : if (len != sizeof(uc) ||
512 : 0 : umove(tcp, addr, &uc) < 0) {
513 : 0 : printaddr(addr);
514 : : } else {
515 : 0 : tprintf("{pid=%u, uid=%u, gid=%u}",
516 : 0 : (unsigned) uc.pid,
517 : 0 : (unsigned) uc.uid,
518 : 0 : (unsigned) uc.gid);
519 : : }
520 : 0 : }
521 : : #endif /* SO_PEERCRED */
522 : :
523 : : #ifdef PACKET_STATISTICS
524 : : static void
525 : 0 : print_tpacket_stats(struct tcb *const tcp, const kernel_ulong_t addr,
526 : : const int len)
527 : : {
528 : : struct tpacket_stats stats;
529 : :
530 [ # # # # ]: 0 : if (len != sizeof(stats) ||
531 : 0 : umove(tcp, addr, &stats) < 0) {
532 : 0 : printaddr(addr);
533 : : } else {
534 : 0 : tprintf("{packets=%u, drops=%u}",
535 : : stats.tp_packets,
536 : : stats.tp_drops);
537 : : }
538 : 0 : }
539 : : #endif /* PACKET_STATISTICS */
540 : :
541 : : #include "xlat/icmpfilterflags.h"
542 : :
543 : : static void
544 : 20 : print_icmp_filter(struct tcb *const tcp, const kernel_ulong_t addr, int len)
545 : : {
546 : 20 : struct icmp_filter filter = {};
547 : :
548 [ + + ]: 20 : if (len > (int) sizeof(filter))
549 : 5 : len = sizeof(filter);
550 [ + + ]: 15 : else if (len <= 0) {
551 : 5 : printaddr(addr);
552 : 10 : return;
553 : : }
554 : :
555 [ + + ]: 15 : if (umoven_or_printaddr(tcp, addr, len, &filter))
556 : 5 : return;
557 : :
558 : 10 : tprints("~(");
559 : 10 : printflags(icmpfilterflags, ~filter.data, "ICMP_???");
560 : 10 : tprints(")");
561 : : }
562 : :
563 : : static void
564 : 15 : print_getsockopt(struct tcb *const tcp, const unsigned int level,
565 : : const unsigned int name, const kernel_ulong_t addr,
566 : : const int len)
567 : : {
568 [ + - ][ + - ]: 15 : if (addr && verbose(tcp))
569 [ + - - + ]: 15 : switch (level) {
570 : : case SOL_SOCKET:
571 [ - - + ]: 10 : switch (name) {
572 : : case SO_LINGER:
573 : 0 : print_linger(tcp, addr, len);
574 : 0 : goto done;
575 : : #ifdef SO_PEERCRED
576 : : case SO_PEERCRED:
577 : 0 : print_ucred(tcp, addr, len);
578 : 0 : goto done;
579 : : #endif
580 : : }
581 : 10 : break;
582 : :
583 : : case SOL_PACKET:
584 [ # # ]: 0 : switch (name) {
585 : : #ifdef PACKET_STATISTICS
586 : : case PACKET_STATISTICS:
587 : 0 : print_tpacket_stats(tcp, addr, len);
588 : 0 : goto done;
589 : : #endif
590 : : }
591 : 0 : break;
592 : :
593 : : case SOL_RAW:
594 [ # # ]: 0 : switch (name) {
595 : : case ICMP_FILTER:
596 : 0 : print_icmp_filter(tcp, addr, len);
597 : 0 : goto done;
598 : : }
599 : 0 : break;
600 : : }
601 : :
602 : : /* default arg printing */
603 : :
604 [ + - ]: 15 : if (verbose(tcp)) {
605 [ + - ]: 15 : if (len == sizeof(int)) {
606 : 15 : printnum_int(tcp, addr, "%d");
607 : : } else {
608 : 15 : printstrn(tcp, addr, len);
609 : : }
610 : : } else {
611 : 0 : printaddr(addr);
612 : : }
613 : : done:
614 : 15 : tprintf(", [%d]", len);
615 : 15 : }
616 : :
617 : 50 : SYS_FUNC(getsockopt)
618 : : {
619 [ + + ]: 50 : if (entering(tcp)) {
620 : 25 : print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
621 : 50 : tcp->u_arg[1], tcp->u_arg[2], true);
622 : : } else {
623 : : int len;
624 : :
625 [ + + ][ - + ]: 25 : if (syserror(tcp) || umove(tcp, tcp->u_arg[4], &len) < 0) {
626 : 10 : printaddr(tcp->u_arg[3]);
627 : 10 : tprints(", ");
628 : 10 : printaddr(tcp->u_arg[4]);
629 : : } else {
630 : 25 : print_getsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
631 : : tcp->u_arg[3], len);
632 : : }
633 : : }
634 : 50 : return 0;
635 : : }
636 : :
637 : : #ifdef IP_ADD_MEMBERSHIP
638 : : static void
639 : 30 : print_mreq(struct tcb *const tcp, const kernel_ulong_t addr,
640 : : const unsigned int len)
641 : : {
642 : : struct ip_mreq mreq;
643 : :
644 [ + + ]: 30 : if (len < sizeof(mreq)) {
645 : 10 : printstrn(tcp, addr, len);
646 : 20 : return;
647 : : }
648 [ + + ]: 20 : if (umove_or_printaddr(tcp, addr, &mreq))
649 : 10 : return;
650 : :
651 : 10 : tprints("{imr_multiaddr=inet_addr(");
652 : 10 : print_quoted_string(inet_ntoa(mreq.imr_multiaddr),
653 : : 16, QUOTE_0_TERMINATED);
654 : 10 : tprints("), imr_interface=inet_addr(");
655 : 10 : print_quoted_string(inet_ntoa(mreq.imr_interface),
656 : : 16, QUOTE_0_TERMINATED);
657 : 10 : tprints(")}");
658 : : }
659 : : #endif /* IP_ADD_MEMBERSHIP */
660 : :
661 : : #ifdef IPV6_ADD_MEMBERSHIP
662 : : static void
663 : 60 : print_mreq6(struct tcb *const tcp, const kernel_ulong_t addr,
664 : : const unsigned int len)
665 : : {
666 : : struct ipv6_mreq mreq;
667 : :
668 [ + + ]: 60 : if (len < sizeof(mreq))
669 : 20 : goto fail;
670 : :
671 [ + + ]: 40 : if (umove_or_printaddr(tcp, addr, &mreq))
672 : 40 : return;
673 : :
674 : 20 : const struct in6_addr *in6 = &mreq.ipv6mr_multiaddr;
675 : : char address[INET6_ADDRSTRLEN];
676 : :
677 [ - + ]: 20 : if (!inet_ntop(AF_INET6, in6, address, sizeof(address)))
678 : 0 : goto fail;
679 : :
680 : 20 : tprints("{ipv6mr_multiaddr=inet_pton(");
681 : 20 : print_quoted_string(address, sizeof(address), QUOTE_0_TERMINATED);
682 : 20 : tprints("), ipv6mr_interface=");
683 : 20 : print_ifindex(mreq.ipv6mr_interface);
684 : 20 : tprints("}");
685 : 20 : return;
686 : :
687 : : fail:
688 : 20 : printstrn(tcp, addr, len);
689 : : }
690 : : #endif /* IPV6_ADD_MEMBERSHIP */
691 : :
692 : : #ifdef MCAST_JOIN_GROUP
693 : : static void
694 : 0 : print_group_req(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
695 : : {
696 : : struct group_req greq;
697 : :
698 [ # # # # ]: 0 : if (len != sizeof(greq) ||
699 : 0 : umove(tcp, addr, &greq) < 0) {
700 : 0 : printaddr(addr);
701 : 0 : return;
702 : : }
703 : :
704 : 0 : tprintf("{gr_interface=%u, gr_group=", greq.gr_interface);
705 : 0 : print_sockaddr(tcp, &greq.gr_group, sizeof(greq.gr_group));
706 : 0 : tprints("}");
707 : :
708 : : }
709 : : #endif /* MCAST_JOIN_GROUP */
710 : :
711 : : #ifdef PACKET_RX_RING
712 : : static void
713 : 0 : print_tpacket_req(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
714 : : {
715 : : struct tpacket_req req;
716 : :
717 [ # # # # ]: 0 : if (len != sizeof(req) ||
718 : 0 : umove(tcp, addr, &req) < 0) {
719 : 0 : printaddr(addr);
720 : : } else {
721 : 0 : tprintf("{block_size=%u, block_nr=%u, "
722 : : "frame_size=%u, frame_nr=%u}",
723 : : req.tp_block_size,
724 : : req.tp_block_nr,
725 : : req.tp_frame_size,
726 : : req.tp_frame_nr);
727 : : }
728 : 0 : }
729 : : #endif /* PACKET_RX_RING */
730 : :
731 : : #ifdef PACKET_ADD_MEMBERSHIP
732 : : # include "xlat/packet_mreq_type.h"
733 : :
734 : : static void
735 : 0 : print_packet_mreq(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
736 : : {
737 : : struct packet_mreq mreq;
738 : :
739 [ # # # # ]: 0 : if (len != sizeof(mreq) ||
740 : 0 : umove(tcp, addr, &mreq) < 0) {
741 : 0 : printaddr(addr);
742 : : } else {
743 : : unsigned int i;
744 : :
745 : 0 : tprintf("{mr_ifindex=%u, mr_type=", mreq.mr_ifindex);
746 : 0 : printxval(packet_mreq_type, mreq.mr_type, "PACKET_MR_???");
747 : 0 : tprintf(", mr_alen=%u, mr_address=", mreq.mr_alen);
748 [ # # ]: 0 : if (mreq.mr_alen > ARRAY_SIZE(mreq.mr_address))
749 : 0 : mreq.mr_alen = ARRAY_SIZE(mreq.mr_address);
750 [ # # ]: 0 : for (i = 0; i < mreq.mr_alen; ++i)
751 : 0 : tprintf("%02x", mreq.mr_address[i]);
752 : 0 : tprints("}");
753 : : }
754 : 0 : }
755 : : #endif /* PACKET_ADD_MEMBERSHIP */
756 : :
757 : : static void
758 : 135 : print_setsockopt(struct tcb *const tcp, const unsigned int level,
759 : : const unsigned int name, const kernel_ulong_t addr,
760 : : const int len)
761 : : {
762 [ + + ][ + - ]: 135 : if (addr && verbose(tcp))
763 [ + + + - : 130 : switch (level) {
+ + ]
764 : : case SOL_SOCKET:
765 [ - + ]: 15 : switch (name) {
766 : : case SO_LINGER:
767 : 0 : print_linger(tcp, addr, len);
768 : 0 : goto done;
769 : : }
770 : 15 : break;
771 : :
772 : : case SOL_IP:
773 [ + - - ]: 30 : switch (name) {
774 : : #ifdef IP_ADD_MEMBERSHIP
775 : : case IP_ADD_MEMBERSHIP:
776 : : case IP_DROP_MEMBERSHIP:
777 : 30 : print_mreq(tcp, addr, len);
778 : 30 : goto done;
779 : : #endif /* IP_ADD_MEMBERSHIP */
780 : : #ifdef MCAST_JOIN_GROUP
781 : : case MCAST_JOIN_GROUP:
782 : : case MCAST_LEAVE_GROUP:
783 : 0 : print_group_req(tcp, addr, len);
784 : 0 : goto done;
785 : : #endif /* MCAST_JOIN_GROUP */
786 : : }
787 : 0 : break;
788 : :
789 : : case SOL_IPV6:
790 [ + - ]: 60 : switch (name) {
791 : : #ifdef IPV6_ADD_MEMBERSHIP
792 : : case IPV6_ADD_MEMBERSHIP:
793 : : case IPV6_DROP_MEMBERSHIP:
794 : : # ifdef IPV6_JOIN_ANYCAST
795 : : case IPV6_JOIN_ANYCAST:
796 : : # endif
797 : : # ifdef IPV6_LEAVE_ANYCAST
798 : : case IPV6_LEAVE_ANYCAST:
799 : : # endif
800 : 60 : print_mreq6(tcp, addr, len);
801 : 60 : goto done;
802 : : #endif /* IPV6_ADD_MEMBERSHIP */
803 : : }
804 : 0 : break;
805 : :
806 : : case SOL_PACKET:
807 [ # # # ]: 0 : switch (name) {
808 : : #ifdef PACKET_RX_RING
809 : : case PACKET_RX_RING:
810 : : # ifdef PACKET_TX_RING
811 : : case PACKET_TX_RING:
812 : : # endif
813 : 0 : print_tpacket_req(tcp, addr, len);
814 : 0 : goto done;
815 : : #endif /* PACKET_RX_RING */
816 : : #ifdef PACKET_ADD_MEMBERSHIP
817 : : case PACKET_ADD_MEMBERSHIP:
818 : : case PACKET_DROP_MEMBERSHIP:
819 : 0 : print_packet_mreq(tcp, addr, len);
820 : 0 : goto done;
821 : : #endif /* PACKET_ADD_MEMBERSHIP */
822 : : }
823 : 0 : break;
824 : :
825 : : case SOL_RAW:
826 [ + - ]: 20 : switch (name) {
827 : : case ICMP_FILTER:
828 : 20 : print_icmp_filter(tcp, addr, len);
829 : 20 : goto done;
830 : : }
831 : 0 : break;
832 : : }
833 : :
834 : : /* default arg printing */
835 : :
836 [ + - ]: 25 : if (verbose(tcp)) {
837 [ + + ]: 25 : if (len == sizeof(int)) {
838 : 20 : printnum_int(tcp, addr, "%d");
839 : : } else {
840 : 25 : printstrn(tcp, addr, len);
841 : : }
842 : : } else {
843 : 0 : printaddr(addr);
844 : : }
845 : : done:
846 : 135 : tprintf(", %d", len);
847 : 135 : }
848 : :
849 : 135 : SYS_FUNC(setsockopt)
850 : : {
851 : 135 : print_sockopt_fd_level_name(tcp, tcp->u_arg[0],
852 : 270 : tcp->u_arg[1], tcp->u_arg[2], false);
853 : 135 : print_setsockopt(tcp, tcp->u_arg[1], tcp->u_arg[2],
854 : 135 : tcp->u_arg[3], tcp->u_arg[4]);
855 : :
856 : 135 : return RVAL_DECODED;
857 : : }
|