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