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