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 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