1 /*
2 * Copyright (c) 2023 The strace developers.
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8 #include "tests.h"
9
10 #include <stdio.h>
11 #include <unistd.h>
12 #include <arpa/inet.h>
13 #include <netinet/in.h>
14 #include <sys/socket.h>
15
16 #ifndef IP_PROTOCOL
17 # define IP_PROTOCOL 52
18 #endif
19
20 #define INJSTR " (INJECTED)"
21
22 int
23 main(void)
24 {
25 static const struct strval32 opts[] = {
26 { ARG_XLAT_KNOWN(0xff, "IPPROTO_RAW") },
27 { ARG_XLAT_UNKNOWN(0xfe, "IPPROTO_???") },
28 };
29
30 TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, protocol);
31 TAIL_ALLOC_OBJECT_CONST_ARR(unsigned int, big_protocol, 2);
32 const char *errstr;
33 socklen_t len;
34 int rc;
35
36 for (unsigned int i = 0; i < ARRAY_SIZE(opts); ++i) {
37 *protocol = opts[i].val;
38
39 /* optlen < 0, EINVAL */
40 len = -1;
41 rc = getsockopt(0, SOL_IP, IP_PROTOCOL, protocol, &len);
42 printf("getsockopt(0, " XLAT_FMT ", " XLAT_FMT ", %p, [-1]) = %s"
43 INJSTR "\n",
44 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_PROTOCOL),
45 protocol, sprintrc(rc));
46
47
48 /* optlen = 0, EINVAL */
49 len = 0;
50 rc = getsockopt(0, SOL_IP, IP_PROTOCOL, protocol, &len);
51 printf("getsockopt(0, " XLAT_FMT ", " XLAT_FMT ", %p, [0]) = %s"
52 INJSTR "\n",
53 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_PROTOCOL),
54 protocol, sprintrc(rc));
55
56
57 /* optlen < sizeof(int), EINVAL */
58 len = sizeof(*protocol) - 1;
59 rc = getsockopt(0, SOL_IP, IP_PROTOCOL, protocol, &len);
60 errstr = sprintrc(rc);
61 printf("getsockopt(0, " XLAT_FMT ", " XLAT_FMT ", ",
62 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_PROTOCOL));
63 print_quoted_hex(protocol, len);
64 printf(", [3]) = %s" INJSTR "\n", errstr);
65
66
67 /* optval EFAULT */
68 len = sizeof(*protocol);
69 rc = getsockopt(0, SOL_IP, IP_PROTOCOL, protocol + 1, &len);
70 printf("getsockopt(0, " XLAT_FMT ", " XLAT_FMT ", %p, [4]) = %s"
71 INJSTR "\n",
72 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_PROTOCOL),
73 protocol + 1, sprintrc(rc));
74
75
76 /* classic */
77 len = sizeof(*protocol);
78 rc = getsockopt(0, SOL_IP, IP_PROTOCOL, protocol, &len);
79 errstr = sprintrc(rc);
80 printf("getsockopt(0, " XLAT_FMT ", " XLAT_FMT ", [%s], [4])"
81 " = %s" INJSTR "\n",
82 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_PROTOCOL),
83 opts[i].str, errstr);
84
85
86 /* optval > sizeof(int), EFAULT */
87 len = sizeof(*protocol) + 1;
88 rc = getsockopt(0, SOL_IP, IP_PROTOCOL, protocol, &len);
89 printf("getsockopt(0, " XLAT_FMT ", " XLAT_FMT ", %p, [5]) = %s"
90 INJSTR "\n",
91 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_PROTOCOL),
92 protocol, sprintrc(rc));
93
94
95 /* optlen > sizeof(int), EINVAL */
96 len = sizeof(*protocol) * 2;
97 big_protocol[0] = opts[i].val;
98 big_protocol[1] = opts[i].val;
99 rc = getsockopt(0, SOL_IP, IP_PROTOCOL, big_protocol, &len);
100 errstr = sprintrc(rc);
101 printf("getsockopt(0, " XLAT_FMT ", " XLAT_FMT ", ",
102 XLAT_ARGS(SOL_IP), XLAT_ARGS(IP_PROTOCOL));
103 print_quoted_hex(big_protocol, len);
104 printf(", [8]) = %s" INJSTR "\n", errstr);
105 }
106
107 puts("+++ exited with 0 +++");
108 return 0;
109 }