1 /*	$FreeBSD: stable/10/contrib/ipfilter/ip_fil.c 341804 2018-12-11 01:49:06Z cy $	*/
2 
3 /*
4  * Copyright (C) 2012 by Darren Reed.
5  *
6  * See the IPFILTER.LICENCE file for details on licencing.
7  *
8  * $Id$
9  */
10 #if !defined(lint)
11 static const char sccsid[] = "@(#)ip_fil.c	2.41 6/5/96 (C) 1993-2000 Darren Reed";
12 static const char rcsid[] = "@(#)$Id$";
13 #endif
14 
15 #include "ipf.h"
16 #include "md5.h"
17 #include "ipt.h"
18 
19 ipf_main_softc_t	ipfmain;
20 
21 static	struct	ifnet **ifneta = NULL;
22 static	int	nifs = 0;
23 
24 struct	rtentry;
25 
26 static	void	ipf_setifpaddr __P((struct ifnet *, char *));
27 void	init_ifp __P((void));
28 #if defined(__sgi) && (IRIX < 60500)
29 static int 	no_output __P((struct ifnet *, struct mbuf *,
30 			       struct sockaddr *));
31 static int	write_output __P((struct ifnet *, struct mbuf *,
32 				  struct sockaddr *));
33 #else
34 # if TRU64 >= 1885
35 static int 	no_output __P((struct ifnet *, struct mbuf *,
36 			       struct sockaddr *, struct rtentry *, char *));
37 static int	write_output __P((struct ifnet *, struct mbuf *,
38 				  struct sockaddr *, struct rtentry *, char *));
39 # else
40 static int 	no_output __P((struct ifnet *, struct mbuf *,
41 			       struct sockaddr *, struct rtentry *));
42 static int	write_output __P((struct ifnet *, struct mbuf *,
43 				  struct sockaddr *, struct rtentry *));
44 # endif
45 #endif
46 
47 
48 int
ipfattach(softc)49 ipfattach(softc)
50 	ipf_main_softc_t *softc;
51 {
52 	return 0;
53 }
54 
55 
56 int
ipfdetach(softc)57 ipfdetach(softc)
58 	ipf_main_softc_t *softc;
59 {
60 	return 0;
61 }
62 
63 
64 /*
65  * Filter ioctl interface.
66  */
67 int
ipfioctl(softc,dev,cmd,data,mode)68 ipfioctl(softc, dev, cmd, data, mode)
69 	ipf_main_softc_t *softc;
70 	int dev;
71 	ioctlcmd_t cmd;
72 	caddr_t data;
73 	int mode;
74 {
75 	int error = 0, unit = 0, uid;
76 
77 	uid = getuid();
78 	unit = dev;
79 
80 	SPL_NET(s);
81 
82 	error = ipf_ioctlswitch(softc, unit, data, cmd, mode, uid, NULL);
83 	if (error != -1) {
84 		SPL_X(s);
85 		return error;
86 	}
87 	SPL_X(s);
88 	return error;
89 }
90 
91 
92 void
ipf_forgetifp(softc,ifp)93 ipf_forgetifp(softc, ifp)
94 	ipf_main_softc_t *softc;
95 	void *ifp;
96 {
97 	register frentry_t *f;
98 
99 	WRITE_ENTER(&softc->ipf_mutex);
100 	for (f = softc->ipf_acct[0][softc->ipf_active]; (f != NULL);
101 	     f = f->fr_next)
102 		if (f->fr_ifa == ifp)
103 			f->fr_ifa = (void *)-1;
104 	for (f = softc->ipf_acct[1][softc->ipf_active]; (f != NULL);
105 	     f = f->fr_next)
106 		if (f->fr_ifa == ifp)
107 			f->fr_ifa = (void *)-1;
108 	for (f = softc->ipf_rules[0][softc->ipf_active]; (f != NULL);
109 	     f = f->fr_next)
110 		if (f->fr_ifa == ifp)
111 			f->fr_ifa = (void *)-1;
112 	for (f = softc->ipf_rules[1][softc->ipf_active]; (f != NULL);
113 	     f = f->fr_next)
114 		if (f->fr_ifa == ifp)
115 			f->fr_ifa = (void *)-1;
116 	RWLOCK_EXIT(&softc->ipf_mutex);
117 	ipf_nat_sync(softc, ifp);
118 	ipf_lookup_sync(softc, ifp);
119 }
120 
121 
122 static int
123 #if defined(__sgi) && (IRIX < 60500)
no_output(ifp,m,s)124 no_output(ifp, m, s)
125 #else
126 # if TRU64 >= 1885
127 no_output (ifp, m, s, rt, cp)
128 	char *cp;
129 # else
130 no_output(ifp, m, s, rt)
131 # endif
132 	struct rtentry *rt;
133 #endif
134 	struct ifnet *ifp;
135 	struct mbuf *m;
136 	struct sockaddr *s;
137 {
138 	return 0;
139 }
140 
141 
142 static int
143 #if defined(__sgi) && (IRIX < 60500)
write_output(ifp,m,s)144 write_output(ifp, m, s)
145 #else
146 # if TRU64 >= 1885
147 write_output (ifp, m, s, rt, cp)
148 	char *cp;
149 # else
150 write_output(ifp, m, s, rt)
151 # endif
152 	struct rtentry *rt;
153 #endif
154 	struct ifnet *ifp;
155 	struct mbuf *m;
156 	struct sockaddr *s;
157 {
158 	char fname[32];
159 	mb_t *mb;
160 	ip_t *ip;
161 	int fd;
162 
163 	mb = (mb_t *)m;
164 	ip = MTOD(mb, ip_t *);
165 
166 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
167     (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
168     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
169 	sprintf(fname, "/tmp/%s", ifp->if_xname);
170 #else
171 	sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
172 #endif
173 	fd = open(fname, O_WRONLY|O_APPEND);
174 	if (fd == -1) {
175 		perror("open");
176 		return -1;
177 	}
178 	write(fd, (char *)ip, ntohs(ip->ip_len));
179 	close(fd);
180 	return 0;
181 }
182 
183 
184 static void
ipf_setifpaddr(ifp,addr)185 ipf_setifpaddr(ifp, addr)
186 	struct ifnet *ifp;
187 	char *addr;
188 {
189 #ifdef __sgi
190 	struct in_ifaddr *ifa;
191 #else
192 	struct ifaddr *ifa;
193 #endif
194 
195 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
196 	if (ifp->if_addrlist.tqh_first != NULL)
197 #else
198 # ifdef __sgi
199 	if (ifp->in_ifaddr != NULL)
200 # else
201 	if (ifp->if_addrlist != NULL)
202 # endif
203 #endif
204 		return;
205 
206 	ifa = (struct ifaddr *)malloc(sizeof(*ifa));
207 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
208 	ifp->if_addrlist.tqh_first = ifa;
209 #else
210 # ifdef __sgi
211 	ifp->in_ifaddr = ifa;
212 # else
213 	ifp->if_addrlist = ifa;
214 # endif
215 #endif
216 
217 	if (ifa != NULL) {
218 		struct sockaddr_in *sin;
219 
220 #ifdef __sgi
221 		sin = (struct sockaddr_in *)&ifa->ia_addr;
222 #else
223 		sin = (struct sockaddr_in *)&ifa->ifa_addr;
224 #endif
225 #ifdef USE_INET6
226 		if (index(addr, ':') != NULL) {
227 			struct sockaddr_in6 *sin6;
228 
229 			sin6 = (struct sockaddr_in6 *)&ifa->ifa_addr;
230 			sin6->sin6_family = AF_INET6;
231 			/* Abort if bad address. */
232 			switch (inet_pton(AF_INET6, addr, &sin6->sin6_addr))
233 			{
234 			case 1:
235 				break;
236 			case -1:
237 				perror("inet_pton");
238 				abort();
239 				break;
240 			default:
241 				abort();
242 				break;
243 			}
244 		} else
245 #endif
246 		{
247 			sin->sin_family = AF_INET;
248 			sin->sin_addr.s_addr = inet_addr(addr);
249 			if (sin->sin_addr.s_addr == 0)
250 				abort();
251 		}
252 	}
253 }
254 
255 struct ifnet *
get_unit(name,family)256 get_unit(name, family)
257 	char *name;
258 	int family;
259 {
260 	struct ifnet *ifp, **ifpp, **old_ifneta;
261 	char *addr;
262 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
263     (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
264     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
265 
266 	if (!*name)
267 		return NULL;
268 
269 	if (name == NULL)
270 		name = "anon0";
271 
272 	addr = strchr(name, '=');
273 	if (addr != NULL)
274 		*addr++ = '\0';
275 
276 	for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
277 		if (!strcmp(name, ifp->if_xname)) {
278 			if (addr != NULL)
279 				ipf_setifpaddr(ifp, addr);
280 			return ifp;
281 		}
282 	}
283 #else
284 	char *s, ifname[LIFNAMSIZ+1];
285 
286 	if (name == NULL)
287 		name = "anon0";
288 
289 	addr = strchr(name, '=');
290 	if (addr != NULL)
291 		*addr++ = '\0';
292 
293 	for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
294 		COPYIFNAME(family, ifp, ifname);
295 		if (!strcmp(name, ifname)) {
296 			if (addr != NULL)
297 				ipf_setifpaddr(ifp, addr);
298 			return ifp;
299 		}
300 	}
301 #endif
302 
303 	if (!ifneta) {
304 		ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2);
305 		if (!ifneta)
306 			return NULL;
307 		ifneta[1] = NULL;
308 		ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp));
309 		if (!ifneta[0]) {
310 			free(ifneta);
311 			return NULL;
312 		}
313 		nifs = 1;
314 	} else {
315 		old_ifneta = ifneta;
316 		nifs++;
317 		ifneta = (struct ifnet **)realloc(ifneta,
318 						  (nifs + 1) * sizeof(ifp));
319 		if (!ifneta) {
320 			free(old_ifneta);
321 			nifs = 0;
322 			return NULL;
323 		}
324 		ifneta[nifs] = NULL;
325 		ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp));
326 		if (!ifneta[nifs - 1]) {
327 			nifs--;
328 			return NULL;
329 		}
330 	}
331 	ifp = ifneta[nifs - 1];
332 
333 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
334 	TAILQ_INIT(&ifp->if_addrlist);
335 #endif
336 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
337     (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
338     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
339 	(void) strncpy(ifp->if_xname, name, sizeof(ifp->if_xname));
340 #else
341 	s = name + strlen(name) - 1;
342 	for (; s > name; s--) {
343 		if (!ISDIGIT(*s)) {
344 			s++;
345 			break;
346 		}
347 	}
348 
349 	if ((s > name) && (*s != 0) && ISDIGIT(*s)) {
350 		ifp->if_unit = atoi(s);
351 		ifp->if_name = (char *)malloc(s - name + 1);
352 		(void) strncpy(ifp->if_name, name, s - name);
353 		ifp->if_name[s - name] = '\0';
354 	} else {
355 		ifp->if_name = strdup(name);
356 		ifp->if_unit = -1;
357 	}
358 #endif
359 	ifp->if_output = (void *)no_output;
360 
361 	if (addr != NULL) {
362 		ipf_setifpaddr(ifp, addr);
363 	}
364 
365 	return ifp;
366 }
367 
368 
369 char *
get_ifname(ifp)370 get_ifname(ifp)
371 	struct ifnet *ifp;
372 {
373 	static char ifname[LIFNAMSIZ];
374 
375 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(linux) || \
376     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
377 	sprintf(ifname, "%s", ifp->if_xname);
378 #else
379 	if (ifp->if_unit != -1)
380 		sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit);
381 	else
382 		strcpy(ifname, ifp->if_name);
383 #endif
384 	return ifname;
385 }
386 
387 
388 
389 void
init_ifp()390 init_ifp()
391 {
392 	struct ifnet *ifp, **ifpp;
393 	char fname[32];
394 	int fd;
395 
396 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
397     (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
398     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
399 	for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
400 		ifp->if_output = (void *)write_output;
401 		sprintf(fname, "/tmp/%s", ifp->if_xname);
402 		fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
403 		if (fd == -1)
404 			perror("open");
405 		else
406 			close(fd);
407 	}
408 #else
409 
410 	for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
411 		ifp->if_output = (void *)write_output;
412 		sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
413 		fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
414 		if (fd == -1)
415 			perror("open");
416 		else
417 			close(fd);
418 	}
419 #endif
420 }
421 
422 
423 int
ipf_fastroute(m,mpp,fin,fdp)424 ipf_fastroute(m, mpp, fin, fdp)
425 	mb_t *m, **mpp;
426 	fr_info_t *fin;
427 	frdest_t *fdp;
428 {
429 	struct ifnet *ifp;
430 	ip_t *ip = fin->fin_ip;
431 	frdest_t node;
432 	int error = 0;
433 	frentry_t *fr;
434 	void *sifp;
435 	int sout;
436 
437 	sifp = fin->fin_ifp;
438 	sout = fin->fin_out;
439 	fr = fin->fin_fr;
440 	ip->ip_sum = 0;
441 
442 	if (!(fr->fr_flags & FR_KEEPSTATE) && (fdp != NULL) &&
443 	    (fdp->fd_type == FRD_DSTLIST)) {
444 		bzero(&node, sizeof(node));
445 		ipf_dstlist_select_node(fin, fdp->fd_ptr, NULL, &node);
446 		fdp = &node;
447 	}
448 	ifp = fdp->fd_ptr;
449 
450 	if (ifp == NULL)
451 		return 0;	/* no routing table out here */
452 
453 	if (fin->fin_out == 0) {
454 		fin->fin_ifp = ifp;
455 		fin->fin_out = 1;
456 		(void) ipf_acctpkt(fin, NULL);
457 		fin->fin_fr = NULL;
458 		if (!fr || !(fr->fr_flags & FR_RETMASK)) {
459 			u_32_t pass;
460 
461 			(void) ipf_state_check(fin, &pass);
462 		}
463 
464 		switch (ipf_nat_checkout(fin, NULL))
465 		{
466 		case 0 :
467 			break;
468 		case 1 :
469 			ip->ip_sum = 0;
470 			break;
471 		case -1 :
472 			error = -1;
473 			goto done;
474 			break;
475 		}
476 
477 	}
478 
479 	m->mb_ifp = ifp;
480 	printpacket(fin->fin_out, m);
481 
482 	(*ifp->if_output)(ifp, (void *)m, NULL, 0);
483 done:
484 	fin->fin_ifp = sifp;
485 	fin->fin_out = sout;
486 	return error;
487 }
488 
489 
490 int
ipf_send_reset(fin)491 ipf_send_reset(fin)
492 	fr_info_t *fin;
493 {
494 	ipfkverbose("- TCP RST sent\n");
495 	return 0;
496 }
497 
498 
499 int
ipf_send_icmp_err(type,fin,dst)500 ipf_send_icmp_err(type, fin, dst)
501 	int type;
502 	fr_info_t *fin;
503 	int dst;
504 {
505 	ipfkverbose("- ICMP unreachable sent\n");
506 	return 0;
507 }
508 
509 
510 void
m_freem(m)511 m_freem(m)
512 	mb_t *m;
513 {
514 	return;
515 }
516 
517 
518 void
m_copydata(m,off,len,cp)519 m_copydata(m, off, len, cp)
520 	mb_t *m;
521 	int off, len;
522 	caddr_t cp;
523 {
524 	bcopy((char *)m + off, cp, len);
525 }
526 
527 
528 int
ipfuiomove(buf,len,rwflag,uio)529 ipfuiomove(buf, len, rwflag, uio)
530 	caddr_t buf;
531 	int len, rwflag;
532 	struct uio *uio;
533 {
534 	int left, ioc, num, offset;
535 	struct iovec *io;
536 	char *start;
537 
538 	if (rwflag == UIO_READ) {
539 		left = len;
540 		ioc = 0;
541 
542 		offset = uio->uio_offset;
543 
544 		while ((left > 0) && (ioc < uio->uio_iovcnt)) {
545 			io = uio->uio_iov + ioc;
546 			num = io->iov_len;
547 			if (num > left)
548 				num = left;
549 			start = (char *)io->iov_base + offset;
550 			if (start > (char *)io->iov_base + io->iov_len) {
551 				offset -= io->iov_len;
552 				ioc++;
553 				continue;
554 			}
555 			bcopy(buf, start, num);
556 			uio->uio_resid -= num;
557 			uio->uio_offset += num;
558 			left -= num;
559 			if (left > 0)
560 				ioc++;
561 		}
562 		if (left > 0)
563 			return EFAULT;
564 	}
565 	return 0;
566 }
567 
568 
569 u_32_t
ipf_newisn(fin)570 ipf_newisn(fin)
571 	fr_info_t *fin;
572 {
573 	static int iss_seq_off = 0;
574 	u_char hash[16];
575 	u_32_t newiss;
576 	MD5_CTX ctx;
577 
578 	/*
579 	 * Compute the base value of the ISS.  It is a hash
580 	 * of (saddr, sport, daddr, dport, secret).
581 	 */
582 	MD5Init(&ctx);
583 
584 	MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src,
585 		  sizeof(fin->fin_fi.fi_src));
586 	MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst,
587 		  sizeof(fin->fin_fi.fi_dst));
588 	MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat));
589 
590 	/* MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); */
591 
592 	MD5Final(hash, &ctx);
593 
594 	memcpy(&newiss, hash, sizeof(newiss));
595 
596 	/*
597 	 * Now increment our "timer", and add it in to
598 	 * the computed value.
599 	 *
600 	 * XXX Use `addin'?
601 	 * XXX TCP_ISSINCR too large to use?
602 	 */
603 	iss_seq_off += 0x00010000;
604 	newiss += iss_seq_off;
605 	return newiss;
606 }
607 
608 
609 /* ------------------------------------------------------------------------ */
610 /* Function:    ipf_nextipid                                                */
611 /* Returns:     int - 0 == success, -1 == error (packet should be droppped) */
612 /* Parameters:  fin(I) - pointer to packet information                      */
613 /*                                                                          */
614 /* Returns the next IPv4 ID to use for this packet.                         */
615 /* ------------------------------------------------------------------------ */
616 INLINE u_short
ipf_nextipid(fin)617 ipf_nextipid(fin)
618 	fr_info_t *fin;
619 {
620 	static u_short ipid = 0;
621 	ipf_main_softc_t *softc = fin->fin_main_soft;
622 	u_short id;
623 
624 	MUTEX_ENTER(&softc->ipf_rw);
625 	if (fin->fin_pktnum != 0) {
626 		/*
627 		 * The -1 is for aligned test results.
628 		 */
629 		id = (fin->fin_pktnum - 1) & 0xffff;
630 	} else {
631 	}
632 		id = ipid++;
633 	MUTEX_EXIT(&softc->ipf_rw);
634 
635 	return id;
636 }
637 
638 
639 INLINE int
ipf_checkv4sum(fin)640 ipf_checkv4sum(fin)
641 	fr_info_t *fin;
642 {
643 
644 	if (fin->fin_flx & FI_SHORT)
645 		return 1;
646 
647 	if (ipf_checkl4sum(fin) == -1) {
648 		fin->fin_flx |= FI_BAD;
649 		return -1;
650 	}
651 	return 0;
652 }
653 
654 
655 #ifdef	USE_INET6
656 INLINE int
ipf_checkv6sum(fin)657 ipf_checkv6sum(fin)
658 	fr_info_t *fin;
659 {
660 	if (fin->fin_flx & FI_SHORT)
661 		return 1;
662 
663 	if (ipf_checkl4sum(fin) == -1) {
664 		fin->fin_flx |= FI_BAD;
665 		return -1;
666 	}
667 	return 0;
668 }
669 #endif
670 
671 
672 #if 0
673 /*
674  * See above for description, except that all addressing is in user space.
675  */
676 int
677 copyoutptr(softc, src, dst, size)
678 	void *src, *dst;
679 	size_t size;
680 {
681 	caddr_t ca;
682 
683 	bcopy(dst, (char *)&ca, sizeof(ca));
684 	bcopy(src, ca, size);
685 	return 0;
686 }
687 
688 
689 /*
690  * See above for description, except that all addressing is in user space.
691  */
692 int
693 copyinptr(src, dst, size)
694 	void *src, *dst;
695 	size_t size;
696 {
697 	caddr_t ca;
698 
699 	bcopy(src, (char *)&ca, sizeof(ca));
700 	bcopy(ca, dst, size);
701 	return 0;
702 }
703 #endif
704 
705 
706 /*
707  * return the first IP Address associated with an interface
708  */
709 int
ipf_ifpaddr(softc,v,atype,ifptr,inp,inpmask)710 ipf_ifpaddr(softc, v, atype, ifptr, inp, inpmask)
711 	ipf_main_softc_t *softc;
712 	int v, atype;
713 	void *ifptr;
714 	i6addr_t *inp, *inpmask;
715 {
716 	struct ifnet *ifp = ifptr;
717 #ifdef __sgi
718 	struct in_ifaddr *ifa;
719 #else
720 	struct ifaddr *ifa;
721 #endif
722 
723 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
724 	ifa = ifp->if_addrlist.tqh_first;
725 #else
726 # ifdef __sgi
727 	ifa = (struct in_ifaddr *)ifp->in_ifaddr;
728 # else
729 	ifa = ifp->if_addrlist;
730 # endif
731 #endif
732 	if (ifa != NULL) {
733 		if (v == 4) {
734 			struct sockaddr_in *sin, mask;
735 
736 			mask.sin_addr.s_addr = 0xffffffff;
737 
738 #ifdef __sgi
739 			sin = (struct sockaddr_in *)&ifa->ia_addr;
740 #else
741 			sin = (struct sockaddr_in *)&ifa->ifa_addr;
742 #endif
743 
744 			return ipf_ifpfillv4addr(atype, sin, &mask,
745 						 &inp->in4, &inpmask->in4);
746 		}
747 #ifdef USE_INET6
748 		if (v == 6) {
749 			struct sockaddr_in6 *sin6, mask;
750 
751 			sin6 = (struct sockaddr_in6 *)&ifa->ifa_addr;
752 			((i6addr_t *)&mask.sin6_addr)->i6[0] = 0xffffffff;
753 			((i6addr_t *)&mask.sin6_addr)->i6[1] = 0xffffffff;
754 			((i6addr_t *)&mask.sin6_addr)->i6[2] = 0xffffffff;
755 			((i6addr_t *)&mask.sin6_addr)->i6[3] = 0xffffffff;
756 			return ipf_ifpfillv6addr(atype, sin6, &mask,
757 						 inp, inpmask);
758 		}
759 #endif
760 	}
761 	return 0;
762 }
763 
764 
765 /*
766  * This function is not meant to be random, rather just produce a
767  * sequence of numbers that isn't linear to show "randomness".
768  */
769 u_32_t
ipf_random()770 ipf_random()
771 {
772 	static unsigned int last = 0xa5a5a5a5;
773 	static int calls = 0;
774 	int number;
775 
776 	calls++;
777 
778 	/*
779 	 * These are deliberately chosen to ensure that there is some
780 	 * attempt to test whether the output covers the range in test n18.
781 	 */
782 	switch (calls)
783 	{
784 	case 1 :
785 		number = 0;
786 		break;
787 	case 2 :
788 		number = 4;
789 		break;
790 	case 3 :
791 		number = 3999;
792 		break;
793 	case 4 :
794 		number = 4000;
795 		break;
796 	case 5 :
797 		number = 48999;
798 		break;
799 	case 6 :
800 		number = 49000;
801 		break;
802 	default :
803 		number = last;
804 		last *= calls;
805 		last++;
806 		number ^= last;
807 		break;
808 	}
809 	return number;
810 }
811 
812 
813 int
ipf_verifysrc(fin)814 ipf_verifysrc(fin)
815 	fr_info_t *fin;
816 {
817 	return 1;
818 }
819 
820 
821 int
ipf_inject(fin,m)822 ipf_inject(fin, m)
823 	fr_info_t *fin;
824 	mb_t *m;
825 {
826 	FREE_MB_T(m);
827 
828 	return 0;
829 }
830 
831 
832 u_int
ipf_pcksum(fin,hlen,sum)833 ipf_pcksum(fin, hlen, sum)
834 	fr_info_t *fin;
835 	int hlen;
836 	u_int sum;
837 {
838 	u_short *sp;
839 	u_int sum2;
840 	int slen;
841 
842 	slen = fin->fin_plen - hlen;
843 	sp = (u_short *)((u_char *)fin->fin_ip + hlen);
844 
845 	for (; slen > 1; slen -= 2)
846 		sum += *sp++;
847 	if (slen)
848 		sum += ntohs(*(u_char *)sp << 8);
849 	while (sum > 0xffff)
850 		sum = (sum & 0xffff) + (sum >> 16);
851 	sum2 = (u_short)(~sum & 0xffff);
852 
853 	return sum2;
854 }
855 
856 
857 void *
ipf_pullup(m,fin,plen)858 ipf_pullup(m, fin, plen)
859 	mb_t *m;
860 	fr_info_t *fin;
861 	int plen;
862 {
863 	if (M_LEN(m) >= plen)
864 		return fin->fin_ip;
865 
866 	/*
867 	 * Fake ipf_pullup failing
868 	 */
869 	fin->fin_reason = FRB_PULLUP;
870 	*fin->fin_mp = NULL;
871 	fin->fin_m = NULL;
872 	fin->fin_ip = NULL;
873 	return NULL;
874 }
875