xref: /freebsd/sys/netipsec/keysock.c (revision 3f2e28fe9ffbb70d26e5cc7abba248e981434853)
1 /*	$FreeBSD$	*/
2 /*	$KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $	*/
3 
4 /*-
5  * Copyright (C) 1995, 1996, 1997, and 1998 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 "opt_ipsec.h"
34 
35 /* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */
36 
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/domain.h>
40 #include <sys/errno.h>
41 #include <sys/kernel.h>
42 #include <sys/lock.h>
43 #include <sys/malloc.h>
44 #include <sys/mbuf.h>
45 #include <sys/mutex.h>
46 #include <sys/protosw.h>
47 #include <sys/signalvar.h>
48 #include <sys/socket.h>
49 #include <sys/socketvar.h>
50 #include <sys/sysctl.h>
51 #include <sys/systm.h>
52 
53 #include <net/raw_cb.h>
54 #include <net/route.h>
55 
56 #include <net/pfkeyv2.h>
57 #include <netipsec/key.h>
58 #include <netipsec/keysock.h>
59 #include <netipsec/key_debug.h>
60 
61 #include <machine/stdarg.h>
62 
63 struct key_cb {
64 	int key_count;
65 	int any_count;
66 };
67 static struct key_cb key_cb;
68 
69 static struct sockaddr key_dst = { 2, PF_KEY, };
70 static struct sockaddr key_src = { 2, PF_KEY, };
71 
72 static int key_sendup0 __P((struct rawcb *, struct mbuf *, int));
73 
74 struct pfkeystat pfkeystat;
75 
76 /*
77  * key_output()
78  */
79 int
80 key_output(struct mbuf *m, struct socket *so)
81 {
82 	struct sadb_msg *msg;
83 	int len, error = 0;
84 	int s;
85 
86 	if (m == 0)
87 		panic("%s: NULL pointer was passed.\n", __func__);
88 
89 	pfkeystat.out_total++;
90 	pfkeystat.out_bytes += m->m_pkthdr.len;
91 
92 	len = m->m_pkthdr.len;
93 	if (len < sizeof(struct sadb_msg)) {
94 		pfkeystat.out_tooshort++;
95 		error = EINVAL;
96 		goto end;
97 	}
98 
99 	if (m->m_len < sizeof(struct sadb_msg)) {
100 		if ((m = m_pullup(m, sizeof(struct sadb_msg))) == 0) {
101 			pfkeystat.out_nomem++;
102 			error = ENOBUFS;
103 			goto end;
104 		}
105 	}
106 
107 	M_ASSERTPKTHDR(m);
108 
109 	KEYDEBUG(KEYDEBUG_KEY_DUMP, kdebug_mbuf(m));
110 
111 	msg = mtod(m, struct sadb_msg *);
112 	pfkeystat.out_msgtype[msg->sadb_msg_type]++;
113 	if (len != PFKEY_UNUNIT64(msg->sadb_msg_len)) {
114 		pfkeystat.out_invlen++;
115 		error = EINVAL;
116 		goto end;
117 	}
118 
119 	/*XXX giant lock*/
120 	s = splnet();
121 	error = key_parse(m, so);
122 	m = NULL;
123 	splx(s);
124 end:
125 	if (m)
126 		m_freem(m);
127 	return error;
128 }
129 
130 /*
131  * send message to the socket.
132  */
133 static int
134 key_sendup0(rp, m, promisc)
135 	struct rawcb *rp;
136 	struct mbuf *m;
137 	int promisc;
138 {
139 	int error;
140 
141 	if (promisc) {
142 		struct sadb_msg *pmsg;
143 
144 		M_PREPEND(m, sizeof(struct sadb_msg), M_DONTWAIT);
145 		if (m && m->m_len < sizeof(struct sadb_msg))
146 			m = m_pullup(m, sizeof(struct sadb_msg));
147 		if (!m) {
148 			pfkeystat.in_nomem++;
149 			m_freem(m);
150 			return ENOBUFS;
151 		}
152 		m->m_pkthdr.len += sizeof(*pmsg);
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.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.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 /* XXX this interface should be obsoleted. */
176 int
177 key_sendup(so, msg, len, target)
178 	struct socket *so;
179 	struct sadb_msg *msg;
180 	u_int len;
181 	int target;	/*target of the resulting message*/
182 {
183 	struct mbuf *m, *n, *mprev;
184 	int tlen;
185 
186 	/* sanity check */
187 	if (so == 0 || msg == 0)
188 		panic("%s: NULL pointer was passed.\n", __func__);
189 
190 	KEYDEBUG(KEYDEBUG_KEY_DUMP,
191 		printf("%s: \n", __func__);
192 		kdebug_sadb(msg));
193 
194 	/*
195 	 * we increment statistics here, just in case we have ENOBUFS
196 	 * in this function.
197 	 */
198 	pfkeystat.in_total++;
199 	pfkeystat.in_bytes += len;
200 	pfkeystat.in_msgtype[msg->sadb_msg_type]++;
201 
202 	/*
203 	 * Get mbuf chain whenever possible (not clusters),
204 	 * to save socket buffer.  We'll be generating many SADB_ACQUIRE
205 	 * messages to listening key sockets.  If we simply allocate clusters,
206 	 * sbappendaddr() will raise ENOBUFS due to too little sbspace().
207 	 * sbspace() computes # of actual data bytes AND mbuf region.
208 	 *
209 	 * TODO: SADB_ACQUIRE filters should be implemented.
210 	 */
211 	tlen = len;
212 	m = mprev = NULL;
213 	while (tlen > 0) {
214 		if (tlen == len) {
215 			MGETHDR(n, M_DONTWAIT, MT_DATA);
216 			n->m_len = MHLEN;
217 		} else {
218 			MGET(n, M_DONTWAIT, MT_DATA);
219 			n->m_len = MLEN;
220 		}
221 		if (!n) {
222 			pfkeystat.in_nomem++;
223 			return ENOBUFS;
224 		}
225 		if (tlen >= MCLBYTES) {	/*XXX better threshold? */
226 			MCLGET(n, M_DONTWAIT);
227 			if ((n->m_flags & M_EXT) == 0) {
228 				m_free(n);
229 				m_freem(m);
230 				pfkeystat.in_nomem++;
231 				return ENOBUFS;
232 			}
233 			n->m_len = MCLBYTES;
234 		}
235 
236 		if (tlen < n->m_len)
237 			n->m_len = tlen;
238 		n->m_next = NULL;
239 		if (m == NULL)
240 			m = mprev = n;
241 		else {
242 			mprev->m_next = n;
243 			mprev = n;
244 		}
245 		tlen -= n->m_len;
246 		n = NULL;
247 	}
248 	m->m_pkthdr.len = len;
249 	m->m_pkthdr.rcvif = NULL;
250 	m_copyback(m, 0, len, (caddr_t)msg);
251 
252 	/* avoid duplicated statistics */
253 	pfkeystat.in_total--;
254 	pfkeystat.in_bytes -= len;
255 	pfkeystat.in_msgtype[msg->sadb_msg_type]--;
256 
257 	return key_sendup_mbuf(so, m, target);
258 }
259 
260 /* so can be NULL if target != KEY_SENDUP_ONE */
261 int
262 key_sendup_mbuf(so, m, target)
263 	struct socket *so;
264 	struct mbuf *m;
265 	int target;
266 {
267 	struct mbuf *n;
268 	struct keycb *kp;
269 	int sendup;
270 	struct rawcb *rp;
271 	int error = 0;
272 
273 	if (m == NULL)
274 		panic("key_sendup_mbuf: NULL pointer was passed.\n");
275 	if (so == NULL && target == KEY_SENDUP_ONE)
276 		panic("%s: NULL pointer was passed.\n", __func__);
277 
278 	pfkeystat.in_total++;
279 	pfkeystat.in_bytes += m->m_pkthdr.len;
280 	if (m->m_len < sizeof(struct sadb_msg)) {
281 #if 1
282 		m = m_pullup(m, sizeof(struct sadb_msg));
283 		if (m == NULL) {
284 			pfkeystat.in_nomem++;
285 			return ENOBUFS;
286 		}
287 #else
288 		/* don't bother pulling it up just for stats */
289 #endif
290 	}
291 	if (m->m_len >= sizeof(struct sadb_msg)) {
292 		struct sadb_msg *msg;
293 		msg = mtod(m, struct sadb_msg *);
294 		pfkeystat.in_msgtype[msg->sadb_msg_type]++;
295 	}
296 
297 	LIST_FOREACH(rp, &rawcb_list, list)
298 	{
299 		if (rp->rcb_proto.sp_family != PF_KEY)
300 			continue;
301 		if (rp->rcb_proto.sp_protocol
302 		 && rp->rcb_proto.sp_protocol != PF_KEY_V2) {
303 			continue;
304 		}
305 
306 		kp = (struct keycb *)rp;
307 
308 		/*
309 		 * If you are in promiscuous mode, and when you get broadcasted
310 		 * reply, you'll get two PF_KEY messages.
311 		 * (based on pf_key@inner.net message on 14 Oct 1998)
312 		 */
313 		if (((struct keycb *)rp)->kp_promisc) {
314 			if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
315 				(void)key_sendup0(rp, n, 1);
316 				n = NULL;
317 			}
318 		}
319 
320 		/* the exact target will be processed later */
321 		if (so && sotorawcb(so) == rp)
322 			continue;
323 
324 		sendup = 0;
325 		switch (target) {
326 		case KEY_SENDUP_ONE:
327 			/* the statement has no effect */
328 			if (so && sotorawcb(so) == rp)
329 				sendup++;
330 			break;
331 		case KEY_SENDUP_ALL:
332 			sendup++;
333 			break;
334 		case KEY_SENDUP_REGISTERED:
335 			if (kp->kp_registered)
336 				sendup++;
337 			break;
338 		}
339 		pfkeystat.in_msgtarget[target]++;
340 
341 		if (!sendup)
342 			continue;
343 
344 		if ((n = m_copy(m, 0, (int)M_COPYALL)) == NULL) {
345 			m_freem(m);
346 			pfkeystat.in_nomem++;
347 			return ENOBUFS;
348 		}
349 
350 		if ((error = key_sendup0(rp, n, 0)) != 0) {
351 			m_freem(m);
352 			return error;
353 		}
354 
355 		n = NULL;
356 	}
357 
358 	if (so) {
359 		error = key_sendup0(sotorawcb(so), m, 0);
360 		m = NULL;
361 	} else {
362 		error = 0;
363 		m_freem(m);
364 	}
365 	return error;
366 }
367 
368 /*
369  * key_abort()
370  * derived from net/rtsock.c:rts_abort()
371  */
372 static int
373 key_abort(struct socket *so)
374 {
375 	int s, error;
376 	s = splnet();
377 	error = raw_usrreqs.pru_abort(so);
378 	splx(s);
379 	return error;
380 }
381 
382 /*
383  * key_attach()
384  * derived from net/rtsock.c:rts_attach()
385  */
386 static int
387 key_attach(struct socket *so, int proto, struct thread *td)
388 {
389 	struct keycb *kp;
390 	int s, error;
391 
392 	if (sotorawcb(so) != 0)
393 		return EISCONN;	/* XXX panic? */
394 	kp = (struct keycb *)malloc(sizeof *kp, M_PCB, M_WAITOK|M_ZERO); /* XXX */
395 	if (kp == 0)
396 		return ENOBUFS;
397 
398 	/*
399 	 * The splnet() is necessary to block protocols from sending
400 	 * error notifications (like RTM_REDIRECT or RTM_LOSING) while
401 	 * this PCB is extant but incompletely initialized.
402 	 * Probably we should try to do more of this work beforehand and
403 	 * eliminate the spl.
404 	 */
405 	s = splnet();
406 	so->so_pcb = (caddr_t)kp;
407 	error = raw_usrreqs.pru_attach(so, proto, td);
408 	kp = (struct keycb *)sotorawcb(so);
409 	if (error) {
410 		free(kp, M_PCB);
411 		so->so_pcb = (caddr_t) 0;
412 		splx(s);
413 		return error;
414 	}
415 
416 	kp->kp_promisc = kp->kp_registered = 0;
417 
418 	if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */
419 		key_cb.key_count++;
420 	key_cb.any_count++;
421 	kp->kp_raw.rcb_laddr = &key_src;
422 	kp->kp_raw.rcb_faddr = &key_dst;
423 	soisconnected(so);
424 	so->so_options |= SO_USELOOPBACK;
425 
426 	splx(s);
427 	return 0;
428 }
429 
430 /*
431  * key_bind()
432  * derived from net/rtsock.c:rts_bind()
433  */
434 static int
435 key_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
436 {
437 	int s, error;
438 	s = splnet();
439 	error = raw_usrreqs.pru_bind(so, nam, td); /* xxx just EINVAL */
440 	splx(s);
441 	return error;
442 }
443 
444 /*
445  * key_connect()
446  * derived from net/rtsock.c:rts_connect()
447  */
448 static int
449 key_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
450 {
451 	int s, error;
452 	s = splnet();
453 	error = raw_usrreqs.pru_connect(so, nam, td); /* XXX just EINVAL */
454 	splx(s);
455 	return error;
456 }
457 
458 /*
459  * key_detach()
460  * derived from net/rtsock.c:rts_detach()
461  */
462 static int
463 key_detach(struct socket *so)
464 {
465 	struct keycb *kp = (struct keycb *)sotorawcb(so);
466 	int s, error;
467 
468 	s = splnet();
469 	if (kp != 0) {
470 		if (kp->kp_raw.rcb_proto.sp_protocol
471 		    == PF_KEY) /* XXX: AF_KEY */
472 			key_cb.key_count--;
473 		key_cb.any_count--;
474 
475 		key_freereg(so);
476 	}
477 	error = raw_usrreqs.pru_detach(so);
478 	splx(s);
479 	return error;
480 }
481 
482 /*
483  * key_disconnect()
484  * derived from net/rtsock.c:key_disconnect()
485  */
486 static int
487 key_disconnect(struct socket *so)
488 {
489 	int s, error;
490 	s = splnet();
491 	error = raw_usrreqs.pru_disconnect(so);
492 	splx(s);
493 	return error;
494 }
495 
496 /*
497  * key_peeraddr()
498  * derived from net/rtsock.c:rts_peeraddr()
499  */
500 static int
501 key_peeraddr(struct socket *so, struct sockaddr **nam)
502 {
503 	int s, error;
504 	s = splnet();
505 	error = raw_usrreqs.pru_peeraddr(so, nam);
506 	splx(s);
507 	return error;
508 }
509 
510 /*
511  * key_send()
512  * derived from net/rtsock.c:rts_send()
513  */
514 static int
515 key_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
516 	 struct mbuf *control, struct thread *td)
517 {
518 	int s, error;
519 	s = splnet();
520 	error = raw_usrreqs.pru_send(so, flags, m, nam, control, td);
521 	splx(s);
522 	return error;
523 }
524 
525 /*
526  * key_shutdown()
527  * derived from net/rtsock.c:rts_shutdown()
528  */
529 static int
530 key_shutdown(struct socket *so)
531 {
532 	int s, error;
533 	s = splnet();
534 	error = raw_usrreqs.pru_shutdown(so);
535 	splx(s);
536 	return error;
537 }
538 
539 /*
540  * key_sockaddr()
541  * derived from net/rtsock.c:rts_sockaddr()
542  */
543 static int
544 key_sockaddr(struct socket *so, struct sockaddr **nam)
545 {
546 	int s, error;
547 	s = splnet();
548 	error = raw_usrreqs.pru_sockaddr(so, nam);
549 	splx(s);
550 	return error;
551 }
552 
553 struct pr_usrreqs key_usrreqs = {
554 	.pru_abort =		key_abort,
555 	.pru_attach =		key_attach,
556 	.pru_bind =		key_bind,
557 	.pru_connect =		key_connect,
558 	.pru_detach =		key_detach,
559 	.pru_disconnect =	key_disconnect,
560 	.pru_peeraddr =		key_peeraddr,
561 	.pru_send =		key_send,
562 	.pru_shutdown =		key_shutdown,
563 	.pru_sockaddr =		key_sockaddr,
564 };
565 
566 /* sysctl */
567 SYSCTL_NODE(_net, PF_KEY, key, CTLFLAG_RW, 0, "Key Family");
568 
569 /*
570  * Definitions of protocols supported in the KEY domain.
571  */
572 
573 extern struct domain keydomain;
574 
575 struct protosw keysw[] = {
576 {
577 	.pr_type =		SOCK_RAW,
578 	.pr_domain =		&keydomain,
579 	.pr_protocol =		PF_KEY_V2,
580 	.pr_flags =		PR_ATOMIC|PR_ADDR,
581 	.pr_output =		key_output,
582 	.pr_ctlinput =		raw_ctlinput,
583 	.pr_init =		raw_init,
584 	.pr_usrreqs =		&key_usrreqs
585 }
586 };
587 
588 static void
589 key_init0(void)
590 {
591 	bzero((caddr_t)&key_cb, sizeof(key_cb));
592 	key_init();
593 }
594 
595 struct domain keydomain = {
596 	.dom_family =		PF_KEY,
597 	.dom_name =		"key",
598 	.dom_init =		key_init0,
599 	.dom_protosw =		keysw,
600 	.dom_protoswNPROTOSW =	&keysw[sizeof(keysw)/sizeof(keysw[0])]
601 };
602 
603 DOMAIN_SET(key);
604