Home | History | Annotate | Line # | Download | only in dist
      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
     56 ipfattach(softc)
     57 	ipf_main_softc_t *softc;
     58 {
     59 	return 0;
     60 }
     61 
     62 
     63 int
     64 ipfdetach(softc)
     65 	ipf_main_softc_t *softc;
     66 {
     67 	return 0;
     68 }
     69 
     70 
     71 /*
     72  * Filter ioctl interface.
     73  */
     74 int
     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
    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)
    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)
    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
    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 *
    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 *
    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
    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
    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
    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
    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
    513 m_freem(m)
    514 	mb_t *m;
    515 {
    516 	return;
    517 }
    518 
    519 
    520 void
    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
    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
    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
    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
    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
    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
    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
    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
    816 ipf_verifysrc(fin)
    817 	fr_info_t *fin;
    818 {
    819 	return 1;
    820 }
    821 
    822 
    823 int
    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
    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 *
    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