9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2017 Joyent, Inc.
14 */
15
16 #include <sys/socket.h>
17 #include <net/pfkeyv2.h>
18 #include <stdio.h>
19 #include <errno.h>
20 #include <err.h>
21 #include <unistd.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #define COOKIE64 0xc0ffee4afee01deaULL
26 #define COOKIE32 0x90125
27 #define RESERVED 0xc0ffee
28
29 /*
30 * Exits app on failure.
31 */
32 static void
33 write_and_read(int s, sadb_msg_t *samsg, uint64_t *readbuf, int readlen,
34 char *msgtypestr)
35 {
36 int rc;
37 uint8_t msgtype = samsg->sadb_msg_type;
38 pid_t pid = samsg->sadb_msg_pid;
39 uint8_t seq = samsg->sadb_msg_seq;
40
41 rc = write(s, samsg, SADB_64TO8(samsg->sadb_msg_len));
42 if (rc == -1)
43 err(-1, "%s write error", msgtypestr);
44
45 /* Yes, parameter re-use, but we're done writing. */
46 samsg = (sadb_msg_t *)readbuf;
47 do {
48 rc = read(s, readbuf, readlen);
49 if (rc == -1)
50 err(-1, "%s read reply error", msgtypestr);
51 } while (samsg->sadb_msg_seq != seq || samsg->sadb_msg_pid != pid ||
52 samsg->sadb_msg_type != msgtype);
53
54 if (samsg->sadb_msg_errno != 0) {
55 errno = samsg->sadb_msg_errno;
56 err(-1, "%s reply has error (diag = %d)", msgtypestr,
57 samsg->sadb_x_msg_diagnostic);
58 }
59 }
60
61 int
62 main(int argc, char *argv[])
63 {
64 uint32_t spi;
65 sadb_ext_t *ext;
66 sadb_sa_t *saext;
67 sadb_msg_t *samsg;
68 sadb_address_t *dstext, *srcext;
69 sadb_x_kmc_t *kmcext;
70 struct sockaddr_in *sin;
71 uint64_t writebuf[20]; /* PF_KEY likes 64-bit alignment. */
72 uint64_t readbuf[128];
73 uint64_t *extptr, *endptr;
74 pid_t pid = getpid();
75 boolean_t do_64_test;
76 int s;
77
78 if (argc != 2 && argc != 3) {
79 (void) fprintf(stderr, "Usage: %s <spi-value> {64}\n",
80 argv[0]);
81 exit(-1);
82 }
83 do_64_test = (argc == 3);
84
85 spi = strtoul(argv[1], NULL, 0);
86 if (spi == 0) {
87 if (errno != 0) {
88 err(-1, "Argument %s is not a parsable number:",
89 argv[1]);
90 } else {
91 errno = EINVAL;
92 err(-1, "Zero SPI not allowed:");
93 }
94 }
95
96 s = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
97 if (s == -1)
98 err(-1, "socket(PF_KEY)");
99
100 /* Base message. */
101 samsg = (sadb_msg_t *)writebuf;
102 samsg->sadb_msg_version = PF_KEY_V2;
103 samsg->sadb_msg_type = SADB_UPDATE;
104 samsg->sadb_msg_errno = 0;
105 samsg->sadb_msg_satype = SADB_SATYPE_AH;
106 samsg->sadb_msg_reserved = 0;
107 samsg->sadb_msg_seq = 1;
108 samsg->sadb_msg_pid = pid;
109 samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg) + sizeof (*saext) +
110 2 * (sizeof (*dstext) + sizeof (*sin)) + sizeof (*kmcext));
111
112 /* SA extension. Only used to set the SPI. */
113 saext = (sadb_sa_t *)(samsg + 1);
114 memset(saext, 0, sizeof (*saext));
115 saext->sadb_sa_len = SADB_8TO64(sizeof (*saext));
116 saext->sadb_sa_exttype = SADB_EXT_SA;
117 saext->sadb_sa_spi = htonl(spi);
118 saext->sadb_sa_state = SADB_SASTATE_MATURE;
168 samsg->sadb_msg_type = SADB_GET;
169 samsg->sadb_msg_len -= SADB_8TO64(sizeof (*kmcext));
170
171 /* Everything else in writebuf is good to go. */
172 write_and_read(s, samsg, readbuf, sizeof (readbuf), "SADB_GET");
173
174 /* Actually find the KMC extension. (expand for loop for readability) */
175 samsg = (sadb_msg_t *)readbuf;
176 extptr = (uint64_t *)(samsg + 1);
177 endptr = extptr + samsg->sadb_msg_len - SADB_8TO64(sizeof (*samsg));
178 ext = (sadb_ext_t *)extptr;
179
180 while ((extptr < endptr) &&
181 (ext->sadb_ext_type != SADB_X_EXT_KM_COOKIE)) {
182 extptr += ext->sadb_ext_len;
183 ext = (sadb_ext_t *)extptr;
184 }
185
186 if (extptr == endptr) {
187 (void) fprintf(stderr, "Can't find KMC extension in reply.\n");
188 exit(-1);
189 }
190 kmcext = (sadb_x_kmc_t *)extptr;
191
192 if (do_64_test) {
193 if (kmcext->sadb_x_kmc_proto != SADB_X_KMP_KINK ||
194 kmcext->sadb_x_kmc_cookie64 != COOKIE64) {
195 (void) fprintf(stderr, "Unexpected 64-bit results: "
196 "KMC received was %d, expecting %d,\n",
197 kmcext->sadb_x_kmc_proto, SADB_X_KMP_KINK);
198 (void) fprintf(stderr, "64-bit cookie recevied was "
199 "0x%"PRIx64", expecting 0x%"PRIx64"\n",
200 kmcext->sadb_x_kmc_cookie64, COOKIE64);
201 exit(1);
202 }
203 } else {
204 if (kmcext->sadb_x_kmc_proto != SADB_X_KMP_IKE ||
205 kmcext->sadb_x_kmc_cookie != COOKIE32 ||
206 kmcext->sadb_x_kmc_reserved != 0) {
207 (void) fprintf(stderr, "Unexpected IKE/32-bit results:"
208 " KMC received was %d, expecting %d,\n",
209 kmcext->sadb_x_kmc_proto, SADB_X_KMP_IKE);
210 (void) fprintf(stderr, "32-bit cookie recevied was "
211 "0x%"PRIx32", expecting 0x%"PRIx32"\n",
212 kmcext->sadb_x_kmc_cookie64, COOKIE32);
213 (void) fprintf(stderr, "32-bit reserved recevied was "
214 "0x%"PRIx32", expecting 0\n",
215 kmcext->sadb_x_kmc_cookie64);
216 exit(1);
217 }
218 }
219
220 exit(0);
221 }
|
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2017 Joyent, Inc.
14 */
15
16 #include <sys/socket.h>
17 #include <net/pfkeyv2.h>
18 #include <stdio.h>
19 #include <errno.h>
20 #include <err.h>
21 #include <unistd.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #define COOKIE64 0xc0ffee4afee01deaULL
26 #define COOKIE32 0x90125
27 #define RESERVED 0xc0ffee
28
29 #define EXIT_SETUP_FAIL -1
30 #define EXIT_TEST_FAIL 1
31 #define EXIT_SUCCESS 0
32
33 /*
34 * Exits app on failure.
35 */
36 static void
37 write_and_read(int s, sadb_msg_t *samsg, uint64_t *readbuf, int readlen,
38 char *msgtypestr)
39 {
40 ssize_t rc;
41 uint8_t msgtype = samsg->sadb_msg_type;
42 pid_t pid = samsg->sadb_msg_pid;
43 uint8_t seq = samsg->sadb_msg_seq;
44
45 rc = write(s, samsg, SADB_64TO8(samsg->sadb_msg_len));
46 if (rc == -1)
47 err(EXIT_SETUP_FAIL, "%s write error", msgtypestr);
48
49 /* Yes, parameter re-use, but we're done writing. */
50 samsg = (sadb_msg_t *)readbuf;
51 do {
52 rc = read(s, readbuf, readlen);
53 if (rc == -1)
54 err(EXIT_SETUP_FAIL, "%s read reply error", msgtypestr);
55 } while (samsg->sadb_msg_seq != seq || samsg->sadb_msg_pid != pid ||
56 samsg->sadb_msg_type != msgtype);
57
58 if (samsg->sadb_msg_errno != 0) {
59 errno = samsg->sadb_msg_errno;
60 err(EXIT_SETUP_FAIL, "%s reply has error (diag = %d)",
61 msgtypestr, samsg->sadb_x_msg_diagnostic);
62 }
63 }
64
65 int
66 main(int argc, char *argv[])
67 {
68 uint32_t spi;
69 sadb_ext_t *ext;
70 sadb_sa_t *saext;
71 sadb_msg_t *samsg;
72 sadb_address_t *dstext, *srcext;
73 sadb_x_kmc_t *kmcext;
74 struct sockaddr_in *sin;
75 uint64_t writebuf[20]; /* PF_KEY likes 64-bit alignment. */
76 uint64_t readbuf[128];
77 uint64_t *extptr, *endptr;
78 pid_t pid = getpid();
79 boolean_t do_64_test;
80 int s;
81
82 if (argc != 2 && argc != 3) {
83 (void) fprintf(stderr, "Usage: %s <spi-value> {64}\n",
84 argv[0]);
85 exit(EXIT_SETUP_FAIL);
86 }
87 do_64_test = (argc == 3);
88
89 errno = 0; /* Clear for strtoul() call. */
90 spi = strtoul(argv[1], NULL, 0);
91 if (spi == 0) {
92 if (errno != 0) {
93 err(EXIT_SETUP_FAIL,
94 "Argument %s is not a parsable number:", argv[1]);
95 } else {
96 errno = EINVAL;
97 err(EXIT_SETUP_FAIL, "Zero SPI not allowed:");
98 }
99 }
100
101 s = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
102 if (s == -1)
103 err(EXIT_SETUP_FAIL, "socket(PF_KEY)");
104
105 /* Base message. */
106 samsg = (sadb_msg_t *)writebuf;
107 samsg->sadb_msg_version = PF_KEY_V2;
108 samsg->sadb_msg_type = SADB_UPDATE;
109 samsg->sadb_msg_errno = 0;
110 samsg->sadb_msg_satype = SADB_SATYPE_AH;
111 samsg->sadb_msg_reserved = 0;
112 samsg->sadb_msg_seq = 1;
113 samsg->sadb_msg_pid = pid;
114 samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg) + sizeof (*saext) +
115 2 * (sizeof (*dstext) + sizeof (*sin)) + sizeof (*kmcext));
116
117 /* SA extension. Only used to set the SPI. */
118 saext = (sadb_sa_t *)(samsg + 1);
119 memset(saext, 0, sizeof (*saext));
120 saext->sadb_sa_len = SADB_8TO64(sizeof (*saext));
121 saext->sadb_sa_exttype = SADB_EXT_SA;
122 saext->sadb_sa_spi = htonl(spi);
123 saext->sadb_sa_state = SADB_SASTATE_MATURE;
173 samsg->sadb_msg_type = SADB_GET;
174 samsg->sadb_msg_len -= SADB_8TO64(sizeof (*kmcext));
175
176 /* Everything else in writebuf is good to go. */
177 write_and_read(s, samsg, readbuf, sizeof (readbuf), "SADB_GET");
178
179 /* Actually find the KMC extension. (expand for loop for readability) */
180 samsg = (sadb_msg_t *)readbuf;
181 extptr = (uint64_t *)(samsg + 1);
182 endptr = extptr + samsg->sadb_msg_len - SADB_8TO64(sizeof (*samsg));
183 ext = (sadb_ext_t *)extptr;
184
185 while ((extptr < endptr) &&
186 (ext->sadb_ext_type != SADB_X_EXT_KM_COOKIE)) {
187 extptr += ext->sadb_ext_len;
188 ext = (sadb_ext_t *)extptr;
189 }
190
191 if (extptr == endptr) {
192 (void) fprintf(stderr, "Can't find KMC extension in reply.\n");
193 exit(EXIT_SETUP_FAIL);
194 }
195 kmcext = (sadb_x_kmc_t *)extptr;
196
197 if (do_64_test) {
198 if (kmcext->sadb_x_kmc_proto != SADB_X_KMP_KINK ||
199 kmcext->sadb_x_kmc_cookie64 != COOKIE64) {
200 (void) fprintf(stderr, "Unexpected 64-bit results: "
201 "KMC received was %d, expecting %d,\n",
202 kmcext->sadb_x_kmc_proto, SADB_X_KMP_KINK);
203 (void) fprintf(stderr, "64-bit cookie recevied was "
204 "0x%"PRIx64", expecting 0x%"PRIx64"\n",
205 kmcext->sadb_x_kmc_cookie64, COOKIE64);
206 exit(EXIT_TEST_FAIL);
207 }
208 } else {
209 if (kmcext->sadb_x_kmc_proto != SADB_X_KMP_IKE ||
210 kmcext->sadb_x_kmc_cookie != COOKIE32 ||
211 kmcext->sadb_x_kmc_reserved != 0) {
212 (void) fprintf(stderr, "Unexpected IKE/32-bit results:"
213 " KMC received was %d, expecting %d,\n",
214 kmcext->sadb_x_kmc_proto, SADB_X_KMP_IKE);
215 (void) fprintf(stderr, "32-bit cookie recevied was "
216 "0x%"PRIx32", expecting 0x%"PRIx32"\n",
217 kmcext->sadb_x_kmc_cookie64, COOKIE32);
218 (void) fprintf(stderr, "32-bit reserved recevied was "
219 "0x%"PRIx32", expecting 0\n",
220 kmcext->sadb_x_kmc_cookie64);
221 exit(EXIT_TEST_FAIL);
222 }
223 }
224
225 exit(EXIT_SUCCESS);
226 }
|