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