| /* $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; |
| } |
| |