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