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