1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright (c) 2017 Joyent, Inc.
14 */
15
16 /*
17 * Designed to be backgrounded and just killed. Open a PF_KEY socket, do
18 * an extended-REGISTER so the kernel will send extended-ACQUIRE messages,
19 * and then read-and-discard everything off the socket.
20 */
21
22 #include <sys/socket.h>
23 #include <net/pfkeyv2.h>
24 #include <stdio.h>
25 #include <errno.h>
26 #include <err.h>
27 #include <unistd.h>
28
29 /* ARGSUSED */
30 int
main(int argc,char * argv[])31 main(int argc, char *argv[])
32 {
33 int s, rc;
34 uint64_t buf[1024]; /* PF_KEY likes 64-bit alignment. */
35 sadb_msg_t *samsg;
36 sadb_x_ereg_t *ereg;
37 boolean_t ah_ack, esp_ack;
38 pid_t pid = getpid();
39
40 s = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
41 if (s == -1)
42 err(-1, "socket(PF_KEY)");
43
44 /* Base message. */
45 samsg = (sadb_msg_t *)buf;
46 ereg = (sadb_x_ereg_t *)(samsg + 1);
47 samsg->sadb_msg_version = PF_KEY_V2;
48 samsg->sadb_msg_type = SADB_REGISTER;
49 samsg->sadb_msg_errno = 0;
50 samsg->sadb_msg_satype = SADB_SATYPE_UNSPEC;
51 samsg->sadb_msg_reserved = 0;
52 samsg->sadb_msg_seq = 1;
53 samsg->sadb_msg_pid = pid;
54 samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg) + sizeof (*ereg));
55
56 /* extended REGISTER so we can listen for extended ACQUIREs. */
57 ereg->sadb_x_ereg_len = SADB_8TO64(sizeof (*ereg));
58 ereg->sadb_x_ereg_exttype = SADB_X_EXT_EREG;
59 ereg->sadb_x_ereg_satypes[0] = SADB_SATYPE_ESP;
60 ereg->sadb_x_ereg_satypes[1] = SADB_SATYPE_AH;
61 ereg->sadb_x_ereg_satypes[2] = SADB_SATYPE_UNSPEC;
62
63 rc = write(s, buf, sizeof (*samsg) + sizeof (*ereg));
64 if (rc == -1)
65 err(-1, "Extended register write error");
66
67 /*
68 * Extended REGISTER expects a regular REGISTER reply for EACH protocol
69 * requested. In our case, AH and ESP.
70 */
71 do {
72
73 do {
74 rc = read(s, buf, sizeof (buf));
75 if (rc == -1)
76 err(-1, "Extended register read error");
77
78 } while (samsg->sadb_msg_seq != 1 ||
79 samsg->sadb_msg_pid != pid ||
80 samsg->sadb_msg_type != SADB_REGISTER);
81
82 if (samsg->sadb_msg_errno != 0) {
83 if (samsg->sadb_msg_errno == EPROTONOSUPPORT) {
84 warn("Protocol %d not supported.",
85 samsg->sadb_msg_satype);
86 } else {
87 errno = samsg->sadb_msg_errno;
88 err(-1, "Extended REGISTER returned");
89 }
90 }
91
92 switch (samsg->sadb_msg_satype) {
93 case SADB_SATYPE_ESP:
94 esp_ack = B_TRUE;
95 break;
96 case SADB_SATYPE_AH:
97 ah_ack = B_TRUE;
98 break;
99 default:
100 err(-1, "Bad satype in extended register ACK %d.",
101 samsg->sadb_msg_satype);
102 }
103 } while (!esp_ack || !ah_ack);
104
105 /* Expect this loop to never end. This program ends via signal. */
106 do {
107 rc = read(s, buf, sizeof (buf));
108 } while (rc != -1);
109
110 err(-1, "PF_KEY read error");
111 }
112