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