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