xref: /openbsd-src/sys/net/pipex.c (revision 0b7734b3d77bb9b21afec6f4621cae6c805dbd45)
1 /*	$OpenBSD: pipex.c,v 1.87 2016/03/22 23:53:01 dlg Exp $	*/
2 
3 /*-
4  * Copyright (c) 2009 Internet Initiative Japan Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/mbuf.h>
32 #include <sys/socket.h>
33 #include <sys/ioctl.h>
34 #include <sys/select.h>
35 #include <sys/sysctl.h>
36 #include <sys/syslog.h>
37 #include <sys/conf.h>
38 #include <sys/time.h>
39 #include <sys/timeout.h>
40 #include <sys/kernel.h>
41 #include <sys/pool.h>
42 
43 #include <net/if.h>
44 #include <net/if_types.h>
45 #include <netinet/in.h>
46 #include <netinet/if_ether.h>
47 #include <net/if_dl.h>
48 
49 #include <net/radix.h>
50 #include <net/route.h>
51 #include <net/netisr.h>
52 #include <net/ppp_defs.h>
53 #include <net/ppp-comp.h>
54 
55 #include "pf.h"
56 #if NPF > 0
57 #include <net/pfvar.h>
58 #endif
59 
60 #include "bpfilter.h"
61 #if NBPFILTER > 0
62 #include <net/bpf.h>
63 #endif
64 
65 #include <netinet/ip.h>
66 #include <netinet/ip_var.h>
67 #ifdef INET6
68 #include <netinet/ip6.h>
69 #include <netinet6/ip6_var.h>
70 #endif
71 #include <netinet/tcp.h>
72 #include <netinet/udp.h>
73 #include <netinet/udp_var.h>
74 #include <crypto/arc4.h>
75 
76 /* drop static for ddb debuggability */
77 #define	Static
78 
79 #include <net/pipex.h>
80 #include "pipex_local.h"
81 
82 struct pool pipex_session_pool;
83 struct pool mppe_key_pool;
84 
85 /*
86  * static/global variables
87  */
88 int	pipex_enable = 0;
89 struct pipex_hash_head
90     pipex_session_list,				/* master session list */
91     pipex_close_wait_list,			/* expired session list */
92     pipex_peer_addr_hashtable[PIPEX_HASH_SIZE],	/* peer's address hash */
93     pipex_id_hashtable[PIPEX_HASH_SIZE]; 	/* peer id hash */
94 
95 struct radix_node_head pipex_rd_head4;
96 struct radix_node_head pipex_rd_head6;
97 int pipex_rd_head4_initialized;
98 int pipex_rd_head6_initialized;
99 struct timeout pipex_timer_ch; 		/* callout timer context */
100 int pipex_prune = 1;			/* walk list every seconds */
101 
102 /* pipex traffic queue */
103 struct mbuf_queue pipexinq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET);
104 struct mbuf_queue pipexoutq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET);
105 void *pipex_softintr = NULL;
106 Static void pipex_softintr_handler(void *);
107 
108 /* borrow an mbuf pkthdr field */
109 #define ph_ppp_proto ether_vtag
110 
111 /* from udp_usrreq.c */
112 extern int udpcksum;
113 
114 #ifdef PIPEX_DEBUG
115 int pipex_debug = 0;		/* systcl net.inet.ip.pipex_debug */
116 #endif
117 
118 /* PPP compression == MPPE is assumed, so don't answer CCP Reset-Request. */
119 #define PIPEX_NO_CCP_RESETACK	1
120 
121 /************************************************************************
122  * Core functions
123  ************************************************************************/
124 void
125 pipex_init(void)
126 {
127 	int		 i;
128 
129 	if (pipex_softintr != NULL)
130 		return;
131 
132 	rn_init(sizeof(struct sockaddr_in6));
133 
134 	pool_init(&pipex_session_pool, sizeof(struct pipex_session), 0, 0, 0,
135 	    "ppxss", NULL);
136 	pool_init(&mppe_key_pool, PIPEX_MPPE_KEYLEN * PIPEX_MPPE_NOLDKEY, 0, 0,
137 	    0, "mppekey", NULL);
138 
139 	LIST_INIT(&pipex_session_list);
140 	LIST_INIT(&pipex_close_wait_list);
141 
142 	for (i = 0; i < nitems(pipex_id_hashtable); i++)
143 		LIST_INIT(&pipex_id_hashtable[i]);
144 	for (i = 0; i < nitems(pipex_peer_addr_hashtable); i++)
145 		LIST_INIT(&pipex_peer_addr_hashtable[i]);
146 	/* softintr init */
147 	pipex_softintr =
148 	    softintr_establish(IPL_SOFTNET, pipex_softintr_handler, NULL);
149 }
150 
151 void
152 pipex_iface_init(struct pipex_iface_context *pipex_iface, struct ifnet *ifp)
153 {
154 	int s;
155 	struct pipex_session *session;
156 
157 	pipex_iface->pipexmode = 0;
158 	pipex_iface->ifnet_this = ifp;
159 
160 	s = splnet();
161 	if (!pipex_rd_head4_initialized) {
162 		pipex_rd_head4_initialized++;
163 		if (!rn_inithead0(&pipex_rd_head4,
164 		    offsetof(struct sockaddr_in, sin_addr)))
165 			panic("rn_inithead0() failed on pipex_init()");
166 	}
167 	if (!pipex_rd_head6_initialized) {
168 		pipex_rd_head6_initialized++;
169 		if (!rn_inithead0(&pipex_rd_head6,
170 		    offsetof(struct sockaddr_in6, sin6_addr)))
171 			panic("rn_inithead0() failed on pipex_init()");
172 	}
173 	splx(s);
174 
175 	/* virtual pipex_session entry for multicast */
176 	session = pool_get(&pipex_session_pool, PR_WAITOK | PR_ZERO);
177 	session->is_multicast = 1;
178 	session->pipex_iface = pipex_iface;
179 	pipex_iface->multicast_session = session;
180 }
181 
182 Static void
183 pipex_iface_start(struct pipex_iface_context *pipex_iface)
184 {
185 	pipex_iface->pipexmode = 1;
186 }
187 
188 Static void
189 pipex_iface_stop(struct pipex_iface_context *pipex_iface)
190 {
191 	struct pipex_session *session;
192 	struct pipex_session *session_next;
193 
194 	pipex_iface->pipexmode = 0;
195 	/*
196 	 * traversal all pipex sessions.
197 	 * it will become heavy if the number of pppac devices bocomes large.
198 	 */
199 	for (session = LIST_FIRST(&pipex_session_list);
200 	    session; session = session_next) {
201 		session_next = LIST_NEXT(session, session_list);
202 		if (session->pipex_iface == pipex_iface)
203 			pipex_destroy_session(session);
204 	}
205 }
206 
207 void
208 pipex_iface_fini(struct pipex_iface_context *pipex_iface)
209 {
210 	int	 s;
211 
212 	s = splnet();
213 
214 	pool_put(&pipex_session_pool, pipex_iface->multicast_session);
215 	pipex_iface_stop(pipex_iface);
216 
217 	splx(s);
218 }
219 
220 /* called from tunioctl() with splnet() */
221 int
222 pipex_ioctl(struct pipex_iface_context *pipex_iface, u_long cmd, caddr_t data)
223 {
224 	int pipexmode, ret;
225 
226 	switch (cmd) {
227 	case PIPEXSMODE:
228 		pipexmode = *(int *)data;
229 		if (pipex_iface->pipexmode != pipexmode) {
230 			if (pipexmode)
231 				pipex_iface_start(pipex_iface);
232 			else
233 				pipex_iface_stop(pipex_iface);
234 		}
235 		break;
236 
237 	case PIPEXGMODE:
238 		*(int *)data = pipex_iface->pipexmode;
239 		break;
240 
241 	case PIPEXASESSION:
242 		ret = pipex_add_session((struct pipex_session_req *)data,
243 		    pipex_iface);
244 		return (ret);
245 
246 	case PIPEXDSESSION:
247 		ret = pipex_close_session(
248 		    (struct pipex_session_close_req *)data);
249 		return (ret);
250 
251 	case PIPEXCSESSION:
252 		ret = pipex_config_session(
253 		    (struct pipex_session_config_req *)data);
254 		return (ret);
255 
256 	case PIPEXGSTAT:
257 		ret = pipex_get_stat((struct pipex_session_stat_req *)data);
258 		return (ret);
259 
260 	case PIPEXGCLOSED:
261 		ret = pipex_get_closed((struct pipex_session_list_req *)data);
262 		return (ret);
263 
264 	default:
265 		return (ENOTTY);
266 
267 	}
268 	return (0);
269 }
270 
271 /************************************************************************
272  * Session management functions
273  ************************************************************************/
274 Static int
275 pipex_add_session(struct pipex_session_req *req,
276     struct pipex_iface_context *iface)
277 {
278 	struct pipex_session *session;
279 	struct pipex_hash_head *chain;
280 	struct radix_node *rn;
281 	int s;
282 #ifdef PIPEX_PPPOE
283 	struct ifnet *over_ifp = NULL;
284 #endif
285 
286 	/* Checks requeted parameters.  */
287 	if (!iface->pipexmode)
288 		return (ENXIO);
289 	switch (req->pr_protocol) {
290 #ifdef PIPEX_PPPOE
291 	case PIPEX_PROTO_PPPOE:
292 		over_ifp = ifunit(req->pr_proto.pppoe.over_ifname);
293 		if (over_ifp == NULL)
294 			return (EINVAL);
295 		if (req->pr_peer_address.ss_family != AF_UNSPEC)
296 			return (EINVAL);
297 		break;
298 #endif
299 #if defined(PIPEX_L2TP) || defined(PIPEX_PPTP)
300 #ifdef PIPEX_PPTP
301 	case PIPEX_PROTO_PPTP:
302 #endif
303 #ifdef PIPEX_L2TP
304 	case PIPEX_PROTO_L2TP:
305 #endif
306 		switch (req->pr_peer_address.ss_family) {
307 		case AF_INET:
308 			if (req->pr_peer_address.ss_len !=
309 			    sizeof(struct sockaddr_in))
310 				return (EINVAL);
311 			break;
312 #ifdef INET6
313 		case AF_INET6:
314 			if (req->pr_peer_address.ss_len !=
315 			    sizeof(struct sockaddr_in6))
316 				return (EINVAL);
317 			break;
318 #endif
319 		default:
320 			return (EPROTONOSUPPORT);
321 		}
322 		if (req->pr_peer_address.ss_family !=
323 		    req->pr_local_address.ss_family ||
324 		    req->pr_peer_address.ss_len !=
325 		    req->pr_local_address.ss_len)
326 			return (EINVAL);
327 		break;
328 #endif
329 	default:
330 		return (EPROTONOSUPPORT);
331 	}
332 
333 	/* prepare a new session */
334 	session = pool_get(&pipex_session_pool, PR_WAITOK | PR_ZERO);
335 	session->state = PIPEX_STATE_OPENED;
336 	session->protocol = req->pr_protocol;
337 	session->session_id = req->pr_session_id;
338 	session->peer_session_id = req->pr_peer_session_id;
339 	session->peer_mru = req->pr_peer_mru;
340 	session->timeout_sec = req->pr_timeout_sec;
341 	session->pipex_iface = iface;
342 	session->ppp_flags = req->pr_ppp_flags;
343 	session->ppp_id = req->pr_ppp_id;
344 
345 	session->ip_forward = 1;
346 
347 	session->ip_address.sin_family = AF_INET;
348 	session->ip_address.sin_len = sizeof(struct sockaddr_in);
349 	session->ip_address.sin_addr = req->pr_ip_address;
350 
351 	session->ip_netmask.sin_family = AF_INET;
352 	session->ip_netmask.sin_len = sizeof(struct sockaddr_in);
353 	session->ip_netmask.sin_addr = req->pr_ip_netmask;
354 
355 	if (session->ip_netmask.sin_addr.s_addr == 0L)
356 		session->ip_netmask.sin_addr.s_addr = 0xffffffffL;
357 	session->ip_address.sin_addr.s_addr &=
358 	    session->ip_netmask.sin_addr.s_addr;
359 
360 	if (req->pr_peer_address.ss_len > 0)
361 		memcpy(&session->peer, &req->pr_peer_address,
362 		    MIN(req->pr_peer_address.ss_len, sizeof(session->peer)));
363 	if (req->pr_local_address.ss_len > 0)
364 		memcpy(&session->local, &req->pr_local_address,
365 		    MIN(req->pr_local_address.ss_len, sizeof(session->local)));
366 #ifdef PIPEX_PPPOE
367 	if (req->pr_protocol == PIPEX_PROTO_PPPOE)
368 		session->proto.pppoe.over_ifp = over_ifp;
369 #endif
370 #ifdef PIPEX_PPTP
371 	if (req->pr_protocol == PIPEX_PROTO_PPTP) {
372 		struct pipex_pptp_session *sess_pptp = &session->proto.pptp;
373 
374 		sess_pptp->snd_gap = 0;
375 		sess_pptp->rcv_gap = 0;
376 		sess_pptp->snd_una = req->pr_proto.pptp.snd_una;
377 		sess_pptp->snd_nxt = req->pr_proto.pptp.snd_nxt;
378 		sess_pptp->rcv_nxt = req->pr_proto.pptp.rcv_nxt;
379 		sess_pptp->rcv_acked = req->pr_proto.pptp.rcv_acked;
380 
381 		sess_pptp->winsz = req->pr_proto.pptp.winsz;
382 		sess_pptp->maxwinsz = req->pr_proto.pptp.maxwinsz;
383 		sess_pptp->peer_maxwinsz = req->pr_proto.pptp.peer_maxwinsz;
384 		/* last ack number */
385 		sess_pptp->ul_snd_una = sess_pptp->snd_una - 1;
386 	}
387 #endif
388 #ifdef PIPEX_L2TP
389 	if (req->pr_protocol == PIPEX_PROTO_L2TP) {
390 		struct pipex_l2tp_session *sess_l2tp = &session->proto.l2tp;
391 
392 		/* session keys */
393 		sess_l2tp->tunnel_id = req->pr_proto.l2tp.tunnel_id;
394 		sess_l2tp->peer_tunnel_id = req->pr_proto.l2tp.peer_tunnel_id;
395 
396 		/* protocol options */
397 		sess_l2tp->option_flags = req->pr_proto.l2tp.option_flags;
398 
399 		/* initial state of dynamic context */
400 		sess_l2tp->ns_gap = sess_l2tp->nr_gap = 0;
401 		sess_l2tp->ns_nxt = req->pr_proto.l2tp.ns_nxt;
402 		sess_l2tp->nr_nxt = req->pr_proto.l2tp.nr_nxt;
403 		sess_l2tp->ns_una = req->pr_proto.l2tp.ns_una;
404 		sess_l2tp->nr_acked = req->pr_proto.l2tp.nr_acked;
405 		/* last ack number */
406 		sess_l2tp->ul_ns_una = sess_l2tp->ns_una - 1;
407 		sess_l2tp->ipsecflowinfo = req->pr_proto.l2tp.ipsecflowinfo;
408 	}
409 #endif
410 #ifdef PIPEX_MPPE
411 	if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_ACCEPTED) != 0) {
412 		if (req->pr_mppe_recv.keylenbits <= 0) {
413 			pool_put(&pipex_session_pool, session);
414 			return (EINVAL);
415 		}
416 		pipex_session_init_mppe_recv(session,
417 		    req->pr_mppe_recv.stateless, req->pr_mppe_recv.keylenbits,
418 		    req->pr_mppe_recv.master_key);
419 	}
420 	if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_ENABLED) != 0) {
421 		if (req->pr_mppe_send.keylenbits <= 0) {
422 			pool_put(&pipex_session_pool, session);
423 			return (EINVAL);
424 		}
425 		pipex_session_init_mppe_send(session,
426 		    req->pr_mppe_send.stateless, req->pr_mppe_send.keylenbits,
427 		    req->pr_mppe_send.master_key);
428 	}
429 
430 	if (pipex_session_is_mppe_required(session)) {
431 		if (!pipex_session_is_mppe_enabled(session) ||
432 		    !pipex_session_is_mppe_accepted(session)) {
433 			pool_put(&pipex_session_pool, session);
434 			return (EINVAL);
435 		}
436 	}
437 #endif
438 
439 	/* commit the session */
440 	s = splnet();
441 	if (!in_nullhost(session->ip_address.sin_addr)) {
442 		if (pipex_lookup_by_ip_address(session->ip_address.sin_addr)
443 		    != NULL) {
444 			splx(s);
445 			pool_put(&pipex_session_pool, session);
446 			return (EADDRINUSE);
447 		}
448 
449 		rn = rn_addroute(&session->ip_address, &session->ip_netmask,
450 		    &pipex_rd_head4, session->ps4_rn, RTP_STATIC);
451 		if (rn == NULL) {
452 			splx(s);
453 			pool_put(&pipex_session_pool, session);
454 			return (ENOMEM);
455 		}
456 	}
457 	if (0) { /* NOT YET */
458 		rn = rn_addroute(&session->ip6_address, &session->ip6_prefixlen,
459 		    &pipex_rd_head6, session->ps6_rn, RTP_STATIC);
460 		if (rn == NULL) {
461 			splx(s);
462 			pool_put(&pipex_session_pool, session);
463 			return (ENOMEM);
464 		}
465 	}
466 
467 	chain = PIPEX_ID_HASHTABLE(session->session_id);
468 	LIST_INSERT_HEAD(chain, session, id_chain);
469 	LIST_INSERT_HEAD(&pipex_session_list, session, session_list);
470 	switch (req->pr_protocol) {
471 	case PIPEX_PROTO_PPTP:
472 	case PIPEX_PROTO_L2TP:
473 		chain = PIPEX_PEER_ADDR_HASHTABLE(
474 		    pipex_sockaddr_hash_key((struct sockaddr *)&session->peer));
475 		LIST_INSERT_HEAD(chain, session, peer_addr_chain);
476 	}
477 
478 	/* if first session is added, start timer */
479 	if (LIST_NEXT(session, session_list) == NULL)
480 		pipex_timer_start();
481 
482 	splx(s);
483 
484 	pipex_session_log(session, LOG_INFO, "PIPEX is ready.");
485 
486 	return (0);
487 }
488 
489 int
490 pipex_notify_close_session(struct pipex_session *session)
491 {
492 	int s;
493 
494 	s = splnet();
495 	session->state = PIPEX_STATE_CLOSE_WAIT;
496 	session->stat.idle_time = 0;
497 	LIST_INSERT_HEAD(&pipex_close_wait_list, session, state_list);
498 	splx(s);
499 
500 	return (0);
501 }
502 
503 int
504 pipex_notify_close_session_all(void)
505 {
506 	struct pipex_session *session;
507 	int s;
508 
509 	s = splnet();
510 	LIST_FOREACH(session, &pipex_session_list, session_list)
511 		if (session->state == PIPEX_STATE_OPENED)
512 			pipex_notify_close_session(session);
513 	splx(s);
514 
515 	return (0);
516 }
517 
518 Static int
519 pipex_close_session(struct pipex_session_close_req *req)
520 {
521 	struct pipex_session *session;
522 	int s;
523 
524 	s = splnet();
525 	session = pipex_lookup_by_session_id(req->pcr_protocol,
526 	    req->pcr_session_id);
527 	if (session == NULL) {
528 		splx(s);
529 		return (EINVAL);
530 	}
531 
532 	/* remove from close_wait list */
533 	if (session->state == PIPEX_STATE_CLOSE_WAIT)
534 		LIST_REMOVE(session, state_list);
535 
536 	/* get statistics before destroy the session */
537 	req->pcr_stat = session->stat;
538 	session->state = PIPEX_STATE_CLOSED;
539 	splx(s);
540 
541 	return (0);
542 }
543 
544 Static int
545 pipex_config_session(struct pipex_session_config_req *req)
546 {
547 	struct pipex_session *session;
548 	int s;
549 
550 	s = splnet();
551 	session = pipex_lookup_by_session_id(req->pcr_protocol,
552 	    req->pcr_session_id);
553 	if (session == NULL) {
554 		splx(s);
555 		return (EINVAL);
556 	}
557 	session->ip_forward = req->pcr_ip_forward;
558 	splx(s);
559 
560 	return (0);
561 }
562 
563 Static int
564 pipex_get_stat(struct pipex_session_stat_req *req)
565 {
566 	struct pipex_session *session;
567 	int s;
568 
569 	s = splnet();
570 	session = pipex_lookup_by_session_id(req->psr_protocol,
571 	    req->psr_session_id);
572 	if (session == NULL) {
573 		splx(s);
574 		return (EINVAL);
575 	}
576 	req->psr_stat = session->stat;
577 	splx(s);
578 
579 	return (0);
580 }
581 
582 Static int
583 pipex_get_closed(struct pipex_session_list_req *req)
584 {
585 	struct pipex_session *session;
586 	int s;
587 
588 	s = splnet();
589 	bzero(req, sizeof(*req));
590 	while (!LIST_EMPTY(&pipex_close_wait_list)) {
591 		session = LIST_FIRST(&pipex_close_wait_list);
592 		req->plr_ppp_id[req->plr_ppp_id_count++] = session->ppp_id;
593 		LIST_REMOVE(session, state_list);
594 		session->state = PIPEX_STATE_CLOSE_WAIT2;
595 		if (req->plr_ppp_id_count >= PIPEX_MAX_LISTREQ) {
596 			if (!LIST_EMPTY(&pipex_close_wait_list))
597 				req->plr_flags |= PIPEX_LISTREQ_MORE;
598 			break;
599 		}
600 	}
601 	splx(s);
602 
603 	return (0);
604 }
605 
606 Static int
607 pipex_destroy_session(struct pipex_session *session)
608 {
609 	struct radix_node *rn;
610 	int s;
611 
612 	/* remove from radix tree and hash chain */
613 	s = splnet();
614 
615 	if (!in_nullhost(session->ip_address.sin_addr)) {
616 		rn = rn_delete(&session->ip_address, &session->ip_netmask,
617 		    &pipex_rd_head4, (struct radix_node *)session);
618 		KASSERT(rn != NULL);
619 	}
620 
621 	LIST_REMOVE(session, id_chain);
622 	LIST_REMOVE(session, session_list);
623 #ifdef PIPEX_PPTP
624 	if (session->protocol == PIPEX_PROTO_PPTP) {
625 		LIST_REMOVE(session, peer_addr_chain);
626 	}
627 #endif
628 #ifdef PIPEX_L2TP
629 	if (session->protocol == PIPEX_PROTO_L2TP) {
630 		LIST_REMOVE(session, peer_addr_chain);
631 	}
632 #endif
633 	/* if final session is destroyed, stop timer */
634 	if (LIST_EMPTY(&pipex_session_list))
635 		pipex_timer_stop();
636 
637 	splx(s);
638 
639 	if (session->mppe_recv.old_session_keys)
640 		pool_put(&mppe_key_pool, session->mppe_recv.old_session_keys);
641 	pool_put(&pipex_session_pool, session);
642 
643 	return (0);
644 }
645 
646 Static struct pipex_session *
647 pipex_lookup_by_ip_address(struct in_addr addr)
648 {
649 	struct pipex_session *session;
650 	struct sockaddr_in pipex_in4, pipex_in4mask;
651 
652 	bzero(&pipex_in4, sizeof(pipex_in4));
653 	pipex_in4.sin_addr = addr;
654 	pipex_in4.sin_family = AF_INET;
655 	pipex_in4.sin_len = sizeof(pipex_in4);
656 
657 	bzero(&pipex_in4mask, sizeof(pipex_in4mask));
658 	pipex_in4mask.sin_addr.s_addr = htonl(0xFFFFFFFFL);
659 	pipex_in4mask.sin_family = AF_INET;
660 	pipex_in4mask.sin_len = sizeof(pipex_in4mask);
661 
662 	session = (struct pipex_session *)rn_lookup(&pipex_in4, &pipex_in4mask,
663 	    &pipex_rd_head4);
664 
665 #ifdef PIPEX_DEBUG
666 	if (session == NULL) {
667 		char buf[INET_ADDRSTRLEN];
668 
669 		PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found (addr=%s)",
670 		    __func__, inet_ntop(AF_INET, &addr, buf, sizeof(buf))));
671 	}
672 #endif
673 
674 	return (session);
675 }
676 
677 Static struct pipex_session *
678 pipex_lookup_by_session_id(int protocol, int session_id)
679 {
680 	struct pipex_hash_head *list;
681 	struct pipex_session *session;
682 
683 	list = PIPEX_ID_HASHTABLE(session_id);
684 	LIST_FOREACH(session, list, id_chain) {
685 		if (session->protocol == protocol &&
686 		    session->session_id == session_id)
687 			break;
688 	}
689 
690 #ifdef PIPEX_DEBUG
691 	if (session == NULL)
692 		PIPEX_DBG((NULL, LOG_DEBUG,
693 		    "<%s> session not found (session_id=%d)", __func__,
694 		    session_id));
695 #endif
696 
697 	return (session);
698 }
699 
700 /***********************************************************************
701  * Queue and Software Interrupt Handler
702  ***********************************************************************/
703 Static void
704 pipex_softintr_handler(void *dummy)
705 {
706 	/* called at splsoftnet() */
707 	pipex_ppp_dequeue();
708 }
709 
710 Static void
711 pipex_ppp_dequeue(void)
712 {
713 	struct pipex_session *pkt_session;
714 	u_int16_t proto;
715 	struct mbuf *m;
716 	struct mbuf_list ml;
717 
718 	/* ppp output */
719 	mq_delist(&pipexoutq, &ml);
720 	while ((m = ml_dequeue(&ml)) != NULL) {
721 		pkt_session = m->m_pkthdr.ph_cookie;
722 		if (pkt_session == NULL) {
723 			m_freem(m);
724 			continue;
725 		}
726 		proto = m->m_pkthdr.ph_ppp_proto;
727 
728 		m->m_pkthdr.ph_cookie = NULL;
729 		m->m_pkthdr.ph_ppp_proto = 0;
730 
731 		if (pkt_session->is_multicast != 0) {
732 			struct pipex_session *session;
733 			struct mbuf *m0;
734 
735 			LIST_FOREACH(session, &pipex_session_list,
736 			    session_list) {
737 				if (session->pipex_iface !=
738 				    pkt_session->pipex_iface)
739 					continue;
740 				if (session->ip_forward == 0 &&
741 				    session->ip6_forward == 0)
742 					continue;
743 				m0 = m_copym(m, 0, M_COPYALL, M_NOWAIT);
744 				if (m0 == NULL) {
745 					session->stat.oerrors++;
746 					continue;
747 				}
748 				pipex_ppp_output(m0, session, proto);
749 			}
750 			m_freem(m);
751 		} else
752 			pipex_ppp_output(m, pkt_session, proto);
753 	}
754 
755 	/* ppp input */
756 	mq_delist(&pipexinq, &ml);
757 	while ((m = ml_dequeue(&ml)) != NULL) {
758 		pkt_session = m->m_pkthdr.ph_cookie;
759 		if (pkt_session == NULL) {
760 			m_freem(m);
761 			continue;
762 		}
763 		pipex_ppp_input(m, pkt_session, 0);
764 	}
765 }
766 
767 Static int
768 pipex_ppp_enqueue(struct mbuf *m0, struct pipex_session *session,
769     struct mbuf_queue *mq)
770 {
771 	m0->m_pkthdr.ph_cookie = session;
772 	/* XXX need to support other protocols */
773 	m0->m_pkthdr.ph_ppp_proto = PPP_IP;
774 
775 	if (mq_enqueue(mq, m0) != 0)
776 		return (1);
777 
778 	softintr_schedule(pipex_softintr);
779 	return (0);
780 }
781 
782 /***********************************************************************
783  * Timer functions
784  ***********************************************************************/
785 Static void
786 pipex_timer_start(void)
787 {
788 	timeout_set(&pipex_timer_ch, pipex_timer, NULL);
789 	timeout_add_sec(&pipex_timer_ch, pipex_prune);
790 }
791 
792 Static void
793 pipex_timer_stop(void)
794 {
795 	timeout_del(&pipex_timer_ch);
796 }
797 
798 Static void
799 pipex_timer(void *ignored_arg)
800 {
801 	int s;
802 	struct pipex_session *session;
803 	struct pipex_session *session_next;
804 
805 	s = splnet();
806 	timeout_add_sec(&pipex_timer_ch, pipex_prune);
807 
808 	/* walk through */
809 	for (session = LIST_FIRST(&pipex_session_list); session;
810 	    session = session_next) {
811 		session_next = LIST_NEXT(session, session_list);
812 		switch (session->state) {
813 		case PIPEX_STATE_OPENED:
814 			if (session->timeout_sec == 0)
815 				continue;
816 
817 			session->stat.idle_time++;
818 			if (session->stat.idle_time < session->timeout_sec)
819 				continue;
820 
821 			pipex_notify_close_session(session);
822 			break;
823 
824 		case PIPEX_STATE_CLOSE_WAIT:
825 		case PIPEX_STATE_CLOSE_WAIT2:
826 			/* Wait PIPEXDSESSION from userland */
827 			session->stat.idle_time++;
828 			if (session->stat.idle_time < PIPEX_CLOSE_TIMEOUT)
829 				continue;
830 
831 			if (session->state == PIPEX_STATE_CLOSE_WAIT)
832 				LIST_REMOVE(session, state_list);
833 			session->state = PIPEX_STATE_CLOSED;
834 			/* FALLTHROUGH */
835 
836 		case PIPEX_STATE_CLOSED:
837 			/*
838 			 * mbuf queued in pipexinq or pipexoutq may have a
839 			 * refererce to this session.
840 			 */
841 			if (!mq_empty(&pipexinq) || !mq_empty(&pipexoutq))
842 				continue;
843 
844 			pipex_destroy_session(session);
845 			break;
846 
847 		default:
848 			break;
849 		}
850 	}
851 
852 	splx(s);
853 }
854 
855 /***********************************************************************
856  * Common network I/O functions.  (tunnel protocol independent)
857  ***********************************************************************/
858 struct mbuf *
859 pipex_output(struct mbuf *m0, int af, int off,
860     struct pipex_iface_context *pipex_iface)
861 {
862 	struct pipex_session *session;
863 	struct ip ip;
864 	struct mbuf *mret;
865 
866 	session = NULL;
867 	mret = NULL;
868 	switch (af) {
869 	case AF_INET:
870 		if (m0->m_pkthdr.len >= sizeof(struct ip) + off) {
871 			m_copydata(m0, off, sizeof(struct ip), (caddr_t)&ip);
872 			if (IN_MULTICAST(ip.ip_dst.s_addr))
873 				session = pipex_iface->multicast_session;
874 			else
875 				session = pipex_lookup_by_ip_address(ip.ip_dst);
876 		}
877 		if (session != NULL) {
878 			if (session == pipex_iface->multicast_session) {
879 				mret = m0;
880 				m0 = m_copym(m0, 0, M_COPYALL, M_NOWAIT);
881 				if (m0 == NULL) {
882 					m0 = mret;
883 					mret = NULL;
884 					goto drop;
885 				}
886 			}
887 
888 			if (off > 0)
889 				m_adj(m0, off);
890 
891 			pipex_ip_output(m0, session);
892 			return (mret);
893 		}
894 		break;
895 	}
896 
897 	return (m0);
898 
899 drop:
900 	m_freem(m0);
901 	if (session != NULL)
902 		session->stat.oerrors++;
903 	return(NULL);
904 }
905 
906 Static void
907 pipex_ip_output(struct mbuf *m0, struct pipex_session *session)
908 {
909 	int is_idle;
910 	struct ifnet *ifp;
911 
912 	/* output succeed here as a interface */
913 	ifp = session->pipex_iface->ifnet_this;
914 	ifp->if_opackets++;
915 	ifp->if_obytes+=m0->m_pkthdr.len;
916 
917 	if (session->is_multicast == 0) {
918 		/*
919 		 * Multicast packet is a idle packet and it's not TCP.
920 		 */
921 		if (session->ip_forward == 0 && session->ip6_forward == 0)
922 			goto drop;
923 		/* reset idle timer */
924 		if (session->timeout_sec != 0) {
925 			is_idle = 0;
926 			m0 = ip_is_idle_packet(m0, &is_idle);
927 			if (m0 == NULL)
928 				goto dropped;
929 			if (is_idle == 0)
930 				/* update expire time */
931 				session->stat.idle_time = 0;
932 		}
933 
934 		/* adjust tcpmss */
935 		if ((session->ppp_flags & PIPEX_PPP_ADJUST_TCPMSS) != 0) {
936 			m0 = adjust_tcp_mss(m0, session->peer_mru);
937 			if (m0 == NULL)
938 				goto dropped;
939 		}
940 	} else
941 		m0->m_flags &= ~(M_BCAST|M_MCAST);
942 
943 	/* output ip packets to the session tunnel */
944 	if (pipex_ppp_enqueue(m0, session, &pipexoutq))
945 		goto dropped;
946 
947 	return;
948 drop:
949 	m_freem(m0);
950 dropped:
951 	session->stat.oerrors++;
952 }
953 
954 Static void
955 pipex_ppp_output(struct mbuf *m0, struct pipex_session *session, int proto)
956 {
957 	u_char *cp, hdr[16];
958 
959 #ifdef PIPEX_MPPE
960 	if (pipex_session_is_mppe_enabled(session)) {
961 		if (proto == PPP_IP) {
962 			pipex_mppe_output(m0, session, PPP_IP);
963 			return;
964 		}
965 	}
966 #endif /* PIPEX_MPPE */
967 	cp = hdr;
968 	if (session->protocol != PIPEX_PROTO_PPPOE) {
969 		/* PPPoE has not address and control field */
970 		PUTCHAR(PPP_ALLSTATIONS, cp);
971 		PUTCHAR(PPP_UI, cp);
972 	}
973 	PUTSHORT(proto, cp);
974 
975 	M_PREPEND(m0, cp - hdr, M_NOWAIT);
976 	if (m0 == NULL)
977 		goto drop;
978 	memcpy(mtod(m0, u_char *), hdr, cp - hdr);
979 
980 	switch (session->protocol) {
981 #ifdef	PIPEX_PPPOE
982 	case PIPEX_PROTO_PPPOE:
983 		pipex_pppoe_output(m0, session);
984 		break;
985 #endif
986 #ifdef PIPEX_PPTP
987 	case PIPEX_PROTO_PPTP:
988 		pipex_pptp_output(m0, session, 1, 1);
989 		break;
990 #endif
991 #ifdef	PIPEX_L2TP
992 	case PIPEX_PROTO_L2TP:
993 		pipex_l2tp_output(m0, session);
994 		break;
995 #endif
996 	default:
997 		goto drop;
998 	}
999 
1000 	return;
1001 drop:
1002 	m_freem(m0);
1003 	session->stat.oerrors++;
1004 }
1005 
1006 Static void
1007 pipex_ppp_input(struct mbuf *m0, struct pipex_session *session, int decrypted)
1008 {
1009 	int proto, hlen = 0;
1010 
1011 	KASSERT(m0->m_pkthdr.len >= PIPEX_PPPMINLEN);
1012 	proto = pipex_ppp_proto(m0, session, 0, &hlen);
1013 #ifdef PIPEX_MPPE
1014 	if (proto == PPP_COMP) {
1015 		if (decrypted)
1016 			goto drop;
1017 
1018 		/* checked this on ppp_common_input() already. */
1019 		KASSERT(pipex_session_is_mppe_accepted(session));
1020 
1021 		m_adj(m0, hlen);
1022 		pipex_mppe_input(m0, session);
1023 		return;
1024 	}
1025 	if (proto == PPP_CCP) {
1026 		if (decrypted)
1027 			goto drop;
1028 
1029 #if NBPFILTER > 0
1030 	    {
1031 		struct ifnet *ifp = session->pipex_iface->ifnet_this;
1032 		if (ifp->if_bpf && ifp->if_type == IFT_PPP)
1033 			bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_IN);
1034 	    }
1035 #endif
1036 		m_adj(m0, hlen);
1037 		pipex_ccp_input(m0, session);
1038 		return;
1039 	}
1040 #endif
1041 	switch (proto) {
1042 	case PPP_IP:
1043 		if (session->ip_forward == 0)
1044 			goto drop;
1045 		if (!decrypted && pipex_session_is_mppe_required(session))
1046 			/*
1047 			 * if ip packet received when mppe
1048 			 * is required, discard it.
1049 			 */
1050 			goto drop;
1051 		m_adj(m0, hlen);
1052 		pipex_ip_input(m0, session);
1053 		return;
1054 #ifdef INET6
1055 	case PPP_IPV6:
1056 		if (session->ip6_forward == 0)
1057 			goto drop;
1058 		if (!decrypted && pipex_session_is_mppe_required(session))
1059 			/*
1060 			 * if ip packet received when mppe
1061 			 * is required, discard it.
1062 			 */
1063 			goto drop;
1064 		m_adj(m0, hlen);
1065 		pipex_ip6_input(m0, session);
1066 		return;
1067 #endif
1068 	default:
1069 		if (decrypted)
1070 			goto drop;
1071 		/* protocol must be checked on pipex_common_input() already */
1072 		KASSERT(0);
1073 		goto drop;
1074 	}
1075 
1076 	return;
1077 drop:
1078 	m_freem(m0);
1079 	session->stat.ierrors++;
1080 }
1081 
1082 Static void
1083 pipex_ip_input(struct mbuf *m0, struct pipex_session *session)
1084 {
1085 	struct ifnet *ifp;
1086 	struct ip *ip;
1087 	int len;
1088 	int is_idle;
1089 
1090 	/* change recvif */
1091 	ifp = session->pipex_iface->ifnet_this;
1092 	m0->m_pkthdr.ph_ifidx = ifp->if_index;
1093 
1094 	PIPEX_PULLUP(m0, sizeof(struct ip));
1095 	if (m0 == NULL)
1096 		goto drop;
1097 
1098 #if 0
1099 	/*
1100 	 * XXX: hsuenaga
1101 	 * we need to know openbsd manners to adjust alignment
1102 	 */
1103 	if (!ALIGNED_POINTER(mtod(m0, caddr_t), struct ip *)) {
1104 		/* ip_output() assumes ip packet is aligned.  */
1105 		if ((m0 = m_copyup(m0, sizeof(struct ip),
1106 		    ((max_linkhdr + 3) & ~3))) == NULL)
1107 			goto drop;
1108 	}
1109 #endif
1110 	if (ISSET(session->ppp_flags, PIPEX_PPP_INGRESS_FILTER)) {
1111 		/* ingress filter */
1112 		ip = mtod(m0, struct ip *);
1113 		if ((ip->ip_src.s_addr & session->ip_netmask.sin_addr.s_addr) !=
1114 		    session->ip_address.sin_addr.s_addr) {
1115 			char src[INET_ADDRSTRLEN];
1116 
1117 			pipex_session_log(session, LOG_DEBUG,
1118 			    "ip packet discarded by ingress filter (src %s)",
1119 			    inet_ntop(AF_INET, &ip->ip_src, src, sizeof(src)));
1120 			goto drop;
1121 		}
1122 	}
1123 
1124 	/* idle timer */
1125 	if (session->timeout_sec != 0) {
1126 		is_idle = 0;
1127 		m0 = ip_is_idle_packet(m0, &is_idle);
1128 		if (m0 == NULL)
1129 			goto drop;
1130 		if (is_idle == 0)
1131 			/* update expire time */
1132 			session->stat.idle_time = 0;
1133 	}
1134 
1135 	/* adjust tcpmss */
1136 	if (session->ppp_flags & PIPEX_PPP_ADJUST_TCPMSS) {
1137 		m0 = adjust_tcp_mss(m0, session->peer_mru);
1138 		if (m0 == NULL)
1139 			goto drop;
1140 	}
1141 
1142 #if NPF > 0
1143 	pf_pkt_addr_changed(m0);
1144 #endif
1145 
1146 	len = m0->m_pkthdr.len;
1147 
1148 #if NBPFILTER > 0
1149 	if (ifp->if_bpf)
1150 		bpf_mtap_af(ifp->if_bpf, AF_INET, m0, BPF_DIRECTION_IN);
1151 #endif
1152 
1153 	if (niq_enqueue(&ipintrq, m0) != 0) {
1154 		ifp->if_collisions++;
1155 		goto dropped;
1156 	}
1157 
1158 	ifp->if_ipackets++;
1159 	ifp->if_ibytes += len;
1160 	session->stat.ipackets++;
1161 	session->stat.ibytes += len;
1162 
1163 	return;
1164 drop:
1165 	m_freem(m0);
1166 dropped:
1167 	session->stat.ierrors++;
1168 }
1169 
1170 #ifdef INET6
1171 Static void
1172 pipex_ip6_input(struct mbuf *m0, struct pipex_session *session)
1173 {
1174 	struct ifnet *ifp;
1175 	int len;
1176 
1177 	/* change recvif */
1178 	ifp = session->pipex_iface->ifnet_this;
1179 	m0->m_pkthdr.ph_ifidx = ifp->if_index;
1180 
1181 #if 0 /* XXX: alignment */
1182 	PIPEX_PULLUP(m0, sizeof(struct ip6_hdr));
1183 	if (m0 == NULL)
1184 		goto drop;
1185 
1186 	if (!ALIGNED_POINTER(mtod(m0, caddr_t), struct ip6_hdr *)) {
1187 		/* ip6_output() assumes ip packet is aligned.  */
1188 		if ((m0 = m_copyup(m0, sizeof(struct ip6_hdr),
1189 		    ((max_linkhdr + 3) & ~3))) == NULL)
1190 			goto drop;
1191 	}
1192 #endif
1193 
1194 	/*
1195 	 * XXX: what is reasonable ingress filter ???
1196 	 *      only one address is enough ??
1197 	 */
1198 
1199 	/* XXX: we must define idle packet for IPv6(ICMPv6). */
1200 
1201 	/*
1202 	 * XXX: tcpmss adjustment for IPv6 is required???
1203 	 *      We may use PMTUD in IPv6....
1204 	 */
1205 
1206 #if NPF > 0
1207 	pf_pkt_addr_changed(m0);
1208 #endif
1209 
1210 	len = m0->m_pkthdr.len;
1211 
1212 #if NBPFILTER > 0
1213 	if (ifp->if_bpf)
1214 		bpf_mtap_af(ifp->if_bpf, AF_INET6, m0, BPF_DIRECTION_IN);
1215 #endif
1216 
1217 	if (niq_enqueue(&ip6intrq, m0) != 0) {
1218 		ifp->if_collisions++;
1219 		goto dropped;
1220 	}
1221 
1222 	ifp->if_ipackets++;
1223 	ifp->if_ibytes += len;
1224 	session->stat.ipackets++;
1225 	session->stat.ibytes += len;
1226 
1227 	return;
1228 dropped:
1229 	session->stat.ierrors++;
1230 }
1231 #endif
1232 
1233 Static struct mbuf *
1234 pipex_common_input(struct pipex_session *session, struct mbuf *m0, int hlen,
1235     int plen)
1236 {
1237 	int proto, ppphlen;
1238 	u_char code;
1239 
1240 	if ((m0->m_pkthdr.len < hlen + PIPEX_PPPMINLEN) ||
1241 	    (plen < PIPEX_PPPMINLEN))
1242 		goto drop;
1243 
1244 	proto = pipex_ppp_proto(m0, session, hlen, &ppphlen);
1245 	switch (proto) {
1246 #ifdef PIPEX_MPPE
1247 	case PPP_CCP:
1248 		code = 0;
1249 		KASSERT(m0->m_pkthdr.len >= hlen + ppphlen + 1);
1250 		m_copydata(m0, hlen + ppphlen, 1, (caddr_t)&code);
1251 		if (code != CCP_RESETREQ && code != CCP_RESETACK)
1252 			goto not_ours;
1253 		break;
1254 
1255 	case PPP_COMP:
1256 		if (pipex_session_is_mppe_accepted(session))
1257 			break;
1258 		goto not_ours;
1259 #endif
1260 	case PPP_IP:
1261 #ifdef INET6
1262 	case PPP_IPV6:
1263 #endif
1264 		break;
1265 	default:
1266 		goto not_ours;
1267 	}
1268 
1269 	/* ok,  The packet is for PIPEX */
1270 	m_adj(m0, hlen);/* cut off the tunnle protocol header */
1271 
1272 	/* ensure the mbuf length equals the PPP frame length */
1273 	if (m0->m_pkthdr.len < plen)
1274 		goto drop;
1275 	if (m0->m_pkthdr.len > plen) {
1276 		if (m0->m_len == m0->m_pkthdr.len) {
1277 			m0->m_len = plen;
1278 			m0->m_pkthdr.len = plen;
1279 		} else
1280 			m_adj(m0, plen - m0->m_pkthdr.len);
1281 	}
1282 
1283 	/* input ppp packets to kernel session */
1284 	if (pipex_ppp_enqueue(m0, session, &pipexinq) != 0)
1285 		goto dropped;
1286 	else
1287 		return (NULL);
1288 drop:
1289 	m_freem(m0);
1290 dropped:
1291 	session->stat.ierrors++;
1292 	return (NULL);
1293 
1294 not_ours:
1295 	return (m0);	/* Not to be handled by PIPEX */
1296 }
1297 
1298 /*
1299  * pipex_ppp_proto
1300  */
1301 Static int
1302 pipex_ppp_proto(struct mbuf *m0, struct pipex_session *session, int off,
1303     int *hlenp)
1304 {
1305 	int proto;
1306 	u_char *cp, pktbuf[4];
1307 
1308 	KASSERT(m0->m_pkthdr.len > sizeof(pktbuf));
1309 	m_copydata(m0, off, sizeof(pktbuf), pktbuf);
1310 	cp = pktbuf;
1311 
1312 	if (pipex_session_has_acf(session)) {
1313 		if (cp[0] == PPP_ALLSTATIONS && cp[1] == PPP_UI)
1314 			cp += 2;
1315 #ifdef PIPEX_DEBUG
1316 		else if (!pipex_session_is_acfc_accepted(session))
1317 			PIPEX_DBG((session, LOG_DEBUG,
1318 			    "no acf but acfc is not accepted by the peer."));
1319 #endif
1320 	}
1321 	if ((*cp & 0x01) != 0) {
1322 		if (!pipex_session_is_pfc_accepted(session)) {
1323 			PIPEX_DBG((session, LOG_DEBUG, "Received a broken ppp "
1324 			    "frame.  No protocol field. %02x-%02x",
1325 			    cp[0], cp[1]));
1326 			return (-1);
1327 		}
1328 		GETCHAR(proto, cp);
1329 	} else
1330 		GETSHORT(proto, cp);
1331 
1332 	if (hlenp != NULL)
1333 		*hlenp = cp - pktbuf;
1334 
1335 	return (proto);
1336 }
1337 
1338 #ifdef PIPEX_PPPOE
1339 /***********************************************************************
1340  * PPPoE
1341  ***********************************************************************/
1342 Static u_char	pipex_pppoe_padding[ETHERMIN];
1343 /*
1344  * pipex_pppoe_lookup_session
1345  */
1346 struct pipex_session *
1347 pipex_pppoe_lookup_session(struct mbuf *m0)
1348 {
1349 	struct pipex_session *session;
1350 	struct pipex_pppoe_header pppoe;
1351 
1352 	/* short packet */
1353 	if (m0->m_pkthdr.len < (sizeof(struct ether_header) + sizeof(pppoe)))
1354 		return (NULL);
1355 
1356 	m_copydata(m0, sizeof(struct ether_header),
1357 	    sizeof(struct pipex_pppoe_header), (caddr_t)&pppoe);
1358 	pppoe.session_id = ntohs(pppoe.session_id);
1359 	session = pipex_lookup_by_session_id(PIPEX_PROTO_PPPOE,
1360 	    pppoe.session_id);
1361 #ifdef PIPEX_DEBUG
1362 	if (session == NULL)
1363 		PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found (id=%d)",
1364 		    __func__, pppoe.session_id));
1365 #endif
1366 
1367 	return (session);
1368 }
1369 
1370 struct mbuf *
1371 pipex_pppoe_input(struct mbuf *m0, struct pipex_session *session)
1372 {
1373 	int hlen;
1374 	struct pipex_pppoe_header pppoe;
1375 
1376 	/* already checked at pipex_pppoe_lookup_session */
1377 	KASSERT(m0->m_pkthdr.len >= (sizeof(struct ether_header) +
1378 	    sizeof(pppoe)));
1379 
1380 	m_copydata(m0, sizeof(struct ether_header),
1381 	    sizeof(struct pipex_pppoe_header), (caddr_t)&pppoe);
1382 
1383 	hlen = sizeof(struct ether_header) + sizeof(struct pipex_pppoe_header);
1384 	if ((m0 = pipex_common_input(session, m0, hlen, ntohs(pppoe.length)))
1385 	    == NULL)
1386 		return (NULL);
1387 	m_freem(m0);
1388 	session->stat.ierrors++;
1389 	return (NULL);
1390 }
1391 
1392 /*
1393  * pipex_ppope_output
1394  */
1395 Static void
1396 pipex_pppoe_output(struct mbuf *m0, struct pipex_session *session)
1397 {
1398 	struct pipex_pppoe_header *pppoe;
1399 	struct ifnet *ifp, *over_ifp;
1400 	int len, padlen;
1401 
1402 	/* save length for pppoe header */
1403 	len = m0->m_pkthdr.len;
1404 
1405 	ifp = session->pipex_iface->ifnet_this;
1406 	over_ifp = session->proto.pppoe.over_ifp;
1407 
1408 	/* prepend protocol header */
1409 	M_PREPEND(m0, sizeof(struct pipex_pppoe_header), M_NOWAIT);
1410 	if (m0 == NULL) {
1411 		PIPEX_DBG((NULL, LOG_ERR,
1412 		    "<%s> cannot prepend header.", __func__));
1413 		session->stat.oerrors++;
1414 		return;
1415 	}
1416 	padlen = ETHERMIN - m0->m_pkthdr.len;
1417 	if (padlen > 0)
1418 		m_copyback(m0, m0->m_pkthdr.len, padlen, pipex_pppoe_padding,
1419 		    M_NOWAIT);
1420 
1421 	/* setup pppoe header information */
1422 	pppoe = mtod(m0, struct pipex_pppoe_header *);
1423 	pppoe->vertype = PIPEX_PPPOE_VERTYPE;
1424 	pppoe->code = PIPEX_PPPOE_CODE_SESSION;
1425 	pppoe->session_id = htons(session->session_id);
1426 	pppoe->length = htons(len);
1427 
1428 	m0->m_pkthdr.ph_ifidx = ifp->if_index;
1429 	m0->m_flags &= ~(M_BCAST|M_MCAST);
1430 
1431 	session->stat.opackets++;
1432 	session->stat.obytes += len;
1433 
1434 	over_ifp->if_output(over_ifp, m0, (struct sockaddr *)&session->peer,
1435 	    NULL);
1436 }
1437 #endif /* PIPEX_PPPOE */
1438 
1439 #ifdef PIPEX_PPTP
1440 /***********************************************************************
1441  * PPTP
1442  ***********************************************************************/
1443 Static void
1444 pipex_pptp_output(struct mbuf *m0, struct pipex_session *session,
1445     int has_seq, int has_ack)
1446 {
1447 	int len, reqlen;
1448 	struct pipex_gre_header *gre = NULL;
1449 	struct ip *ip;
1450 	u_char *cp;
1451 
1452 	reqlen = PIPEX_IPGRE_HDRLEN + (has_seq + has_ack) * 4;
1453 
1454 	len = 0;
1455 	if (m0 != NULL) {
1456 		/* save length for gre header */
1457 		len = m0->m_pkthdr.len;
1458 		/* prepend protocol header */
1459 		M_PREPEND(m0, reqlen, M_NOWAIT);
1460 		if (m0 == NULL)
1461 			goto drop;
1462 	} else {
1463 		MGETHDR(m0, M_DONTWAIT, MT_DATA);
1464 		if (m0 && reqlen > MHLEN) {
1465 			MCLGET(m0, M_DONTWAIT);
1466 			if ((m0->m_flags & M_EXT) == 0) {
1467 				m_freem(m0);
1468 				m0 = NULL;
1469 			}
1470 		}
1471 		if (m0 == NULL)
1472 			goto drop;
1473 		m0->m_pkthdr.len = m0->m_len = reqlen;
1474 	}
1475 
1476 	/* setup ip header information */
1477 	ip = mtod(m0, struct ip *);
1478 
1479 	ip->ip_len = htons(m0->m_pkthdr.len);
1480 	ip->ip_off = 0;
1481 	ip->ip_ttl = MAXTTL;
1482 	ip->ip_p = IPPROTO_GRE;
1483 	ip->ip_tos = 0;
1484 
1485 	ip->ip_src = session->local.sin4.sin_addr;
1486 	ip->ip_dst = session->peer.sin4.sin_addr;
1487 #if NPF > 0
1488 	pf_pkt_addr_changed(m0);
1489 #endif
1490 
1491 	/* setup gre(ver1) header information */
1492 	gre = PIPEX_SEEK_NEXTHDR(ip, sizeof(struct ip),
1493 	    struct pipex_gre_header *);
1494 	gre->type = htons(PIPEX_GRE_PROTO_PPP);
1495 	gre->call_id = htons(session->peer_session_id);
1496 	gre->flags = PIPEX_GRE_KFLAG | PIPEX_GRE_VER;	/* do htons later */
1497 	gre->len = htons(len);
1498 
1499 	cp = PIPEX_SEEK_NEXTHDR(gre, sizeof(struct pipex_gre_header),u_char *);
1500 	if (has_seq) {
1501 		gre->flags |= PIPEX_GRE_SFLAG;
1502 		PUTLONG(session->proto.pptp.snd_nxt, cp);
1503 		session->proto.pptp.snd_nxt++;
1504 		session->proto.pptp.snd_gap++;
1505 	}
1506 	if (has_ack) {
1507 		gre->flags |= PIPEX_GRE_AFLAG;
1508 		session->proto.pptp.rcv_acked = session->proto.pptp.rcv_nxt - 1;
1509 		PUTLONG(session->proto.pptp.rcv_acked, cp);
1510 	}
1511 	gre->flags = htons(gre->flags);
1512 
1513 	m0->m_pkthdr.ph_ifidx = session->pipex_iface->ifnet_this->if_index;
1514 	if (ip_output(m0, NULL, NULL, 0, NULL, NULL, 0) != 0) {
1515 		PIPEX_DBG((session, LOG_DEBUG, "ip_output failed."));
1516 		goto drop;
1517 	}
1518 	if (len > 0) {	/* network layer only */
1519 		/* countup statistics */
1520 		session->stat.opackets++;
1521 		session->stat.obytes += len;
1522 	}
1523 
1524 	return;
1525 drop:
1526 	session->stat.oerrors++;
1527 }
1528 
1529 struct pipex_session *
1530 pipex_pptp_lookup_session(struct mbuf *m0)
1531 {
1532 	struct pipex_session *session;
1533 	struct pipex_gre_header gre;
1534 	struct ip ip;
1535 	uint16_t flags;
1536 	uint16_t id;
1537 	int hlen;
1538 
1539 	if (m0->m_pkthdr.len < PIPEX_IPGRE_HDRLEN) {
1540 		PIPEX_DBG((NULL, LOG_DEBUG,
1541 		    "<%s> packet length is too short", __func__));
1542 		goto not_ours;
1543 	}
1544 
1545 	/* get ip header info */
1546 	m_copydata(m0, 0, sizeof(struct ip), (caddr_t)&ip);
1547 	hlen = ip.ip_hl << 2;
1548 
1549 	/*
1550 	 * m0 has already passed ip_input(), so there is
1551 	 * no necessity for ip packet inspection.
1552 	 */
1553 
1554 	/* get gre flags */
1555 	m_copydata(m0, hlen, sizeof(gre), (caddr_t)&gre);
1556 	flags = ntohs(gre.flags);
1557 
1558 	/* gre version must be '1' */
1559 	if ((flags & PIPEX_GRE_VERMASK) != PIPEX_GRE_VER) {
1560 		PIPEX_DBG((NULL, LOG_DEBUG,
1561 		    "<%s> gre header wrong version.", __func__));
1562 		goto not_ours;
1563 	}
1564 
1565 	/* gre keys must be present */
1566 	if ((flags & PIPEX_GRE_KFLAG) == 0) {
1567 		PIPEX_DBG((NULL, LOG_DEBUG,
1568 		    "<%s> gre header has no keys.", __func__));
1569 		goto not_ours;
1570 	}
1571 
1572 	/* flag check */
1573 	if ((flags & PIPEX_GRE_UNUSEDFLAGS) != 0) {
1574 		PIPEX_DBG((NULL, LOG_DEBUG,
1575 		    "<%s> gre header has unused flags at pptp.", __func__));
1576 		goto not_ours;
1577 	}
1578 
1579 	/* lookup pipex session table */
1580 	id = ntohs(gre.call_id);
1581 	session = pipex_lookup_by_session_id(PIPEX_PROTO_PPTP, id);
1582 #ifdef PIPEX_DEBUG
1583 	if (session == NULL) {
1584 		PIPEX_DBG((NULL, LOG_DEBUG,
1585 		    "<%s> session not found (id=%d)", __func__, id));
1586 		goto not_ours;
1587 	}
1588 #endif
1589 
1590 	return (session);
1591 
1592 not_ours:
1593 	return (NULL);
1594 }
1595 
1596 struct mbuf *
1597 pipex_pptp_input(struct mbuf *m0, struct pipex_session *session)
1598 {
1599 	int hlen, has_seq, has_ack, nseq;
1600 	const char *reason = "";
1601 	u_char *cp, *seqp = NULL, *ackp = NULL;
1602 	uint32_t flags, seq = 0, ack = 0;
1603 	struct ip *ip;
1604 	struct pipex_gre_header *gre;
1605 	struct pipex_pptp_session *pptp_session;
1606 	int rewind = 0;
1607 
1608 	KASSERT(m0->m_pkthdr.len >= PIPEX_IPGRE_HDRLEN);
1609 	pptp_session = &session->proto.pptp;
1610 
1611 	/* get ip header */
1612 	ip = mtod(m0, struct ip *);
1613 	hlen = ip->ip_hl << 2;
1614 
1615 	/* seek gre header */
1616 	gre = PIPEX_SEEK_NEXTHDR(ip, hlen, struct pipex_gre_header *);
1617 	flags = ntohs(gre->flags);
1618 
1619 	/* pullup for seek sequences in header */
1620 	has_seq = (flags & PIPEX_GRE_SFLAG) ? 1 : 0;
1621 	has_ack = (flags & PIPEX_GRE_AFLAG) ? 1 : 0;
1622 	hlen = PIPEX_IPGRE_HDRLEN + 4 * (has_seq + has_ack);
1623 	if (m0->m_len < hlen) {
1624 		m0 = m_pullup(m0, hlen);
1625 		if (m0 == NULL) {
1626 			PIPEX_DBG((session, LOG_DEBUG, "pullup failed."));
1627 			goto drop;
1628 		}
1629 	}
1630 
1631 	/* check sequence */
1632 	cp = PIPEX_SEEK_NEXTHDR(gre, sizeof(struct pipex_gre_header),u_char *);
1633 	if (has_seq) {
1634 		seqp = cp;
1635 		GETLONG(seq, cp);
1636 	}
1637 	if (has_ack) {
1638 		ackp = cp;
1639 		GETLONG(ack, cp);
1640 		if (ack + 1 == pptp_session->snd_una) {
1641 			/* ack has not changed before */
1642 		} else if (SEQ32_LT(ack, pptp_session->snd_una)) {
1643 			/* OoO ack packets should not be dropped. */
1644 			rewind = 1;
1645 		} else if (SEQ32_GT(ack, pptp_session->snd_nxt)) {
1646 			reason = "ack for unknown sequence";
1647 			goto out_seq;
1648 		} else
1649 			pptp_session->snd_una = ack + 1;
1650 	}
1651 	if (!has_seq) {
1652 		/* ack only packet */
1653 		goto not_ours;
1654 	}
1655 	if (SEQ32_LT(seq, pptp_session->rcv_nxt)) {
1656 		rewind = 1;
1657 		if (SEQ32_LT(seq,
1658 		    pptp_session->rcv_nxt - PIPEX_REWIND_LIMIT)) {
1659 			reason = "out of sequence";
1660 			goto out_seq;
1661 		}
1662 	} else if (SEQ32_GE(seq, pptp_session->rcv_nxt +
1663 	    pptp_session->maxwinsz)) {
1664 		pipex_session_log(session, LOG_DEBUG,
1665 		    "received packet caused window overflow. seq=%u(%u-%u)"
1666 		    "may lost %d packets.", seq, pptp_session->rcv_nxt,
1667 		    pptp_session->rcv_nxt + pptp_session->maxwinsz,
1668 		    (int)SEQ32_SUB(seq, pptp_session->rcv_nxt));
1669 	}
1670 
1671 	seq++;
1672 	nseq = SEQ32_SUB(seq, pptp_session->rcv_nxt);
1673 	if (!rewind) {
1674 		pptp_session->rcv_nxt = seq;
1675 		if (SEQ32_SUB(seq, pptp_session->rcv_acked) >
1676 		    roundup(pptp_session->winsz, 2) / 2) /* Send ack only packet. */
1677 			pipex_pptp_output(NULL, session, 0, 1);
1678 	}
1679 
1680 	if ((m0 = pipex_common_input(session, m0, hlen, (int)ntohs(gre->len)))
1681 	    == NULL) {
1682 		/* ok,  The packet is for PIPEX */
1683 		if (!rewind)
1684 			session->proto.pptp.rcv_gap += nseq;
1685 		return (NULL);
1686 	}
1687 
1688 	if (rewind)
1689 		goto out_seq;
1690 
1691 not_ours:
1692 	seq--;	/* revert original seq value */
1693 
1694 	/*
1695 	 * overwrite sequence numbers to adjust a gap between pipex and
1696 	 * userland.
1697 	 */
1698 	if (seqp != NULL) {
1699 		seq -= pptp_session->rcv_gap;
1700 		PUTLONG(seq, seqp);
1701 	}
1702 	if (ackp != NULL) {
1703 		if (pptp_session->snd_nxt == pptp_session->snd_una) {
1704 			ack -= session->proto.pptp.snd_gap;
1705 			pptp_session->ul_snd_una = ack;
1706 		} else {
1707 			/*
1708 			 * There are sending packets they are not acked.
1709 			 * In this situation, (ack - snd_gap) may points
1710 			 * before sending window of userland.  So we don't
1711 			 * update the ack number.
1712 			 */
1713 			ack = pptp_session->ul_snd_una;
1714 		}
1715 		PUTLONG(ack, ackp);
1716 	}
1717 
1718 	return (m0);
1719 out_seq:
1720 	pipex_session_log(session, LOG_DEBUG,
1721 	    "Received bad data packet: %s: seq=%u(%u-%u) ack=%u(%u-%u)",
1722 	    reason, seq, pptp_session->rcv_nxt,
1723 	    pptp_session->rcv_nxt + pptp_session->maxwinsz,
1724 	    ack, pptp_session->snd_una,
1725 	    pptp_session->snd_nxt);
1726 
1727 	/* FALLTHROUGH */
1728 drop:
1729 	m_freem(m0);
1730 	session->stat.ierrors++;
1731 
1732 	return (NULL);
1733 }
1734 
1735 struct pipex_session *
1736 pipex_pptp_userland_lookup_session_ipv4(struct mbuf *m0, struct in_addr dst)
1737 {
1738 	struct sockaddr_in sin;
1739 
1740 	memset(&sin, 0, sizeof(sin));
1741 	sin.sin_len = sizeof(sin);
1742 	sin.sin_family = AF_INET;
1743 	sin.sin_addr = dst;
1744 
1745 	return pipex_pptp_userland_lookup_session(m0, sintosa(&sin));
1746 }
1747 
1748 #ifdef INET6
1749 struct pipex_session *
1750 pipex_pptp_userland_lookup_session_ipv6(struct mbuf *m0, struct in6_addr dst)
1751 {
1752 	struct sockaddr_in6 sin6;
1753 
1754 	memset(&sin6, 0, sizeof(sin6));
1755 	sin6.sin6_len = sizeof(sin6);
1756 	sin6.sin6_family = AF_INET6;
1757 	in6_recoverscope(&sin6, &dst);
1758 
1759 	return pipex_pptp_userland_lookup_session(m0, sin6tosa(&sin6));
1760 }
1761 #endif
1762 
1763 Static struct pipex_session *
1764 pipex_pptp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa)
1765 {
1766 	struct pipex_gre_header gre;
1767 	struct pipex_hash_head *list;
1768 	struct pipex_session *session;
1769 	uint16_t id, flags;
1770 
1771 	/* pullup */
1772 	if (m0->m_pkthdr.len < sizeof(gre)) {
1773 		PIPEX_DBG((NULL, LOG_DEBUG,
1774 		    "<%s> packet length is too short", __func__));
1775 		return (NULL);
1776 	}
1777 
1778 	/* get flags */
1779 	m_copydata(m0, 0, sizeof(struct pipex_gre_header), (caddr_t)&gre);
1780 	flags = ntohs(gre.flags);
1781 
1782 	/* gre version must be '1' */
1783 	if ((flags & PIPEX_GRE_VERMASK) != PIPEX_GRE_VER) {
1784 		PIPEX_DBG((NULL, LOG_DEBUG,
1785 		    "<%s> gre header wrong version.", __func__));
1786 		return (NULL);
1787 	}
1788 
1789 	/* gre keys must be present */
1790 	if ((flags & PIPEX_GRE_KFLAG) == 0) {
1791 		PIPEX_DBG((NULL, LOG_DEBUG,
1792 		    "<%s> gre header has no keys.", __func__));
1793 		return (NULL);
1794 	}
1795 
1796 	/* lookup pipex session table */
1797 	id = ntohs(gre.call_id);
1798 
1799 	list = PIPEX_PEER_ADDR_HASHTABLE(pipex_sockaddr_hash_key(sa));
1800 	LIST_FOREACH(session, list, peer_addr_chain) {
1801 		if (pipex_sockaddr_compar_addr(
1802 		    (struct sockaddr *)&session->peer, sa) != 0)
1803 			continue;
1804 		if (session->peer_session_id == id)
1805 			break;
1806 	}
1807 #ifdef PIPEX_DEBUG
1808 	if (session == NULL) {
1809 		PIPEX_DBG((NULL, LOG_DEBUG,
1810 		    "<%s> session not found (,call_id=%d)",
1811 		    __func__, (int)gre.call_id));
1812 	}
1813 #endif
1814 	return (session);
1815 }
1816 
1817 /*
1818  * pipex_pptp_userland_output
1819  */
1820 struct mbuf *
1821 pipex_pptp_userland_output(struct mbuf *m0, struct pipex_session *session)
1822 {
1823 	int len;
1824 	struct pipex_gre_header *gre, gre0;
1825 	uint16_t flags;
1826 	u_char *cp, *cp0;
1827 	uint32_t val32;
1828 
1829 	len = sizeof(struct pipex_gre_header);
1830 	m_copydata(m0, 0, len, (caddr_t)&gre0);
1831 	gre = &gre0;
1832 	flags = ntohs(gre->flags);
1833 	if ((flags & PIPEX_GRE_SFLAG) != 0)
1834 		len += 4;
1835 	if ((flags & PIPEX_GRE_AFLAG) != 0)
1836 		len += 4;
1837 
1838 	/* check length */
1839 	PIPEX_PULLUP(m0, len);
1840 	if (m0 == NULL) {
1841 		PIPEX_DBG((session, LOG_DEBUG, "gre header is too short."));
1842 		return (NULL);
1843 	}
1844 
1845 	gre = mtod(m0, struct pipex_gre_header *);
1846 	cp = PIPEX_SEEK_NEXTHDR(gre, sizeof(struct pipex_gre_header), u_char *);
1847 
1848 	/*
1849 	 * overwrite sequence numbers to adjust a gap between pipex and
1850 	 * userland.
1851 	 */
1852 	if ((flags & PIPEX_GRE_SFLAG) != 0) {
1853 		cp0 = cp;
1854 		GETLONG(val32, cp);
1855 		val32 += session->proto.pptp.snd_gap;
1856 		PUTLONG(val32, cp0);
1857 		session->proto.pptp.snd_nxt++;
1858 	}
1859 	if ((flags & PIPEX_GRE_AFLAG) != 0) {
1860 		cp0 = cp;
1861 		GETLONG(val32, cp);
1862 		val32 += session->proto.pptp.rcv_gap;
1863 		PUTLONG(val32, cp0);
1864 		if (SEQ32_GT(val32, session->proto.pptp.rcv_acked))
1865 			session->proto.pptp.rcv_acked = val32;
1866 	}
1867 
1868 	return (m0);
1869 }
1870 #endif /* PIPEX_PPTP */
1871 
1872 #ifdef PIPEX_L2TP
1873 /***********************************************************************
1874  * L2TP support
1875  ***********************************************************************/
1876 Static void
1877 pipex_l2tp_output(struct mbuf *m0, struct pipex_session *session)
1878 {
1879 	int hlen, plen, datalen;
1880 	struct pipex_l2tp_header *l2tp = NULL;
1881 	struct pipex_l2tp_seq_header *seq = NULL;
1882 	struct udphdr *udp;
1883 	struct ip *ip;
1884 #ifdef INET6
1885 	struct ip6_hdr *ip6;
1886 #endif
1887 
1888 	hlen = sizeof(struct pipex_l2tp_header) +
1889 	    ((pipex_session_is_l2tp_data_sequencing_on(session))
1890 		    ? sizeof(struct pipex_l2tp_seq_header) : 0) +
1891 	    sizeof(struct udphdr) +
1892 #ifdef INET6
1893 	    ((session->peer.sin6.sin6_family == AF_INET6)
1894 		    ? sizeof(struct ip6_hdr) : sizeof(struct ip));
1895 #else
1896 	    sizeof(struct ip);
1897 #endif
1898 
1899 	datalen = 0;
1900 	if (m0 != NULL) {
1901 		datalen = m0->m_pkthdr.len;
1902 		M_PREPEND(m0, hlen, M_NOWAIT);
1903 		if (m0 == NULL)
1904 			goto drop;
1905 	} else {
1906 		MGETHDR(m0, M_DONTWAIT, MT_DATA);
1907 		if (m0 == NULL)
1908 			goto drop;
1909 		KASSERT(hlen <= MHLEN);
1910 		m0->m_pkthdr.len = m0->m_len = hlen;
1911 	}
1912 
1913 #ifdef INET6
1914 	hlen = (session->peer.sin6.sin6_family == AF_INET6)
1915 	    ? sizeof(struct ip6_hdr) : sizeof(struct ip);
1916 #else
1917 	hlen = sizeof(struct ip);
1918 #endif
1919 	plen = datalen + sizeof(struct pipex_l2tp_header) +
1920 	    ((pipex_session_is_l2tp_data_sequencing_on(session))
1921 		    ? sizeof(struct pipex_l2tp_seq_header) : 0);
1922 
1923 	l2tp = (struct pipex_l2tp_header *)
1924 	    (mtod(m0, caddr_t) + hlen + sizeof(struct udphdr));
1925 	l2tp->flagsver = PIPEX_L2TP_VER | PIPEX_L2TP_FLAG_LENGTH;
1926 	l2tp->length = htons(plen);
1927 	l2tp->tunnel_id = htons(session->proto.l2tp.peer_tunnel_id);
1928 	l2tp->session_id = htons(session->peer_session_id);
1929 	if (pipex_session_is_l2tp_data_sequencing_on(session)) {
1930 		seq = (struct pipex_l2tp_seq_header *)(l2tp + 1);
1931 		l2tp->flagsver |= PIPEX_L2TP_FLAG_SEQUENCE;
1932 		seq->ns = htons(session->proto.l2tp.ns_nxt);
1933 		session->proto.l2tp.ns_nxt++;
1934 		session->proto.l2tp.ns_gap++;
1935 		session->proto.l2tp.nr_acked = session->proto.l2tp.nr_nxt - 1;
1936 		seq->nr = htons(session->proto.l2tp.nr_acked);
1937 	}
1938 	l2tp->flagsver = htons(l2tp->flagsver);
1939 
1940 	plen += sizeof(struct udphdr);
1941 	udp = (struct udphdr *)(mtod(m0, caddr_t) + hlen);
1942 	udp->uh_sport = session->local.sin6.sin6_port;
1943 	udp->uh_dport = session->peer.sin6.sin6_port;
1944 	udp->uh_ulen = htons(plen);
1945 	udp->uh_sum = 0;
1946 
1947 	m0->m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
1948 	m0->m_pkthdr.ph_ifidx = session->pipex_iface->ifnet_this->if_index;
1949 #if NPF > 0
1950 	pf_pkt_addr_changed(m0);
1951 #endif
1952 	switch (session->peer.sin6.sin6_family) {
1953 	case AF_INET:
1954 		ip = mtod(m0, struct ip *);
1955 		ip->ip_p = IPPROTO_UDP;
1956 		ip->ip_src = session->local.sin4.sin_addr;
1957 		ip->ip_dst = session->peer.sin4.sin_addr;
1958 		ip->ip_len = htons(hlen + plen);
1959 		ip->ip_ttl = MAXTTL;
1960 		ip->ip_tos = 0;
1961 		ip->ip_off = 0;
1962 
1963 		if (ip_output(m0, NULL, NULL, 0, NULL, NULL,
1964 		    session->proto.l2tp.ipsecflowinfo) != 0) {
1965 			PIPEX_DBG((session, LOG_DEBUG, "ip_output failed."));
1966 			goto drop;
1967 		}
1968 		break;
1969 #ifdef INET6
1970 	case AF_INET6:
1971 		ip6 = mtod(m0, struct ip6_hdr *);
1972 
1973 		ip6->ip6_flow = 0;
1974 		ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
1975 		ip6->ip6_vfc |= IPV6_VERSION;
1976 		ip6->ip6_nxt = IPPROTO_UDP;
1977 		ip6->ip6_src = session->local.sin6.sin6_addr;
1978 		(void)in6_embedscope(&ip6->ip6_dst,
1979 		    &session->peer.sin6, NULL);
1980 		/* ip6->ip6_plen will be filled in ip6_output. */
1981 
1982 		if (ip6_output(m0, NULL, NULL, 0, NULL, NULL) != 0) {
1983 			PIPEX_DBG((session, LOG_DEBUG, "ip6_output failed."));
1984 			goto drop;
1985 		}
1986 		break;
1987 #endif
1988 	}
1989 	udpstat.udps_opackets++;
1990 
1991 	if (datalen > 0) {	/* network layer only */
1992 		/* countup statistics */
1993 		session->stat.opackets++;
1994 		session->stat.obytes += datalen;
1995 	}
1996 
1997 	return;
1998 drop:
1999 	session->stat.oerrors++;
2000 }
2001 
2002 struct pipex_session *
2003 pipex_l2tp_lookup_session(struct mbuf *m0, int off)
2004 {
2005 	struct pipex_session *session;
2006 	uint16_t flags, session_id, ver;
2007 	u_char *cp, buf[PIPEX_L2TP_MINLEN];
2008 
2009 	if (m0->m_pkthdr.len < off + PIPEX_L2TP_MINLEN) {
2010 		PIPEX_DBG((NULL, LOG_DEBUG,
2011 		    "<%s> packet length is too short", __func__));
2012 		goto not_ours;
2013 	}
2014 
2015 	/* get first 16bits of L2TP */
2016 	m_copydata(m0, off, sizeof(buf), buf);
2017 	cp = buf;
2018 	GETSHORT(flags, cp);
2019 	ver = flags & PIPEX_L2TP_VER_MASK;
2020 
2021 	/* l2tp version must be '2' */
2022 	if (ver != PIPEX_L2TP_VER) {
2023 		PIPEX_DBG((NULL, LOG_DEBUG,
2024 		    "<%s> l2tp header wrong version %u.", __func__, ver));
2025 		goto not_ours;
2026 	}
2027 	if ((flags & PIPEX_L2TP_FLAG_TYPE) != 0)
2028 		goto not_ours;
2029 
2030 	if (flags & PIPEX_L2TP_FLAG_LENGTH)
2031 		cp += 2;			/* skip length field */
2032 	cp += 2;				/* skip tunnel-id field */
2033 	GETSHORT(session_id, cp);		/* get session-id field */
2034 
2035 	/* lookup pipex session table */
2036 	session = pipex_lookup_by_session_id(PIPEX_PROTO_L2TP, session_id);
2037 #ifdef PIPEX_DEBUG
2038 	if (session == NULL) {
2039 		PIPEX_DBG((NULL, LOG_DEBUG,
2040 		    "<%s> session not found (id=%d)", __func__, session_id));
2041 		goto not_ours;
2042 	}
2043 #endif
2044 
2045 	return (session);
2046 
2047 not_ours:
2048 	return (NULL);
2049 }
2050 
2051 struct mbuf *
2052 pipex_l2tp_input(struct mbuf *m0, int off0, struct pipex_session *session,
2053     uint32_t ipsecflowinfo)
2054 {
2055 	struct pipex_l2tp_session *l2tp_session;
2056 	int length, offset, hlen, nseq;
2057 	u_char *cp, *nsp, *nrp;
2058 	uint16_t flags, ns = 0, nr = 0;
2059 	int rewind = 0;
2060 
2061 	length = offset = ns = nr = 0;
2062 	l2tp_session = &session->proto.l2tp;
2063 	l2tp_session->ipsecflowinfo = ipsecflowinfo;
2064 	nsp = nrp = NULL;
2065 
2066 	m_copydata(m0, off0, sizeof(flags), (caddr_t)&flags);
2067 
2068 	flags = ntohs(flags) & PIPEX_L2TP_FLAG_MASK;
2069 	KASSERT((flags & PIPEX_L2TP_FLAG_TYPE) == 0);
2070 
2071 	hlen = 2;				/* flags and version fields */
2072 	if (flags & PIPEX_L2TP_FLAG_LENGTH)	/* length */
2073 		hlen += 2;
2074 	hlen += 4;				/* tunnel-id and session-id */
2075 	if (flags & PIPEX_L2TP_FLAG_SEQUENCE)	/* ns and nr */
2076 		hlen += 4;
2077 	if (flags & PIPEX_L2TP_FLAG_OFFSET)	/* offset */
2078 		hlen += 2;
2079 
2080 	PIPEX_PULLUP(m0, off0 + hlen);
2081 	if (m0  == NULL)
2082 		goto drop;
2083 
2084 	cp = mtod(m0, u_char *) + off0;
2085 	cp += 2;	/* flags and version */
2086 	if (flags & PIPEX_L2TP_FLAG_LENGTH)
2087 		GETSHORT(length, cp);
2088 	else
2089 		length = m0->m_pkthdr.len - off0;
2090 	cp += 4;	/* skip tunnel-id and session-id field */
2091 
2092 	/* pullup for seek sequences in header */
2093 	nseq = 0;
2094 	if (flags & PIPEX_L2TP_FLAG_SEQUENCE) {
2095 		nsp = cp;
2096 		GETSHORT(ns, cp);
2097 		nrp = cp;
2098 		GETSHORT(nr, cp);
2099 
2100 		nr++;
2101 		if (SEQ16_GT(nr, l2tp_session->ns_una) &&
2102 		    SEQ16_LE(nr, l2tp_session->ns_nxt))
2103 			/* update 'ns_una' only if the ns is in valid range */
2104 			l2tp_session->ns_una = nr;
2105 		if (SEQ16_LT(ns, l2tp_session->nr_nxt)) {
2106 			rewind = 1;
2107 			if (SEQ16_LT(ns,
2108 			    l2tp_session->nr_nxt - PIPEX_REWIND_LIMIT))
2109 				goto out_seq;
2110 		}
2111 
2112 		ns++;
2113 		nseq = SEQ16_SUB(ns, l2tp_session->nr_nxt);
2114 		if (!rewind)
2115 			l2tp_session->nr_nxt = ns;
2116 	}
2117 	if (flags & PIPEX_L2TP_FLAG_OFFSET)
2118 		GETSHORT(offset, cp);
2119 
2120 	length -= hlen + offset;
2121 	hlen += off0 + offset;
2122 	if ((m0 = pipex_common_input(session, m0, hlen, length)) == NULL) {
2123 		/* ok,  The packet is for PIPEX */
2124 		if (!rewind)
2125 			session->proto.l2tp.nr_gap += nseq;
2126 		return (NULL);
2127 	}
2128 
2129 	if (rewind)
2130 		goto out_seq;
2131 
2132 	/*
2133 	 * overwrite sequence numbers to adjust a gap between pipex and
2134 	 * userland.
2135 	 */
2136 	if (flags & PIPEX_L2TP_FLAG_SEQUENCE) {
2137 		--ns; --nr;	/* revert original values */
2138 		ns -= l2tp_session->nr_gap;
2139 		PUTSHORT(ns, nsp);
2140 
2141 		if (l2tp_session->ns_nxt == l2tp_session->ns_una) {
2142 			nr -= l2tp_session->ns_gap;
2143 			l2tp_session->ul_ns_una = nr;
2144 		} else {
2145 			/*
2146 			 * There are sending packets they are not acked.
2147 			 * In this situation, (ack - snd_gap) may points
2148 			 * before sending window of userland.  So we don't
2149 			 * update the ack number.
2150 			 */
2151 			nr = l2tp_session->ul_ns_una;
2152 		}
2153 		PUTSHORT(nr, nrp);
2154 	}
2155 
2156 	return (m0);
2157 out_seq:
2158 	pipex_session_log(session, LOG_DEBUG,
2159 	    "Received bad data packet: out of sequence: seq=%u(%u-) "
2160 	    "ack=%u(%u-%u)", ns, l2tp_session->nr_nxt, nr, l2tp_session->ns_una,
2161 	    l2tp_session->ns_nxt);
2162 
2163 	/* FALLTHROUGH */
2164 drop:
2165 	m_freem(m0);
2166 	session->stat.ierrors++;
2167 
2168 	return (NULL);
2169 }
2170 
2171 struct pipex_session *
2172 pipex_l2tp_userland_lookup_session_ipv4(struct mbuf *m0, struct in_addr dst)
2173 {
2174 	struct sockaddr_in sin;
2175 
2176 	memset(&sin, 0, sizeof(sin));
2177 	sin.sin_len = sizeof(sin);
2178 	sin.sin_family = AF_INET;
2179 	sin.sin_addr = dst;
2180 
2181 	return pipex_l2tp_userland_lookup_session(m0, sintosa(&sin));
2182 }
2183 
2184 #ifdef INET6
2185 struct pipex_session *
2186 pipex_l2tp_userland_lookup_session_ipv6(struct mbuf *m0, struct in6_addr dst)
2187 {
2188 	struct sockaddr_in6 sin6;
2189 
2190 	memset(&sin6, 0, sizeof(sin6));
2191 	sin6.sin6_len = sizeof(sin6);
2192 	sin6.sin6_family = AF_INET6;
2193 	in6_recoverscope(&sin6, &dst);
2194 
2195 	return pipex_l2tp_userland_lookup_session(m0, sin6tosa(&sin6));
2196 }
2197 #endif
2198 
2199 struct pipex_session *
2200 pipex_l2tp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa)
2201 {
2202 	struct pipex_l2tp_header l2tp;
2203 	struct pipex_hash_head *list;
2204 	struct pipex_session *session;
2205 	uint16_t session_id, tunnel_id, flags;
2206 
2207 	if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6)
2208 		return (NULL);
2209 
2210 	/* pullup */
2211 	if (m0->m_pkthdr.len < sizeof(l2tp)) {
2212 		PIPEX_DBG((NULL, LOG_DEBUG,
2213 		    "<%s> packet length is too short", __func__));
2214 		return (NULL);
2215 	}
2216 
2217 	/* get flags */
2218 	m_copydata(m0, 0, sizeof(l2tp), (caddr_t)&l2tp);
2219 	flags = ntohs(l2tp.flagsver);
2220 
2221 	/* l2tp version must be '2' */
2222 	if ((flags & PIPEX_L2TP_VER_MASK) != PIPEX_L2TP_VER) {
2223 		PIPEX_DBG((NULL, LOG_DEBUG,
2224 		    "<%s> l2tp header wrong version.", __func__));
2225 		return (NULL);
2226 	}
2227 	/* We need L2TP data messages only */
2228 	if ((flags & PIPEX_L2TP_FLAG_TYPE) != 0)
2229 		return (NULL);
2230 	/* No need to hook packets that don't have the sequence field */
2231 	if ((flags & PIPEX_L2TP_FLAG_SEQUENCE) == 0)
2232 		return (NULL);
2233 
2234 	session_id = ntohs(l2tp.session_id);
2235 	tunnel_id = ntohs(l2tp.tunnel_id);
2236 
2237 	list = PIPEX_PEER_ADDR_HASHTABLE(pipex_sockaddr_hash_key(sa));
2238 	LIST_FOREACH(session, list, peer_addr_chain) {
2239 		if (pipex_sockaddr_compar_addr(
2240 		    (struct sockaddr *)&session->peer, sa) != 0)
2241 			continue;
2242 		if (session->proto.l2tp.peer_tunnel_id != tunnel_id)
2243 			continue;
2244 		if (session->peer_session_id == session_id)
2245 			break;
2246 	}
2247 #ifdef PIPEX_DEBUG
2248 	if (session == NULL) {
2249 		PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found "
2250 		    "(tunnel_id=%d, session_id=%d)", __func__,
2251 		    tunnel_id, session_id));
2252 	}
2253 #endif
2254 
2255 	return (session);
2256 }
2257 
2258 struct mbuf *
2259 pipex_l2tp_userland_output(struct mbuf *m0, struct pipex_session *session)
2260 {
2261 	struct pipex_l2tp_header *l2tp;
2262 	struct pipex_l2tp_seq_header *seq;
2263 	uint16_t ns, nr;
2264 
2265 	/* check length */
2266 	PIPEX_PULLUP(m0, sizeof(struct pipex_l2tp_header) +
2267 	    sizeof(struct pipex_l2tp_seq_header));
2268 	if (m0 == NULL)
2269 		return (NULL);
2270 
2271 	l2tp = mtod(m0, struct pipex_l2tp_header *);
2272 	KASSERT(ntohs(l2tp->flagsver) & PIPEX_L2TP_FLAG_SEQUENCE);
2273 
2274 	/*
2275 	 * overwrite sequence numbers to adjust a gap between pipex and
2276 	 * userland.
2277 	 */
2278 		seq = (struct pipex_l2tp_seq_header *)(l2tp + 1);
2279 		ns = ntohs(seq->ns);
2280 		nr = ntohs(seq->nr);
2281 
2282 		ns += session->proto.l2tp.ns_gap;
2283 		seq->ns = htons(ns);
2284 		session->proto.l2tp.ns_nxt++;
2285 
2286 		nr += session->proto.l2tp.nr_gap;
2287 		seq->nr = htons(nr);
2288 		if (SEQ16_GT(nr, session->proto.l2tp.nr_acked))
2289 			session->proto.l2tp.nr_acked = nr;
2290 
2291 	return (m0);
2292 }
2293 #endif /* PIPEX_L2TP */
2294 
2295 #ifdef PIPEX_MPPE
2296 /**********************************************************************
2297  * MPPE
2298  ***********************************************************************/
2299 #define	PIPEX_COHERENCY_CNT_MASK		0x0fff
2300 Static void
2301 pipex_mppe_init(struct pipex_mppe *mppe, int stateless, int keylenbits,
2302     u_char *master_key, int has_oldkey)
2303 {
2304 	memset(mppe, 0, sizeof(struct pipex_mppe));
2305 	if (stateless)
2306 		mppe->stateless = 1;
2307 	if (has_oldkey)
2308 		mppe->old_session_keys =
2309 		    pool_get(&mppe_key_pool, PR_WAITOK);
2310 	else
2311 		mppe->old_session_keys = NULL;
2312 	memcpy(mppe->master_key, master_key, sizeof(mppe->master_key));
2313 
2314 	mppe->keylenbits = keylenbits;
2315 	switch (keylenbits) {
2316 	case 40:
2317 	case 56:
2318 		mppe->keylen = 8;
2319 		break;
2320 	case 128:
2321 		mppe->keylen = 16;
2322 		break;
2323 	}
2324 
2325 	GetNewKeyFromSHA(mppe->master_key, mppe->master_key, mppe->keylen,
2326 	    mppe->session_key);
2327 	pipex_mppe_reduce_key(mppe);
2328 	pipex_mppe_setkey(mppe);
2329 }
2330 
2331 void
2332 pipex_session_init_mppe_recv(struct pipex_session *session, int stateless,
2333     int keylenbits, u_char *master_key)
2334 {
2335 	pipex_mppe_init(&session->mppe_recv, stateless, keylenbits,
2336 	    master_key, stateless);
2337 	session->ppp_flags |= PIPEX_PPP_MPPE_ACCEPTED;
2338 }
2339 
2340 void
2341 pipex_session_init_mppe_send(struct pipex_session *session, int stateless,
2342     int keylenbits, u_char *master_key)
2343 {
2344 	pipex_mppe_init(&session->mppe_send, stateless, keylenbits,
2345 	    master_key, 0);
2346 	session->ppp_flags |= PIPEX_PPP_MPPE_ENABLED;
2347 }
2348 
2349 #include <crypto/sha1.h>
2350 
2351 static u_char SHAPad1[] = {
2352 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2353 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2354 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2355 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2356 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2357 }, SHAPad2[] = {
2358 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2359 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2360 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2361 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2362 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2363 };
2364 
2365 Static void
2366 GetNewKeyFromSHA(u_char *StartKey, u_char *SessionKey, int SessionKeyLength,
2367     u_char *InterimKey)
2368 {
2369 	u_char Digest[20];
2370 	SHA1_CTX Context;
2371 
2372 	SHA1Init(&Context);
2373 	SHA1Update(&Context, StartKey, SessionKeyLength);
2374 	SHA1Update(&Context, SHAPad1, 40);
2375 	SHA1Update(&Context, SessionKey, SessionKeyLength);
2376 	SHA1Update(&Context, SHAPad2, 40);
2377 	SHA1Final(Digest, &Context);
2378 
2379 	memcpy(InterimKey, Digest, SessionKeyLength);
2380 }
2381 
2382 Static void
2383 pipex_mppe_reduce_key(struct pipex_mppe *mppe)
2384 {
2385 	switch (mppe->keylenbits) {
2386 	case 40:
2387 		mppe->session_key[1] = 0x26;
2388 		mppe->session_key[2] = 0x9e;
2389 	case 56:
2390 		mppe->session_key[0] = 0xd1;
2391 	}
2392 }
2393 
2394 Static void
2395 mppe_key_change(struct pipex_mppe *mppe)
2396 {
2397 	u_char interim[16];
2398 	struct rc4_ctx keychg;
2399 
2400 	memset(&keychg, 0, sizeof(keychg));
2401 
2402 	GetNewKeyFromSHA(mppe->master_key, mppe->session_key, mppe->keylen,
2403 	    interim);
2404 
2405 	rc4_keysetup(&keychg, interim, mppe->keylen);
2406 	rc4_crypt(&keychg, interim, mppe->session_key, mppe->keylen);
2407 
2408 	pipex_mppe_reduce_key(mppe);
2409 
2410 	if (mppe->old_session_keys) {
2411 		int idx = mppe->coher_cnt & PIPEX_MPPE_OLDKEYMASK;
2412 		memcpy(mppe->old_session_keys[idx],
2413 		    mppe->session_key, PIPEX_MPPE_KEYLEN);
2414 	}
2415 }
2416 
2417 Static void
2418 pipex_mppe_input(struct mbuf *m0, struct pipex_session *session)
2419 {
2420 	int pktloss, encrypt, flushed, m, n, len;
2421 	struct pipex_mppe *mppe;
2422 	uint16_t coher_cnt;
2423 	struct mbuf *m1;
2424 	u_char *cp;
2425 	int rewind = 0;
2426 
2427 	/* pullup */
2428 	PIPEX_PULLUP(m0, sizeof(coher_cnt));
2429 	if (m0 == NULL)
2430 		goto drop;
2431 
2432 	mppe = &session->mppe_recv;
2433 	/* get header information */
2434 	cp = mtod(m0, u_char *);
2435 	GETSHORT(coher_cnt, cp);
2436 	flushed = ((coher_cnt & 0x8000) != 0) ? 1 : 0;
2437 	encrypt = ((coher_cnt & 0x1000) != 0) ? 1 : 0;
2438 	coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2439 	pktloss = 0;
2440 
2441 	PIPEX_MPPE_DBG((session, LOG_DEBUG, "in coher_cnt=%03x %s%s",
2442 	    mppe->coher_cnt, (flushed) ? "[flushed]" : "",
2443 	    (encrypt) ? "[encrypt]" : ""));
2444 
2445 	if (encrypt == 0) {
2446 		pipex_session_log(session, LOG_DEBUG,
2447 		    "Received unexpected MPPE packet.(no ecrypt)");
2448 		goto drop;
2449 	}
2450 
2451 	/* adjust mbuf */
2452 	m_adj(m0, sizeof(coher_cnt));
2453 
2454 	/*
2455 	 * L2TP data session may be used without sequencing, PPP frames may
2456 	 * arrive in disorder.  The 'coherency counter' of MPPE detects such
2457 	 * situations, but we cannot distinguish between 'disorder' and
2458 	 * 'packet loss' exactly.
2459 	 *
2460 	 * When 'coherency counter' detects lost packets greater than
2461 	 * (4096 - 256), we treat as 'disorder' otherwise treat as
2462 	 * 'packet loss'.
2463 	 */
2464     {
2465 	int coher_cnt0;
2466 
2467 	coher_cnt0 = coher_cnt;
2468 	if (coher_cnt < mppe->coher_cnt)
2469 		coher_cnt0 += 0x1000;
2470 	if (coher_cnt0 - mppe->coher_cnt > 0x0f00) {
2471 		if (!mppe->stateless ||
2472 		    coher_cnt0 - mppe->coher_cnt
2473 		    <= 0x1000 - PIPEX_MPPE_NOLDKEY) {
2474 			pipex_session_log(session, LOG_DEBUG,
2475 			    "Workaround the out-of-sequence PPP framing problem: "
2476 			    "%d => %d", mppe->coher_cnt, coher_cnt);
2477 			goto drop;
2478 		}
2479 		rewind = 1;
2480 	}
2481     }
2482 
2483 	if (mppe->stateless != 0) {
2484 		if (!rewind) {
2485 			mppe_key_change(mppe);
2486 			while (mppe->coher_cnt != coher_cnt) {
2487 				mppe->coher_cnt++;
2488 				mppe->coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2489 				mppe_key_change(mppe);
2490 				pktloss++;
2491 			}
2492 		}
2493 		pipex_mppe_setoldkey(mppe, coher_cnt);
2494 	} else {
2495 		if (flushed) {
2496 			if (coher_cnt < mppe->coher_cnt) {
2497 				coher_cnt += 0x1000;
2498 			}
2499 			pktloss += coher_cnt - mppe->coher_cnt;
2500 			m = mppe->coher_cnt / 256;
2501 			n = coher_cnt / 256;
2502 			while (m++ < n)
2503 				mppe_key_change(mppe);
2504 
2505 			coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2506 			mppe->coher_cnt = coher_cnt;
2507 		} else if (mppe->coher_cnt != coher_cnt) {
2508 			/* Send CCP ResetReq */
2509 			PIPEX_DBG((session, LOG_DEBUG, "CCP SendResetReq"));
2510 			pipex_ccp_output(session, CCP_RESETREQ,
2511 			    session->ccp_id++);
2512 			goto drop;
2513 		}
2514 		if ((coher_cnt & 0xff) == 0xff) {
2515 			mppe_key_change(mppe);
2516 			flushed = 1;
2517 		}
2518 		if (flushed)
2519 			pipex_mppe_setkey(mppe);
2520 	}
2521 
2522 	if (pktloss > 1000) {
2523 		pipex_session_log(session, LOG_DEBUG,
2524 		    "%d packets loss.", pktloss);
2525 	}
2526 
2527 	/* decrypt ppp payload */
2528 	for (m1 = m0; m1; m1 = m1->m_next) {
2529 		cp = mtod(m1, u_char *);
2530 		len = m1->m_len;
2531 		pipex_mppe_crypt(mppe, len, cp, cp);
2532 	}
2533 
2534 	if (!rewind) {
2535 		/* update coher_cnt */
2536 		mppe->coher_cnt++;
2537 		mppe->coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2538 	}
2539 	if (m0->m_pkthdr.len < PIPEX_PPPMINLEN)
2540 		goto drop;
2541 
2542 	pipex_ppp_input(m0, session, 1);
2543 
2544 	return;
2545 drop:
2546 	m_freem(m0);
2547 	session->stat.ierrors++;
2548 }
2549 
2550 Static void
2551 pipex_mppe_output(struct mbuf *m0, struct pipex_session *session,
2552     uint16_t protocol)
2553 {
2554 	int encrypt, flushed, len;
2555 	struct mppe_header {
2556 		uint16_t coher_cnt;
2557 		uint16_t protocol;
2558 	} __packed *hdr;
2559 	u_char *cp;
2560 	struct pipex_mppe *mppe;
2561 	struct mbuf *m;
2562 
2563 	mppe = &session->mppe_send;
2564 
2565 	/*
2566 	 * create a deep-copy if the mbuf has a shared mbuf cluster.
2567 	 * this is required to handle cases of tcp retransmition.
2568 	 */
2569 	for (m = m0; m != NULL; m = m->m_next) {
2570 		if (M_READONLY(m)) {
2571 			m = m_dup_pkt(m0, max_linkhdr, M_NOWAIT);
2572 			m_freem(m0);
2573 			if (m == NULL)
2574 				goto drop;
2575 			m0 = m;
2576 			break;
2577 		}
2578 	}
2579 	/* prepend mppe header */
2580 	M_PREPEND(m0, sizeof(struct mppe_header), M_NOWAIT);
2581 	if (m0 == NULL)
2582 		goto drop;
2583 	hdr = mtod(m0, struct mppe_header *);
2584 	hdr->protocol = protocol;
2585 
2586 	/* check coherency counter */
2587 	flushed = 0;
2588 	encrypt = 1;
2589 
2590 	if (mppe->stateless != 0) {
2591 		flushed = 1;
2592 		mppe_key_change(mppe);
2593 	} else {
2594 		if ((mppe->coher_cnt % 0x100) == 0xff) {
2595 			flushed = 1;
2596 			mppe_key_change(mppe);
2597 		} else if (mppe->resetreq != 0) {
2598 			flushed = 1;
2599 			mppe->resetreq = 0;
2600 		}
2601 	}
2602 
2603 	if (flushed)
2604 		pipex_mppe_setkey(mppe);
2605 
2606 	PIPEX_MPPE_DBG((session, LOG_DEBUG, "out coher_cnt=%03x %s%s",
2607 	    mppe->coher_cnt, (flushed) ? "[flushed]" : "",
2608 	    (encrypt) ? "[encrypt]" : ""));
2609 
2610 	/* setup header information */
2611 	hdr->coher_cnt = (mppe->coher_cnt++) & PIPEX_COHERENCY_CNT_MASK;
2612 	hdr->coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2613 	if (flushed)
2614 		hdr->coher_cnt |= 0x8000;
2615 	if (encrypt)
2616 		hdr->coher_cnt |= 0x1000;
2617 
2618 	hdr->protocol = htons(hdr->protocol);
2619 	hdr->coher_cnt = htons(hdr->coher_cnt);
2620 
2621 	/* encrypt chain */
2622 	for (m = m0; m; m = m->m_next) {
2623 		cp = mtod(m, u_char *);
2624 		len = m->m_len;
2625 		if (m == m0 && len > offsetof(struct mppe_header, protocol)) {
2626 			len -= offsetof(struct mppe_header, protocol);
2627 			cp += offsetof(struct mppe_header, protocol);
2628 		}
2629 		pipex_mppe_crypt(mppe, len, cp, cp);
2630 	}
2631 
2632 	pipex_ppp_output(m0, session, PPP_COMP);
2633 
2634 	return;
2635 drop:
2636 	session->stat.oerrors++;
2637 }
2638 
2639 Static void
2640 pipex_ccp_input(struct mbuf *m0, struct pipex_session *session)
2641 {
2642 	u_char *cp;
2643 	int code, id, len;
2644 
2645 	if (m0->m_pkthdr.len < PPP_HDRLEN)
2646 		goto drop;
2647 	if ((m0 = m_pullup(m0, PPP_HDRLEN)) == NULL)
2648 		goto drop;
2649 
2650 	cp = mtod(m0, u_char *);
2651 	GETCHAR(code, cp);
2652 	GETCHAR(id, cp);
2653 	GETSHORT(len, cp);
2654 
2655 	switch (code) {
2656 	case CCP_RESETREQ:
2657 		PIPEX_DBG((session, LOG_DEBUG, "CCP RecvResetReq"));
2658 		session->mppe_send.resetreq = 1;
2659 #ifndef PIPEX_NO_CCP_RESETACK
2660 		PIPEX_DBG((session, LOG_DEBUG, "CCP SendResetAck"));
2661 		pipex_ccp_output(session, CCP_RESETACK, id);
2662 #endif
2663 		/* ignore error */
2664 		break;
2665 	case CCP_RESETACK:
2666 		PIPEX_DBG((session, LOG_DEBUG, "CCP RecvResetAck"));
2667 		break;
2668 	default:
2669 		PIPEX_DBG((session, LOG_DEBUG, "CCP Recv code=%d", code));
2670 		goto drop;
2671 	}
2672 	m_freem(m0);
2673 
2674 	return;
2675 drop:
2676 	m_freem(m0);
2677 	session->stat.ierrors++;
2678 }
2679 
2680 Static int
2681 pipex_ccp_output(struct pipex_session *session, int code, int id)
2682 {
2683 	u_char *cp;
2684 	struct mbuf *m;
2685 
2686 	MGETHDR(m, M_DONTWAIT, MT_DATA);
2687 	if (m == NULL) {
2688 		session->stat.oerrors++;
2689 		return (1);
2690 	}
2691 	m->m_pkthdr.len = m->m_len = 4;
2692 	cp = mtod(m, u_char *);
2693 	PUTCHAR(code, cp);
2694 	PUTCHAR(id, cp);
2695 	PUTSHORT(4, cp);
2696 
2697 	pipex_ppp_output(m, session, PPP_CCP);
2698 
2699 	return (0);
2700 }
2701 #endif
2702 /***********************************************************************
2703  * Miscellaneous fuctions
2704  ***********************************************************************/
2705 /* adapted from FreeBSD:src/usr.sbin/ppp/tcpmss.c */
2706 /*
2707  * Copyright (c) 2000 Ruslan Ermilov and Brian Somers <brian@Awfulhak.org>
2708  * All rights reserved.
2709  *
2710  * Redistribution and use in source and binary forms, with or without
2711  * modification, are permitted provided that the following conditions
2712  * are met:
2713  * 1. Redistributions of source code must retain the above copyright
2714  *    notice, this list of conditions and the following disclaimer.
2715  * 2. Redistributions in binary form must reproduce the above copyright
2716  *    notice, this list of conditions and the following disclaimer in the
2717  *    documentation and/or other materials provided with the distribution.
2718  *
2719  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2720  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2721  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2722  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2723  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2724  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2725  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2726  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2727  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2728  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2729  * SUCH DAMAGE.
2730  *
2731  * $FreeBSD: src/usr.sbin/ppp/tcpmss.c,v 1.1.4.3 2001/07/19 11:39:54 brian Exp $
2732  */
2733 #define TCP_OPTLEN_IN_SEGMENT	12	/* timestamp option and padding */
2734 #define MAXMSS(mtu) (mtu - sizeof(struct ip) - sizeof(struct tcphdr) - \
2735     TCP_OPTLEN_IN_SEGMENT)
2736 /*
2737  * The following macro is used to update an internet checksum.  "acc" is a
2738  * 32-bit accumulation of all the changes to the checksum (adding in old
2739  * 16-bit words and subtracting out new words), and "cksum" is the checksum
2740  * value to be updated.
2741  */
2742 #define ADJUST_CHECKSUM(acc, cksum) {			\
2743 	acc += cksum;					\
2744 	if (acc < 0) {					\
2745 		acc = -acc;				\
2746 		acc = (acc >> 16) + (acc & 0xffff);	\
2747 		acc += acc >> 16;			\
2748 		cksum = (u_short) ~acc;			\
2749 	} else {					\
2750 		acc = (acc >> 16) + (acc & 0xffff);	\
2751 		acc += acc >> 16;			\
2752 		cksum = (u_short) acc;			\
2753 	}						\
2754 }
2755 
2756 /*
2757  * Rewrite max-segment-size TCP option to avoid PMTU blackhole issues.
2758  * The mtu parameter should be the MTU bottleneck (as far as we know)
2759  * on the link between the source and the destination.
2760  */
2761 Static struct mbuf *
2762 adjust_tcp_mss(struct mbuf *m0, int mtu)
2763 {
2764 	int opt, optlen, acc, mss, maxmss, lpktp;
2765 	struct ip *pip;
2766 	struct tcphdr *th;
2767 	u_char *pktp, *mssp;
2768 	u_int16_t ip_off;
2769 
2770 	lpktp = sizeof(struct ip) + sizeof(struct tcphdr) + PIPEX_TCP_OPTLEN;
2771 	lpktp = MIN(lpktp, m0->m_pkthdr.len);
2772 
2773 	PIPEX_PULLUP(m0, lpktp);
2774 	if (m0 == NULL)
2775 		goto drop;
2776 
2777 	pktp = mtod(m0, char *);
2778 	pip = (struct ip *)pktp;
2779 	ip_off = ntohs(pip->ip_off);
2780 
2781 	/* Non TCP or fragmented packet must not have a MSS option */
2782 	if (pip->ip_p != IPPROTO_TCP ||
2783 	    (ip_off & IP_MF) != 0 || (ip_off & IP_OFFMASK) != 0)
2784 		goto handled;
2785 
2786 	pktp += pip->ip_hl << 2;
2787 	lpktp -= pip->ip_hl << 2;
2788 
2789 	/* packet is broken */
2790 	if (sizeof(struct tcphdr) > lpktp)
2791 		goto drop;
2792 	th = (struct tcphdr *)pktp;
2793 
2794 	/*
2795 	 * As RFC 973, a MSS field must only be sent in the initial
2796 	 * connection request(it must be with SYN).
2797 	 */
2798 	if ((th->th_flags & TH_SYN) == 0)
2799 		goto handled;
2800 
2801 	lpktp = MIN(th->th_off << 4, lpktp);
2802 
2803 	pktp += sizeof(struct tcphdr);
2804 	lpktp -= sizeof(struct tcphdr);
2805 	while (lpktp >= TCPOLEN_MAXSEG) {
2806 		GETCHAR(opt, pktp);
2807 		switch (opt) {
2808 		case TCPOPT_MAXSEG:
2809 			GETCHAR(optlen, pktp);
2810 			mssp = pktp;		/* mss place holder */
2811 			GETSHORT(mss, pktp);
2812 			maxmss = MAXMSS(mtu);
2813 			if (mss > maxmss) {
2814 				PIPEX_DBG((NULL, LOG_DEBUG,
2815 				    "change tcp-mss %d => %d", mss, maxmss));
2816 				PUTSHORT(maxmss, mssp);
2817 				acc = htons(mss);
2818 				acc -= htons(maxmss);
2819 				ADJUST_CHECKSUM(acc, th->th_sum);
2820 			}
2821 			goto handled;
2822 			/* NOTREACHED */
2823 		case TCPOPT_EOL:
2824 			goto handled;
2825 			/* NOTREACHED */
2826 		case TCPOPT_NOP:
2827 			lpktp--;
2828 			break;
2829 		default:
2830 			GETCHAR(optlen, pktp);
2831 			if (optlen < 2)	/* packet is broken */
2832 				goto drop;
2833 			pktp += optlen - 2;
2834 			lpktp -= optlen;
2835 			break;
2836 		}
2837 	}
2838 
2839 handled:
2840 	return (m0);
2841 
2842 drop:
2843 	m_freem(m0);
2844 	return (NULL);
2845 }
2846 
2847 /*
2848  *  Check whether a packet should reset idle timer
2849  *  Returns 1 to don't reset timer (i.e. the packet is "idle" packet)
2850  */
2851 Static struct mbuf *
2852 ip_is_idle_packet(struct mbuf *m0, int *ris_idle)
2853 {
2854 	u_int16_t ip_off;
2855 	const struct udphdr *uh;
2856 	struct ip *pip;
2857 	int len;
2858 
2859 	/* pullup ip header */
2860 	len = sizeof(struct ip);
2861 	PIPEX_PULLUP(m0, len);
2862 	if (m0 == NULL)
2863 		goto error;
2864 	pip = mtod(m0, struct ip *);
2865 
2866 	/*
2867 	 * the packet which fragmentations was not the idle packet.
2868 	 */
2869 	ip_off = ntohs(pip->ip_off);
2870 	if ((ip_off & IP_MF) || ((ip_off & IP_OFFMASK) != 0))
2871 		goto is_active;
2872 
2873 	switch (pip->ip_p) {
2874 	case IPPROTO_IGMP:
2875 		goto is_active;
2876 	case IPPROTO_ICMP:
2877 		len = pip->ip_hl * 4 + 8;
2878 		PIPEX_PULLUP(m0, len);
2879 		if (m0 == NULL)
2880 			goto error;
2881 		pip = mtod(m0, struct ip *);
2882 
2883 		switch (((unsigned char *) pip)[pip->ip_hl * 4]) {
2884 		case 0:	/* Echo Reply */
2885 		case 8:	/* Echo Request */
2886 			goto is_active;
2887 		default:
2888 			goto is_idle;
2889 		}
2890 
2891 	case IPPROTO_UDP:
2892 	case IPPROTO_TCP:
2893 		len = pip->ip_hl * 4 + sizeof(struct udphdr);
2894 		PIPEX_PULLUP(m0, len);
2895 		if (m0 == NULL)
2896 			goto error;
2897 		pip = mtod(m0, struct ip *);
2898 		uh = (struct udphdr *)(mtod(m0, caddr_t) + pip->ip_hl * 4);
2899 
2900 		switch (ntohs(uh->uh_sport)) {
2901 		case 53:	/* DOMAIN */
2902 		case 67:	/* BOOTPS */
2903 		case 68:	/* BOOTPC */
2904 		case 123:	/* NTP */
2905 		case 137:	/* NETBIOS-NS */
2906 		case 520:	/* RIP */
2907 			goto is_idle;
2908 		}
2909 		switch (ntohs(uh->uh_dport)) {
2910 		case 53:	/* DOMAIN */
2911 		case 67:	/* BOOTPS */
2912 		case 68:	/* BOOTPC */
2913 		case 123:	/* NTP */
2914 		case 137:	/* NETBIOS-NS */
2915 		case 520:	/* RIP */
2916 			goto is_idle;
2917 		}
2918 		goto is_active;
2919 	default:
2920 		goto is_active;
2921 	}
2922 
2923 is_active:
2924 	*ris_idle = 0;
2925 	return (m0);
2926 
2927 is_idle:
2928 	*ris_idle = 1;
2929 	return (m0);
2930 
2931 error:
2932 	return (NULL);
2933 }
2934 
2935 Static void
2936 pipex_session_log(struct pipex_session *session, int prio, const char *fmt, ...)
2937 {
2938 	char logbuf[1024];
2939 	va_list ap;
2940 
2941 	logpri(prio);
2942 	if (session != NULL) {
2943 		addlog("pipex: ppp=%d iface=%s protocol=%s id=%d ",
2944 		    session->ppp_id, session->pipex_iface->ifnet_this->if_xname,
2945 		    (session->protocol == PIPEX_PROTO_PPPOE)? "PPPoE" :
2946 		    (session->protocol == PIPEX_PROTO_PPTP)? "PPTP" :
2947 		    (session->protocol == PIPEX_PROTO_L2TP) ? "L2TP" :
2948 		    "Unknown", session->session_id);
2949 	} else
2950 		addlog("pipex: ");
2951 
2952 	va_start(ap, fmt);
2953 	vsnprintf(logbuf, sizeof(logbuf), fmt, ap);
2954 	va_end(ap);
2955 	addlog("%s\n", logbuf);
2956 }
2957 
2958 Static uint32_t
2959 pipex_sockaddr_hash_key(struct sockaddr *sa)
2960 {
2961 	switch (sa->sa_family) {
2962 	case AF_INET:
2963 		return ntohl(satosin(sa)->sin_addr.s_addr);
2964 	case AF_INET6:
2965 		return ntohl(satosin6(sa)->sin6_addr.s6_addr32[3]);
2966 	}
2967 	panic("pipex_sockaddr_hash_key: unknown address family");
2968 	return (0);
2969 }
2970 
2971 /*
2972  * Compare struct sockaddr_in{,6} with the address only.
2973  * The port number is not covered.
2974  */
2975 Static int
2976 pipex_sockaddr_compar_addr(struct sockaddr *a, struct sockaddr *b)
2977 {
2978 	int cmp;
2979 
2980 	cmp = b->sa_family - a->sa_family;
2981 	if (cmp != 0)
2982 		return cmp;
2983 	switch (a->sa_family) {
2984 	case AF_INET:
2985 		return (satosin(b)->sin_addr.s_addr -
2986 		    satosin(a)->sin_addr.s_addr);
2987 	case AF_INET6:
2988 		cmp = (satosin6(b)->sin6_scope_id - satosin6(a)->sin6_scope_id);
2989 		if (cmp != 0)
2990 			return cmp;
2991 		return (memcmp(&satosin6(a)->sin6_addr,
2992 		    &satosin6(b)->sin6_addr,
2993 		    sizeof(struct in6_addr)));
2994 	}
2995 	panic("pipex_sockaddr_compar_addr: unknown address family");
2996 
2997 	return (-1);
2998 }
2999 
3000 Static inline int
3001 pipex_mppe_setkey(struct pipex_mppe *mppe)
3002 {
3003 	rc4_keysetup(&mppe->rc4ctx, mppe->session_key, mppe->keylen);
3004 
3005 	return (0);
3006 }
3007 
3008 Static inline int
3009 pipex_mppe_setoldkey(struct pipex_mppe *mppe, uint16_t coher_cnt)
3010 {
3011 	KASSERT(mppe->old_session_keys != NULL);
3012 
3013 	rc4_keysetup(&mppe->rc4ctx,
3014 	    mppe->old_session_keys[coher_cnt & PIPEX_MPPE_OLDKEYMASK],
3015 	    mppe->keylen);
3016 
3017 	return (0);
3018 }
3019 
3020 Static inline void
3021 pipex_mppe_crypt(struct pipex_mppe *mppe, int len, u_char *indata,
3022     u_char *outdata)
3023 {
3024 	rc4_crypt(&mppe->rc4ctx, indata, outdata, len);
3025 }
3026 
3027 int
3028 pipex_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
3029     size_t newlen)
3030 {
3031 	switch (name[0]) {
3032 	case PIPEXCTL_ENABLE:
3033 		if (namelen != 1)
3034 			return (ENOTDIR);
3035 		return (sysctl_int(oldp, oldlenp, newp, newlen,
3036 		    &pipex_enable));
3037 	case PIPEXCTL_INQ:
3038 	        return (sysctl_mq(name + 1, namelen - 1,
3039 		    oldp, oldlenp, newp, newlen, &pipexinq));
3040 	case PIPEXCTL_OUTQ:
3041 	        return (sysctl_mq(name + 1, namelen - 1,
3042 		    oldp, oldlenp, newp, newlen, &pipexoutq));
3043 	default:
3044 		return (ENOPROTOOPT);
3045 	}
3046 	/* NOTREACHED */
3047 }
3048