]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ipfilter/ip_fil.c
Merge libc++ trunk r351319, and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / ipfilter / ip_fil.c
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
52 ipfattach(softc)
53         ipf_main_softc_t *softc;
54 {
55         return 0;
56 }
57
58
59 int
60 ipfdetach(softc)
61         ipf_main_softc_t *softc;
62 {
63         return 0;
64 }
65
66
67 /*
68  * Filter ioctl interface.
69  */
70 int
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
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)
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)
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
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 *
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 **)reallocarray(ifneta, nifs + 1, 
321                                                   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 *
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
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
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         (*ifp->if_output)(ifp, (void *)m, NULL, 0);
486 done:
487         fin->fin_ifp = sifp;
488         fin->fin_out = sout;
489         return error;
490 }
491
492
493 int
494 ipf_send_reset(fin)
495         fr_info_t *fin;
496 {
497         ipfkverbose("- TCP RST sent\n");
498         return 0;
499 }
500
501
502 int
503 ipf_send_icmp_err(type, fin, dst)
504         int type;
505         fr_info_t *fin;
506         int dst;
507 {
508         ipfkverbose("- ICMP unreachable sent\n");
509         return 0;
510 }
511
512
513 void
514 m_freem(m)
515         mb_t *m;
516 {
517         return;
518 }
519
520
521 void
522 m_copydata(m, off, len, cp)
523         mb_t *m;
524         int off, len;
525         caddr_t cp;
526 {
527         bcopy((char *)m + off, cp, len);
528 }
529
530
531 int
532 ipfuiomove(buf, len, rwflag, uio)
533         caddr_t buf;
534         int len, rwflag;
535         struct uio *uio;
536 {
537         int left, ioc, num, offset;
538         struct iovec *io;
539         char *start;
540
541         if (rwflag == UIO_READ) {
542                 left = len;
543                 ioc = 0;
544
545                 offset = uio->uio_offset;
546
547                 while ((left > 0) && (ioc < uio->uio_iovcnt)) {
548                         io = uio->uio_iov + ioc;
549                         num = io->iov_len;
550                         if (num > left)
551                                 num = left;
552                         start = (char *)io->iov_base + offset;
553                         if (start > (char *)io->iov_base + io->iov_len) {
554                                 offset -= io->iov_len;
555                                 ioc++;
556                                 continue;
557                         }
558                         bcopy(buf, start, num);
559                         uio->uio_resid -= num;
560                         uio->uio_offset += num;
561                         left -= num;
562                         if (left > 0)
563                                 ioc++;
564                 }
565                 if (left > 0)
566                         return EFAULT;
567         }
568         return 0;
569 }
570
571
572 u_32_t
573 ipf_newisn(fin)
574         fr_info_t *fin;
575 {
576         static int iss_seq_off = 0;
577         u_char hash[16];
578         u_32_t newiss;
579         MD5_CTX ctx;
580
581         /*
582          * Compute the base value of the ISS.  It is a hash
583          * of (saddr, sport, daddr, dport, secret).
584          */
585         MD5Init(&ctx);
586
587         MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src,
588                   sizeof(fin->fin_fi.fi_src));
589         MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst,
590                   sizeof(fin->fin_fi.fi_dst));
591         MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat));
592
593         /* MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); */
594
595         MD5Final(hash, &ctx);
596
597         memcpy(&newiss, hash, sizeof(newiss));
598
599         /*
600          * Now increment our "timer", and add it in to
601          * the computed value.
602          *
603          * XXX Use `addin'?
604          * XXX TCP_ISSINCR too large to use?
605          */
606         iss_seq_off += 0x00010000;
607         newiss += iss_seq_off;
608         return newiss;
609 }
610
611
612 /* ------------------------------------------------------------------------ */
613 /* Function:    ipf_nextipid                                                */
614 /* Returns:     int - 0 == success, -1 == error (packet should be droppped) */
615 /* Parameters:  fin(I) - pointer to packet information                      */
616 /*                                                                          */
617 /* Returns the next IPv4 ID to use for this packet.                         */
618 /* ------------------------------------------------------------------------ */
619 INLINE u_short
620 ipf_nextipid(fin)
621         fr_info_t *fin;
622 {
623         static u_short ipid = 0;
624         ipf_main_softc_t *softc = fin->fin_main_soft;
625         u_short id;
626
627         MUTEX_ENTER(&softc->ipf_rw);
628         if (fin->fin_pktnum != 0) {
629                 /*
630                  * The -1 is for aligned test results.
631                  */
632                 id = (fin->fin_pktnum - 1) & 0xffff;
633         } else {
634         }
635                 id = ipid++;
636         MUTEX_EXIT(&softc->ipf_rw);
637
638         return id;
639 }
640
641
642 INLINE int
643 ipf_checkv4sum(fin)
644         fr_info_t *fin;
645 {
646
647         if (fin->fin_flx & FI_SHORT)
648                 return 1;
649
650         if (ipf_checkl4sum(fin) == -1) {
651                 fin->fin_flx |= FI_BAD;
652                 return -1;
653         }
654         return 0;
655 }
656
657
658 #ifdef  USE_INET6
659 INLINE int
660 ipf_checkv6sum(fin)
661         fr_info_t *fin;
662 {
663         if (fin->fin_flx & FI_SHORT)
664                 return 1;
665
666         if (ipf_checkl4sum(fin) == -1) {
667                 fin->fin_flx |= FI_BAD;
668                 return -1;
669         }
670         return 0;
671 }
672 #endif
673
674
675 #if 0
676 /*
677  * See above for description, except that all addressing is in user space.
678  */
679 int
680 copyoutptr(softc, src, dst, size)
681         void *src, *dst;
682         size_t size;
683 {
684         caddr_t ca;
685
686         bcopy(dst, (char *)&ca, sizeof(ca));
687         bcopy(src, ca, size);
688         return 0;
689 }
690
691
692 /*
693  * See above for description, except that all addressing is in user space.
694  */
695 int
696 copyinptr(src, dst, size)
697         void *src, *dst;
698         size_t size;
699 {
700         caddr_t ca;
701
702         bcopy(src, (char *)&ca, sizeof(ca));
703         bcopy(ca, dst, size);
704         return 0;
705 }
706 #endif
707
708
709 /*
710  * return the first IP Address associated with an interface
711  */
712 int
713 ipf_ifpaddr(softc, v, atype, ifptr, inp, inpmask)
714         ipf_main_softc_t *softc;
715         int v, atype;
716         void *ifptr;
717         i6addr_t *inp, *inpmask;
718 {
719         struct ifnet *ifp = ifptr;
720 #ifdef __sgi
721         struct in_ifaddr *ifa;
722 #else
723         struct ifaddr *ifa;
724 #endif
725
726 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
727         ifa = ifp->if_addrlist.tqh_first;
728 #else
729 # ifdef __sgi
730         ifa = (struct in_ifaddr *)ifp->in_ifaddr;
731 # else
732         ifa = ifp->if_addrlist;
733 # endif
734 #endif
735         if (ifa != NULL) {
736                 if (v == 4) {
737                         struct sockaddr_in *sin, mask;
738
739                         mask.sin_addr.s_addr = 0xffffffff;
740
741 #ifdef __sgi
742                         sin = (struct sockaddr_in *)&ifa->ia_addr;
743 #else
744                         sin = (struct sockaddr_in *)&ifa->ifa_addr;
745 #endif
746
747                         return ipf_ifpfillv4addr(atype, sin, &mask,
748                                                  &inp->in4, &inpmask->in4);
749                 }
750 #ifdef USE_INET6
751                 if (v == 6) {
752                         struct sockaddr_in6 *sin6, mask;
753
754                         sin6 = (struct sockaddr_in6 *)&ifa->ifa_addr;
755                         ((i6addr_t *)&mask.sin6_addr)->i6[0] = 0xffffffff;
756                         ((i6addr_t *)&mask.sin6_addr)->i6[1] = 0xffffffff;
757                         ((i6addr_t *)&mask.sin6_addr)->i6[2] = 0xffffffff;
758                         ((i6addr_t *)&mask.sin6_addr)->i6[3] = 0xffffffff;
759                         return ipf_ifpfillv6addr(atype, sin6, &mask,
760                                                  inp, inpmask);
761                 }
762 #endif
763         }
764         return 0;
765 }
766
767
768 /*
769  * This function is not meant to be random, rather just produce a
770  * sequence of numbers that isn't linear to show "randomness".
771  */
772 u_32_t
773 ipf_random()
774 {
775         static unsigned int last = 0xa5a5a5a5;
776         static int calls = 0;
777         int number;
778
779         calls++;
780
781         /*
782          * These are deliberately chosen to ensure that there is some
783          * attempt to test whether the output covers the range in test n18.
784          */
785         switch (calls)
786         {
787         case 1 :
788                 number = 0;
789                 break;
790         case 2 :
791                 number = 4;
792                 break;
793         case 3 :
794                 number = 3999;
795                 break;
796         case 4 :
797                 number = 4000;
798                 break;
799         case 5 :
800                 number = 48999;
801                 break;
802         case 6 :
803                 number = 49000;
804                 break;
805         default :
806                 number = last;
807                 last *= calls;
808                 last++;
809                 number ^= last;
810                 break;
811         }
812         return number;
813 }
814
815
816 int
817 ipf_verifysrc(fin)
818         fr_info_t *fin;
819 {
820         return 1;
821 }
822
823
824 int
825 ipf_inject(fin, m)
826         fr_info_t *fin;
827         mb_t *m;
828 {
829         FREE_MB_T(m);
830
831         return 0;
832 }
833
834
835 u_int
836 ipf_pcksum(fin, hlen, sum)
837         fr_info_t *fin;
838         int hlen;
839         u_int sum;
840 {
841         u_short *sp;
842         u_int sum2;
843         int slen;
844
845         slen = fin->fin_plen - hlen;
846         sp = (u_short *)((u_char *)fin->fin_ip + hlen);
847
848         for (; slen > 1; slen -= 2)
849                 sum += *sp++;
850         if (slen)
851                 sum += ntohs(*(u_char *)sp << 8);
852         while (sum > 0xffff)
853                 sum = (sum & 0xffff) + (sum >> 16);
854         sum2 = (u_short)(~sum & 0xffff);
855
856         return sum2;
857 }
858
859
860 void *
861 ipf_pullup(m, fin, plen)
862         mb_t *m;
863         fr_info_t *fin;
864         int plen;
865 {
866         if (M_LEN(m) >= plen)
867                 return fin->fin_ip;
868
869         /*
870          * Fake ipf_pullup failing
871          */
872         fin->fin_reason = FRB_PULLUP;
873         *fin->fin_mp = NULL;
874         fin->fin_m = NULL;
875         fin->fin_ip = NULL;
876         return NULL;
877 }