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