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