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