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