diff options
Diffstat (limited to 'ipsec-tools/src/setkey/test-pfkey.c')
-rw-r--r-- | ipsec-tools/src/setkey/test-pfkey.c | 590 |
1 files changed, 590 insertions, 0 deletions
diff --git a/ipsec-tools/src/setkey/test-pfkey.c b/ipsec-tools/src/setkey/test-pfkey.c new file mode 100644 index 00000000..bb0ad7bf --- /dev/null +++ b/ipsec-tools/src/setkey/test-pfkey.c @@ -0,0 +1,590 @@ +/* $NetBSD: test-pfkey.c,v 1.7 2006/10/06 12:02:27 manu Exp $ */ + +/* $KAME: test-pfkey.c,v 1.4 2000/06/07 00:29:14 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <net/route.h> +#include <net/pfkeyv2.h> +#include <netinet/in.h> +#include <netkey/keydb.h> +#include <netkey/key_var.h> +#include <netkey/key_debug.h> + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> +#include <string.h> +#include <ctype.h> +#include <unistd.h> +#include <errno.h> +#include <netdb.h> + +u_char m_buf[BUFSIZ]; +u_int m_len; +char *pname; + +void Usage __P((void)); +int sendkeymsg __P((void)); +void key_setsadbmsg __P((u_int)); +void key_setsadbsens __P((void)); +void key_setsadbprop __P((void)); +void key_setsadbid __P((u_int, caddr_t)); +void key_setsadblft __P((u_int, u_int)); +void key_setspirange __P((void)); +void key_setsadbkey __P((u_int, caddr_t)); +void key_setsadbsa __P((void)); +void key_setsadbaddr __P((u_int, u_int, caddr_t)); +void key_setsadbextbuf __P((caddr_t, int, caddr_t, int, caddr_t, int)); + +void +Usage() +{ + printf("Usage:\t%s number\n", pname); + exit(0); +} + +int +main(ac, av) + int ac; + char **av; +{ + pname = *av; + + if (ac == 1) Usage(); + + key_setsadbmsg(atoi(*(av+1))); + sendkeymsg(); + + exit(0); +} + +/* %%% */ +int +sendkeymsg() +{ + u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ + int so, len; + + if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { + perror("socket(PF_KEY)"); + goto end; + } +#if 0 + { +#include <sys/time.h> + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { + perror("setsockopt"); + goto end; + } + } +#endif + + pfkey_sadump((struct sadb_msg *)m_buf); + + if ((len = send(so, m_buf, m_len, 0)) < 0) { + perror("send"); + goto end; + } + + if ((len = recv(so, rbuf, sizeof(rbuf), 0)) < 0) { + perror("recv"); + goto end; + } + + pfkey_sadump((struct sadb_msg *)rbuf); + +end: + (void)close(so); + return(0); +} + +void +key_setsadbmsg(type) + u_int type; +{ + struct sadb_msg m_msg; + + memset(&m_msg, 0, sizeof(m_msg)); + m_msg.sadb_msg_version = PF_KEY_V2; + m_msg.sadb_msg_type = type; + m_msg.sadb_msg_errno = 0; + m_msg.sadb_msg_satype = SADB_SATYPE_ESP; +#if 0 + m_msg.sadb_msg_reserved = 0; +#endif + m_msg.sadb_msg_seq = 0; + m_msg.sadb_msg_pid = getpid(); + + m_len = sizeof(struct sadb_msg); + memcpy(m_buf, &m_msg, m_len); + + switch (type) { + case SADB_GETSPI: + /*<base, address(SD), SPI range>*/ + key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "10.0.3.4"); + key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "127.0.0.1"); + key_setspirange(); + /*<base, SA(*), address(SD)>*/ + break; + + case SADB_ADD: + /* <base, SA, (lifetime(HSC),) address(SD), (address(P),) + key(AE), (identity(SD),) (sensitivity)> */ + key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); + case SADB_UPDATE: + key_setsadbsa(); + key_setsadblft(SADB_EXT_LIFETIME_HARD, 10); + key_setsadblft(SADB_EXT_LIFETIME_SOFT, 5); + key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); + key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); + /* XXX key_setsadbkey(SADB_EXT_KEY_AUTH, "abcde"); */ + key_setsadbkey(SADB_EXT_KEY_AUTH, "1234567812345678"); + key_setsadbkey(SADB_EXT_KEY_ENCRYPT, "12345678"); + key_setsadbid(SADB_EXT_IDENTITY_SRC, "hoge1234@hoge.com"); + key_setsadbid(SADB_EXT_IDENTITY_DST, "hage5678@hage.net"); + key_setsadbsens(); + /* <base, SA, (lifetime(HSC),) address(SD), (address(P),) + (identity(SD),) (sensitivity)> */ + break; + + case SADB_DELETE: + /* <base, SA(*), address(SDP)> */ + key_setsadbsa(); + key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); + key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); + key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); + /* <base, SA(*), address(SDP)> */ + break; + + case SADB_GET: + /* <base, SA(*), address(SDP)> */ + key_setsadbsa(); + key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); + key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); + key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); + /* <base, SA, (lifetime(HSC),) address(SD), (address(P),) + key(AE), (identity(SD),) (sensitivity)> */ + break; + + case SADB_ACQUIRE: + /* <base, address(SD), (address(P),) (identity(SD),) + (sensitivity,) proposal> */ + key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); + key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); + key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1"); + key_setsadbid(SADB_EXT_IDENTITY_SRC, "hoge1234@hoge.com"); + key_setsadbid(SADB_EXT_IDENTITY_DST, "hage5678@hage.net"); + key_setsadbsens(); + key_setsadbprop(); + /* <base, address(SD), (address(P),) (identity(SD),) + (sensitivity,) proposal> */ + break; + + case SADB_REGISTER: + /* <base> */ + /* <base, supported> */ + break; + + case SADB_EXPIRE: + case SADB_FLUSH: + break; + + case SADB_DUMP: + break; + + case SADB_X_PROMISC: + /* <base> */ + /* <base, base(, others)> */ + break; + + case SADB_X_PCHANGE: + break; + + /* for SPD management */ + case SADB_X_SPDFLUSH: + case SADB_X_SPDDUMP: + break; + + case SADB_X_SPDADD: +#if 0 + { + struct sadb_x_policy m_policy; + + m_policy.sadb_x_policy_len = PFKEY_UNIT64(sizeof(m_policy)); + m_policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY; + m_policy.sadb_x_policy_type = SADB_X_PL_IPSEC; + m_policy.sadb_x_policy_esp_trans = 1; + m_policy.sadb_x_policy_ah_trans = 2; + m_policy.sadb_x_policy_esp_network = 3; + m_policy.sadb_x_policy_ah_network = 4; + m_policy.sadb_x_policy_reserved = 0; + + memcpy(m_buf + m_len, &m_policy, sizeof(struct sadb_x_policy)); + m_len += sizeof(struct sadb_x_policy); + } +#endif + + case SADB_X_SPDDELETE: + key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1"); + key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4"); + break; + } + + ((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len); + + return; +} + +void +key_setsadbsens() +{ + struct sadb_sens m_sens; + u_char buf[64]; + u_int s, i, slen, ilen, len; + + /* make sens & integ */ + s = htonl(0x01234567); + i = htonl(0x89abcdef); + slen = sizeof(s); + ilen = sizeof(i); + memcpy(buf, &s, slen); + memcpy(buf + slen, &i, ilen); + + len = sizeof(m_sens) + PFKEY_ALIGN8(slen) + PFKEY_ALIGN8(ilen); + m_sens.sadb_sens_len = PFKEY_UNIT64(len); + m_sens.sadb_sens_exttype = SADB_EXT_SENSITIVITY; + m_sens.sadb_sens_dpd = 1; + m_sens.sadb_sens_sens_level = 2; + m_sens.sadb_sens_sens_len = PFKEY_ALIGN8(slen); + m_sens.sadb_sens_integ_level = 3; + m_sens.sadb_sens_integ_len = PFKEY_ALIGN8(ilen); + m_sens.sadb_sens_reserved = 0; + + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_sens, sizeof(struct sadb_sens), + buf, slen + ilen); + m_len += len; + + return; +} + +void +key_setsadbprop() +{ + struct sadb_prop m_prop; + struct sadb_comb *m_comb; + u_char buf[256]; +#if (defined(SADB_X_EALG_AESCBC) || defined(SADB_X_EALG_CAMELLIACBC)) && defined(SADB_X_AALG_SHA2_256) + u_int len = sizeof(m_prop) + sizeof(m_comb) * 3; +#else + u_int len = sizeof(m_prop) + sizeof(m_comb) * 2; +#endif + + /* make prop & comb */ + m_prop.sadb_prop_len = PFKEY_UNIT64(len); + m_prop.sadb_prop_exttype = SADB_EXT_PROPOSAL; + m_prop.sadb_prop_replay = 0; + m_prop.sadb_prop_reserved[0] = 0; + m_prop.sadb_prop_reserved[1] = 0; + m_prop.sadb_prop_reserved[2] = 0; + + /* the 1st is ESP DES-CBC HMAC-MD5 */ + m_comb = (struct sadb_comb *)buf; + m_comb->sadb_comb_auth = SADB_AALG_MD5HMAC; + m_comb->sadb_comb_encrypt = SADB_EALG_DESCBC; + m_comb->sadb_comb_flags = 0; + m_comb->sadb_comb_auth_minbits = 8; + m_comb->sadb_comb_auth_maxbits = 96; + m_comb->sadb_comb_encrypt_minbits = 64; + m_comb->sadb_comb_encrypt_maxbits = 64; + m_comb->sadb_comb_reserved = 0; + m_comb->sadb_comb_soft_allocations = 0; + m_comb->sadb_comb_hard_allocations = 0; + m_comb->sadb_comb_soft_bytes = 0; + m_comb->sadb_comb_hard_bytes = 0; + m_comb->sadb_comb_soft_addtime = 0; + m_comb->sadb_comb_hard_addtime = 0; + m_comb->sadb_comb_soft_usetime = 0; + m_comb->sadb_comb_hard_usetime = 0; + + /* the 2st is ESP 3DES-CBC and AH HMAC-SHA1 */ + m_comb = (struct sadb_comb *)(buf + sizeof(*m_comb)); + m_comb->sadb_comb_auth = SADB_AALG_SHA1HMAC; + m_comb->sadb_comb_encrypt = SADB_EALG_3DESCBC; + m_comb->sadb_comb_flags = 0; + m_comb->sadb_comb_auth_minbits = 8; + m_comb->sadb_comb_auth_maxbits = 96; + m_comb->sadb_comb_encrypt_minbits = 64; + m_comb->sadb_comb_encrypt_maxbits = 64; + m_comb->sadb_comb_reserved = 0; + m_comb->sadb_comb_soft_allocations = 0; + m_comb->sadb_comb_hard_allocations = 0; + m_comb->sadb_comb_soft_bytes = 0; + m_comb->sadb_comb_hard_bytes = 0; + m_comb->sadb_comb_soft_addtime = 0; + m_comb->sadb_comb_hard_addtime = 0; + m_comb->sadb_comb_soft_usetime = 0; + m_comb->sadb_comb_hard_usetime = 0; + + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_prop, sizeof(struct sadb_prop), + buf, sizeof(*m_comb) * 2); + m_len += len; + + #if defined(SADB_X_EALG_AESCBC) && defined(SADB_X_AALG_SHA2_256) + /* the 3rd is ESP AES-CBC and AH HMAC-SHA256 */ + m_comb = (struct sadb_comb *)(buf + sizeof(*m_comb)); + m_comb->sadb_comb_auth = SADB_X_AALG_SHA2_256; + m_comb->sadb_comb_encrypt = SADB_X_EALG_AESCBC; + m_comb->sadb_comb_flags = 0; + m_comb->sadb_comb_auth_minbits = 8; + m_comb->sadb_comb_auth_maxbits = 96; + m_comb->sadb_comb_encrypt_minbits = 128; + m_comb->sadb_comb_encrypt_maxbits = 128; + m_comb->sadb_comb_reserved = 0; + m_comb->sadb_comb_soft_allocations = 0; + m_comb->sadb_comb_hard_allocations = 0; + m_comb->sadb_comb_soft_bytes = 0; + m_comb->sadb_comb_hard_bytes = 0; + m_comb->sadb_comb_soft_addtime = 0; + m_comb->sadb_comb_hard_addtime = 0; + m_comb->sadb_comb_soft_usetime = 0; + m_comb->sadb_comb_hard_usetime = 0; + + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_prop, sizeof(struct sadb_prop), + buf, sizeof(*m_comb) * 3); + m_len += len; + #elif defined(SADB_X_EALG_CAMELLIACBC) && defined(SADB_X_AALG_SHA2_256) + /* the 3rd is ESP CAMELLIA-CBC and AH HMAC-SHA256 */ + m_comb = (struct sadb_comb *)(buf + sizeof(*m_comb)); + m_comb->sadb_comb_auth = SADB_X_AALG_SHA2_256; + m_comb->sadb_comb_encrypt = SADB_X_EALG_CAMELLIACBC; + m_comb->sadb_comb_flags = 0; + m_comb->sadb_comb_auth_minbits = 8; + m_comb->sadb_comb_auth_maxbits = 96; + m_comb->sadb_comb_encrypt_minbits = 128; + m_comb->sadb_comb_encrypt_maxbits = 128; + m_comb->sadb_comb_reserved = 0; + m_comb->sadb_comb_soft_allocations = 0; + m_comb->sadb_comb_hard_allocations = 0; + m_comb->sadb_comb_soft_bytes = 0; + m_comb->sadb_comb_hard_bytes = 0; + m_comb->sadb_comb_soft_addtime = 0; + m_comb->sadb_comb_hard_addtime = 0; + m_comb->sadb_comb_soft_usetime = 0; + m_comb->sadb_comb_hard_usetime = 0; + + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_prop, sizeof(struct sadb_prop), + buf, sizeof(*m_comb) * 3); + m_len += len; +#else + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_prop, sizeof(struct sadb_prop), + buf, sizeof(*m_comb) * 2); + m_len += len; +#endif + return; +} + +void +key_setsadbid(ext, str) + u_int ext; + caddr_t str; +{ + struct sadb_ident m_id; + u_int idlen = strlen(str), len; + + len = sizeof(m_id) + PFKEY_ALIGN8(idlen); + m_id.sadb_ident_len = PFKEY_UNIT64(len); + m_id.sadb_ident_exttype = ext; + m_id.sadb_ident_type = SADB_IDENTTYPE_USERFQDN; + m_id.sadb_ident_reserved = 0; + m_id.sadb_ident_id = getpid(); + + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_id, sizeof(struct sadb_ident), + str, idlen); + m_len += len; + + return; +} + +void +key_setsadblft(ext, time) + u_int ext, time; +{ + struct sadb_lifetime m_lft; + + m_lft.sadb_lifetime_len = PFKEY_UNIT64(sizeof(m_lft)); + m_lft.sadb_lifetime_exttype = ext; + m_lft.sadb_lifetime_allocations = 0x2; + m_lft.sadb_lifetime_bytes = 0x1000; + m_lft.sadb_lifetime_addtime = time; + m_lft.sadb_lifetime_usetime = 0x0020; + + memcpy(m_buf + m_len, &m_lft, sizeof(struct sadb_lifetime)); + m_len += sizeof(struct sadb_lifetime); + + return; +} + +void +key_setspirange() +{ + struct sadb_spirange m_spi; + + m_spi.sadb_spirange_len = PFKEY_UNIT64(sizeof(m_spi)); + m_spi.sadb_spirange_exttype = SADB_EXT_SPIRANGE; + m_spi.sadb_spirange_min = 0x00001000; + m_spi.sadb_spirange_max = 0x00002000; + m_spi.sadb_spirange_reserved = 0; + + memcpy(m_buf + m_len, &m_spi, sizeof(struct sadb_spirange)); + m_len += sizeof(struct sadb_spirange); + + return; +} + +void +key_setsadbkey(ext, str) + u_int ext; + caddr_t str; +{ + struct sadb_key m_key; + u_int keylen = strlen(str); + u_int len; + + len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen); + m_key.sadb_key_len = PFKEY_UNIT64(len); + m_key.sadb_key_exttype = ext; + m_key.sadb_key_bits = keylen * 8; + m_key.sadb_key_reserved = 0; + + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_key, sizeof(struct sadb_key), + str, keylen); + m_len += len; + + return; +} + +void +key_setsadbsa() +{ + struct sadb_sa m_sa; + + m_sa.sadb_sa_len = PFKEY_UNIT64(sizeof(struct sadb_sa)); + m_sa.sadb_sa_exttype = SADB_EXT_SA; + m_sa.sadb_sa_spi = htonl(0x12345678); + m_sa.sadb_sa_replay = 4; + m_sa.sadb_sa_state = 0; + m_sa.sadb_sa_auth = SADB_AALG_MD5HMAC; + m_sa.sadb_sa_encrypt = SADB_EALG_DESCBC; + m_sa.sadb_sa_flags = 0; + + memcpy(m_buf + m_len, &m_sa, sizeof(struct sadb_sa)); + m_len += sizeof(struct sadb_sa); + + return; +} + +void +key_setsadbaddr(ext, af, str) + u_int ext, af; + caddr_t str; +{ + struct sadb_address m_addr; + u_int len; + struct addrinfo hints, *res; + const char *serv; + int plen; + + switch (af) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + /* XXX bark */ + exit(1); + } + + /* make sockaddr buffer */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_NUMERICHOST; + serv = (ext == SADB_EXT_ADDRESS_PROXY ? "0" : "4660"); /*0x1234*/ + if (getaddrinfo(str, serv, &hints, &res) != 0 || res->ai_next) { + /* XXX bark */ + exit(1); + } + + len = sizeof(struct sadb_address) + PFKEY_ALIGN8(res->ai_addrlen); + m_addr.sadb_address_len = PFKEY_UNIT64(len); + m_addr.sadb_address_exttype = ext; + m_addr.sadb_address_proto = + (ext == SADB_EXT_ADDRESS_PROXY ? 0 : IPPROTO_TCP); + m_addr.sadb_address_prefixlen = plen; + m_addr.sadb_address_reserved = 0; + + key_setsadbextbuf(m_buf, m_len, + (caddr_t)&m_addr, sizeof(struct sadb_address), + (caddr_t)res->ai_addr, res->ai_addrlen); + m_len += len; + + freeaddrinfo(res); + + return; +} + +void +key_setsadbextbuf(dst, off, ebuf, elen, vbuf, vlen) + caddr_t dst, ebuf, vbuf; + int off, elen, vlen; +{ + memset(dst + off, 0, elen + vlen); + memcpy(dst + off, (caddr_t)ebuf, elen); + memcpy(dst + off + elen, vbuf, vlen); + + return; +} + |