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