xref: /openbsd-src/sys/net/pipex.c (revision 1a8dbaac879b9f3335ad7fb25429ce63ac1d6bac)
1 /*	$OpenBSD: pipex.c,v 1.127 2020/08/30 19:48:16 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 PIPEXSMODE:
167 		break;
168 
169 	case PIPEXGMODE:
170 		*(int *)data = 1;
171 		break;
172 
173 	case PIPEXCSESSION:
174 		ret = pipex_config_session(
175 		    (struct pipex_session_config_req *)data, ownersc);
176 		break;
177 
178 	case PIPEXGSTAT:
179 		ret = pipex_get_stat((struct pipex_session_stat_req *)data,
180 		    ownersc);
181 		break;
182 
183 	case PIPEXGCLOSED:
184 		ret = pipex_get_closed((struct pipex_session_list_req *)data,
185 		    ownersc);
186 		break;
187 
188 	default:
189 		ret = ENOTTY;
190 		break;
191 	}
192 
193 	return (ret);
194 }
195 
196 /************************************************************************
197  * Session management functions
198  ************************************************************************/
199 int
200 pipex_init_session(struct pipex_session **rsession,
201     struct pipex_session_req *req)
202 {
203 	struct pipex_session *session;
204 #ifdef PIPEX_PPPOE
205 	struct ifnet *over_ifp = NULL;
206 #endif
207 
208 	/* Checks requeted parameters.  */
209 	switch (req->pr_protocol) {
210 #ifdef PIPEX_PPPOE
211 	case PIPEX_PROTO_PPPOE:
212 		over_ifp = ifunit(req->pr_proto.pppoe.over_ifname);
213 		if (over_ifp == NULL)
214 			return (EINVAL);
215 		if (req->pr_peer_address.ss_family != AF_UNSPEC)
216 			return (EINVAL);
217 		break;
218 #endif
219 #if defined(PIPEX_L2TP) || defined(PIPEX_PPTP)
220 	case PIPEX_PROTO_PPTP:
221 	case PIPEX_PROTO_L2TP:
222 		switch (req->pr_peer_address.ss_family) {
223 		case AF_INET:
224 			if (req->pr_peer_address.ss_len !=
225 			    sizeof(struct sockaddr_in))
226 				return (EINVAL);
227 			break;
228 #ifdef INET6
229 		case AF_INET6:
230 			if (req->pr_peer_address.ss_len !=
231 			    sizeof(struct sockaddr_in6))
232 				return (EINVAL);
233 			break;
234 #endif
235 		default:
236 			return (EPROTONOSUPPORT);
237 		}
238 		if (req->pr_peer_address.ss_family !=
239 		    req->pr_local_address.ss_family ||
240 		    req->pr_peer_address.ss_len !=
241 		    req->pr_local_address.ss_len)
242 			return (EINVAL);
243 		break;
244 #endif /* defined(PIPEX_PPTP) || defined(PIPEX_L2TP) */
245 	default:
246 		return (EPROTONOSUPPORT);
247 	}
248 #ifdef PIPEX_MPPE
249 	if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_ACCEPTED) != 0) {
250 		if (req->pr_mppe_recv.keylenbits <= 0)
251 			return (EINVAL);
252 	}
253 	if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_ENABLED) != 0) {
254 		if (req->pr_mppe_send.keylenbits <= 0)
255 			return (EINVAL);
256 	}
257 	if ((req->pr_ppp_flags & PIPEX_PPP_MPPE_REQUIRED) != 0) {
258 		if ((req->pr_ppp_flags &
259 		    (PIPEX_PPP_MPPE_ACCEPTED | PIPEX_PPP_MPPE_ENABLED)) !=
260 		    (PIPEX_PPP_MPPE_ACCEPTED | PIPEX_PPP_MPPE_ENABLED))
261 			return (EINVAL);
262 	}
263 #endif
264 
265 	/* prepare a new session */
266 	session = pool_get(&pipex_session_pool, PR_WAITOK | PR_ZERO);
267 	session->state = PIPEX_STATE_INITIAL;
268 	session->protocol = req->pr_protocol;
269 	session->session_id = req->pr_session_id;
270 	session->peer_session_id = req->pr_peer_session_id;
271 	session->peer_mru = req->pr_peer_mru;
272 	session->timeout_sec = req->pr_timeout_sec;
273 	session->ppp_flags = req->pr_ppp_flags;
274 	session->ppp_id = req->pr_ppp_id;
275 
276 	session->ip_forward = 1;
277 
278 	session->ip_address.sin_family = AF_INET;
279 	session->ip_address.sin_len = sizeof(struct sockaddr_in);
280 	session->ip_address.sin_addr = req->pr_ip_address;
281 
282 	session->ip_netmask.sin_family = AF_INET;
283 	session->ip_netmask.sin_len = sizeof(struct sockaddr_in);
284 	session->ip_netmask.sin_addr = req->pr_ip_netmask;
285 
286 	if (session->ip_netmask.sin_addr.s_addr == 0L)
287 		session->ip_netmask.sin_addr.s_addr = 0xffffffffL;
288 	session->ip_address.sin_addr.s_addr &=
289 	    session->ip_netmask.sin_addr.s_addr;
290 
291 	if (req->pr_peer_address.ss_len > 0)
292 		memcpy(&session->peer, &req->pr_peer_address,
293 		    MIN(req->pr_peer_address.ss_len, sizeof(session->peer)));
294 	if (req->pr_local_address.ss_len > 0)
295 		memcpy(&session->local, &req->pr_local_address,
296 		    MIN(req->pr_local_address.ss_len, sizeof(session->local)));
297 #ifdef PIPEX_PPPOE
298 	if (req->pr_protocol == PIPEX_PROTO_PPPOE)
299 		session->proto.pppoe.over_ifidx = over_ifp->if_index;
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, (caddr_t)&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), (caddr_t)&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), (caddr_t)&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), (caddr_t)&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), (caddr_t)&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), (caddr_t)&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, (caddr_t)&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 
1632 	hlen = sizeof(struct pipex_l2tp_header) +
1633 	    ((pipex_session_is_l2tp_data_sequencing_on(session))
1634 		    ? sizeof(struct pipex_l2tp_seq_header) : 0) +
1635 	    sizeof(struct udphdr) +
1636 #ifdef INET6
1637 	    ((session->peer.sin6.sin6_family == AF_INET6)
1638 		    ? sizeof(struct ip6_hdr) : sizeof(struct ip));
1639 #else
1640 	    sizeof(struct ip);
1641 #endif
1642 
1643 	datalen = 0;
1644 	if (m0 != NULL) {
1645 		datalen = m0->m_pkthdr.len;
1646 		M_PREPEND(m0, hlen, M_NOWAIT);
1647 		if (m0 == NULL)
1648 			goto drop;
1649 	} else {
1650 		MGETHDR(m0, M_DONTWAIT, MT_DATA);
1651 		if (m0 == NULL)
1652 			goto drop;
1653 		KASSERT(hlen <= MHLEN);
1654 		m0->m_pkthdr.len = m0->m_len = hlen;
1655 	}
1656 
1657 #ifdef INET6
1658 	hlen = (session->peer.sin6.sin6_family == AF_INET6)
1659 	    ? sizeof(struct ip6_hdr) : sizeof(struct ip);
1660 #else
1661 	hlen = sizeof(struct ip);
1662 #endif
1663 	plen = datalen + sizeof(struct pipex_l2tp_header) +
1664 	    ((pipex_session_is_l2tp_data_sequencing_on(session))
1665 		    ? sizeof(struct pipex_l2tp_seq_header) : 0);
1666 
1667 	l2tp = (struct pipex_l2tp_header *)
1668 	    (mtod(m0, caddr_t) + hlen + sizeof(struct udphdr));
1669 	l2tp->flagsver = PIPEX_L2TP_VER | PIPEX_L2TP_FLAG_LENGTH;
1670 	l2tp->length = htons(plen);
1671 	l2tp->tunnel_id = htons(session->proto.l2tp.peer_tunnel_id);
1672 	l2tp->session_id = htons(session->peer_session_id);
1673 	if (pipex_session_is_l2tp_data_sequencing_on(session)) {
1674 		seq = (struct pipex_l2tp_seq_header *)(l2tp + 1);
1675 		l2tp->flagsver |= PIPEX_L2TP_FLAG_SEQUENCE;
1676 		seq->ns = htons(session->proto.l2tp.ns_nxt);
1677 		session->proto.l2tp.ns_nxt++;
1678 		session->proto.l2tp.ns_gap++;
1679 		session->proto.l2tp.nr_acked = session->proto.l2tp.nr_nxt - 1;
1680 		seq->nr = htons(session->proto.l2tp.nr_acked);
1681 	}
1682 	l2tp->flagsver = htons(l2tp->flagsver);
1683 
1684 	plen += sizeof(struct udphdr);
1685 	udp = (struct udphdr *)(mtod(m0, caddr_t) + hlen);
1686 	udp->uh_sport = session->local.sin6.sin6_port;
1687 	udp->uh_dport = session->peer.sin6.sin6_port;
1688 	udp->uh_ulen = htons(plen);
1689 	udp->uh_sum = 0;
1690 
1691 	m0->m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
1692 	m0->m_pkthdr.ph_ifidx = session->ifindex;
1693 #if NPF > 0
1694 	pf_pkt_addr_changed(m0);
1695 #endif
1696 	switch (session->peer.sin6.sin6_family) {
1697 	case AF_INET:
1698 		ip = mtod(m0, struct ip *);
1699 		ip->ip_p = IPPROTO_UDP;
1700 		ip->ip_src = session->local.sin4.sin_addr;
1701 		ip->ip_dst = session->peer.sin4.sin_addr;
1702 		ip->ip_len = htons(hlen + plen);
1703 		ip->ip_ttl = MAXTTL;
1704 		ip->ip_tos = 0;
1705 		ip->ip_off = 0;
1706 
1707 		ip_send(m0);
1708 		break;
1709 #ifdef INET6
1710 	case AF_INET6:
1711 		ip6 = mtod(m0, struct ip6_hdr *);
1712 
1713 		ip6->ip6_flow = 0;
1714 		ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
1715 		ip6->ip6_vfc |= IPV6_VERSION;
1716 		ip6->ip6_nxt = IPPROTO_UDP;
1717 		ip6->ip6_src = session->local.sin6.sin6_addr;
1718 		(void)in6_embedscope(&ip6->ip6_dst,
1719 		    &session->peer.sin6, NULL);
1720 		/* ip6->ip6_plen will be filled in ip6_output. */
1721 
1722 		ip6_send(m0);
1723 		break;
1724 #endif
1725 	}
1726 	udpstat_inc(udps_opackets);
1727 
1728 	if (datalen > 0) {	/* network layer only */
1729 		/* countup statistics */
1730 		session->stat.opackets++;
1731 		session->stat.obytes += datalen;
1732 	}
1733 
1734 	return;
1735 drop:
1736 	session->stat.oerrors++;
1737 }
1738 
1739 struct pipex_session *
1740 pipex_l2tp_lookup_session(struct mbuf *m0, int off)
1741 {
1742 	struct pipex_session *session;
1743 	uint16_t flags, session_id, ver;
1744 	u_char *cp, buf[PIPEX_L2TP_MINLEN];
1745 
1746 	if (m0->m_pkthdr.len < off + PIPEX_L2TP_MINLEN) {
1747 		PIPEX_DBG((NULL, LOG_DEBUG,
1748 		    "<%s> packet length is too short", __func__));
1749 		goto not_ours;
1750 	}
1751 
1752 	/* get first 16bits of L2TP */
1753 	m_copydata(m0, off, sizeof(buf), buf);
1754 	cp = buf;
1755 	GETSHORT(flags, cp);
1756 	ver = flags & PIPEX_L2TP_VER_MASK;
1757 
1758 	/* l2tp version must be '2' */
1759 	if (ver != PIPEX_L2TP_VER) {
1760 		PIPEX_DBG((NULL, LOG_DEBUG,
1761 		    "<%s> l2tp header wrong version %u.", __func__, ver));
1762 		goto not_ours;
1763 	}
1764 	if ((flags & PIPEX_L2TP_FLAG_TYPE) != 0)
1765 		goto not_ours;
1766 
1767 	if (flags & PIPEX_L2TP_FLAG_LENGTH)
1768 		cp += 2;			/* skip length field */
1769 	cp += 2;				/* skip tunnel-id field */
1770 	GETSHORT(session_id, cp);		/* get session-id field */
1771 
1772 	/* lookup pipex session table */
1773 	session = pipex_lookup_by_session_id(PIPEX_PROTO_L2TP, session_id);
1774 #ifdef PIPEX_DEBUG
1775 	if (session == NULL) {
1776 		PIPEX_DBG((NULL, LOG_DEBUG,
1777 		    "<%s> session not found (id=%d)", __func__, session_id));
1778 		goto not_ours;
1779 	}
1780 #endif
1781 
1782 	return (session);
1783 
1784 not_ours:
1785 	return (NULL);
1786 }
1787 
1788 struct mbuf *
1789 pipex_l2tp_input(struct mbuf *m0, int off0, struct pipex_session *session,
1790     uint32_t ipsecflowinfo)
1791 {
1792 	struct pipex_l2tp_session *l2tp_session;
1793 	int length, offset, hlen, nseq;
1794 	u_char *cp, *nsp, *nrp;
1795 	uint16_t flags, ns = 0, nr = 0;
1796 	int rewind = 0;
1797 
1798 	NET_ASSERT_LOCKED();
1799 	length = offset = ns = nr = 0;
1800 	l2tp_session = &session->proto.l2tp;
1801 	l2tp_session->ipsecflowinfo = ipsecflowinfo;
1802 	nsp = nrp = NULL;
1803 
1804 	m_copydata(m0, off0, sizeof(flags), (caddr_t)&flags);
1805 
1806 	flags = ntohs(flags) & PIPEX_L2TP_FLAG_MASK;
1807 	KASSERT((flags & PIPEX_L2TP_FLAG_TYPE) == 0);
1808 
1809 	hlen = 2;				/* flags and version fields */
1810 	if (flags & PIPEX_L2TP_FLAG_LENGTH)	/* length */
1811 		hlen += 2;
1812 	hlen += 4;				/* tunnel-id and session-id */
1813 	if (flags & PIPEX_L2TP_FLAG_SEQUENCE)	/* ns and nr */
1814 		hlen += 4;
1815 	if (flags & PIPEX_L2TP_FLAG_OFFSET)	/* offset */
1816 		hlen += 2;
1817 
1818 	PIPEX_PULLUP(m0, off0 + hlen);
1819 	if (m0  == NULL)
1820 		goto drop;
1821 
1822 	cp = mtod(m0, u_char *) + off0;
1823 	cp += 2;	/* flags and version */
1824 	if (flags & PIPEX_L2TP_FLAG_LENGTH)
1825 		GETSHORT(length, cp);
1826 	else
1827 		length = m0->m_pkthdr.len - off0;
1828 	cp += 4;	/* skip tunnel-id and session-id field */
1829 
1830 	/* pullup for seek sequences in header */
1831 	nseq = 0;
1832 	if (flags & PIPEX_L2TP_FLAG_SEQUENCE) {
1833 		nsp = cp;
1834 		GETSHORT(ns, cp);
1835 		nrp = cp;
1836 		GETSHORT(nr, cp);
1837 
1838 		nr++;
1839 		if (SEQ16_GT(nr, l2tp_session->ns_una) &&
1840 		    SEQ16_LE(nr, l2tp_session->ns_nxt))
1841 			/* update 'ns_una' only if the ns is in valid range */
1842 			l2tp_session->ns_una = nr;
1843 		if (SEQ16_LT(ns, l2tp_session->nr_nxt)) {
1844 			rewind = 1;
1845 			if (SEQ16_LT(ns,
1846 			    l2tp_session->nr_nxt - PIPEX_REWIND_LIMIT))
1847 				goto out_seq;
1848 		}
1849 
1850 		ns++;
1851 		nseq = SEQ16_SUB(ns, l2tp_session->nr_nxt);
1852 		if (!rewind)
1853 			l2tp_session->nr_nxt = ns;
1854 	}
1855 	if (flags & PIPEX_L2TP_FLAG_OFFSET)
1856 		GETSHORT(offset, cp);
1857 
1858 	length -= hlen + offset;
1859 	hlen += off0 + offset;
1860 	if ((m0 = pipex_common_input(session, m0, hlen, length)) == NULL) {
1861 		/* ok,  The packet is for PIPEX */
1862 		if (!rewind)
1863 			session->proto.l2tp.nr_gap += nseq;
1864 		return (NULL);
1865 	}
1866 
1867 	if (rewind)
1868 		goto out_seq;
1869 
1870 	/*
1871 	 * overwrite sequence numbers to adjust a gap between pipex and
1872 	 * userland.
1873 	 */
1874 	if (flags & PIPEX_L2TP_FLAG_SEQUENCE) {
1875 		--ns; --nr;	/* revert original values */
1876 		ns -= l2tp_session->nr_gap;
1877 		PUTSHORT(ns, nsp);
1878 
1879 		if (l2tp_session->ns_nxt == l2tp_session->ns_una) {
1880 			nr -= l2tp_session->ns_gap;
1881 			l2tp_session->ul_ns_una = nr;
1882 		} else {
1883 			/*
1884 			 * There are sending packets they are not acked.
1885 			 * In this situation, (ack - snd_gap) may points
1886 			 * before sending window of userland.  So we don't
1887 			 * update the ack number.
1888 			 */
1889 			nr = l2tp_session->ul_ns_una;
1890 		}
1891 		PUTSHORT(nr, nrp);
1892 	}
1893 
1894 	return (m0);
1895 out_seq:
1896 	pipex_session_log(session, LOG_DEBUG,
1897 	    "Received bad data packet: out of sequence: seq=%u(%u-) "
1898 	    "ack=%u(%u-%u)", ns, l2tp_session->nr_nxt, nr, l2tp_session->ns_una,
1899 	    l2tp_session->ns_nxt);
1900 
1901 	/* FALLTHROUGH */
1902 drop:
1903 	m_freem(m0);
1904 	session->stat.ierrors++;
1905 
1906 	return (NULL);
1907 }
1908 
1909 struct pipex_session *
1910 pipex_l2tp_userland_lookup_session_ipv4(struct mbuf *m0, struct in_addr dst)
1911 {
1912 	struct sockaddr_in sin;
1913 
1914 	memset(&sin, 0, sizeof(sin));
1915 	sin.sin_len = sizeof(sin);
1916 	sin.sin_family = AF_INET;
1917 	sin.sin_addr = dst;
1918 
1919 	return pipex_l2tp_userland_lookup_session(m0, sintosa(&sin));
1920 }
1921 
1922 #ifdef INET6
1923 struct pipex_session *
1924 pipex_l2tp_userland_lookup_session_ipv6(struct mbuf *m0, struct in6_addr dst)
1925 {
1926 	struct sockaddr_in6 sin6;
1927 
1928 	memset(&sin6, 0, sizeof(sin6));
1929 	sin6.sin6_len = sizeof(sin6);
1930 	sin6.sin6_family = AF_INET6;
1931 	in6_recoverscope(&sin6, &dst);
1932 
1933 	return pipex_l2tp_userland_lookup_session(m0, sin6tosa(&sin6));
1934 }
1935 #endif
1936 
1937 struct pipex_session *
1938 pipex_l2tp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa)
1939 {
1940 	struct pipex_l2tp_header l2tp;
1941 	struct pipex_hash_head *list;
1942 	struct pipex_session *session;
1943 	uint16_t session_id, tunnel_id, flags;
1944 
1945 	if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6)
1946 		return (NULL);
1947 
1948 	/* pullup */
1949 	if (m0->m_pkthdr.len < sizeof(l2tp)) {
1950 		PIPEX_DBG((NULL, LOG_DEBUG,
1951 		    "<%s> packet length is too short", __func__));
1952 		return (NULL);
1953 	}
1954 
1955 	/* get flags */
1956 	m_copydata(m0, 0, sizeof(l2tp), (caddr_t)&l2tp);
1957 	flags = ntohs(l2tp.flagsver);
1958 
1959 	/* l2tp version must be '2' */
1960 	if ((flags & PIPEX_L2TP_VER_MASK) != PIPEX_L2TP_VER) {
1961 		PIPEX_DBG((NULL, LOG_DEBUG,
1962 		    "<%s> l2tp header wrong version.", __func__));
1963 		return (NULL);
1964 	}
1965 	/* We need L2TP data messages only */
1966 	if ((flags & PIPEX_L2TP_FLAG_TYPE) != 0)
1967 		return (NULL);
1968 	/* No need to hook packets that don't have the sequence field */
1969 	if ((flags & PIPEX_L2TP_FLAG_SEQUENCE) == 0)
1970 		return (NULL);
1971 
1972 	session_id = ntohs(l2tp.session_id);
1973 	tunnel_id = ntohs(l2tp.tunnel_id);
1974 
1975 	list = PIPEX_PEER_ADDR_HASHTABLE(pipex_sockaddr_hash_key(sa));
1976 	LIST_FOREACH(session, list, peer_addr_chain) {
1977 		if (pipex_sockaddr_compar_addr(&session->peer.sa, sa) != 0)
1978 			continue;
1979 		if (session->proto.l2tp.peer_tunnel_id != tunnel_id)
1980 			continue;
1981 		if (session->peer_session_id == session_id)
1982 			break;
1983 	}
1984 #ifdef PIPEX_DEBUG
1985 	if (session == NULL) {
1986 		PIPEX_DBG((NULL, LOG_DEBUG, "<%s> session not found "
1987 		    "(tunnel_id=%d, session_id=%d)", __func__,
1988 		    tunnel_id, session_id));
1989 	}
1990 #endif
1991 
1992 	return (session);
1993 }
1994 
1995 struct mbuf *
1996 pipex_l2tp_userland_output(struct mbuf *m0, struct pipex_session *session)
1997 {
1998 	struct pipex_l2tp_header *l2tp;
1999 	struct pipex_l2tp_seq_header *seq;
2000 	uint16_t ns, nr;
2001 
2002 	/* check length */
2003 	PIPEX_PULLUP(m0, sizeof(struct pipex_l2tp_header) +
2004 	    sizeof(struct pipex_l2tp_seq_header));
2005 	if (m0 == NULL)
2006 		return (NULL);
2007 
2008 	l2tp = mtod(m0, struct pipex_l2tp_header *);
2009 	KASSERT(ntohs(l2tp->flagsver) & PIPEX_L2TP_FLAG_SEQUENCE);
2010 
2011 	/*
2012 	 * overwrite sequence numbers to adjust a gap between pipex and
2013 	 * userland.
2014 	 */
2015 		seq = (struct pipex_l2tp_seq_header *)(l2tp + 1);
2016 		ns = ntohs(seq->ns);
2017 		nr = ntohs(seq->nr);
2018 
2019 		ns += session->proto.l2tp.ns_gap;
2020 		seq->ns = htons(ns);
2021 		session->proto.l2tp.ns_nxt++;
2022 
2023 		nr += session->proto.l2tp.nr_gap;
2024 		seq->nr = htons(nr);
2025 		if (SEQ16_GT(nr, session->proto.l2tp.nr_acked))
2026 			session->proto.l2tp.nr_acked = nr;
2027 
2028 	return (m0);
2029 }
2030 #endif /* PIPEX_L2TP */
2031 
2032 #ifdef PIPEX_MPPE
2033 /**********************************************************************
2034  * MPPE
2035  ***********************************************************************/
2036 #define	PIPEX_COHERENCY_CNT_MASK		0x0fff
2037 
2038 static inline int
2039 pipex_mppe_setkey(struct pipex_mppe *mppe)
2040 {
2041 	rc4_keysetup(&mppe->rc4ctx, mppe->session_key, mppe->keylen);
2042 
2043 	return (0);
2044 }
2045 
2046 static inline int
2047 pipex_mppe_setoldkey(struct pipex_mppe *mppe, uint16_t coher_cnt)
2048 {
2049 	KASSERT(mppe->old_session_keys != NULL);
2050 
2051 	rc4_keysetup(&mppe->rc4ctx,
2052 	    mppe->old_session_keys[coher_cnt & PIPEX_MPPE_OLDKEYMASK],
2053 	    mppe->keylen);
2054 
2055 	return (0);
2056 }
2057 
2058 static inline void
2059 pipex_mppe_crypt(struct pipex_mppe *mppe, int len, u_char *indata,
2060     u_char *outdata)
2061 {
2062 	rc4_crypt(&mppe->rc4ctx, indata, outdata, len);
2063 }
2064 
2065 Static void
2066 pipex_mppe_init(struct pipex_mppe *mppe, int stateless, int keylenbits,
2067     u_char *master_key, int has_oldkey)
2068 {
2069 	memset(mppe, 0, sizeof(struct pipex_mppe));
2070 	if (stateless)
2071 		mppe->stateless = 1;
2072 	if (has_oldkey)
2073 		mppe->old_session_keys =
2074 		    pool_get(&mppe_key_pool, PR_WAITOK);
2075 	else
2076 		mppe->old_session_keys = NULL;
2077 	memcpy(mppe->master_key, master_key, sizeof(mppe->master_key));
2078 
2079 	mppe->keylenbits = keylenbits;
2080 	switch (keylenbits) {
2081 	case 40:
2082 	case 56:
2083 		mppe->keylen = 8;
2084 		break;
2085 	case 128:
2086 		mppe->keylen = 16;
2087 		break;
2088 	}
2089 
2090 	GetNewKeyFromSHA(mppe->master_key, mppe->master_key, mppe->keylen,
2091 	    mppe->session_key);
2092 	pipex_mppe_reduce_key(mppe);
2093 	pipex_mppe_setkey(mppe);
2094 }
2095 
2096 void
2097 pipex_session_init_mppe_recv(struct pipex_session *session, int stateless,
2098     int keylenbits, u_char *master_key)
2099 {
2100 	pipex_mppe_init(&session->mppe_recv, stateless, keylenbits,
2101 	    master_key, stateless);
2102 	session->ppp_flags |= PIPEX_PPP_MPPE_ACCEPTED;
2103 }
2104 
2105 void
2106 pipex_session_init_mppe_send(struct pipex_session *session, int stateless,
2107     int keylenbits, u_char *master_key)
2108 {
2109 	pipex_mppe_init(&session->mppe_send, stateless, keylenbits,
2110 	    master_key, 0);
2111 	session->ppp_flags |= PIPEX_PPP_MPPE_ENABLED;
2112 }
2113 
2114 #include <crypto/sha1.h>
2115 
2116 static u_char SHAPad1[] = {
2117 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2118 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2119 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2120 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2121 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2122 }, SHAPad2[] = {
2123 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2124 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2125 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2126 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2127 	0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
2128 };
2129 
2130 Static void
2131 GetNewKeyFromSHA(u_char *StartKey, u_char *SessionKey, int SessionKeyLength,
2132     u_char *InterimKey)
2133 {
2134 	u_char Digest[20];
2135 	SHA1_CTX Context;
2136 
2137 	SHA1Init(&Context);
2138 	SHA1Update(&Context, StartKey, SessionKeyLength);
2139 	SHA1Update(&Context, SHAPad1, 40);
2140 	SHA1Update(&Context, SessionKey, SessionKeyLength);
2141 	SHA1Update(&Context, SHAPad2, 40);
2142 	SHA1Final(Digest, &Context);
2143 
2144 	memcpy(InterimKey, Digest, SessionKeyLength);
2145 }
2146 
2147 Static void
2148 pipex_mppe_reduce_key(struct pipex_mppe *mppe)
2149 {
2150 	switch (mppe->keylenbits) {
2151 	case 40:
2152 		mppe->session_key[0] = 0xd1;
2153 		mppe->session_key[1] = 0x26;
2154 		mppe->session_key[2] = 0x9e;
2155 		break;
2156 	case 56:
2157 		mppe->session_key[0] = 0xd1;
2158 		break;
2159 	}
2160 }
2161 
2162 Static void
2163 mppe_key_change(struct pipex_mppe *mppe)
2164 {
2165 	u_char interim[16];
2166 	struct rc4_ctx keychg;
2167 
2168 	memset(&keychg, 0, sizeof(keychg));
2169 
2170 	GetNewKeyFromSHA(mppe->master_key, mppe->session_key, mppe->keylen,
2171 	    interim);
2172 
2173 	rc4_keysetup(&keychg, interim, mppe->keylen);
2174 	rc4_crypt(&keychg, interim, mppe->session_key, mppe->keylen);
2175 
2176 	pipex_mppe_reduce_key(mppe);
2177 
2178 	if (mppe->old_session_keys) {
2179 		int idx = mppe->coher_cnt & PIPEX_MPPE_OLDKEYMASK;
2180 		memcpy(mppe->old_session_keys[idx],
2181 		    mppe->session_key, PIPEX_MPPE_KEYLEN);
2182 	}
2183 }
2184 
2185 Static void
2186 pipex_mppe_input(struct mbuf *m0, struct pipex_session *session)
2187 {
2188 	int pktloss, encrypt, flushed, m, n, len;
2189 	struct pipex_mppe *mppe;
2190 	uint16_t coher_cnt;
2191 	struct mbuf *m1;
2192 	u_char *cp;
2193 	int rewind = 0;
2194 
2195 	/* pullup */
2196 	PIPEX_PULLUP(m0, sizeof(coher_cnt));
2197 	if (m0 == NULL)
2198 		goto drop;
2199 
2200 	mppe = &session->mppe_recv;
2201 	/* get header information */
2202 	cp = mtod(m0, u_char *);
2203 	GETSHORT(coher_cnt, cp);
2204 	flushed = ((coher_cnt & 0x8000) != 0) ? 1 : 0;
2205 	encrypt = ((coher_cnt & 0x1000) != 0) ? 1 : 0;
2206 	coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2207 	pktloss = 0;
2208 
2209 	PIPEX_MPPE_DBG((session, LOG_DEBUG, "in coher_cnt=%03x %s%s",
2210 	    mppe->coher_cnt, (flushed) ? "[flushed]" : "",
2211 	    (encrypt) ? "[encrypt]" : ""));
2212 
2213 	if (encrypt == 0) {
2214 		pipex_session_log(session, LOG_DEBUG,
2215 		    "Received unexpected MPPE packet.(no ecrypt)");
2216 		goto drop;
2217 	}
2218 
2219 	/* adjust mbuf */
2220 	m_adj(m0, sizeof(coher_cnt));
2221 
2222 	/*
2223 	 * L2TP data session may be used without sequencing, PPP frames may
2224 	 * arrive in disorder.  The 'coherency counter' of MPPE detects such
2225 	 * situations, but we cannot distinguish between 'disorder' and
2226 	 * 'packet loss' exactly.
2227 	 *
2228 	 * When 'coherency counter' detects lost packets greater than
2229 	 * (4096 - 256), we treat as 'disorder' otherwise treat as
2230 	 * 'packet loss'.
2231 	 */
2232     {
2233 	int coher_cnt0;
2234 
2235 	coher_cnt0 = coher_cnt;
2236 	if (coher_cnt < mppe->coher_cnt)
2237 		coher_cnt0 += 0x1000;
2238 	if (coher_cnt0 - mppe->coher_cnt > 0x0f00) {
2239 		if (!mppe->stateless ||
2240 		    coher_cnt0 - mppe->coher_cnt
2241 		    <= 0x1000 - PIPEX_MPPE_NOLDKEY) {
2242 			pipex_session_log(session, LOG_DEBUG,
2243 			    "Workaround the out-of-sequence PPP framing problem: "
2244 			    "%d => %d", mppe->coher_cnt, coher_cnt);
2245 			goto drop;
2246 		}
2247 		rewind = 1;
2248 	}
2249     }
2250 
2251 	if (mppe->stateless != 0) {
2252 		if (!rewind) {
2253 			mppe_key_change(mppe);
2254 			while (mppe->coher_cnt != coher_cnt) {
2255 				mppe->coher_cnt++;
2256 				mppe->coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2257 				mppe_key_change(mppe);
2258 				pktloss++;
2259 			}
2260 		}
2261 		pipex_mppe_setoldkey(mppe, coher_cnt);
2262 	} else {
2263 		if (flushed) {
2264 			if (coher_cnt < mppe->coher_cnt) {
2265 				coher_cnt += 0x1000;
2266 			}
2267 			pktloss += coher_cnt - mppe->coher_cnt;
2268 			m = mppe->coher_cnt / 256;
2269 			n = coher_cnt / 256;
2270 			while (m++ < n)
2271 				mppe_key_change(mppe);
2272 
2273 			coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2274 			mppe->coher_cnt = coher_cnt;
2275 		} else if (mppe->coher_cnt != coher_cnt) {
2276 			/* Send CCP ResetReq */
2277 			PIPEX_DBG((session, LOG_DEBUG, "CCP SendResetReq"));
2278 			pipex_ccp_output(session, CCP_RESETREQ,
2279 			    session->ccp_id++);
2280 			goto drop;
2281 		}
2282 		if ((coher_cnt & 0xff) == 0xff) {
2283 			mppe_key_change(mppe);
2284 			flushed = 1;
2285 		}
2286 		if (flushed)
2287 			pipex_mppe_setkey(mppe);
2288 	}
2289 
2290 	if (pktloss > 1000) {
2291 		pipex_session_log(session, LOG_DEBUG,
2292 		    "%d packets loss.", pktloss);
2293 	}
2294 
2295 	/* decrypt ppp payload */
2296 	for (m1 = m0; m1; m1 = m1->m_next) {
2297 		cp = mtod(m1, u_char *);
2298 		len = m1->m_len;
2299 		pipex_mppe_crypt(mppe, len, cp, cp);
2300 	}
2301 
2302 	if (!rewind) {
2303 		/* update coher_cnt */
2304 		mppe->coher_cnt++;
2305 		mppe->coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2306 	}
2307 	if (m0->m_pkthdr.len < PIPEX_PPPMINLEN)
2308 		goto drop;
2309 
2310 	pipex_ppp_input(m0, session, 1);
2311 
2312 	return;
2313 drop:
2314 	m_freem(m0);
2315 	session->stat.ierrors++;
2316 }
2317 
2318 Static void
2319 pipex_mppe_output(struct mbuf *m0, struct pipex_session *session,
2320     uint16_t protocol)
2321 {
2322 	int encrypt, flushed, len;
2323 	struct mppe_header {
2324 		uint16_t coher_cnt;
2325 		uint16_t protocol;
2326 	} __packed *hdr;
2327 	u_char *cp;
2328 	struct pipex_mppe *mppe;
2329 	struct mbuf *m;
2330 
2331 	mppe = &session->mppe_send;
2332 
2333 	/*
2334 	 * create a deep-copy if the mbuf has a shared mbuf cluster.
2335 	 * this is required to handle cases of tcp retransmition.
2336 	 */
2337 	for (m = m0; m != NULL; m = m->m_next) {
2338 		if (M_READONLY(m)) {
2339 			m = m_dup_pkt(m0, max_linkhdr, M_NOWAIT);
2340 			m_freem(m0);
2341 			if (m == NULL)
2342 				goto drop;
2343 			m0 = m;
2344 			break;
2345 		}
2346 	}
2347 	/* prepend mppe header */
2348 	M_PREPEND(m0, sizeof(struct mppe_header), M_NOWAIT);
2349 	if (m0 == NULL)
2350 		goto drop;
2351 	hdr = mtod(m0, struct mppe_header *);
2352 	hdr->protocol = protocol;
2353 
2354 	/* check coherency counter */
2355 	flushed = 0;
2356 	encrypt = 1;
2357 
2358 	if (mppe->stateless != 0) {
2359 		flushed = 1;
2360 		mppe_key_change(mppe);
2361 	} else {
2362 		if ((mppe->coher_cnt % 0x100) == 0xff) {
2363 			flushed = 1;
2364 			mppe_key_change(mppe);
2365 		} else if (mppe->resetreq != 0) {
2366 			flushed = 1;
2367 			mppe->resetreq = 0;
2368 		}
2369 	}
2370 
2371 	if (flushed)
2372 		pipex_mppe_setkey(mppe);
2373 
2374 	PIPEX_MPPE_DBG((session, LOG_DEBUG, "out coher_cnt=%03x %s%s",
2375 	    mppe->coher_cnt, (flushed) ? "[flushed]" : "",
2376 	    (encrypt) ? "[encrypt]" : ""));
2377 
2378 	/* setup header information */
2379 	hdr->coher_cnt = (mppe->coher_cnt++) & PIPEX_COHERENCY_CNT_MASK;
2380 	hdr->coher_cnt &= PIPEX_COHERENCY_CNT_MASK;
2381 	if (flushed)
2382 		hdr->coher_cnt |= 0x8000;
2383 	if (encrypt)
2384 		hdr->coher_cnt |= 0x1000;
2385 
2386 	hdr->protocol = htons(hdr->protocol);
2387 	hdr->coher_cnt = htons(hdr->coher_cnt);
2388 
2389 	/* encrypt chain */
2390 	for (m = m0; m; m = m->m_next) {
2391 		cp = mtod(m, u_char *);
2392 		len = m->m_len;
2393 		if (m == m0 && len > offsetof(struct mppe_header, protocol)) {
2394 			len -= offsetof(struct mppe_header, protocol);
2395 			cp += offsetof(struct mppe_header, protocol);
2396 		}
2397 		pipex_mppe_crypt(mppe, len, cp, cp);
2398 	}
2399 
2400 	pipex_ppp_output(m0, session, PPP_COMP);
2401 
2402 	return;
2403 drop:
2404 	session->stat.oerrors++;
2405 }
2406 
2407 Static void
2408 pipex_ccp_input(struct mbuf *m0, struct pipex_session *session)
2409 {
2410 	u_char *cp;
2411 	int code, id, len;
2412 
2413 	if (m0->m_pkthdr.len < PPP_HDRLEN)
2414 		goto drop;
2415 	if ((m0 = m_pullup(m0, PPP_HDRLEN)) == NULL)
2416 		goto drop;
2417 
2418 	cp = mtod(m0, u_char *);
2419 	GETCHAR(code, cp);
2420 	GETCHAR(id, cp);
2421 	GETSHORT(len, cp);
2422 
2423 	switch (code) {
2424 	case CCP_RESETREQ:
2425 		PIPEX_DBG((session, LOG_DEBUG, "CCP RecvResetReq"));
2426 		session->mppe_send.resetreq = 1;
2427 #ifndef PIPEX_NO_CCP_RESETACK
2428 		PIPEX_DBG((session, LOG_DEBUG, "CCP SendResetAck"));
2429 		pipex_ccp_output(session, CCP_RESETACK, id);
2430 #endif
2431 		/* ignore error */
2432 		break;
2433 	case CCP_RESETACK:
2434 		PIPEX_DBG((session, LOG_DEBUG, "CCP RecvResetAck"));
2435 		break;
2436 	default:
2437 		PIPEX_DBG((session, LOG_DEBUG, "CCP Recv code=%d", code));
2438 		goto drop;
2439 	}
2440 	m_freem(m0);
2441 
2442 	return;
2443 drop:
2444 	m_freem(m0);
2445 	session->stat.ierrors++;
2446 }
2447 
2448 Static int
2449 pipex_ccp_output(struct pipex_session *session, int code, int id)
2450 {
2451 	u_char *cp;
2452 	struct mbuf *m;
2453 
2454 	MGETHDR(m, M_DONTWAIT, MT_DATA);
2455 	if (m == NULL) {
2456 		session->stat.oerrors++;
2457 		return (1);
2458 	}
2459 	m->m_pkthdr.len = m->m_len = 4;
2460 	cp = mtod(m, u_char *);
2461 	PUTCHAR(code, cp);
2462 	PUTCHAR(id, cp);
2463 	PUTSHORT(4, cp);
2464 
2465 	pipex_ppp_output(m, session, PPP_CCP);
2466 
2467 	return (0);
2468 }
2469 #endif
2470 /***********************************************************************
2471  * Miscellaneous fuctions
2472  ***********************************************************************/
2473 /* adapted from FreeBSD:src/usr.sbin/ppp/tcpmss.c */
2474 /*
2475  * Copyright (c) 2000 Ruslan Ermilov and Brian Somers <brian@Awfulhak.org>
2476  * All rights reserved.
2477  *
2478  * Redistribution and use in source and binary forms, with or without
2479  * modification, are permitted provided that the following conditions
2480  * are met:
2481  * 1. Redistributions of source code must retain the above copyright
2482  *    notice, this list of conditions and the following disclaimer.
2483  * 2. Redistributions in binary form must reproduce the above copyright
2484  *    notice, this list of conditions and the following disclaimer in the
2485  *    documentation and/or other materials provided with the distribution.
2486  *
2487  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2488  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2489  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2490  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2491  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2492  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2493  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2494  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2495  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2496  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2497  * SUCH DAMAGE.
2498  *
2499  * $FreeBSD: src/usr.sbin/ppp/tcpmss.c,v 1.1.4.3 2001/07/19 11:39:54 brian Exp $
2500  */
2501 #define TCP_OPTLEN_IN_SEGMENT	12	/* timestamp option and padding */
2502 #define MAXMSS(mtu) (mtu - sizeof(struct ip) - sizeof(struct tcphdr) - \
2503     TCP_OPTLEN_IN_SEGMENT)
2504 /*
2505  * The following macro is used to update an internet checksum.  "acc" is a
2506  * 32-bit accumulation of all the changes to the checksum (adding in old
2507  * 16-bit words and subtracting out new words), and "cksum" is the checksum
2508  * value to be updated.
2509  */
2510 #define ADJUST_CHECKSUM(acc, cksum) {			\
2511 	acc += cksum;					\
2512 	if (acc < 0) {					\
2513 		acc = -acc;				\
2514 		acc = (acc >> 16) + (acc & 0xffff);	\
2515 		acc += acc >> 16;			\
2516 		cksum = (u_short) ~acc;			\
2517 	} else {					\
2518 		acc = (acc >> 16) + (acc & 0xffff);	\
2519 		acc += acc >> 16;			\
2520 		cksum = (u_short) acc;			\
2521 	}						\
2522 }
2523 
2524 /*
2525  * Rewrite max-segment-size TCP option to avoid PMTU blackhole issues.
2526  * The mtu parameter should be the MTU bottleneck (as far as we know)
2527  * on the link between the source and the destination.
2528  */
2529 Static struct mbuf *
2530 adjust_tcp_mss(struct mbuf *m0, int mtu)
2531 {
2532 	int opt, optlen, acc, mss, maxmss, lpktp;
2533 	struct ip *pip;
2534 	struct tcphdr *th;
2535 	u_char *pktp, *mssp;
2536 	u_int16_t ip_off;
2537 
2538 	lpktp = sizeof(struct ip) + sizeof(struct tcphdr) + PIPEX_TCP_OPTLEN;
2539 	lpktp = MIN(lpktp, m0->m_pkthdr.len);
2540 
2541 	PIPEX_PULLUP(m0, lpktp);
2542 	if (m0 == NULL)
2543 		goto drop;
2544 
2545 	pktp = mtod(m0, char *);
2546 	pip = (struct ip *)pktp;
2547 	ip_off = ntohs(pip->ip_off);
2548 
2549 	/* Non TCP or fragmented packet must not have a MSS option */
2550 	if (pip->ip_p != IPPROTO_TCP ||
2551 	    (ip_off & IP_MF) != 0 || (ip_off & IP_OFFMASK) != 0)
2552 		goto handled;
2553 
2554 	pktp += pip->ip_hl << 2;
2555 	lpktp -= pip->ip_hl << 2;
2556 
2557 	/* packet is broken */
2558 	if (sizeof(struct tcphdr) > lpktp)
2559 		goto drop;
2560 	th = (struct tcphdr *)pktp;
2561 
2562 	/*
2563 	 * As RFC 973, a MSS field must only be sent in the initial
2564 	 * connection request(it must be with SYN).
2565 	 */
2566 	if ((th->th_flags & TH_SYN) == 0)
2567 		goto handled;
2568 
2569 	lpktp = MIN(th->th_off << 4, lpktp);
2570 
2571 	pktp += sizeof(struct tcphdr);
2572 	lpktp -= sizeof(struct tcphdr);
2573 	while (lpktp >= TCPOLEN_MAXSEG) {
2574 		GETCHAR(opt, pktp);
2575 		switch (opt) {
2576 		case TCPOPT_MAXSEG:
2577 			GETCHAR(optlen, pktp);
2578 			mssp = pktp;		/* mss place holder */
2579 			GETSHORT(mss, pktp);
2580 			maxmss = MAXMSS(mtu);
2581 			if (mss > maxmss) {
2582 				PIPEX_DBG((NULL, LOG_DEBUG,
2583 				    "change tcp-mss %d => %d", mss, maxmss));
2584 				PUTSHORT(maxmss, mssp);
2585 				acc = htons(mss);
2586 				acc -= htons(maxmss);
2587 				ADJUST_CHECKSUM(acc, th->th_sum);
2588 			}
2589 			goto handled;
2590 			/* NOTREACHED */
2591 		case TCPOPT_EOL:
2592 			goto handled;
2593 			/* NOTREACHED */
2594 		case TCPOPT_NOP:
2595 			lpktp--;
2596 			break;
2597 		default:
2598 			GETCHAR(optlen, pktp);
2599 			if (optlen < 2)	/* packet is broken */
2600 				goto drop;
2601 			pktp += optlen - 2;
2602 			lpktp -= optlen;
2603 			break;
2604 		}
2605 	}
2606 
2607 handled:
2608 	return (m0);
2609 
2610 drop:
2611 	m_freem(m0);
2612 	return (NULL);
2613 }
2614 
2615 /*
2616  *  Check whether a packet should reset idle timer
2617  *  Returns 1 to don't reset timer (i.e. the packet is "idle" packet)
2618  */
2619 Static struct mbuf *
2620 ip_is_idle_packet(struct mbuf *m0, int *ris_idle)
2621 {
2622 	u_int16_t ip_off;
2623 	const struct udphdr *uh;
2624 	struct ip *pip;
2625 	int len;
2626 
2627 	/* pullup ip header */
2628 	len = sizeof(struct ip);
2629 	PIPEX_PULLUP(m0, len);
2630 	if (m0 == NULL)
2631 		goto error;
2632 	pip = mtod(m0, struct ip *);
2633 
2634 	/*
2635 	 * the packet which fragmentations was not the idle packet.
2636 	 */
2637 	ip_off = ntohs(pip->ip_off);
2638 	if ((ip_off & IP_MF) || ((ip_off & IP_OFFMASK) != 0))
2639 		goto is_active;
2640 
2641 	switch (pip->ip_p) {
2642 	case IPPROTO_IGMP:
2643 		goto is_active;
2644 	case IPPROTO_ICMP:
2645 		len = pip->ip_hl * 4 + 8;
2646 		PIPEX_PULLUP(m0, len);
2647 		if (m0 == NULL)
2648 			goto error;
2649 		pip = mtod(m0, struct ip *);
2650 
2651 		switch (((unsigned char *) pip)[pip->ip_hl * 4]) {
2652 		case 0:	/* Echo Reply */
2653 		case 8:	/* Echo Request */
2654 			goto is_active;
2655 		default:
2656 			goto is_idle;
2657 		}
2658 
2659 	case IPPROTO_UDP:
2660 	case IPPROTO_TCP:
2661 		len = pip->ip_hl * 4 + sizeof(struct udphdr);
2662 		PIPEX_PULLUP(m0, len);
2663 		if (m0 == NULL)
2664 			goto error;
2665 		pip = mtod(m0, struct ip *);
2666 		uh = (struct udphdr *)(mtod(m0, caddr_t) + pip->ip_hl * 4);
2667 
2668 		switch (ntohs(uh->uh_sport)) {
2669 		case 53:	/* DOMAIN */
2670 		case 67:	/* BOOTPS */
2671 		case 68:	/* BOOTPC */
2672 		case 123:	/* NTP */
2673 		case 137:	/* NETBIOS-NS */
2674 		case 520:	/* RIP */
2675 			goto is_idle;
2676 		}
2677 		switch (ntohs(uh->uh_dport)) {
2678 		case 53:	/* DOMAIN */
2679 		case 67:	/* BOOTPS */
2680 		case 68:	/* BOOTPC */
2681 		case 123:	/* NTP */
2682 		case 137:	/* NETBIOS-NS */
2683 		case 520:	/* RIP */
2684 			goto is_idle;
2685 		}
2686 		goto is_active;
2687 	default:
2688 		goto is_active;
2689 	}
2690 
2691 is_active:
2692 	*ris_idle = 0;
2693 	return (m0);
2694 
2695 is_idle:
2696 	*ris_idle = 1;
2697 	return (m0);
2698 
2699 error:
2700 	return (NULL);
2701 }
2702 
2703 Static void
2704 pipex_session_log(struct pipex_session *session, int prio, const char *fmt, ...)
2705 {
2706 	char logbuf[1024];
2707 	va_list ap;
2708 
2709 	logpri(prio);
2710 	if (session != NULL) {
2711 		struct ifnet *ifp;
2712 
2713 		ifp = if_get(session->ifindex);
2714 		addlog("pipex: ppp=%d iface=%s protocol=%s id=%d ",
2715 		    session->ppp_id,
2716 		    ifp? ifp->if_xname : "Unknown",
2717 		    (session->protocol == PIPEX_PROTO_PPPOE)? "PPPoE" :
2718 		    (session->protocol == PIPEX_PROTO_PPTP)? "PPTP" :
2719 		    (session->protocol == PIPEX_PROTO_L2TP) ? "L2TP" :
2720 		    "Unknown", session->session_id);
2721 		if_put(ifp);
2722 	} else
2723 		addlog("pipex: ");
2724 
2725 	va_start(ap, fmt);
2726 	vsnprintf(logbuf, sizeof(logbuf), fmt, ap);
2727 	va_end(ap);
2728 	addlog("%s\n", logbuf);
2729 }
2730 
2731 Static uint32_t
2732 pipex_sockaddr_hash_key(struct sockaddr *sa)
2733 {
2734 	switch (sa->sa_family) {
2735 	case AF_INET:
2736 		return ntohl(satosin(sa)->sin_addr.s_addr);
2737 	case AF_INET6:
2738 		return ntohl(satosin6(sa)->sin6_addr.s6_addr32[3]);
2739 	}
2740 	panic("pipex_sockaddr_hash_key: unknown address family");
2741 	return (0);
2742 }
2743 
2744 /*
2745  * Compare struct sockaddr_in{,6} with the address only.
2746  * The port number is not covered.
2747  */
2748 Static int
2749 pipex_sockaddr_compar_addr(struct sockaddr *a, struct sockaddr *b)
2750 {
2751 	int cmp;
2752 
2753 	cmp = b->sa_family - a->sa_family;
2754 	if (cmp != 0)
2755 		return cmp;
2756 	switch (a->sa_family) {
2757 	case AF_INET:
2758 		return (satosin(b)->sin_addr.s_addr -
2759 		    satosin(a)->sin_addr.s_addr);
2760 	case AF_INET6:
2761 		cmp = (satosin6(b)->sin6_scope_id - satosin6(a)->sin6_scope_id);
2762 		if (cmp != 0)
2763 			return cmp;
2764 		return (memcmp(&satosin6(a)->sin6_addr,
2765 		    &satosin6(b)->sin6_addr,
2766 		    sizeof(struct in6_addr)));
2767 	}
2768 	panic("pipex_sockaddr_compar_addr: unknown address family");
2769 
2770 	return (-1);
2771 }
2772 
2773 int
2774 pipex_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
2775     size_t newlen)
2776 {
2777 	switch (name[0]) {
2778 	case PIPEXCTL_ENABLE:
2779 		if (namelen != 1)
2780 			return (ENOTDIR);
2781 		return (sysctl_int(oldp, oldlenp, newp, newlen,
2782 		    &pipex_enable));
2783 	default:
2784 		return (ENOPROTOOPT);
2785 	}
2786 	/* NOTREACHED */
2787 }
2788