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