1/* $FreeBSD: head/lib/libipsec/pfkey.c 62583 2000-07-04 16:22:05Z itojun $ */ 2/* $KAME: pfkey.c,v 1.31 2000/06/10 14:17:43 sakane Exp $ */
| 1/* $FreeBSD: head/lib/libipsec/pfkey.c 78064 2001-06-11 12:39:29Z ume $ */ 2/* $KAME: pfkey.c,v 1.39 2001/03/05 18:22:17 thorpej Exp $ */
|
3 4/* 5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33#include <sys/types.h> 34#include <sys/param.h> 35#include <sys/socket.h> 36#include <net/pfkeyv2.h> 37#include <netkey/key_var.h> 38#include <netinet/in.h> 39#include <netinet6/ipsec.h> 40 41#include <stdlib.h> 42#include <unistd.h> 43#include <string.h> 44#include <errno.h>
| 3 4/* 5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33#include <sys/types.h> 34#include <sys/param.h> 35#include <sys/socket.h> 36#include <net/pfkeyv2.h> 37#include <netkey/key_var.h> 38#include <netinet/in.h> 39#include <netinet6/ipsec.h> 40 41#include <stdlib.h> 42#include <unistd.h> 43#include <string.h> 44#include <errno.h>
|
| 45#include <stdio.h>
|
45 46#include "ipsec_strerror.h" 47#include "libpfkey.h" 48 49#define CALLOC(size, cast) (cast)calloc(1, (size)) 50
| 46 47#include "ipsec_strerror.h" 48#include "libpfkey.h" 49 50#define CALLOC(size, cast) (cast)calloc(1, (size)) 51
|
| 52static int findsupportedmap __P((int)); 53static int setsupportedmap __P((struct sadb_supported *)); 54static struct sadb_alg *findsupportedalg __P((u_int, u_int));
|
51static int pfkey_send_x1 __P((int, u_int, u_int, u_int, struct sockaddr *, 52 struct sockaddr *, u_int32_t, u_int32_t, u_int, caddr_t, 53 u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int32_t, 54 u_int32_t, u_int32_t, u_int32_t)); 55static int pfkey_send_x2 __P((int, u_int, u_int, u_int, 56 struct sockaddr *, struct sockaddr *, u_int32_t)); 57static int pfkey_send_x3 __P((int, u_int, u_int)); 58static int pfkey_send_x4 __P((int, u_int, struct sockaddr *, u_int,
| 55static int pfkey_send_x1 __P((int, u_int, u_int, u_int, struct sockaddr *, 56 struct sockaddr *, u_int32_t, u_int32_t, u_int, caddr_t, 57 u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int32_t, 58 u_int32_t, u_int32_t, u_int32_t)); 59static int pfkey_send_x2 __P((int, u_int, u_int, u_int, 60 struct sockaddr *, struct sockaddr *, u_int32_t)); 61static int pfkey_send_x3 __P((int, u_int, u_int)); 62static int pfkey_send_x4 __P((int, u_int, struct sockaddr *, u_int,
|
59 struct sockaddr *, u_int, u_int, char *, int, u_int32_t));
| 63 struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t, 64 char *, int, u_int32_t));
|
60static int pfkey_send_x5 __P((int, u_int, u_int32_t)); 61
| 65static int pfkey_send_x5 __P((int, u_int, u_int32_t)); 66
|
62static caddr_t pfkey_setsadbmsg __P((caddr_t, u_int, u_int,
| 67static caddr_t pfkey_setsadbmsg __P((caddr_t, caddr_t, u_int, u_int,
|
63 u_int, u_int32_t, pid_t));
| 68 u_int, u_int32_t, pid_t));
|
64static caddr_t pfkey_setsadbsa __P((caddr_t, u_int32_t, u_int,
| 69static caddr_t pfkey_setsadbsa __P((caddr_t, caddr_t, u_int32_t, u_int,
|
65 u_int, u_int, u_int32_t));
| 70 u_int, u_int, u_int32_t));
|
66static caddr_t pfkey_setsadbaddr __P((caddr_t, u_int,
| 71static caddr_t pfkey_setsadbaddr __P((caddr_t, caddr_t, u_int,
|
67 struct sockaddr *, u_int, u_int));
| 72 struct sockaddr *, u_int, u_int));
|
68static caddr_t pfkey_setsadbkey __P((caddr_t, u_int, caddr_t, u_int)); 69static caddr_t pfkey_setsadblifetime __P((caddr_t, u_int, u_int32_t, u_int32_t, 70 u_int32_t, u_int32_t)); 71static caddr_t pfkey_setsadbxsa2 __P((caddr_t, u_int32_t, u_int32_t));
| 73static caddr_t pfkey_setsadbkey __P((caddr_t, caddr_t, u_int, caddr_t, u_int)); 74static caddr_t pfkey_setsadblifetime __P((caddr_t, caddr_t, u_int, u_int32_t, 75 u_int32_t, u_int32_t, u_int32_t)); 76static caddr_t pfkey_setsadbxsa2 __P((caddr_t, caddr_t, u_int32_t, u_int32_t));
|
72 73/*
| 77 78/*
|
| 79 * make and search supported algorithm structure. 80 */ 81static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL, }; 82 83static int supported_map[] = { 84 SADB_SATYPE_AH, 85 SADB_SATYPE_ESP, 86 SADB_X_SATYPE_IPCOMP, 87}; 88 89static int 90findsupportedmap(satype) 91 int satype; 92{ 93 int i; 94 95 for (i = 0; i < sizeof(supported_map)/sizeof(supported_map[0]); i++) 96 if (supported_map[i] == satype) 97 return i; 98 return -1; 99} 100 101static struct sadb_alg * 102findsupportedalg(satype, alg_id) 103 u_int satype, alg_id; 104{ 105 int algno; 106 int tlen; 107 caddr_t p; 108 109 /* validity check */ 110 algno = findsupportedmap(satype); 111 if (algno == -1) { 112 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 113 return NULL; 114 } 115 if (ipsec_supported[algno] == NULL) { 116 __ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST; 117 return NULL; 118 } 119 120 tlen = ipsec_supported[algno]->sadb_supported_len 121 - sizeof(struct sadb_supported); 122 p = (caddr_t)(ipsec_supported[algno] + 1); 123 while (tlen > 0) { 124 if (tlen < sizeof(struct sadb_alg)) { 125 /* invalid format */ 126 break; 127 } 128 if (((struct sadb_alg *)p)->sadb_alg_id == alg_id) 129 return (struct sadb_alg *)p; 130 131 tlen -= sizeof(struct sadb_alg); 132 p += sizeof(struct sadb_alg); 133 } 134 135 __ipsec_errcode = EIPSEC_NOT_SUPPORTED; 136 return NULL; 137} 138 139static int 140setsupportedmap(sup) 141 struct sadb_supported *sup; 142{ 143 struct sadb_supported **ipsup; 144 145 switch (sup->sadb_supported_exttype) { 146 case SADB_EXT_SUPPORTED_AUTH: 147 ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_AH)]; 148 break; 149 case SADB_EXT_SUPPORTED_ENCRYPT: 150 ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_ESP)]; 151 break; 152 default: 153 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 154 return -1; 155 } 156 157 if (*ipsup) 158 free(*ipsup); 159 160 *ipsup = malloc(sup->sadb_supported_len); 161 if (!*ipsup) { 162 __ipsec_set_strerror(strerror(errno)); 163 return -1; 164 } 165 memcpy(*ipsup, sup, sup->sadb_supported_len); 166 167 return 0; 168} 169 170/*
|
74 * check key length against algorithm specified.
| 171 * check key length against algorithm specified.
|
75 * supported is either SADB_EXT_SUPPORTED_ENCRYPT or SADB_EXT_SUPPORTED_AUTH. 76 * Refer to keyv2.h to get more info.
| 172 * This function is called with SADB_EXT_SUPPORTED_{AUTH,ENCRYPT} as the 173 * augument, and only calls to ipsec_check_keylen2();
|
77 * keylen is the unit of bit. 78 * OUT: 79 * -1: invalid. 80 * 0: valid. 81 */
| 174 * keylen is the unit of bit. 175 * OUT: 176 * -1: invalid. 177 * 0: valid. 178 */
|
82struct sadb_msg *ipsec_supported = NULL; 83
| |
84int 85ipsec_check_keylen(supported, alg_id, keylen) 86 u_int supported; 87 u_int alg_id; 88 u_int keylen; 89{
| 179int 180ipsec_check_keylen(supported, alg_id, keylen) 181 u_int supported; 182 u_int alg_id; 183 u_int keylen; 184{
|
90 u_int tlen; 91 caddr_t p; 92 struct sadb_supported *sup; 93 struct sadb_alg *alg;
| 185 int satype;
|
94 95 /* validity check */
| 186 187 /* validity check */
|
96 if (ipsec_supported == NULL) { 97 __ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST; 98 return -1; 99 }
| |
100 switch (supported) { 101 case SADB_EXT_SUPPORTED_AUTH:
| 188 switch (supported) { 189 case SADB_EXT_SUPPORTED_AUTH:
|
| 190 satype = SADB_SATYPE_AH; 191 break;
|
102 case SADB_EXT_SUPPORTED_ENCRYPT:
| 192 case SADB_EXT_SUPPORTED_ENCRYPT:
|
| 193 satype = SADB_SATYPE_ESP;
|
103 break; 104 default: 105 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 106 return -1; 107 } 108
| 194 break; 195 default: 196 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 197 return -1; 198 } 199
|
109 tlen = ipsec_supported->sadb_msg_len - sizeof(struct sadb_msg); 110 p = (caddr_t)ipsec_supported + sizeof(struct sadb_msg);
| 200 return ipsec_check_keylen2(satype, alg_id, keylen); 201}
|
111
| 202
|
112 for (; 113 tlen > 0; 114 tlen -= sup->sadb_supported_len, p += sup->sadb_supported_len) {
| 203/* 204 * check key length against algorithm specified. 205 * satype is one of satype defined at pfkeyv2.h. 206 * keylen is the unit of bit. 207 * OUT: 208 * -1: invalid. 209 * 0: valid. 210 */ 211int 212ipsec_check_keylen2(satype, alg_id, keylen) 213 u_int satype; 214 u_int alg_id; 215 u_int keylen; 216{ 217 struct sadb_alg *alg;
|
115
| 218
|
116 sup = (struct sadb_supported *)p;
| 219 alg = findsupportedalg(satype, alg_id); 220 if (!alg) 221 return -1;
|
117
| 222
|
118 if (sup->sadb_supported_exttype != supported) 119 continue;
| 223 if (keylen < alg->sadb_alg_minbits || keylen > alg->sadb_alg_maxbits) { 224 __ipsec_errcode = EIPSEC_INVAL_KEYLEN; 225 return -1; 226 }
|
120
| 227
|
121 { 122 u_int ttlen = sup->sadb_supported_len; 123 caddr_t pp = p + sizeof(*sup);
| 228 __ipsec_errcode = EIPSEC_NO_ERROR; 229 return 0; 230}
|
124
| 231
|
125 for (; 126 ttlen > 0; 127 ttlen -= sizeof(*alg), pp += sizeof(*alg)) { 128 alg = (struct sadb_alg *)pp;
| 232/* 233 * get max/min key length against algorithm specified. 234 * satype is one of satype defined at pfkeyv2.h. 235 * keylen is the unit of bit. 236 * OUT: 237 * -1: invalid. 238 * 0: valid. 239 */ 240int 241ipsec_get_keylen(supported, alg_id, alg0) 242 u_int supported, alg_id; 243 struct sadb_alg *alg0; 244{ 245 struct sadb_alg *alg; 246 u_int satype;
|
129
| 247
|
130 if (alg->sadb_alg_id == alg_id) 131 goto found; 132 } 133 }
| 248 /* validity check */ 249 if (!alg0) { 250 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 251 return -1;
|
134 } 135
| 252 } 253
|
136 __ipsec_errcode = EIPSEC_NOT_SUPPORTED; 137 return -1; 138 /* NOTREACHED */ 139 140 found: 141 if (keylen < alg->sadb_alg_minbits 142 || keylen > alg->sadb_alg_maxbits) { 143 __ipsec_errcode = EIPSEC_INVAL_KEYLEN;
| 254 switch (supported) { 255 case SADB_EXT_SUPPORTED_AUTH: 256 satype = SADB_SATYPE_AH; 257 break; 258 case SADB_EXT_SUPPORTED_ENCRYPT: 259 satype = SADB_SATYPE_ESP; 260 break; 261 default: 262 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
|
144 return -1; 145 } 146
| 263 return -1; 264 } 265
|
| 266 alg = findsupportedalg(satype, alg_id); 267 if (!alg) 268 return -1; 269 270 memcpy(alg0, alg, sizeof(*alg0)); 271
|
147 __ipsec_errcode = EIPSEC_NO_ERROR; 148 return 0; 149} 150 151/* 152 * set the rate for SOFT lifetime against HARD one. 153 * If rate is more than 100 or equal to zero, then set to 100. 154 */ 155static u_int soft_lifetime_allocations_rate = PFKEY_SOFT_LIFETIME_RATE; 156static u_int soft_lifetime_bytes_rate = PFKEY_SOFT_LIFETIME_RATE; 157static u_int soft_lifetime_addtime_rate = PFKEY_SOFT_LIFETIME_RATE; 158static u_int soft_lifetime_usetime_rate = PFKEY_SOFT_LIFETIME_RATE; 159 160u_int 161pfkey_set_softrate(type, rate) 162 u_int type, rate; 163{ 164 __ipsec_errcode = EIPSEC_NO_ERROR; 165 166 if (rate > 100 || rate == 0) 167 rate = 100; 168 169 switch (type) { 170 case SADB_X_LIFETIME_ALLOCATIONS: 171 soft_lifetime_allocations_rate = rate; 172 return 0; 173 case SADB_X_LIFETIME_BYTES: 174 soft_lifetime_bytes_rate = rate; 175 return 0; 176 case SADB_X_LIFETIME_ADDTIME: 177 soft_lifetime_addtime_rate = rate; 178 return 0; 179 case SADB_X_LIFETIME_USETIME: 180 soft_lifetime_usetime_rate = rate; 181 return 0; 182 } 183 184 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 185 return 1; 186} 187 188/* 189 * get current rate for SOFT lifetime against HARD one. 190 * ATTENTION: ~0 is returned if invalid type was passed. 191 */ 192u_int 193pfkey_get_softrate(type) 194 u_int type; 195{ 196 switch (type) { 197 case SADB_X_LIFETIME_ALLOCATIONS: 198 return soft_lifetime_allocations_rate; 199 case SADB_X_LIFETIME_BYTES: 200 return soft_lifetime_bytes_rate; 201 case SADB_X_LIFETIME_ADDTIME: 202 return soft_lifetime_addtime_rate; 203 case SADB_X_LIFETIME_USETIME: 204 return soft_lifetime_usetime_rate; 205 } 206 207 return ~0; 208} 209 210/* 211 * sending SADB_GETSPI message to the kernel. 212 * OUT: 213 * positive: success and return length sent. 214 * -1 : error occured, and set errno. 215 */ 216int 217pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) 218 int so; 219 u_int satype, mode; 220 struct sockaddr *src, *dst; 221 u_int32_t min, max, reqid, seq; 222{ 223 struct sadb_msg *newmsg;
| 272 __ipsec_errcode = EIPSEC_NO_ERROR; 273 return 0; 274} 275 276/* 277 * set the rate for SOFT lifetime against HARD one. 278 * If rate is more than 100 or equal to zero, then set to 100. 279 */ 280static u_int soft_lifetime_allocations_rate = PFKEY_SOFT_LIFETIME_RATE; 281static u_int soft_lifetime_bytes_rate = PFKEY_SOFT_LIFETIME_RATE; 282static u_int soft_lifetime_addtime_rate = PFKEY_SOFT_LIFETIME_RATE; 283static u_int soft_lifetime_usetime_rate = PFKEY_SOFT_LIFETIME_RATE; 284 285u_int 286pfkey_set_softrate(type, rate) 287 u_int type, rate; 288{ 289 __ipsec_errcode = EIPSEC_NO_ERROR; 290 291 if (rate > 100 || rate == 0) 292 rate = 100; 293 294 switch (type) { 295 case SADB_X_LIFETIME_ALLOCATIONS: 296 soft_lifetime_allocations_rate = rate; 297 return 0; 298 case SADB_X_LIFETIME_BYTES: 299 soft_lifetime_bytes_rate = rate; 300 return 0; 301 case SADB_X_LIFETIME_ADDTIME: 302 soft_lifetime_addtime_rate = rate; 303 return 0; 304 case SADB_X_LIFETIME_USETIME: 305 soft_lifetime_usetime_rate = rate; 306 return 0; 307 } 308 309 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 310 return 1; 311} 312 313/* 314 * get current rate for SOFT lifetime against HARD one. 315 * ATTENTION: ~0 is returned if invalid type was passed. 316 */ 317u_int 318pfkey_get_softrate(type) 319 u_int type; 320{ 321 switch (type) { 322 case SADB_X_LIFETIME_ALLOCATIONS: 323 return soft_lifetime_allocations_rate; 324 case SADB_X_LIFETIME_BYTES: 325 return soft_lifetime_bytes_rate; 326 case SADB_X_LIFETIME_ADDTIME: 327 return soft_lifetime_addtime_rate; 328 case SADB_X_LIFETIME_USETIME: 329 return soft_lifetime_usetime_rate; 330 } 331 332 return ~0; 333} 334 335/* 336 * sending SADB_GETSPI message to the kernel. 337 * OUT: 338 * positive: success and return length sent. 339 * -1 : error occured, and set errno. 340 */ 341int 342pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) 343 int so; 344 u_int satype, mode; 345 struct sockaddr *src, *dst; 346 u_int32_t min, max, reqid, seq; 347{ 348 struct sadb_msg *newmsg;
|
| 349 caddr_t ep;
|
224 int len; 225 int need_spirange = 0; 226 caddr_t p; 227 int plen; 228 229 /* validity check */ 230 if (src == NULL || dst == NULL) { 231 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 232 return -1; 233 } 234 if (src->sa_family != dst->sa_family) { 235 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 236 return -1; 237 } 238 if (min > max || (min > 0 && min <= 255)) { 239 __ipsec_errcode = EIPSEC_INVAL_SPI; 240 return -1; 241 } 242 switch (src->sa_family) { 243 case AF_INET: 244 plen = sizeof(struct in_addr) << 3; 245 break; 246 case AF_INET6: 247 plen = sizeof(struct in6_addr) << 3; 248 break; 249 default: 250 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 251 return -1; 252 } 253 254 /* create new sadb_msg to send. */ 255 len = sizeof(struct sadb_msg) 256 + sizeof(struct sadb_x_sa2) 257 + sizeof(struct sadb_address) 258 + PFKEY_ALIGN8(src->sa_len) 259 + sizeof(struct sadb_address) 260 + PFKEY_ALIGN8(dst->sa_len); 261 262 if (min > 255 && max < ~0) { 263 need_spirange++; 264 len += sizeof(struct sadb_spirange); 265 } 266 267 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 268 __ipsec_set_strerror(strerror(errno)); 269 return -1; 270 }
| 350 int len; 351 int need_spirange = 0; 352 caddr_t p; 353 int plen; 354 355 /* validity check */ 356 if (src == NULL || dst == NULL) { 357 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 358 return -1; 359 } 360 if (src->sa_family != dst->sa_family) { 361 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 362 return -1; 363 } 364 if (min > max || (min > 0 && min <= 255)) { 365 __ipsec_errcode = EIPSEC_INVAL_SPI; 366 return -1; 367 } 368 switch (src->sa_family) { 369 case AF_INET: 370 plen = sizeof(struct in_addr) << 3; 371 break; 372 case AF_INET6: 373 plen = sizeof(struct in6_addr) << 3; 374 break; 375 default: 376 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 377 return -1; 378 } 379 380 /* create new sadb_msg to send. */ 381 len = sizeof(struct sadb_msg) 382 + sizeof(struct sadb_x_sa2) 383 + sizeof(struct sadb_address) 384 + PFKEY_ALIGN8(src->sa_len) 385 + sizeof(struct sadb_address) 386 + PFKEY_ALIGN8(dst->sa_len); 387 388 if (min > 255 && max < ~0) { 389 need_spirange++; 390 len += sizeof(struct sadb_spirange); 391 } 392 393 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 394 __ipsec_set_strerror(strerror(errno)); 395 return -1; 396 }
|
| 397 ep = ((caddr_t)newmsg) + len;
|
271
| 398
|
272 p = pfkey_setsadbmsg((caddr_t)newmsg, SADB_GETSPI, 273 len, satype, seq, getpid());
| 399 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_GETSPI, 400 len, satype, seq, getpid()); 401 if (!p) { 402 free(newmsg); 403 return -1; 404 }
|
274
| 405
|
275 p = pfkey_setsadbxsa2(p, mode, reqid);
| 406 p = pfkey_setsadbxsa2(p, ep, mode, reqid); 407 if (!p) { 408 free(newmsg); 409 return -1; 410 }
|
276 277 /* set sadb_address for source */
| 411 412 /* set sadb_address for source */
|
278 p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen,
| 413 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
|
279 IPSEC_ULPROTO_ANY);
| 414 IPSEC_ULPROTO_ANY);
|
| 415 if (!p) { 416 free(newmsg); 417 return -1; 418 }
|
280 281 /* set sadb_address for destination */
| 419 420 /* set sadb_address for destination */
|
282 p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen,
| 421 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
|
283 IPSEC_ULPROTO_ANY);
| 422 IPSEC_ULPROTO_ANY);
|
| 423 if (!p) { 424 free(newmsg); 425 return -1; 426 }
|
284 285 /* proccessing spi range */ 286 if (need_spirange) {
| 427 428 /* proccessing spi range */ 429 if (need_spirange) {
|
287 int _len = sizeof(struct sadb_spirange);
| 430 struct sadb_spirange spirange;
|
288
| 431
|
289#define _SADB_SPIRANGE(p) ((struct sadb_spirange *)(p)) 290 _SADB_SPIRANGE(p)->sadb_spirange_len = PFKEY_UNIT64(_len); 291 _SADB_SPIRANGE(p)->sadb_spirange_exttype = SADB_EXT_SPIRANGE; 292 _SADB_SPIRANGE(p)->sadb_spirange_min = min; 293 _SADB_SPIRANGE(p)->sadb_spirange_max = max; 294#undef _SADB_SPIRANGE(p) 295 p += _len;
| 432 if (p + sizeof(spirange) > ep) { 433 free(newmsg); 434 return -1; 435 } 436 437 memset(&spirange, 0, sizeof(spirange)); 438 spirange.sadb_spirange_len = PFKEY_UNIT64(sizeof(spirange)); 439 spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE; 440 spirange.sadb_spirange_min = min; 441 spirange.sadb_spirange_max = max; 442 443 memcpy(p, &spirange, sizeof(spirange)); 444 445 p += sizeof(spirange);
|
296 }
| 446 }
|
| 447 if (p != ep) { 448 free(newmsg); 449 return -1; 450 }
|
297 298 /* send message */ 299 len = pfkey_send(so, newmsg, len); 300 free(newmsg); 301 302 if (len < 0) 303 return -1; 304 305 __ipsec_errcode = EIPSEC_NO_ERROR; 306 return len; 307} 308 309/* 310 * sending SADB_UPDATE message to the kernel. 311 * The length of key material is a_keylen + e_keylen. 312 * OUT: 313 * positive: success and return length sent. 314 * -1 : error occured, and set errno. 315 */ 316int 317pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize, 318 keymat, e_type, e_keylen, a_type, a_keylen, flags, 319 l_alloc, l_bytes, l_addtime, l_usetime, seq) 320 int so; 321 u_int satype, mode, wsize; 322 struct sockaddr *src, *dst; 323 u_int32_t spi, reqid; 324 caddr_t keymat; 325 u_int e_type, e_keylen, a_type, a_keylen, flags; 326 u_int32_t l_alloc; 327 u_int64_t l_bytes, l_addtime, l_usetime; 328 u_int32_t seq; 329{ 330 int len; 331 if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi, 332 reqid, wsize, 333 keymat, e_type, e_keylen, a_type, a_keylen, flags, 334 l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0) 335 return -1; 336 337 return len; 338} 339 340/* 341 * sending SADB_ADD message to the kernel. 342 * The length of key material is a_keylen + e_keylen. 343 * OUT: 344 * positive: success and return length sent. 345 * -1 : error occured, and set errno. 346 */ 347int 348pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize, 349 keymat, e_type, e_keylen, a_type, a_keylen, flags, 350 l_alloc, l_bytes, l_addtime, l_usetime, seq) 351 int so; 352 u_int satype, mode, wsize; 353 struct sockaddr *src, *dst; 354 u_int32_t spi, reqid; 355 caddr_t keymat; 356 u_int e_type, e_keylen, a_type, a_keylen, flags; 357 u_int32_t l_alloc; 358 u_int64_t l_bytes, l_addtime, l_usetime; 359 u_int32_t seq; 360{ 361 int len; 362 if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi, 363 reqid, wsize, 364 keymat, e_type, e_keylen, a_type, a_keylen, flags, 365 l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0) 366 return -1; 367 368 return len; 369} 370 371/* 372 * sending SADB_DELETE message to the kernel. 373 * OUT: 374 * positive: success and return length sent. 375 * -1 : error occured, and set errno. 376 */ 377int 378pfkey_send_delete(so, satype, mode, src, dst, spi) 379 int so; 380 u_int satype, mode; 381 struct sockaddr *src, *dst; 382 u_int32_t spi; 383{ 384 int len; 385 if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0) 386 return -1; 387 388 return len; 389} 390 391/*
| 451 452 /* send message */ 453 len = pfkey_send(so, newmsg, len); 454 free(newmsg); 455 456 if (len < 0) 457 return -1; 458 459 __ipsec_errcode = EIPSEC_NO_ERROR; 460 return len; 461} 462 463/* 464 * sending SADB_UPDATE message to the kernel. 465 * The length of key material is a_keylen + e_keylen. 466 * OUT: 467 * positive: success and return length sent. 468 * -1 : error occured, and set errno. 469 */ 470int 471pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize, 472 keymat, e_type, e_keylen, a_type, a_keylen, flags, 473 l_alloc, l_bytes, l_addtime, l_usetime, seq) 474 int so; 475 u_int satype, mode, wsize; 476 struct sockaddr *src, *dst; 477 u_int32_t spi, reqid; 478 caddr_t keymat; 479 u_int e_type, e_keylen, a_type, a_keylen, flags; 480 u_int32_t l_alloc; 481 u_int64_t l_bytes, l_addtime, l_usetime; 482 u_int32_t seq; 483{ 484 int len; 485 if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi, 486 reqid, wsize, 487 keymat, e_type, e_keylen, a_type, a_keylen, flags, 488 l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0) 489 return -1; 490 491 return len; 492} 493 494/* 495 * sending SADB_ADD message to the kernel. 496 * The length of key material is a_keylen + e_keylen. 497 * OUT: 498 * positive: success and return length sent. 499 * -1 : error occured, and set errno. 500 */ 501int 502pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize, 503 keymat, e_type, e_keylen, a_type, a_keylen, flags, 504 l_alloc, l_bytes, l_addtime, l_usetime, seq) 505 int so; 506 u_int satype, mode, wsize; 507 struct sockaddr *src, *dst; 508 u_int32_t spi, reqid; 509 caddr_t keymat; 510 u_int e_type, e_keylen, a_type, a_keylen, flags; 511 u_int32_t l_alloc; 512 u_int64_t l_bytes, l_addtime, l_usetime; 513 u_int32_t seq; 514{ 515 int len; 516 if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi, 517 reqid, wsize, 518 keymat, e_type, e_keylen, a_type, a_keylen, flags, 519 l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0) 520 return -1; 521 522 return len; 523} 524 525/* 526 * sending SADB_DELETE message to the kernel. 527 * OUT: 528 * positive: success and return length sent. 529 * -1 : error occured, and set errno. 530 */ 531int 532pfkey_send_delete(so, satype, mode, src, dst, spi) 533 int so; 534 u_int satype, mode; 535 struct sockaddr *src, *dst; 536 u_int32_t spi; 537{ 538 int len; 539 if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0) 540 return -1; 541 542 return len; 543} 544 545/*
|
| 546 * sending SADB_DELETE without spi to the kernel. This is 547 * the "delete all" request (an extension also present in 548 * Solaris). 549 * 550 * OUT: 551 * positive: success and return length sent 552 * -1 : error occured, and set errno 553 */ 554int 555pfkey_send_delete_all(so, satype, mode, src, dst) 556 int so; 557 u_int satype, mode; 558 struct sockaddr *src, *dst; 559{ 560 struct sadb_msg *newmsg; 561 int len; 562 caddr_t p; 563 int plen; 564 caddr_t ep; 565 566 /* validity check */ 567 if (src == NULL || dst == NULL) { 568 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 569 return -1; 570 } 571 if (src->sa_family != dst->sa_family) { 572 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 573 return -1; 574 } 575 switch (src->sa_family) { 576 case AF_INET: 577 plen = sizeof(struct in_addr) << 3; 578 break; 579 case AF_INET6: 580 plen = sizeof(struct in6_addr) << 3; 581 break; 582 default: 583 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 584 return -1; 585 } 586 587 /* create new sadb_msg to reply. */ 588 len = sizeof(struct sadb_msg) 589 + sizeof(struct sadb_address) 590 + PFKEY_ALIGN8(src->sa_len) 591 + sizeof(struct sadb_address) 592 + PFKEY_ALIGN8(dst->sa_len); 593 594 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 595 __ipsec_set_strerror(strerror(errno)); 596 return -1; 597 } 598 ep = ((caddr_t)newmsg) + len; 599 600 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_DELETE, len, satype, 0, 601 getpid()); 602 if (!p) { 603 free(newmsg); 604 return -1; 605 } 606 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen, 607 IPSEC_ULPROTO_ANY); 608 if (!p) { 609 free(newmsg); 610 return -1; 611 } 612 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen, 613 IPSEC_ULPROTO_ANY); 614 if (!p || p != ep) { 615 free(newmsg); 616 return -1; 617 } 618 619 /* send message */ 620 len = pfkey_send(so, newmsg, len); 621 free(newmsg); 622 623 if (len < 0) 624 return -1; 625 626 __ipsec_errcode = EIPSEC_NO_ERROR; 627 return len; 628} 629 630/*
|
392 * sending SADB_GET message to the kernel. 393 * OUT: 394 * positive: success and return length sent. 395 * -1 : error occured, and set errno. 396 */ 397int 398pfkey_send_get(so, satype, mode, src, dst, spi) 399 int so; 400 u_int satype, mode; 401 struct sockaddr *src, *dst; 402 u_int32_t spi; 403{ 404 int len; 405 if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0) 406 return -1; 407 408 return len; 409} 410 411/* 412 * sending SADB_REGISTER message to the kernel. 413 * OUT: 414 * positive: success and return length sent. 415 * -1 : error occured, and set errno. 416 */ 417int 418pfkey_send_register(so, satype) 419 int so; 420 u_int satype; 421{
| 631 * sending SADB_GET message to the kernel. 632 * OUT: 633 * positive: success and return length sent. 634 * -1 : error occured, and set errno. 635 */ 636int 637pfkey_send_get(so, satype, mode, src, dst, spi) 638 int so; 639 u_int satype, mode; 640 struct sockaddr *src, *dst; 641 u_int32_t spi; 642{ 643 int len; 644 if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0) 645 return -1; 646 647 return len; 648} 649 650/* 651 * sending SADB_REGISTER message to the kernel. 652 * OUT: 653 * positive: success and return length sent. 654 * -1 : error occured, and set errno. 655 */ 656int 657pfkey_send_register(so, satype) 658 int so; 659 u_int satype; 660{
|
422 int len;
| 661 int len, algno;
|
423
| 662
|
| 663 if (satype == PF_UNSPEC) { 664 for (algno = 0; 665 algno < sizeof(supported_map)/sizeof(supported_map[0]); 666 algno++) { 667 if (ipsec_supported[algno]) { 668 free(ipsec_supported[algno]); 669 ipsec_supported[algno] = NULL; 670 } 671 } 672 } else { 673 algno = findsupportedmap(satype); 674 if (algno == -1) { 675 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 676 return -1; 677 } 678 679 if (ipsec_supported[algno]) { 680 free(ipsec_supported[algno]); 681 ipsec_supported[algno] = NULL; 682 } 683 } 684
|
424 if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0) 425 return -1; 426 427 return len; 428} 429 430/* 431 * receiving SADB_REGISTER message from the kernel, and copy buffer for 432 * sadb_supported returned into ipsec_supported. 433 * OUT: 434 * 0: success and return length sent. 435 * -1: error occured, and set errno. 436 */ 437int 438pfkey_recv_register(so) 439 int so; 440{ 441 pid_t pid = getpid(); 442 struct sadb_msg *newmsg;
| 685 if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0) 686 return -1; 687 688 return len; 689} 690 691/* 692 * receiving SADB_REGISTER message from the kernel, and copy buffer for 693 * sadb_supported returned into ipsec_supported. 694 * OUT: 695 * 0: success and return length sent. 696 * -1: error occured, and set errno. 697 */ 698int 699pfkey_recv_register(so) 700 int so; 701{ 702 pid_t pid = getpid(); 703 struct sadb_msg *newmsg;
|
443 struct sadb_supported *sup; 444 caddr_t p; 445 int tlen;
| 704 int error = -1;
|
446 447 /* receive message */ 448 do { 449 if ((newmsg = pfkey_recv(so)) == NULL) 450 return -1;
| 705 706 /* receive message */ 707 do { 708 if ((newmsg = pfkey_recv(so)) == NULL) 709 return -1;
|
451
| |
452 } while (newmsg->sadb_msg_type != SADB_REGISTER 453 || newmsg->sadb_msg_pid != pid); 454 455 /* check and fix */ 456 newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len); 457
| 710 } while (newmsg->sadb_msg_type != SADB_REGISTER 711 || newmsg->sadb_msg_pid != pid); 712 713 /* check and fix */ 714 newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len); 715
|
458 tlen = newmsg->sadb_msg_len - sizeof(struct sadb_msg); 459 p = (caddr_t)newmsg + sizeof(struct sadb_msg); 460 while (tlen > 0) {
| 716 error = pfkey_set_supported(newmsg, newmsg->sadb_msg_len); 717 free(newmsg); 718 719 if (error == 0) 720 __ipsec_errcode = EIPSEC_NO_ERROR; 721 722 return error; 723} 724 725/* 726 * receiving SADB_REGISTER message from the kernel, and copy buffer for 727 * sadb_supported returned into ipsec_supported. 728 * NOTE: sadb_msg_len must be host order. 729 * IN: 730 * tlen: msg length, it's to makeing sure. 731 * OUT: 732 * 0: success and return length sent. 733 * -1: error occured, and set errno. 734 */ 735int 736pfkey_set_supported(msg, tlen) 737 struct sadb_msg *msg; 738 int tlen; 739{ 740 struct sadb_supported *sup; 741 caddr_t p; 742 caddr_t ep; 743 744 /* validity */ 745 if (msg->sadb_msg_len != tlen) { 746 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 747 return -1; 748 } 749 750 p = (caddr_t)msg; 751 ep = p + tlen; 752 753 p += sizeof(struct sadb_msg); 754 755 while (p < ep) {
|
461 sup = (struct sadb_supported *)p;
| 756 sup = (struct sadb_supported *)p;
|
| 757 if (ep < p + sizeof(*sup) || 758 PFKEY_EXTLEN(sup) < sizeof(*sup) || 759 ep < p + sup->sadb_supported_len) { 760 /* invalid format */ 761 break; 762 } 763
|
462 switch (sup->sadb_supported_exttype) { 463 case SADB_EXT_SUPPORTED_AUTH: 464 case SADB_EXT_SUPPORTED_ENCRYPT:
| 764 switch (sup->sadb_supported_exttype) { 765 case SADB_EXT_SUPPORTED_AUTH: 766 case SADB_EXT_SUPPORTED_ENCRYPT:
|
465 sup->sadb_supported_len = PFKEY_EXTLEN(sup);
| |
466 break; 467 default: 468 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
| 767 break; 768 default: 769 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
|
469 free(newmsg);
| |
470 return -1; 471 } 472
| 770 return -1; 771 } 772
|
473 tlen -= sup->sadb_supported_len;
| 773 /* fixed length */ 774 sup->sadb_supported_len = PFKEY_EXTLEN(sup); 775 776 /* set supported map */ 777 if (setsupportedmap(sup) != 0) 778 return -1; 779
|
474 p += sup->sadb_supported_len; 475 } 476
| 780 p += sup->sadb_supported_len; 781 } 782
|
477 if (tlen < 0) {
| 783 if (p != ep) {
|
478 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 479 return -1; 480 } 481
| 784 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 785 return -1; 786 } 787
|
482 if (ipsec_supported != NULL) 483 free(ipsec_supported); 484 485 ipsec_supported = newmsg; 486
| |
487 __ipsec_errcode = EIPSEC_NO_ERROR;
| 788 __ipsec_errcode = EIPSEC_NO_ERROR;
|
| 789
|
488 return 0; 489} 490 491/* 492 * sending SADB_FLUSH message to the kernel. 493 * OUT: 494 * positive: success and return length sent. 495 * -1 : error occured, and set errno. 496 */ 497int 498pfkey_send_flush(so, satype) 499 int so; 500 u_int satype; 501{ 502 int len; 503 504 if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0) 505 return -1; 506 507 return len; 508} 509 510/* 511 * sending SADB_DUMP message to the kernel. 512 * OUT: 513 * positive: success and return length sent. 514 * -1 : error occured, and set errno. 515 */ 516int 517pfkey_send_dump(so, satype) 518 int so; 519 u_int satype; 520{ 521 int len; 522 523 if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0) 524 return -1; 525 526 return len; 527} 528 529/* 530 * sending SADB_X_PROMISC message to the kernel. 531 * NOTE that this function handles promisc mode toggle only. 532 * IN: 533 * flag: set promisc off if zero, set promisc on if non-zero. 534 * OUT: 535 * positive: success and return length sent. 536 * -1 : error occured, and set errno. 537 * 0 : error occured, and set errno. 538 * others: a pointer to new allocated buffer in which supported 539 * algorithms is. 540 */ 541int 542pfkey_send_promisc_toggle(so, flag) 543 int so; 544 int flag; 545{ 546 int len; 547 548 if ((len = pfkey_send_x3(so, SADB_X_PROMISC, (flag ? 1 : 0))) < 0) 549 return -1; 550 551 return len; 552} 553 554/* 555 * sending SADB_X_SPDADD message to the kernel. 556 * OUT: 557 * positive: success and return length sent. 558 * -1 : error occured, and set errno. 559 */ 560int 561pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 562 int so; 563 struct sockaddr *src, *dst; 564 u_int prefs, prefd, proto; 565 caddr_t policy; 566 int policylen; 567 u_int32_t seq; 568{ 569 int len; 570 571 if ((len = pfkey_send_x4(so, SADB_X_SPDADD, 572 src, prefs, dst, prefd, proto,
| 790 return 0; 791} 792 793/* 794 * sending SADB_FLUSH message to the kernel. 795 * OUT: 796 * positive: success and return length sent. 797 * -1 : error occured, and set errno. 798 */ 799int 800pfkey_send_flush(so, satype) 801 int so; 802 u_int satype; 803{ 804 int len; 805 806 if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0) 807 return -1; 808 809 return len; 810} 811 812/* 813 * sending SADB_DUMP message to the kernel. 814 * OUT: 815 * positive: success and return length sent. 816 * -1 : error occured, and set errno. 817 */ 818int 819pfkey_send_dump(so, satype) 820 int so; 821 u_int satype; 822{ 823 int len; 824 825 if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0) 826 return -1; 827 828 return len; 829} 830 831/* 832 * sending SADB_X_PROMISC message to the kernel. 833 * NOTE that this function handles promisc mode toggle only. 834 * IN: 835 * flag: set promisc off if zero, set promisc on if non-zero. 836 * OUT: 837 * positive: success and return length sent. 838 * -1 : error occured, and set errno. 839 * 0 : error occured, and set errno. 840 * others: a pointer to new allocated buffer in which supported 841 * algorithms is. 842 */ 843int 844pfkey_send_promisc_toggle(so, flag) 845 int so; 846 int flag; 847{ 848 int len; 849 850 if ((len = pfkey_send_x3(so, SADB_X_PROMISC, (flag ? 1 : 0))) < 0) 851 return -1; 852 853 return len; 854} 855 856/* 857 * sending SADB_X_SPDADD message to the kernel. 858 * OUT: 859 * positive: success and return length sent. 860 * -1 : error occured, and set errno. 861 */ 862int 863pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 864 int so; 865 struct sockaddr *src, *dst; 866 u_int prefs, prefd, proto; 867 caddr_t policy; 868 int policylen; 869 u_int32_t seq; 870{ 871 int len; 872 873 if ((len = pfkey_send_x4(so, SADB_X_SPDADD, 874 src, prefs, dst, prefd, proto,
|
| 875 0, 0,
|
573 policy, policylen, seq)) < 0) 574 return -1; 575 576 return len; 577} 578 579/*
| 876 policy, policylen, seq)) < 0) 877 return -1; 878 879 return len; 880} 881 882/*
|
| 883 * sending SADB_X_SPDADD message to the kernel. 884 * OUT: 885 * positive: success and return length sent. 886 * -1 : error occured, and set errno. 887 */ 888int 889pfkey_send_spdadd2(so, src, prefs, dst, prefd, proto, ltime, vtime, 890 policy, policylen, seq) 891 int so; 892 struct sockaddr *src, *dst; 893 u_int prefs, prefd, proto; 894 u_int64_t ltime, vtime; 895 caddr_t policy; 896 int policylen; 897 u_int32_t seq; 898{ 899 int len; 900 901 if ((len = pfkey_send_x4(so, SADB_X_SPDADD, 902 src, prefs, dst, prefd, proto, 903 ltime, vtime, 904 policy, policylen, seq)) < 0) 905 return -1; 906 907 return len; 908} 909 910/*
|
580 * sending SADB_X_SPDUPDATE message to the kernel. 581 * OUT: 582 * positive: success and return length sent. 583 * -1 : error occured, and set errno. 584 */ 585int 586pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 587 int so; 588 struct sockaddr *src, *dst; 589 u_int prefs, prefd, proto; 590 caddr_t policy; 591 int policylen; 592 u_int32_t seq; 593{ 594 int len; 595 596 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, 597 src, prefs, dst, prefd, proto,
| 911 * sending SADB_X_SPDUPDATE message to the kernel. 912 * OUT: 913 * positive: success and return length sent. 914 * -1 : error occured, and set errno. 915 */ 916int 917pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 918 int so; 919 struct sockaddr *src, *dst; 920 u_int prefs, prefd, proto; 921 caddr_t policy; 922 int policylen; 923 u_int32_t seq; 924{ 925 int len; 926 927 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, 928 src, prefs, dst, prefd, proto,
|
| 929 0, 0,
|
598 policy, policylen, seq)) < 0) 599 return -1; 600 601 return len; 602} 603 604/*
| 930 policy, policylen, seq)) < 0) 931 return -1; 932 933 return len; 934} 935 936/*
|
| 937 * sending SADB_X_SPDUPDATE message to the kernel. 938 * OUT: 939 * positive: success and return length sent. 940 * -1 : error occured, and set errno. 941 */ 942int 943pfkey_send_spdupdate2(so, src, prefs, dst, prefd, proto, ltime, vtime, 944 policy, policylen, seq) 945 int so; 946 struct sockaddr *src, *dst; 947 u_int prefs, prefd, proto; 948 u_int64_t ltime, vtime; 949 caddr_t policy; 950 int policylen; 951 u_int32_t seq; 952{ 953 int len; 954 955 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, 956 src, prefs, dst, prefd, proto, 957 ltime, vtime, 958 policy, policylen, seq)) < 0) 959 return -1; 960 961 return len; 962} 963 964/*
|
605 * sending SADB_X_SPDDELETE message to the kernel. 606 * OUT: 607 * positive: success and return length sent. 608 * -1 : error occured, and set errno. 609 */ 610int 611pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 612 int so; 613 struct sockaddr *src, *dst; 614 u_int prefs, prefd, proto; 615 caddr_t policy; 616 int policylen; 617 u_int32_t seq; 618{ 619 int len; 620 621 if (policylen != sizeof(struct sadb_x_policy)) { 622 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 623 return -1; 624 } 625 626 if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE, 627 src, prefs, dst, prefd, proto,
| 965 * sending SADB_X_SPDDELETE message to the kernel. 966 * OUT: 967 * positive: success and return length sent. 968 * -1 : error occured, and set errno. 969 */ 970int 971pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 972 int so; 973 struct sockaddr *src, *dst; 974 u_int prefs, prefd, proto; 975 caddr_t policy; 976 int policylen; 977 u_int32_t seq; 978{ 979 int len; 980 981 if (policylen != sizeof(struct sadb_x_policy)) { 982 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 983 return -1; 984 } 985 986 if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE, 987 src, prefs, dst, prefd, proto,
|
| 988 0, 0,
|
628 policy, policylen, seq)) < 0) 629 return -1; 630 631 return len; 632} 633 634/* 635 * sending SADB_X_SPDDELETE message to the kernel. 636 * OUT: 637 * positive: success and return length sent. 638 * -1 : error occured, and set errno. 639 */ 640int 641pfkey_send_spddelete2(so, spid) 642 int so; 643 u_int32_t spid; 644{ 645 int len; 646 647 if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0) 648 return -1; 649 650 return len; 651} 652 653/* 654 * sending SADB_X_SPDGET message to the kernel. 655 * OUT: 656 * positive: success and return length sent. 657 * -1 : error occured, and set errno. 658 */ 659int 660pfkey_send_spdget(so, spid) 661 int so; 662 u_int32_t spid; 663{ 664 int len; 665 666 if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0) 667 return -1; 668 669 return len; 670} 671 672/* 673 * sending SADB_X_SPDSETIDX message to the kernel. 674 * OUT: 675 * positive: success and return length sent. 676 * -1 : error occured, and set errno. 677 */ 678int 679pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 680 int so; 681 struct sockaddr *src, *dst; 682 u_int prefs, prefd, proto; 683 caddr_t policy; 684 int policylen; 685 u_int32_t seq; 686{ 687 int len; 688 689 if (policylen != sizeof(struct sadb_x_policy)) { 690 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 691 return -1; 692 } 693 694 if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX, 695 src, prefs, dst, prefd, proto,
| 989 policy, policylen, seq)) < 0) 990 return -1; 991 992 return len; 993} 994 995/* 996 * sending SADB_X_SPDDELETE message to the kernel. 997 * OUT: 998 * positive: success and return length sent. 999 * -1 : error occured, and set errno. 1000 */ 1001int 1002pfkey_send_spddelete2(so, spid) 1003 int so; 1004 u_int32_t spid; 1005{ 1006 int len; 1007 1008 if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0) 1009 return -1; 1010 1011 return len; 1012} 1013 1014/* 1015 * sending SADB_X_SPDGET message to the kernel. 1016 * OUT: 1017 * positive: success and return length sent. 1018 * -1 : error occured, and set errno. 1019 */ 1020int 1021pfkey_send_spdget(so, spid) 1022 int so; 1023 u_int32_t spid; 1024{ 1025 int len; 1026 1027 if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0) 1028 return -1; 1029 1030 return len; 1031} 1032 1033/* 1034 * sending SADB_X_SPDSETIDX message to the kernel. 1035 * OUT: 1036 * positive: success and return length sent. 1037 * -1 : error occured, and set errno. 1038 */ 1039int 1040pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 1041 int so; 1042 struct sockaddr *src, *dst; 1043 u_int prefs, prefd, proto; 1044 caddr_t policy; 1045 int policylen; 1046 u_int32_t seq; 1047{ 1048 int len; 1049 1050 if (policylen != sizeof(struct sadb_x_policy)) { 1051 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1052 return -1; 1053 } 1054 1055 if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX, 1056 src, prefs, dst, prefd, proto,
|
| 1057 0, 0,
|
696 policy, policylen, seq)) < 0) 697 return -1; 698 699 return len; 700} 701 702/* 703 * sending SADB_SPDFLUSH message to the kernel. 704 * OUT: 705 * positive: success and return length sent. 706 * -1 : error occured, and set errno. 707 */ 708int 709pfkey_send_spdflush(so) 710 int so; 711{ 712 int len; 713 714 if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0) 715 return -1; 716 717 return len; 718} 719 720/* 721 * sending SADB_SPDDUMP message to the kernel. 722 * OUT: 723 * positive: success and return length sent. 724 * -1 : error occured, and set errno. 725 */ 726int 727pfkey_send_spddump(so) 728 int so; 729{ 730 int len; 731 732 if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0) 733 return -1; 734 735 return len; 736} 737 738/* sending SADB_ADD or SADB_UPDATE message to the kernel */ 739static int 740pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, 741 keymat, e_type, e_keylen, a_type, a_keylen, flags, 742 l_alloc, l_bytes, l_addtime, l_usetime, seq) 743 int so; 744 u_int type, satype, mode; 745 struct sockaddr *src, *dst; 746 u_int32_t spi, reqid; 747 u_int wsize; 748 caddr_t keymat; 749 u_int e_type, e_keylen, a_type, a_keylen, flags; 750 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime, seq; 751{ 752 struct sadb_msg *newmsg; 753 int len; 754 caddr_t p; 755 int plen;
| 1058 policy, policylen, seq)) < 0) 1059 return -1; 1060 1061 return len; 1062} 1063 1064/* 1065 * sending SADB_SPDFLUSH message to the kernel. 1066 * OUT: 1067 * positive: success and return length sent. 1068 * -1 : error occured, and set errno. 1069 */ 1070int 1071pfkey_send_spdflush(so) 1072 int so; 1073{ 1074 int len; 1075 1076 if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0) 1077 return -1; 1078 1079 return len; 1080} 1081 1082/* 1083 * sending SADB_SPDDUMP message to the kernel. 1084 * OUT: 1085 * positive: success and return length sent. 1086 * -1 : error occured, and set errno. 1087 */ 1088int 1089pfkey_send_spddump(so) 1090 int so; 1091{ 1092 int len; 1093 1094 if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0) 1095 return -1; 1096 1097 return len; 1098} 1099 1100/* sending SADB_ADD or SADB_UPDATE message to the kernel */ 1101static int 1102pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, 1103 keymat, e_type, e_keylen, a_type, a_keylen, flags, 1104 l_alloc, l_bytes, l_addtime, l_usetime, seq) 1105 int so; 1106 u_int type, satype, mode; 1107 struct sockaddr *src, *dst; 1108 u_int32_t spi, reqid; 1109 u_int wsize; 1110 caddr_t keymat; 1111 u_int e_type, e_keylen, a_type, a_keylen, flags; 1112 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime, seq; 1113{ 1114 struct sadb_msg *newmsg; 1115 int len; 1116 caddr_t p; 1117 int plen;
|
| 1118 caddr_t ep;
|
756 757 /* validity check */ 758 if (src == NULL || dst == NULL) { 759 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 760 return -1; 761 } 762 if (src->sa_family != dst->sa_family) { 763 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 764 return -1; 765 } 766 switch (src->sa_family) { 767 case AF_INET: 768 plen = sizeof(struct in_addr) << 3; 769 break; 770 case AF_INET6: 771 plen = sizeof(struct in6_addr) << 3; 772 break; 773 default: 774 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 775 return -1; 776 } 777 778 switch (satype) { 779 case SADB_SATYPE_ESP: 780 if (e_type == SADB_EALG_NONE) { 781 __ipsec_errcode = EIPSEC_NO_ALGS; 782 return -1; 783 } 784 break; 785 case SADB_SATYPE_AH: 786 if (e_type != SADB_EALG_NONE) { 787 __ipsec_errcode = EIPSEC_INVAL_ALGS; 788 return -1; 789 } 790 if (a_type == SADB_AALG_NONE) { 791 __ipsec_errcode = EIPSEC_NO_ALGS; 792 return -1; 793 } 794 break; 795 case SADB_X_SATYPE_IPCOMP:
| 1119 1120 /* validity check */ 1121 if (src == NULL || dst == NULL) { 1122 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1123 return -1; 1124 } 1125 if (src->sa_family != dst->sa_family) { 1126 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1127 return -1; 1128 } 1129 switch (src->sa_family) { 1130 case AF_INET: 1131 plen = sizeof(struct in_addr) << 3; 1132 break; 1133 case AF_INET6: 1134 plen = sizeof(struct in6_addr) << 3; 1135 break; 1136 default: 1137 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1138 return -1; 1139 } 1140 1141 switch (satype) { 1142 case SADB_SATYPE_ESP: 1143 if (e_type == SADB_EALG_NONE) { 1144 __ipsec_errcode = EIPSEC_NO_ALGS; 1145 return -1; 1146 } 1147 break; 1148 case SADB_SATYPE_AH: 1149 if (e_type != SADB_EALG_NONE) { 1150 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1151 return -1; 1152 } 1153 if (a_type == SADB_AALG_NONE) { 1154 __ipsec_errcode = EIPSEC_NO_ALGS; 1155 return -1; 1156 } 1157 break; 1158 case SADB_X_SATYPE_IPCOMP:
|
| 1159 if (e_type == SADB_X_CALG_NONE) { 1160 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1161 return -1; 1162 } 1163 if (a_type != SADB_AALG_NONE) { 1164 __ipsec_errcode = EIPSEC_NO_ALGS; 1165 return -1; 1166 }
|
796 break; 797 default: 798 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 799 return -1; 800 } 801 802 /* create new sadb_msg to reply. */ 803 len = sizeof(struct sadb_msg) 804 + sizeof(struct sadb_sa) 805 + sizeof(struct sadb_x_sa2) 806 + sizeof(struct sadb_address) 807 + PFKEY_ALIGN8(src->sa_len) 808 + sizeof(struct sadb_address) 809 + PFKEY_ALIGN8(dst->sa_len) 810 + sizeof(struct sadb_lifetime) 811 + sizeof(struct sadb_lifetime); 812 813 if (e_type != SADB_EALG_NONE) 814 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen)); 815 if (a_type != SADB_AALG_NONE) 816 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen)); 817 818 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 819 __ipsec_set_strerror(strerror(errno)); 820 return -1; 821 }
| 1167 break; 1168 default: 1169 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1170 return -1; 1171 } 1172 1173 /* create new sadb_msg to reply. */ 1174 len = sizeof(struct sadb_msg) 1175 + sizeof(struct sadb_sa) 1176 + sizeof(struct sadb_x_sa2) 1177 + sizeof(struct sadb_address) 1178 + PFKEY_ALIGN8(src->sa_len) 1179 + sizeof(struct sadb_address) 1180 + PFKEY_ALIGN8(dst->sa_len) 1181 + sizeof(struct sadb_lifetime) 1182 + sizeof(struct sadb_lifetime); 1183 1184 if (e_type != SADB_EALG_NONE) 1185 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen)); 1186 if (a_type != SADB_AALG_NONE) 1187 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen)); 1188 1189 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1190 __ipsec_set_strerror(strerror(errno)); 1191 return -1; 1192 }
|
| 1193 ep = ((caddr_t)newmsg) + len;
|
822
| 1194
|
823 p = pfkey_setsadbmsg((caddr_t)newmsg, type, len,
| 1195 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
|
824 satype, seq, getpid());
| 1196 satype, seq, getpid());
|
825 p = pfkey_setsadbsa(p, spi, wsize, a_type, e_type, flags); 826 p = pfkey_setsadbxsa2(p, mode, reqid); 827 p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen,
| 1197 if (!p) { 1198 free(newmsg); 1199 return -1; 1200 } 1201 p = pfkey_setsadbsa(p, ep, spi, wsize, a_type, e_type, flags); 1202 if (!p) { 1203 free(newmsg); 1204 return -1; 1205 } 1206 p = pfkey_setsadbxsa2(p, ep, mode, reqid); 1207 if (!p) { 1208 free(newmsg); 1209 return -1; 1210 } 1211 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
|
828 IPSEC_ULPROTO_ANY);
| 1212 IPSEC_ULPROTO_ANY);
|
829 p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen,
| 1213 if (!p) { 1214 free(newmsg); 1215 return -1; 1216 } 1217 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
|
830 IPSEC_ULPROTO_ANY);
| 1218 IPSEC_ULPROTO_ANY);
|
| 1219 if (!p) { 1220 free(newmsg); 1221 return -1; 1222 }
|
831
| 1223
|
832 if (e_type != SADB_EALG_NONE) 833 p = pfkey_setsadbkey(p, SADB_EXT_KEY_ENCRYPT,
| 1224 if (e_type != SADB_EALG_NONE) { 1225 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT,
|
834 keymat, e_keylen);
| 1226 keymat, e_keylen);
|
835 if (a_type != SADB_AALG_NONE) 836 p = pfkey_setsadbkey(p, SADB_EXT_KEY_AUTH,
| 1227 if (!p) { 1228 free(newmsg); 1229 return -1; 1230 } 1231 } 1232 if (a_type != SADB_AALG_NONE) { 1233 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH,
|
837 keymat + e_keylen, a_keylen);
| 1234 keymat + e_keylen, a_keylen);
|
| 1235 if (!p) { 1236 free(newmsg); 1237 return -1; 1238 } 1239 }
|
838 839 /* set sadb_lifetime for destination */
| 1240 1241 /* set sadb_lifetime for destination */
|
840 p = pfkey_setsadblifetime(p, SADB_EXT_LIFETIME_HARD,
| 1242 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
|
841 l_alloc, l_bytes, l_addtime, l_usetime);
| 1243 l_alloc, l_bytes, l_addtime, l_usetime);
|
842 p = pfkey_setsadblifetime(p, SADB_EXT_LIFETIME_SOFT,
| 1244 if (!p) { 1245 free(newmsg); 1246 return -1; 1247 } 1248 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT,
|
843 l_alloc, l_bytes, l_addtime, l_usetime);
| 1249 l_alloc, l_bytes, l_addtime, l_usetime);
|
| 1250 if (!p || p != ep) { 1251 free(newmsg); 1252 return -1; 1253 }
|
844 845 /* send message */ 846 len = pfkey_send(so, newmsg, len); 847 free(newmsg); 848 849 if (len < 0) 850 return -1; 851 852 __ipsec_errcode = EIPSEC_NO_ERROR; 853 return len; 854} 855 856/* sending SADB_DELETE or SADB_GET message to the kernel */ 857static int 858pfkey_send_x2(so, type, satype, mode, src, dst, spi) 859 int so; 860 u_int type, satype, mode; 861 struct sockaddr *src, *dst; 862 u_int32_t spi; 863{ 864 struct sadb_msg *newmsg; 865 int len; 866 caddr_t p; 867 int plen;
| 1254 1255 /* send message */ 1256 len = pfkey_send(so, newmsg, len); 1257 free(newmsg); 1258 1259 if (len < 0) 1260 return -1; 1261 1262 __ipsec_errcode = EIPSEC_NO_ERROR; 1263 return len; 1264} 1265 1266/* sending SADB_DELETE or SADB_GET message to the kernel */ 1267static int 1268pfkey_send_x2(so, type, satype, mode, src, dst, spi) 1269 int so; 1270 u_int type, satype, mode; 1271 struct sockaddr *src, *dst; 1272 u_int32_t spi; 1273{ 1274 struct sadb_msg *newmsg; 1275 int len; 1276 caddr_t p; 1277 int plen;
|
| 1278 caddr_t ep;
|
868 869 /* validity check */ 870 if (src == NULL || dst == NULL) { 871 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 872 return -1; 873 } 874 if (src->sa_family != dst->sa_family) { 875 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 876 return -1; 877 } 878 switch (src->sa_family) { 879 case AF_INET: 880 plen = sizeof(struct in_addr) << 3; 881 break; 882 case AF_INET6: 883 plen = sizeof(struct in6_addr) << 3; 884 break; 885 default: 886 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 887 return -1; 888 } 889 890 /* create new sadb_msg to reply. */ 891 len = sizeof(struct sadb_msg) 892 + sizeof(struct sadb_sa) 893 + sizeof(struct sadb_address) 894 + PFKEY_ALIGN8(src->sa_len) 895 + sizeof(struct sadb_address) 896 + PFKEY_ALIGN8(dst->sa_len); 897 898 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 899 __ipsec_set_strerror(strerror(errno)); 900 return -1; 901 }
| 1279 1280 /* validity check */ 1281 if (src == NULL || dst == NULL) { 1282 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1283 return -1; 1284 } 1285 if (src->sa_family != dst->sa_family) { 1286 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1287 return -1; 1288 } 1289 switch (src->sa_family) { 1290 case AF_INET: 1291 plen = sizeof(struct in_addr) << 3; 1292 break; 1293 case AF_INET6: 1294 plen = sizeof(struct in6_addr) << 3; 1295 break; 1296 default: 1297 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1298 return -1; 1299 } 1300 1301 /* create new sadb_msg to reply. */ 1302 len = sizeof(struct sadb_msg) 1303 + sizeof(struct sadb_sa) 1304 + sizeof(struct sadb_address) 1305 + PFKEY_ALIGN8(src->sa_len) 1306 + sizeof(struct sadb_address) 1307 + PFKEY_ALIGN8(dst->sa_len); 1308 1309 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1310 __ipsec_set_strerror(strerror(errno)); 1311 return -1; 1312 }
|
| 1313 ep = ((caddr_t)newmsg) + len;
|
902
| 1314
|
903 p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, 0, getpid()); 904 p = pfkey_setsadbsa(p, spi, 0, 0, 0, 0); 905 p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_SRC, src, plen,
| 1315 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, satype, 0, 1316 getpid()); 1317 if (!p) { 1318 free(newmsg); 1319 return -1; 1320 } 1321 p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0); 1322 if (!p) { 1323 free(newmsg); 1324 return -1; 1325 } 1326 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
|
906 IPSEC_ULPROTO_ANY);
| 1327 IPSEC_ULPROTO_ANY);
|
907 p = pfkey_setsadbaddr(p, SADB_EXT_ADDRESS_DST, dst, plen,
| 1328 if (!p) { 1329 free(newmsg); 1330 return -1; 1331 } 1332 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
|
908 IPSEC_ULPROTO_ANY);
| 1333 IPSEC_ULPROTO_ANY);
|
| 1334 if (!p || p != ep) { 1335 free(newmsg); 1336 return -1; 1337 }
|
909 910 /* send message */ 911 len = pfkey_send(so, newmsg, len); 912 free(newmsg); 913 914 if (len < 0) 915 return -1; 916 917 __ipsec_errcode = EIPSEC_NO_ERROR; 918 return len; 919} 920 921/* 922 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message 923 * to the kernel 924 */ 925static int 926pfkey_send_x3(so, type, satype) 927 int so; 928 u_int type, satype; 929{ 930 struct sadb_msg *newmsg; 931 int len;
| 1338 1339 /* send message */ 1340 len = pfkey_send(so, newmsg, len); 1341 free(newmsg); 1342 1343 if (len < 0) 1344 return -1; 1345 1346 __ipsec_errcode = EIPSEC_NO_ERROR; 1347 return len; 1348} 1349 1350/* 1351 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message 1352 * to the kernel 1353 */ 1354static int 1355pfkey_send_x3(so, type, satype) 1356 int so; 1357 u_int type, satype; 1358{ 1359 struct sadb_msg *newmsg; 1360 int len;
|
| 1361 caddr_t p; 1362 caddr_t ep;
|
932 933 /* validity check */ 934 switch (type) { 935 case SADB_X_PROMISC: 936 if (satype != 0 && satype != 1) { 937 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 938 return -1; 939 } 940 break; 941 default: 942 switch (satype) { 943 case SADB_SATYPE_UNSPEC: 944 case SADB_SATYPE_AH: 945 case SADB_SATYPE_ESP: 946 case SADB_X_SATYPE_IPCOMP: 947 break; 948 default: 949 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 950 return -1; 951 } 952 } 953 954 /* create new sadb_msg to send. */ 955 len = sizeof(struct sadb_msg); 956 957 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 958 __ipsec_set_strerror(strerror(errno)); 959 return -1; 960 }
| 1363 1364 /* validity check */ 1365 switch (type) { 1366 case SADB_X_PROMISC: 1367 if (satype != 0 && satype != 1) { 1368 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1369 return -1; 1370 } 1371 break; 1372 default: 1373 switch (satype) { 1374 case SADB_SATYPE_UNSPEC: 1375 case SADB_SATYPE_AH: 1376 case SADB_SATYPE_ESP: 1377 case SADB_X_SATYPE_IPCOMP: 1378 break; 1379 default: 1380 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1381 return -1; 1382 } 1383 } 1384 1385 /* create new sadb_msg to send. */ 1386 len = sizeof(struct sadb_msg); 1387 1388 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1389 __ipsec_set_strerror(strerror(errno)); 1390 return -1; 1391 }
|
| 1392 ep = ((caddr_t)newmsg) + len;
|
961
| 1393
|
962 (void)pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, 0, getpid());
| 1394 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, satype, 0, 1395 getpid()); 1396 if (!p || p != ep) { 1397 free(newmsg); 1398 return -1; 1399 }
|
963 964 /* send message */ 965 len = pfkey_send(so, newmsg, len); 966 free(newmsg); 967 968 if (len < 0) 969 return -1; 970 971 __ipsec_errcode = EIPSEC_NO_ERROR; 972 return len; 973} 974 975/* sending SADB_X_SPDADD message to the kernel */ 976static int
| 1400 1401 /* send message */ 1402 len = pfkey_send(so, newmsg, len); 1403 free(newmsg); 1404 1405 if (len < 0) 1406 return -1; 1407 1408 __ipsec_errcode = EIPSEC_NO_ERROR; 1409 return len; 1410} 1411 1412/* sending SADB_X_SPDADD message to the kernel */ 1413static int
|
977pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, policy, policylen, seq)
| 1414pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, 1415 ltime, vtime, policy, policylen, seq)
|
978 int so; 979 struct sockaddr *src, *dst; 980 u_int type, prefs, prefd, proto;
| 1416 int so; 1417 struct sockaddr *src, *dst; 1418 u_int type, prefs, prefd, proto;
|
| 1419 u_int64_t ltime, vtime;
|
981 char *policy; 982 int policylen; 983 u_int32_t seq; 984{ 985 struct sadb_msg *newmsg; 986 int len; 987 caddr_t p; 988 int plen;
| 1420 char *policy; 1421 int policylen; 1422 u_int32_t seq; 1423{ 1424 struct sadb_msg *newmsg; 1425 int len; 1426 caddr_t p; 1427 int plen;
|
| 1428 caddr_t ep;
|
989 990 /* validity check */ 991 if (src == NULL || dst == NULL) { 992 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 993 return -1; 994 } 995 if (src->sa_family != dst->sa_family) { 996 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 997 return -1; 998 } 999 1000 switch (src->sa_family) { 1001 case AF_INET: 1002 plen = sizeof(struct in_addr) << 3; 1003 break; 1004 case AF_INET6: 1005 plen = sizeof(struct in6_addr) << 3; 1006 break; 1007 default: 1008 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1009 return -1; 1010 } 1011 if (prefs > plen || prefd > plen) { 1012 __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; 1013 return -1; 1014 } 1015 1016 /* create new sadb_msg to reply. */ 1017 len = sizeof(struct sadb_msg) 1018 + sizeof(struct sadb_address) 1019 + PFKEY_ALIGN8(src->sa_len) 1020 + sizeof(struct sadb_address) 1021 + PFKEY_ALIGN8(src->sa_len)
| 1429 1430 /* validity check */ 1431 if (src == NULL || dst == NULL) { 1432 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1433 return -1; 1434 } 1435 if (src->sa_family != dst->sa_family) { 1436 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1437 return -1; 1438 } 1439 1440 switch (src->sa_family) { 1441 case AF_INET: 1442 plen = sizeof(struct in_addr) << 3; 1443 break; 1444 case AF_INET6: 1445 plen = sizeof(struct in6_addr) << 3; 1446 break; 1447 default: 1448 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1449 return -1; 1450 } 1451 if (prefs > plen || prefd > plen) { 1452 __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; 1453 return -1; 1454 } 1455 1456 /* create new sadb_msg to reply. */ 1457 len = sizeof(struct sadb_msg) 1458 + sizeof(struct sadb_address) 1459 + PFKEY_ALIGN8(src->sa_len) 1460 + sizeof(struct sadb_address) 1461 + PFKEY_ALIGN8(src->sa_len)
|
| 1462 + sizeof(struct sadb_lifetime)
|
1022 + policylen; 1023 1024 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1025 __ipsec_set_strerror(strerror(errno)); 1026 return -1; 1027 }
| 1463 + policylen; 1464 1465 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1466 __ipsec_set_strerror(strerror(errno)); 1467 return -1; 1468 }
|
| 1469 ep = ((caddr_t)newmsg) + len;
|
1028
| 1470
|
1029 p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, 1030 SADB_SATYPE_UNSPEC, seq, getpid()); 1031 p = pfkey_setsadbaddr(p, 1032 SADB_EXT_ADDRESS_SRC, 1033 src, 1034 prefs, 1035 proto); 1036 p = pfkey_setsadbaddr(p, 1037 SADB_EXT_ADDRESS_DST, 1038 dst, 1039 prefd, 1040 proto);
| 1471 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, 1472 SADB_SATYPE_UNSPEC, seq, getpid()); 1473 if (!p) { 1474 free(newmsg); 1475 return -1; 1476 } 1477 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto); 1478 if (!p) { 1479 free(newmsg); 1480 return -1; 1481 } 1482 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto); 1483 if (!p) { 1484 free(newmsg); 1485 return -1; 1486 } 1487 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD, 1488 0, 0, ltime, vtime); 1489 if (!p || p + policylen != ep) { 1490 free(newmsg); 1491 return -1; 1492 }
|
1041 memcpy(p, policy, policylen); 1042 1043 /* send message */ 1044 len = pfkey_send(so, newmsg, len); 1045 free(newmsg); 1046 1047 if (len < 0) 1048 return -1; 1049 1050 __ipsec_errcode = EIPSEC_NO_ERROR; 1051 return len; 1052} 1053 1054/* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */ 1055static int 1056pfkey_send_x5(so, type, spid) 1057 int so; 1058 u_int type; 1059 u_int32_t spid; 1060{ 1061 struct sadb_msg *newmsg; 1062 struct sadb_x_policy xpl; 1063 int len; 1064 caddr_t p;
| 1493 memcpy(p, policy, policylen); 1494 1495 /* send message */ 1496 len = pfkey_send(so, newmsg, len); 1497 free(newmsg); 1498 1499 if (len < 0) 1500 return -1; 1501 1502 __ipsec_errcode = EIPSEC_NO_ERROR; 1503 return len; 1504} 1505 1506/* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */ 1507static int 1508pfkey_send_x5(so, type, spid) 1509 int so; 1510 u_int type; 1511 u_int32_t spid; 1512{ 1513 struct sadb_msg *newmsg; 1514 struct sadb_x_policy xpl; 1515 int len; 1516 caddr_t p;
|
| 1517 caddr_t ep;
|
1065 1066 /* create new sadb_msg to reply. */ 1067 len = sizeof(struct sadb_msg) 1068 + sizeof(xpl); 1069 1070 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1071 __ipsec_set_strerror(strerror(errno)); 1072 return -1; 1073 }
| 1518 1519 /* create new sadb_msg to reply. */ 1520 len = sizeof(struct sadb_msg) 1521 + sizeof(xpl); 1522 1523 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1524 __ipsec_set_strerror(strerror(errno)); 1525 return -1; 1526 }
|
| 1527 ep = ((caddr_t)newmsg) + len;
|
1074
| 1528
|
1075 p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, 1076 SADB_SATYPE_UNSPEC, 0, getpid());
| 1529 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, 1530 SADB_SATYPE_UNSPEC, 0, getpid()); 1531 if (!p) { 1532 free(newmsg); 1533 return -1; 1534 }
|
1077
| 1535
|
| 1536 if (p + sizeof(xpl) != ep) { 1537 free(newmsg); 1538 return -1; 1539 }
|
1078 memset(&xpl, 0, sizeof(xpl)); 1079 xpl.sadb_x_policy_len = PFKEY_UNUNIT64(sizeof(xpl)); 1080 xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY; 1081 xpl.sadb_x_policy_id = spid;
| 1540 memset(&xpl, 0, sizeof(xpl)); 1541 xpl.sadb_x_policy_len = PFKEY_UNUNIT64(sizeof(xpl)); 1542 xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY; 1543 xpl.sadb_x_policy_id = spid;
|
1082
| |
1083 memcpy(p, &xpl, sizeof(xpl)); 1084 1085 /* send message */ 1086 len = pfkey_send(so, newmsg, len); 1087 free(newmsg); 1088 1089 if (len < 0) 1090 return -1; 1091 1092 __ipsec_errcode = EIPSEC_NO_ERROR; 1093 return len; 1094} 1095 1096/* 1097 * open a socket. 1098 * OUT: 1099 * -1: fail. 1100 * others : success and return value of socket. 1101 */ 1102int 1103pfkey_open() 1104{ 1105 int so; 1106 const int bufsiz = 128 * 1024; /*is 128K enough?*/ 1107 1108 if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { 1109 __ipsec_set_strerror(strerror(errno)); 1110 return -1; 1111 } 1112 1113 /* 1114 * This is a temporary workaround for KAME PR 154. 1115 * Don't really care even if it fails. 1116 */ 1117 (void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz)); 1118 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)); 1119 1120 __ipsec_errcode = EIPSEC_NO_ERROR; 1121 return so; 1122} 1123 1124/* 1125 * close a socket. 1126 * OUT: 1127 * 0: success. 1128 * -1: fail. 1129 */ 1130void 1131pfkey_close(so) 1132 int so; 1133{ 1134 (void)close(so); 1135 1136 __ipsec_errcode = EIPSEC_NO_ERROR; 1137 return; 1138} 1139 1140/* 1141 * receive sadb_msg data, and return pointer to new buffer allocated. 1142 * Must free this buffer later. 1143 * OUT: 1144 * NULL : error occured. 1145 * others : a pointer to sadb_msg structure.
| 1544 memcpy(p, &xpl, sizeof(xpl)); 1545 1546 /* send message */ 1547 len = pfkey_send(so, newmsg, len); 1548 free(newmsg); 1549 1550 if (len < 0) 1551 return -1; 1552 1553 __ipsec_errcode = EIPSEC_NO_ERROR; 1554 return len; 1555} 1556 1557/* 1558 * open a socket. 1559 * OUT: 1560 * -1: fail. 1561 * others : success and return value of socket. 1562 */ 1563int 1564pfkey_open() 1565{ 1566 int so; 1567 const int bufsiz = 128 * 1024; /*is 128K enough?*/ 1568 1569 if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { 1570 __ipsec_set_strerror(strerror(errno)); 1571 return -1; 1572 } 1573 1574 /* 1575 * This is a temporary workaround for KAME PR 154. 1576 * Don't really care even if it fails. 1577 */ 1578 (void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz)); 1579 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)); 1580 1581 __ipsec_errcode = EIPSEC_NO_ERROR; 1582 return so; 1583} 1584 1585/* 1586 * close a socket. 1587 * OUT: 1588 * 0: success. 1589 * -1: fail. 1590 */ 1591void 1592pfkey_close(so) 1593 int so; 1594{ 1595 (void)close(so); 1596 1597 __ipsec_errcode = EIPSEC_NO_ERROR; 1598 return; 1599} 1600 1601/* 1602 * receive sadb_msg data, and return pointer to new buffer allocated. 1603 * Must free this buffer later. 1604 * OUT: 1605 * NULL : error occured. 1606 * others : a pointer to sadb_msg structure.
|
| 1607 * 1608 * XXX should be rewritten to pass length explicitly
|
1146 */ 1147struct sadb_msg * 1148pfkey_recv(so) 1149 int so; 1150{ 1151 struct sadb_msg buf, *newmsg; 1152 int len, reallen; 1153 1154 while ((len = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK)) < 0) {
| 1609 */ 1610struct sadb_msg * 1611pfkey_recv(so) 1612 int so; 1613{ 1614 struct sadb_msg buf, *newmsg; 1615 int len, reallen; 1616 1617 while ((len = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK)) < 0) {
|
1155 if (errno == EINTR) continue;
| 1618 if (errno == EINTR) 1619 continue;
|
1156 __ipsec_set_strerror(strerror(errno)); 1157 return NULL; 1158 } 1159 1160 if (len < sizeof(buf)) { 1161 recv(so, (caddr_t)&buf, sizeof(buf), 0); 1162 __ipsec_errcode = EIPSEC_MAX; 1163 return NULL; 1164 } 1165 1166 /* read real message */ 1167 reallen = PFKEY_UNUNIT64(buf.sadb_msg_len); 1168 if ((newmsg = CALLOC(reallen, struct sadb_msg *)) == 0) { 1169 __ipsec_set_strerror(strerror(errno)); 1170 return NULL; 1171 } 1172 1173 while ((len = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) {
| 1620 __ipsec_set_strerror(strerror(errno)); 1621 return NULL; 1622 } 1623 1624 if (len < sizeof(buf)) { 1625 recv(so, (caddr_t)&buf, sizeof(buf), 0); 1626 __ipsec_errcode = EIPSEC_MAX; 1627 return NULL; 1628 } 1629 1630 /* read real message */ 1631 reallen = PFKEY_UNUNIT64(buf.sadb_msg_len); 1632 if ((newmsg = CALLOC(reallen, struct sadb_msg *)) == 0) { 1633 __ipsec_set_strerror(strerror(errno)); 1634 return NULL; 1635 } 1636 1637 while ((len = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) {
|
1174 if (errno == EINTR) continue;
| 1638 if (errno == EINTR) 1639 continue;
|
1175 __ipsec_set_strerror(strerror(errno)); 1176 free(newmsg); 1177 return NULL; 1178 } 1179 1180 if (len != reallen) { 1181 __ipsec_errcode = EIPSEC_SYSTEM_ERROR; 1182 free(newmsg); 1183 return NULL; 1184 } 1185
| 1640 __ipsec_set_strerror(strerror(errno)); 1641 free(newmsg); 1642 return NULL; 1643 } 1644 1645 if (len != reallen) { 1646 __ipsec_errcode = EIPSEC_SYSTEM_ERROR; 1647 free(newmsg); 1648 return NULL; 1649 } 1650
|
| 1651 /* don't trust what the kernel says, validate! */ 1652 if (PFKEY_UNUNIT64(newmsg->sadb_msg_len) != len) { 1653 __ipsec_errcode = EIPSEC_SYSTEM_ERROR; 1654 free(newmsg); 1655 return NULL; 1656 } 1657
|
1186 __ipsec_errcode = EIPSEC_NO_ERROR; 1187 return newmsg; 1188} 1189 1190/* 1191 * send message to a socket. 1192 * OUT: 1193 * others: success and return length sent. 1194 * -1 : fail. 1195 */ 1196int 1197pfkey_send(so, msg, len) 1198 int so; 1199 struct sadb_msg *msg; 1200 int len; 1201{ 1202 if ((len = send(so, (caddr_t)msg, len, 0)) < 0) { 1203 __ipsec_set_strerror(strerror(errno)); 1204 return -1; 1205 } 1206 1207 __ipsec_errcode = EIPSEC_NO_ERROR; 1208 return len; 1209} 1210 1211/* 1212 * %%% Utilities 1213 * NOTE: These functions are derived from netkey/key.c in KAME. 1214 */ 1215/* 1216 * set the pointer to each header in this message buffer. 1217 * IN: msg: pointer to message buffer. 1218 * mhp: pointer to the buffer initialized like below: 1219 * caddr_t mhp[SADB_EXT_MAX + 1]; 1220 * OUT: -1: invalid. 1221 * 0: valid.
| 1658 __ipsec_errcode = EIPSEC_NO_ERROR; 1659 return newmsg; 1660} 1661 1662/* 1663 * send message to a socket. 1664 * OUT: 1665 * others: success and return length sent. 1666 * -1 : fail. 1667 */ 1668int 1669pfkey_send(so, msg, len) 1670 int so; 1671 struct sadb_msg *msg; 1672 int len; 1673{ 1674 if ((len = send(so, (caddr_t)msg, len, 0)) < 0) { 1675 __ipsec_set_strerror(strerror(errno)); 1676 return -1; 1677 } 1678 1679 __ipsec_errcode = EIPSEC_NO_ERROR; 1680 return len; 1681} 1682 1683/* 1684 * %%% Utilities 1685 * NOTE: These functions are derived from netkey/key.c in KAME. 1686 */ 1687/* 1688 * set the pointer to each header in this message buffer. 1689 * IN: msg: pointer to message buffer. 1690 * mhp: pointer to the buffer initialized like below: 1691 * caddr_t mhp[SADB_EXT_MAX + 1]; 1692 * OUT: -1: invalid. 1693 * 0: valid.
|
| 1694 * 1695 * XXX should be rewritten to obtain length explicitly
|
1222 */ 1223int 1224pfkey_align(msg, mhp) 1225 struct sadb_msg *msg; 1226 caddr_t *mhp; 1227{ 1228 struct sadb_ext *ext;
| 1696 */ 1697int 1698pfkey_align(msg, mhp) 1699 struct sadb_msg *msg; 1700 caddr_t *mhp; 1701{ 1702 struct sadb_ext *ext;
|
1229 int tlen, extlen;
| |
1230 int i;
| 1703 int i;
|
| 1704 caddr_t p; 1705 caddr_t ep; /* XXX should be passed from upper layer */
|
1231 1232 /* validity check */ 1233 if (msg == NULL || mhp == NULL) { 1234 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1235 return -1; 1236 } 1237 1238 /* initialize */ 1239 for (i = 0; i < SADB_EXT_MAX + 1; i++) 1240 mhp[i] = NULL; 1241 1242 mhp[0] = (caddr_t)msg; 1243
| 1706 1707 /* validity check */ 1708 if (msg == NULL || mhp == NULL) { 1709 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1710 return -1; 1711 } 1712 1713 /* initialize */ 1714 for (i = 0; i < SADB_EXT_MAX + 1; i++) 1715 mhp[i] = NULL; 1716 1717 mhp[0] = (caddr_t)msg; 1718
|
1244 tlen = PFKEY_UNUNIT64(msg->sadb_msg_len) - sizeof(struct sadb_msg); 1245 ext = (struct sadb_ext *)((caddr_t)msg + sizeof(struct sadb_msg));
| 1719 /* initialize */ 1720 p = (caddr_t) msg; 1721 ep = p + PFKEY_UNUNIT64(msg->sadb_msg_len);
|
1246
| 1722
|
1247 while (tlen > 0) {
| 1723 /* skip base header */ 1724 p += sizeof(struct sadb_msg); 1725 1726 while (p < ep) { 1727 ext = (struct sadb_ext *)p; 1728 if (ep < p + sizeof(*ext) || PFKEY_EXTLEN(ext) < sizeof(*ext) || 1729 ep < p + PFKEY_EXTLEN(ext)) { 1730 /* invalid format */ 1731 break; 1732 } 1733
|
1248 /* duplicate check */ 1249 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/ 1250 if (mhp[ext->sadb_ext_type] != NULL) { 1251 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; 1252 return -1; 1253 } 1254 1255 /* set pointer */ 1256 switch (ext->sadb_ext_type) { 1257 case SADB_EXT_SA: 1258 case SADB_EXT_LIFETIME_CURRENT: 1259 case SADB_EXT_LIFETIME_HARD: 1260 case SADB_EXT_LIFETIME_SOFT: 1261 case SADB_EXT_ADDRESS_SRC: 1262 case SADB_EXT_ADDRESS_DST: 1263 case SADB_EXT_ADDRESS_PROXY: 1264 case SADB_EXT_KEY_AUTH: 1265 /* XXX should to be check weak keys. */ 1266 case SADB_EXT_KEY_ENCRYPT: 1267 /* XXX should to be check weak keys. */ 1268 case SADB_EXT_IDENTITY_SRC: 1269 case SADB_EXT_IDENTITY_DST: 1270 case SADB_EXT_SENSITIVITY: 1271 case SADB_EXT_PROPOSAL: 1272 case SADB_EXT_SUPPORTED_AUTH: 1273 case SADB_EXT_SUPPORTED_ENCRYPT: 1274 case SADB_EXT_SPIRANGE: 1275 case SADB_X_EXT_POLICY: 1276 case SADB_X_EXT_SA2: 1277 mhp[ext->sadb_ext_type] = (caddr_t)ext; 1278 break; 1279 default: 1280 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; 1281 return -1; 1282 } 1283
| 1734 /* duplicate check */ 1735 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/ 1736 if (mhp[ext->sadb_ext_type] != NULL) { 1737 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; 1738 return -1; 1739 } 1740 1741 /* set pointer */ 1742 switch (ext->sadb_ext_type) { 1743 case SADB_EXT_SA: 1744 case SADB_EXT_LIFETIME_CURRENT: 1745 case SADB_EXT_LIFETIME_HARD: 1746 case SADB_EXT_LIFETIME_SOFT: 1747 case SADB_EXT_ADDRESS_SRC: 1748 case SADB_EXT_ADDRESS_DST: 1749 case SADB_EXT_ADDRESS_PROXY: 1750 case SADB_EXT_KEY_AUTH: 1751 /* XXX should to be check weak keys. */ 1752 case SADB_EXT_KEY_ENCRYPT: 1753 /* XXX should to be check weak keys. */ 1754 case SADB_EXT_IDENTITY_SRC: 1755 case SADB_EXT_IDENTITY_DST: 1756 case SADB_EXT_SENSITIVITY: 1757 case SADB_EXT_PROPOSAL: 1758 case SADB_EXT_SUPPORTED_AUTH: 1759 case SADB_EXT_SUPPORTED_ENCRYPT: 1760 case SADB_EXT_SPIRANGE: 1761 case SADB_X_EXT_POLICY: 1762 case SADB_X_EXT_SA2: 1763 mhp[ext->sadb_ext_type] = (caddr_t)ext; 1764 break; 1765 default: 1766 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; 1767 return -1; 1768 } 1769
|
1284 extlen = PFKEY_EXTLEN(ext); 1285 tlen -= extlen; 1286 ext = (struct sadb_ext *)((caddr_t)ext + extlen);
| 1770 p += PFKEY_EXTLEN(ext);
|
1287 } 1288
| 1771 } 1772
|
| 1773 if (p != ep) { 1774 __ipsec_errcode = EIPSEC_INVAL_SADBMSG; 1775 return -1; 1776 } 1777
|
1289 __ipsec_errcode = EIPSEC_NO_ERROR; 1290 return 0; 1291} 1292 1293/* 1294 * check basic usage for sadb_msg, 1295 * NOTE: This routine is derived from netkey/key.c in KAME. 1296 * IN: msg: pointer to message buffer. 1297 * mhp: pointer to the buffer initialized like below: 1298 * 1299 * caddr_t mhp[SADB_EXT_MAX + 1]; 1300 * 1301 * OUT: -1: invalid. 1302 * 0: valid. 1303 */ 1304int 1305pfkey_check(mhp) 1306 caddr_t *mhp; 1307{ 1308 struct sadb_msg *msg; 1309 1310 /* validity check */ 1311 if (mhp == NULL || mhp[0] == NULL) { 1312 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1313 return -1; 1314 } 1315 1316 msg = (struct sadb_msg *)mhp[0]; 1317 1318 /* check version */ 1319 if (msg->sadb_msg_version != PF_KEY_V2) { 1320 __ipsec_errcode = EIPSEC_INVAL_VERSION; 1321 return -1; 1322 } 1323 1324 /* check type */ 1325 if (msg->sadb_msg_type > SADB_MAX) { 1326 __ipsec_errcode = EIPSEC_INVAL_MSGTYPE; 1327 return -1; 1328 } 1329 1330 /* check SA type */ 1331 switch (msg->sadb_msg_satype) { 1332 case SADB_SATYPE_UNSPEC: 1333 switch (msg->sadb_msg_type) { 1334 case SADB_GETSPI: 1335 case SADB_UPDATE: 1336 case SADB_ADD: 1337 case SADB_DELETE: 1338 case SADB_GET: 1339 case SADB_ACQUIRE: 1340 case SADB_EXPIRE: 1341 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1342 return -1; 1343 } 1344 break; 1345 case SADB_SATYPE_ESP: 1346 case SADB_SATYPE_AH: 1347 case SADB_X_SATYPE_IPCOMP: 1348 switch (msg->sadb_msg_type) { 1349 case SADB_X_SPDADD: 1350 case SADB_X_SPDDELETE: 1351 case SADB_X_SPDGET: 1352 case SADB_X_SPDDUMP: 1353 case SADB_X_SPDFLUSH: 1354 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1355 return -1; 1356 } 1357 break; 1358 case SADB_SATYPE_RSVP: 1359 case SADB_SATYPE_OSPFV2: 1360 case SADB_SATYPE_RIPV2: 1361 case SADB_SATYPE_MIP: 1362 __ipsec_errcode = EIPSEC_NOT_SUPPORTED; 1363 return -1; 1364 case 1: /* XXX: What does it do ? */ 1365 if (msg->sadb_msg_type == SADB_X_PROMISC) 1366 break; 1367 /*FALLTHROUGH*/ 1368 default: 1369 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1370 return -1; 1371 } 1372 1373 /* check field of upper layer protocol and address family */ 1374 if (mhp[SADB_EXT_ADDRESS_SRC] != NULL 1375 && mhp[SADB_EXT_ADDRESS_DST] != NULL) { 1376 struct sadb_address *src0, *dst0; 1377 1378 src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]); 1379 dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]); 1380 1381 if (src0->sadb_address_proto != dst0->sadb_address_proto) { 1382 __ipsec_errcode = EIPSEC_PROTO_MISMATCH; 1383 return -1; 1384 } 1385 1386 if (PFKEY_ADDR_SADDR(src0)->sa_family 1387 != PFKEY_ADDR_SADDR(dst0)->sa_family) { 1388 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1389 return -1; 1390 } 1391 1392 switch (PFKEY_ADDR_SADDR(src0)->sa_family) { 1393 case AF_INET: 1394 case AF_INET6: 1395 break; 1396 default: 1397 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1398 return -1; 1399 } 1400 1401 /* 1402 * prefixlen == 0 is valid because there must be the case 1403 * all addresses are matched. 1404 */ 1405 } 1406 1407 __ipsec_errcode = EIPSEC_NO_ERROR; 1408 return 0; 1409} 1410 1411/* 1412 * set data into sadb_msg. 1413 * `buf' must has been allocated sufficiently. 1414 */ 1415static caddr_t
| 1778 __ipsec_errcode = EIPSEC_NO_ERROR; 1779 return 0; 1780} 1781 1782/* 1783 * check basic usage for sadb_msg, 1784 * NOTE: This routine is derived from netkey/key.c in KAME. 1785 * IN: msg: pointer to message buffer. 1786 * mhp: pointer to the buffer initialized like below: 1787 * 1788 * caddr_t mhp[SADB_EXT_MAX + 1]; 1789 * 1790 * OUT: -1: invalid. 1791 * 0: valid. 1792 */ 1793int 1794pfkey_check(mhp) 1795 caddr_t *mhp; 1796{ 1797 struct sadb_msg *msg; 1798 1799 /* validity check */ 1800 if (mhp == NULL || mhp[0] == NULL) { 1801 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1802 return -1; 1803 } 1804 1805 msg = (struct sadb_msg *)mhp[0]; 1806 1807 /* check version */ 1808 if (msg->sadb_msg_version != PF_KEY_V2) { 1809 __ipsec_errcode = EIPSEC_INVAL_VERSION; 1810 return -1; 1811 } 1812 1813 /* check type */ 1814 if (msg->sadb_msg_type > SADB_MAX) { 1815 __ipsec_errcode = EIPSEC_INVAL_MSGTYPE; 1816 return -1; 1817 } 1818 1819 /* check SA type */ 1820 switch (msg->sadb_msg_satype) { 1821 case SADB_SATYPE_UNSPEC: 1822 switch (msg->sadb_msg_type) { 1823 case SADB_GETSPI: 1824 case SADB_UPDATE: 1825 case SADB_ADD: 1826 case SADB_DELETE: 1827 case SADB_GET: 1828 case SADB_ACQUIRE: 1829 case SADB_EXPIRE: 1830 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1831 return -1; 1832 } 1833 break; 1834 case SADB_SATYPE_ESP: 1835 case SADB_SATYPE_AH: 1836 case SADB_X_SATYPE_IPCOMP: 1837 switch (msg->sadb_msg_type) { 1838 case SADB_X_SPDADD: 1839 case SADB_X_SPDDELETE: 1840 case SADB_X_SPDGET: 1841 case SADB_X_SPDDUMP: 1842 case SADB_X_SPDFLUSH: 1843 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1844 return -1; 1845 } 1846 break; 1847 case SADB_SATYPE_RSVP: 1848 case SADB_SATYPE_OSPFV2: 1849 case SADB_SATYPE_RIPV2: 1850 case SADB_SATYPE_MIP: 1851 __ipsec_errcode = EIPSEC_NOT_SUPPORTED; 1852 return -1; 1853 case 1: /* XXX: What does it do ? */ 1854 if (msg->sadb_msg_type == SADB_X_PROMISC) 1855 break; 1856 /*FALLTHROUGH*/ 1857 default: 1858 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1859 return -1; 1860 } 1861 1862 /* check field of upper layer protocol and address family */ 1863 if (mhp[SADB_EXT_ADDRESS_SRC] != NULL 1864 && mhp[SADB_EXT_ADDRESS_DST] != NULL) { 1865 struct sadb_address *src0, *dst0; 1866 1867 src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]); 1868 dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]); 1869 1870 if (src0->sadb_address_proto != dst0->sadb_address_proto) { 1871 __ipsec_errcode = EIPSEC_PROTO_MISMATCH; 1872 return -1; 1873 } 1874 1875 if (PFKEY_ADDR_SADDR(src0)->sa_family 1876 != PFKEY_ADDR_SADDR(dst0)->sa_family) { 1877 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1878 return -1; 1879 } 1880 1881 switch (PFKEY_ADDR_SADDR(src0)->sa_family) { 1882 case AF_INET: 1883 case AF_INET6: 1884 break; 1885 default: 1886 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1887 return -1; 1888 } 1889 1890 /* 1891 * prefixlen == 0 is valid because there must be the case 1892 * all addresses are matched. 1893 */ 1894 } 1895 1896 __ipsec_errcode = EIPSEC_NO_ERROR; 1897 return 0; 1898} 1899 1900/* 1901 * set data into sadb_msg. 1902 * `buf' must has been allocated sufficiently. 1903 */ 1904static caddr_t
|
1416pfkey_setsadbmsg(buf, type, tlen, satype, seq, pid)
| 1905pfkey_setsadbmsg(buf, lim, type, tlen, satype, seq, pid)
|
1417 caddr_t buf;
| 1906 caddr_t buf;
|
| 1907 caddr_t lim;
|
1418 u_int type, satype; 1419 u_int tlen; 1420 u_int32_t seq; 1421 pid_t pid; 1422{ 1423 struct sadb_msg *p; 1424 u_int len; 1425 1426 p = (struct sadb_msg *)buf; 1427 len = sizeof(struct sadb_msg); 1428
| 1908 u_int type, satype; 1909 u_int tlen; 1910 u_int32_t seq; 1911 pid_t pid; 1912{ 1913 struct sadb_msg *p; 1914 u_int len; 1915 1916 p = (struct sadb_msg *)buf; 1917 len = sizeof(struct sadb_msg); 1918
|
| 1919 if (buf + len > lim) 1920 return NULL; 1921
|
1429 memset(p, 0, len); 1430 p->sadb_msg_version = PF_KEY_V2; 1431 p->sadb_msg_type = type; 1432 p->sadb_msg_errno = 0; 1433 p->sadb_msg_satype = satype; 1434 p->sadb_msg_len = PFKEY_UNIT64(tlen); 1435 p->sadb_msg_reserved = 0; 1436 p->sadb_msg_seq = seq; 1437 p->sadb_msg_pid = (u_int32_t)pid; 1438 1439 return(buf + len); 1440} 1441 1442/* 1443 * copy secasvar data into sadb_address. 1444 * `buf' must has been allocated sufficiently. 1445 */ 1446static caddr_t
| 1922 memset(p, 0, len); 1923 p->sadb_msg_version = PF_KEY_V2; 1924 p->sadb_msg_type = type; 1925 p->sadb_msg_errno = 0; 1926 p->sadb_msg_satype = satype; 1927 p->sadb_msg_len = PFKEY_UNIT64(tlen); 1928 p->sadb_msg_reserved = 0; 1929 p->sadb_msg_seq = seq; 1930 p->sadb_msg_pid = (u_int32_t)pid; 1931 1932 return(buf + len); 1933} 1934 1935/* 1936 * copy secasvar data into sadb_address. 1937 * `buf' must has been allocated sufficiently. 1938 */ 1939static caddr_t
|
1447pfkey_setsadbsa(buf, spi, wsize, auth, enc, flags)
| 1940pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags)
|
1448 caddr_t buf;
| 1941 caddr_t buf;
|
| 1942 caddr_t lim;
|
1449 u_int32_t spi, flags; 1450 u_int wsize, auth, enc; 1451{ 1452 struct sadb_sa *p; 1453 u_int len; 1454 1455 p = (struct sadb_sa *)buf; 1456 len = sizeof(struct sadb_sa); 1457
| 1943 u_int32_t spi, flags; 1944 u_int wsize, auth, enc; 1945{ 1946 struct sadb_sa *p; 1947 u_int len; 1948 1949 p = (struct sadb_sa *)buf; 1950 len = sizeof(struct sadb_sa); 1951
|
| 1952 if (buf + len > lim) 1953 return NULL; 1954
|
1458 memset(p, 0, len); 1459 p->sadb_sa_len = PFKEY_UNIT64(len); 1460 p->sadb_sa_exttype = SADB_EXT_SA; 1461 p->sadb_sa_spi = spi; 1462 p->sadb_sa_replay = wsize; 1463 p->sadb_sa_state = SADB_SASTATE_LARVAL; 1464 p->sadb_sa_auth = auth; 1465 p->sadb_sa_encrypt = enc; 1466 p->sadb_sa_flags = flags; 1467 1468 return(buf + len); 1469} 1470 1471/* 1472 * set data into sadb_address. 1473 * `buf' must has been allocated sufficiently. 1474 * prefixlen is in bits. 1475 */ 1476static caddr_t
| 1955 memset(p, 0, len); 1956 p->sadb_sa_len = PFKEY_UNIT64(len); 1957 p->sadb_sa_exttype = SADB_EXT_SA; 1958 p->sadb_sa_spi = spi; 1959 p->sadb_sa_replay = wsize; 1960 p->sadb_sa_state = SADB_SASTATE_LARVAL; 1961 p->sadb_sa_auth = auth; 1962 p->sadb_sa_encrypt = enc; 1963 p->sadb_sa_flags = flags; 1964 1965 return(buf + len); 1966} 1967 1968/* 1969 * set data into sadb_address. 1970 * `buf' must has been allocated sufficiently. 1971 * prefixlen is in bits. 1972 */ 1973static caddr_t
|
1477pfkey_setsadbaddr(buf, exttype, saddr, prefixlen, ul_proto)
| 1974pfkey_setsadbaddr(buf, lim, exttype, saddr, prefixlen, ul_proto)
|
1478 caddr_t buf;
| 1975 caddr_t buf;
|
| 1976 caddr_t lim;
|
1479 u_int exttype; 1480 struct sockaddr *saddr; 1481 u_int prefixlen; 1482 u_int ul_proto; 1483{ 1484 struct sadb_address *p; 1485 u_int len; 1486 1487 p = (struct sadb_address *)buf; 1488 len = sizeof(struct sadb_address) + PFKEY_ALIGN8(saddr->sa_len); 1489
| 1977 u_int exttype; 1978 struct sockaddr *saddr; 1979 u_int prefixlen; 1980 u_int ul_proto; 1981{ 1982 struct sadb_address *p; 1983 u_int len; 1984 1985 p = (struct sadb_address *)buf; 1986 len = sizeof(struct sadb_address) + PFKEY_ALIGN8(saddr->sa_len); 1987
|
| 1988 if (buf + len > lim) 1989 return NULL; 1990
|
1490 memset(p, 0, len); 1491 p->sadb_address_len = PFKEY_UNIT64(len); 1492 p->sadb_address_exttype = exttype & 0xffff; 1493 p->sadb_address_proto = ul_proto & 0xff; 1494 p->sadb_address_prefixlen = prefixlen; 1495 p->sadb_address_reserved = 0; 1496 1497 memcpy(p + 1, saddr, saddr->sa_len); 1498 1499 return(buf + len); 1500} 1501 1502/* 1503 * set sadb_key structure after clearing buffer with zero. 1504 * OUT: the pointer of buf + len. 1505 */ 1506static caddr_t
| 1991 memset(p, 0, len); 1992 p->sadb_address_len = PFKEY_UNIT64(len); 1993 p->sadb_address_exttype = exttype & 0xffff; 1994 p->sadb_address_proto = ul_proto & 0xff; 1995 p->sadb_address_prefixlen = prefixlen; 1996 p->sadb_address_reserved = 0; 1997 1998 memcpy(p + 1, saddr, saddr->sa_len); 1999 2000 return(buf + len); 2001} 2002 2003/* 2004 * set sadb_key structure after clearing buffer with zero. 2005 * OUT: the pointer of buf + len. 2006 */ 2007static caddr_t
|
1507pfkey_setsadbkey(buf, type, key, keylen) 1508 caddr_t buf, key;
| 2008pfkey_setsadbkey(buf, lim, type, key, keylen) 2009 caddr_t buf; 2010 caddr_t lim; 2011 caddr_t key;
|
1509 u_int type, keylen; 1510{ 1511 struct sadb_key *p; 1512 u_int len; 1513 1514 p = (struct sadb_key *)buf; 1515 len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen); 1516
| 2012 u_int type, keylen; 2013{ 2014 struct sadb_key *p; 2015 u_int len; 2016 2017 p = (struct sadb_key *)buf; 2018 len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen); 2019
|
| 2020 if (buf + len > lim) 2021 return NULL; 2022
|
1517 memset(p, 0, len); 1518 p->sadb_key_len = PFKEY_UNIT64(len); 1519 p->sadb_key_exttype = type; 1520 p->sadb_key_bits = keylen << 3; 1521 p->sadb_key_reserved = 0; 1522 1523 memcpy(p + 1, key, keylen); 1524 1525 return buf + len; 1526} 1527 1528/* 1529 * set sadb_lifetime structure after clearing buffer with zero. 1530 * OUT: the pointer of buf + len. 1531 */ 1532static caddr_t
| 2023 memset(p, 0, len); 2024 p->sadb_key_len = PFKEY_UNIT64(len); 2025 p->sadb_key_exttype = type; 2026 p->sadb_key_bits = keylen << 3; 2027 p->sadb_key_reserved = 0; 2028 2029 memcpy(p + 1, key, keylen); 2030 2031 return buf + len; 2032} 2033 2034/* 2035 * set sadb_lifetime structure after clearing buffer with zero. 2036 * OUT: the pointer of buf + len. 2037 */ 2038static caddr_t
|
1533pfkey_setsadblifetime(buf, type, l_alloc, l_bytes, l_addtime, l_usetime)
| 2039pfkey_setsadblifetime(buf, lim, type, l_alloc, l_bytes, l_addtime, l_usetime)
|
1534 caddr_t buf;
| 2040 caddr_t buf;
|
| 2041 caddr_t lim;
|
1535 u_int type; 1536 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime; 1537{ 1538 struct sadb_lifetime *p; 1539 u_int len; 1540 1541 p = (struct sadb_lifetime *)buf; 1542 len = sizeof(struct sadb_lifetime); 1543
| 2042 u_int type; 2043 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime; 2044{ 2045 struct sadb_lifetime *p; 2046 u_int len; 2047 2048 p = (struct sadb_lifetime *)buf; 2049 len = sizeof(struct sadb_lifetime); 2050
|
| 2051 if (buf + len > lim) 2052 return NULL; 2053
|
1544 memset(p, 0, len); 1545 p->sadb_lifetime_len = PFKEY_UNIT64(len); 1546 p->sadb_lifetime_exttype = type; 1547 1548 switch (type) { 1549 case SADB_EXT_LIFETIME_SOFT: 1550 p->sadb_lifetime_allocations 1551 = (l_alloc * soft_lifetime_allocations_rate) /100; 1552 p->sadb_lifetime_bytes 1553 = (l_bytes * soft_lifetime_bytes_rate) /100; 1554 p->sadb_lifetime_addtime 1555 = (l_addtime * soft_lifetime_addtime_rate) /100; 1556 p->sadb_lifetime_usetime 1557 = (l_usetime * soft_lifetime_usetime_rate) /100; 1558 break; 1559 case SADB_EXT_LIFETIME_HARD: 1560 p->sadb_lifetime_allocations = l_alloc; 1561 p->sadb_lifetime_bytes = l_bytes; 1562 p->sadb_lifetime_addtime = l_addtime; 1563 p->sadb_lifetime_usetime = l_usetime; 1564 break; 1565 } 1566 1567 return buf + len; 1568} 1569 1570/* 1571 * copy secasvar data into sadb_address. 1572 * `buf' must has been allocated sufficiently. 1573 */ 1574static caddr_t
| 2054 memset(p, 0, len); 2055 p->sadb_lifetime_len = PFKEY_UNIT64(len); 2056 p->sadb_lifetime_exttype = type; 2057 2058 switch (type) { 2059 case SADB_EXT_LIFETIME_SOFT: 2060 p->sadb_lifetime_allocations 2061 = (l_alloc * soft_lifetime_allocations_rate) /100; 2062 p->sadb_lifetime_bytes 2063 = (l_bytes * soft_lifetime_bytes_rate) /100; 2064 p->sadb_lifetime_addtime 2065 = (l_addtime * soft_lifetime_addtime_rate) /100; 2066 p->sadb_lifetime_usetime 2067 = (l_usetime * soft_lifetime_usetime_rate) /100; 2068 break; 2069 case SADB_EXT_LIFETIME_HARD: 2070 p->sadb_lifetime_allocations = l_alloc; 2071 p->sadb_lifetime_bytes = l_bytes; 2072 p->sadb_lifetime_addtime = l_addtime; 2073 p->sadb_lifetime_usetime = l_usetime; 2074 break; 2075 } 2076 2077 return buf + len; 2078} 2079 2080/* 2081 * copy secasvar data into sadb_address. 2082 * `buf' must has been allocated sufficiently. 2083 */ 2084static caddr_t
|
1575pfkey_setsadbxsa2(buf, mode0, reqid)
| 2085pfkey_setsadbxsa2(buf, lim, mode0, reqid)
|
1576 caddr_t buf;
| 2086 caddr_t buf;
|
| 2087 caddr_t lim;
|
1577 u_int32_t mode0; 1578 u_int32_t reqid; 1579{ 1580 struct sadb_x_sa2 *p; 1581 u_int8_t mode = mode0 & 0xff; 1582 u_int len; 1583 1584 p = (struct sadb_x_sa2 *)buf; 1585 len = sizeof(struct sadb_x_sa2); 1586
| 2088 u_int32_t mode0; 2089 u_int32_t reqid; 2090{ 2091 struct sadb_x_sa2 *p; 2092 u_int8_t mode = mode0 & 0xff; 2093 u_int len; 2094 2095 p = (struct sadb_x_sa2 *)buf; 2096 len = sizeof(struct sadb_x_sa2); 2097
|
| 2098 if (buf + len > lim) 2099 return NULL; 2100
|
1587 memset(p, 0, len); 1588 p->sadb_x_sa2_len = PFKEY_UNIT64(len); 1589 p->sadb_x_sa2_exttype = SADB_X_EXT_SA2; 1590 p->sadb_x_sa2_mode = mode; 1591 p->sadb_x_sa2_reqid = reqid; 1592 1593 return(buf + len); 1594}
| 2101 memset(p, 0, len); 2102 p->sadb_x_sa2_len = PFKEY_UNIT64(len); 2103 p->sadb_x_sa2_exttype = SADB_X_EXT_SA2; 2104 p->sadb_x_sa2_mode = mode; 2105 p->sadb_x_sa2_reqid = reqid; 2106 2107 return(buf + len); 2108}
|
1595
| |
| |