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