1 /* $FreeBSD$ */ 2 /* $KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $ */ 3 4 /*- 5 * SPDX-License-Identifier: BSD-3-Clause 6 * 7 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the project nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include "opt_ipsec.h" 36 37 /* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */ 38 39 #include <sys/types.h> 40 #include <sys/param.h> 41 #include <sys/domain.h> 42 #include <sys/errno.h> 43 #include <sys/kernel.h> 44 #include <sys/lock.h> 45 #include <sys/malloc.h> 46 #include <sys/mbuf.h> 47 #include <sys/mutex.h> 48 #include <sys/priv.h> 49 #include <sys/protosw.h> 50 #include <sys/signalvar.h> 51 #include <sys/socket.h> 52 #include <sys/socketvar.h> 53 #include <sys/sysctl.h> 54 #include <sys/systm.h> 55 56 #include <net/if.h> 57 #include <net/vnet.h> 58 #include <net/raw_cb.h> 59 60 #include <netinet/in.h> 61 62 #include <net/pfkeyv2.h> 63 #include <netipsec/key.h> 64 #include <netipsec/keysock.h> 65 #include <netipsec/key_debug.h> 66 #include <netipsec/ipsec.h> 67 68 #include <machine/stdarg.h> 69 70 struct key_cb { 71 int key_count; 72 int any_count; 73 }; 74 static VNET_DEFINE(struct key_cb, key_cb); 75 #define V_key_cb VNET(key_cb) 76 77 static struct sockaddr key_src = { 2, PF_KEY, }; 78 79 static int key_sendup0(struct rawcb *, struct mbuf *, int); 80 81 VNET_PCPUSTAT_DEFINE(struct pfkeystat, pfkeystat); 82 VNET_PCPUSTAT_SYSINIT(pfkeystat); 83 84 #ifdef VIMAGE 85 VNET_PCPUSTAT_SYSUNINIT(pfkeystat); 86 #endif /* VIMAGE */ 87 88 /* 89 * key_output() 90 */ 91 int 92 key_output(struct mbuf *m, struct socket *so, ...) 93 { 94 struct sadb_msg *msg; 95 int len, error = 0; 96 97 if (m == NULL) 98 panic("%s: NULL pointer was passed.\n", __func__); 99 100 PFKEYSTAT_INC(out_total); 101 PFKEYSTAT_ADD(out_bytes, m->m_pkthdr.len); 102 103 len = m->m_pkthdr.len; 104 if (len < sizeof(struct sadb_msg)) { 105 PFKEYSTAT_INC(out_tooshort); 106 error = EINVAL; 107 goto end; 108 } 109 110 if (m->m_len < sizeof(struct sadb_msg)) { 111 if ((m = m_pullup(m, sizeof(struct sadb_msg))) == NULL) { 112 PFKEYSTAT_INC(out_nomem); 113 error = ENOBUFS; 114 goto end; 115 } 116 } 117 118 M_ASSERTPKTHDR(m); 119 120 KEYDBG(KEY_DUMP, kdebug_mbuf(m)); 121 122 msg = mtod(m, struct sadb_msg *); 123 PFKEYSTAT_INC(out_msgtype[msg->sadb_msg_type]); 124 if (len != PFKEY_UNUNIT64(msg->sadb_msg_len)) { 125 PFKEYSTAT_INC(out_invlen); 126 error = EINVAL; 127 goto end; 128 } 129 130 error = key_parse(m, so); 131 m = NULL; 132 end: 133 if (m) 134 m_freem(m); 135 return error; 136 } 137 138 /* 139 * send message to the socket. 140 */ 141 static int 142 key_sendup0(struct rawcb *rp, struct mbuf *m, int promisc) 143 { 144 int error; 145 146 if (promisc) { 147 struct sadb_msg *pmsg; 148 149 M_PREPEND(m, sizeof(struct sadb_msg), M_NOWAIT); 150 if (m == NULL) { 151 PFKEYSTAT_INC(in_nomem); 152 return (ENOBUFS); 153 } 154 pmsg = mtod(m, struct sadb_msg *); 155 bzero(pmsg, sizeof(*pmsg)); 156 pmsg->sadb_msg_version = PF_KEY_V2; 157 pmsg->sadb_msg_type = SADB_X_PROMISC; 158 pmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len); 159 /* pid and seq? */ 160 161 PFKEYSTAT_INC(in_msgtype[pmsg->sadb_msg_type]); 162 } 163 164 if (!sbappendaddr(&rp->rcb_socket->so_rcv, (struct sockaddr *)&key_src, 165 m, NULL)) { 166 PFKEYSTAT_INC(in_nomem); 167 m_freem(m); 168 error = ENOBUFS; 169 } else 170 error = 0; 171 sorwakeup(rp->rcb_socket); 172 return error; 173 } 174 175 /* so can be NULL if target != KEY_SENDUP_ONE */ 176 int 177 key_sendup_mbuf(struct socket *so, struct mbuf *m, int target) 178 { 179 struct mbuf *n; 180 struct keycb *kp; 181 struct rawcb *rp; 182 int error = 0; 183 184 KASSERT(m != NULL, ("NULL mbuf pointer was passed.")); 185 KASSERT(so != NULL || target != KEY_SENDUP_ONE, 186 ("NULL socket pointer was passed.")); 187 KASSERT(target == KEY_SENDUP_ONE || target == KEY_SENDUP_ALL || 188 target == KEY_SENDUP_REGISTERED, ("Wrong target %d", target)); 189 190 PFKEYSTAT_INC(in_total); 191 PFKEYSTAT_ADD(in_bytes, m->m_pkthdr.len); 192 if (m->m_len < sizeof(struct sadb_msg)) { 193 m = m_pullup(m, sizeof(struct sadb_msg)); 194 if (m == NULL) { 195 PFKEYSTAT_INC(in_nomem); 196 return ENOBUFS; 197 } 198 } 199 if (m->m_len >= sizeof(struct sadb_msg)) { 200 struct sadb_msg *msg; 201 msg = mtod(m, struct sadb_msg *); 202 PFKEYSTAT_INC(in_msgtype[msg->sadb_msg_type]); 203 } 204 mtx_lock(&rawcb_mtx); 205 if (V_key_cb.any_count == 0) { 206 mtx_unlock(&rawcb_mtx); 207 m_freem(m); 208 return (0); 209 } 210 LIST_FOREACH(rp, &V_rawcb_list, list) 211 { 212 if (rp->rcb_proto.sp_family != PF_KEY) 213 continue; 214 if (rp->rcb_proto.sp_protocol 215 && rp->rcb_proto.sp_protocol != PF_KEY_V2) { 216 continue; 217 } 218 219 /* 220 * If you are in promiscuous mode, and when you get broadcasted 221 * reply, you'll get two PF_KEY messages. 222 * (based on pf_key@inner.net message on 14 Oct 1998) 223 */ 224 kp = (struct keycb *)rp; 225 if (kp->kp_promisc) { 226 n = m_copym(m, 0, M_COPYALL, M_NOWAIT); 227 if (n != NULL) 228 key_sendup0(rp, n, 1); 229 else 230 PFKEYSTAT_INC(in_nomem); 231 } 232 233 /* the exact target will be processed later */ 234 if (so && sotorawcb(so) == rp) 235 continue; 236 237 if (target == KEY_SENDUP_ONE || ( 238 target == KEY_SENDUP_REGISTERED && kp->kp_registered == 0)) 239 continue; 240 241 /* KEY_SENDUP_ALL + KEY_SENDUP_REGISTERED */ 242 n = m_copym(m, 0, M_COPYALL, M_NOWAIT); 243 if (n == NULL) { 244 PFKEYSTAT_INC(in_nomem); 245 /* Try send to another socket */ 246 continue; 247 } 248 249 if (key_sendup0(rp, n, 0) == 0) 250 PFKEYSTAT_INC(in_msgtarget[target]); 251 } 252 253 if (so) { /* KEY_SENDUP_ONE */ 254 error = key_sendup0(sotorawcb(so), m, 0); 255 if (error == 0) 256 PFKEYSTAT_INC(in_msgtarget[KEY_SENDUP_ONE]); 257 } else { 258 error = 0; 259 m_freem(m); 260 } 261 mtx_unlock(&rawcb_mtx); 262 return (error); 263 } 264 265 /* 266 * key_abort() 267 * derived from net/rtsock.c:rts_abort() 268 */ 269 static void 270 key_abort(struct socket *so) 271 { 272 raw_usrreqs.pru_abort(so); 273 } 274 275 /* 276 * key_attach() 277 * derived from net/rtsock.c:rts_attach() 278 */ 279 static int 280 key_attach(struct socket *so, int proto, struct thread *td) 281 { 282 struct keycb *kp; 283 int error; 284 285 KASSERT(so->so_pcb == NULL, ("key_attach: so_pcb != NULL")); 286 287 if (td != NULL) { 288 error = priv_check(td, PRIV_NET_RAW); 289 if (error) 290 return error; 291 } 292 293 /* XXX */ 294 kp = malloc(sizeof *kp, M_PCB, M_WAITOK | M_ZERO); 295 if (kp == NULL) 296 return ENOBUFS; 297 298 so->so_pcb = (caddr_t)kp; 299 error = raw_attach(so, proto); 300 kp = (struct keycb *)sotorawcb(so); 301 if (error) { 302 free(kp, M_PCB); 303 so->so_pcb = (caddr_t) 0; 304 return error; 305 } 306 307 kp->kp_promisc = kp->kp_registered = 0; 308 309 if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */ 310 V_key_cb.key_count++; 311 V_key_cb.any_count++; 312 soisconnected(so); 313 so->so_options |= SO_USELOOPBACK; 314 315 return 0; 316 } 317 318 /* 319 * key_bind() 320 * derived from net/rtsock.c:rts_bind() 321 */ 322 static int 323 key_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 324 { 325 return EINVAL; 326 } 327 328 /* 329 * key_close() 330 * derived from net/rtsock.c:rts_close(). 331 */ 332 static void 333 key_close(struct socket *so) 334 { 335 336 raw_usrreqs.pru_close(so); 337 } 338 339 /* 340 * key_connect() 341 * derived from net/rtsock.c:rts_connect() 342 */ 343 static int 344 key_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 345 { 346 return EINVAL; 347 } 348 349 /* 350 * key_detach() 351 * derived from net/rtsock.c:rts_detach() 352 */ 353 static void 354 key_detach(struct socket *so) 355 { 356 struct keycb *kp = (struct keycb *)sotorawcb(so); 357 358 KASSERT(kp != NULL, ("key_detach: kp == NULL")); 359 if (kp->kp_raw.rcb_proto.sp_protocol 360 == PF_KEY) /* XXX: AF_KEY */ 361 V_key_cb.key_count--; 362 V_key_cb.any_count--; 363 364 key_freereg(so); 365 raw_usrreqs.pru_detach(so); 366 } 367 368 /* 369 * key_disconnect() 370 * derived from net/rtsock.c:key_disconnect() 371 */ 372 static int 373 key_disconnect(struct socket *so) 374 { 375 return(raw_usrreqs.pru_disconnect(so)); 376 } 377 378 /* 379 * key_peeraddr() 380 * derived from net/rtsock.c:rts_peeraddr() 381 */ 382 static int 383 key_peeraddr(struct socket *so, struct sockaddr **nam) 384 { 385 return(raw_usrreqs.pru_peeraddr(so, nam)); 386 } 387 388 /* 389 * key_send() 390 * derived from net/rtsock.c:rts_send() 391 */ 392 static int 393 key_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, 394 struct mbuf *control, struct thread *td) 395 { 396 return(raw_usrreqs.pru_send(so, flags, m, nam, control, td)); 397 } 398 399 /* 400 * key_shutdown() 401 * derived from net/rtsock.c:rts_shutdown() 402 */ 403 static int 404 key_shutdown(struct socket *so) 405 { 406 return(raw_usrreqs.pru_shutdown(so)); 407 } 408 409 /* 410 * key_sockaddr() 411 * derived from net/rtsock.c:rts_sockaddr() 412 */ 413 static int 414 key_sockaddr(struct socket *so, struct sockaddr **nam) 415 { 416 return(raw_usrreqs.pru_sockaddr(so, nam)); 417 } 418 419 struct pr_usrreqs key_usrreqs = { 420 .pru_abort = key_abort, 421 .pru_attach = key_attach, 422 .pru_bind = key_bind, 423 .pru_connect = key_connect, 424 .pru_detach = key_detach, 425 .pru_disconnect = key_disconnect, 426 .pru_peeraddr = key_peeraddr, 427 .pru_send = key_send, 428 .pru_shutdown = key_shutdown, 429 .pru_sockaddr = key_sockaddr, 430 .pru_close = key_close, 431 }; 432 433 /* sysctl */ 434 SYSCTL_NODE(_net, PF_KEY, key, CTLFLAG_RW, 0, "Key Family"); 435 436 /* 437 * Definitions of protocols supported in the KEY domain. 438 */ 439 440 extern struct domain keydomain; 441 442 struct protosw keysw[] = { 443 { 444 .pr_type = SOCK_RAW, 445 .pr_domain = &keydomain, 446 .pr_protocol = PF_KEY_V2, 447 .pr_flags = PR_ATOMIC|PR_ADDR, 448 .pr_output = key_output, 449 .pr_ctlinput = raw_ctlinput, 450 .pr_init = raw_init, 451 .pr_usrreqs = &key_usrreqs 452 } 453 }; 454 455 static void 456 key_init0(void) 457 { 458 459 bzero((caddr_t)&V_key_cb, sizeof(V_key_cb)); 460 key_init(); 461 } 462 463 struct domain keydomain = { 464 .dom_family = PF_KEY, 465 .dom_name = "key", 466 .dom_init = key_init0, 467 #ifdef VIMAGE 468 .dom_destroy = key_destroy, 469 #endif 470 .dom_protosw = keysw, 471 .dom_protoswNPROTOSW = &keysw[nitems(keysw)] 472 }; 473 474 VNET_DOMAIN_SET(key); 475