]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/ipfilter/ip_fil.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / ipfilter / ip_fil.c
1 /*      $FreeBSD$       */
2
3 /*
4  * Copyright (C) 1993-2001 by Darren Reed.
5  *
6  * See the IPFILTER.LICENCE file for details on licencing.
7  */
8 #if !defined(lint)
9 static const char sccsid[] = "@(#)ip_fil.c      2.41 6/5/96 (C) 1993-2000 Darren Reed";
10 static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.133.2.18 2007/09/09 11:32:05 darrenr Exp $";
11 #endif
12
13 #ifndef SOLARIS
14 #define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
15 #endif
16
17 #include <sys/param.h>
18 #if defined(__FreeBSD__) && !defined(__FreeBSD_version)
19 # if defined(IPFILTER_LKM)
20 #  ifndef __FreeBSD_cc_version
21 #   include <osreldate.h>
22 #  else
23 #   if __FreeBSD_cc_version < 430000
24 #    include <osreldate.h>
25 #   endif
26 #  endif
27 # endif
28 #endif
29 #include <sys/errno.h>
30 #if defined(__hpux) && (HPUXREV >= 1111) && !defined(_KERNEL)
31 # include <sys/kern_svcs.h>
32 #endif
33 #include <sys/types.h>
34 #define _KERNEL
35 #define KERNEL
36 #ifdef __OpenBSD__
37 struct file;
38 #endif
39 #include <sys/uio.h>
40 #undef _KERNEL
41 #undef KERNEL
42 #include <sys/file.h>
43 #include <sys/ioctl.h>
44 #ifdef __sgi
45 # include <sys/ptimers.h>
46 #endif
47 #include <sys/time.h>
48 #if !SOLARIS
49 # if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000)
50 #  include <sys/dirent.h>
51 # else
52 #  include <sys/dir.h>
53 # endif
54 #else
55 # include <sys/filio.h>
56 #endif
57 #ifndef linux
58 # include <sys/protosw.h>
59 #endif
60 #include <sys/socket.h>
61
62 #include <stdio.h>
63 #include <string.h>
64 #include <stdlib.h>
65 #include <ctype.h>
66 #include <fcntl.h>
67
68 #ifdef __hpux
69 # define _NET_ROUTE_INCLUDED
70 #endif
71 #include <net/if.h>
72 #ifdef sun
73 # include <net/af.h>
74 #endif
75 #if __FreeBSD_version >= 300000
76 # include <net/if_var.h>
77 #endif
78 #ifdef __sgi
79 #include <sys/debug.h>
80 # ifdef IFF_DRVRLOCK /* IRIX6 */
81 #include <sys/hashing.h>
82 # endif
83 #endif
84 #if defined(__FreeBSD__) || defined(SOLARIS2)
85 # include "radix_ipf.h"
86 #endif
87 #ifndef __osf__
88 # include <net/route.h>
89 #endif
90 #include <netinet/in.h>
91 #if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /* IRIX < 6 */ && \
92     !defined(__hpux) && !defined(linux)
93 # include <netinet/in_var.h>
94 #endif
95 #include <netinet/in_systm.h>
96 #include <netinet/ip.h>
97 #if !defined(linux)
98 # include <netinet/ip_var.h>
99 #endif
100 #include <netinet/tcp.h>
101 #if defined(__osf__)
102 # include <netinet/tcp_timer.h>
103 #endif
104 #if defined(__osf__) || defined(__hpux) || defined(__sgi)
105 # include "radix_ipf_local.h"
106 # define _RADIX_H_
107 #endif
108 #include <netinet/udp.h>
109 #include <netinet/tcpip.h>
110 #include <netinet/ip_icmp.h>
111 #include <unistd.h>
112 #include <syslog.h>
113 #include <arpa/inet.h>
114 #ifdef __hpux
115 # undef _NET_ROUTE_INCLUDED
116 #endif
117 #include "netinet/ip_compat.h"
118 #include "netinet/ip_fil.h"
119 #include "netinet/ip_nat.h"
120 #include "netinet/ip_frag.h"
121 #include "netinet/ip_state.h"
122 #include "netinet/ip_proxy.h"
123 #include "netinet/ip_auth.h"
124 #ifdef  IPFILTER_SYNC
125 #include "netinet/ip_sync.h"
126 #endif
127 #ifdef  IPFILTER_SCAN
128 #include "netinet/ip_scan.h"
129 #endif
130 #include "netinet/ip_pool.h"
131 #ifdef IPFILTER_COMPILED
132 # include "netinet/ip_rules.h"
133 #endif
134 #if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
135 # include <sys/malloc.h>
136 #endif
137 #ifdef __hpux
138 struct rtentry;
139 #endif
140 #include "md5.h"
141
142
143 #if !defined(__osf__) && !defined(__linux__)
144 extern  struct  protosw inetsw[];
145 #endif
146
147 #include "ipt.h"
148 static  struct  ifnet **ifneta = NULL;
149 static  int     nifs = 0;
150
151 static  void    fr_setifpaddr __P((struct ifnet *, char *));
152 void    init_ifp __P((void));
153 #if defined(__sgi) && (IRIX < 60500)
154 static int      no_output __P((struct ifnet *, struct mbuf *,
155                                struct sockaddr *));
156 static int      write_output __P((struct ifnet *, struct mbuf *,
157                                   struct sockaddr *));
158 #else
159 # if TRU64 >= 1885
160 static int      no_output __P((struct ifnet *, struct mbuf *,
161                                struct sockaddr *, struct rtentry *, char *));
162 static int      write_output __P((struct ifnet *, struct mbuf *,
163                                   struct sockaddr *, struct rtentry *, char *));
164 # else
165 static int      no_output __P((struct ifnet *, struct mbuf *,
166                                struct sockaddr *, struct rtentry *));
167 static int      write_output __P((struct ifnet *, struct mbuf *,
168                                   struct sockaddr *, struct rtentry *));
169 # endif
170 #endif
171
172
173 int ipfattach()
174 {
175         fr_running = 1;
176         return 0;
177 }
178
179
180 int ipfdetach()
181 {
182         fr_running = -1;
183         return 0;
184 }
185
186
187 /*
188  * Filter ioctl interface.
189  */
190 int iplioctl(dev, cmd, data, mode)
191 int dev;
192 ioctlcmd_t cmd;
193 caddr_t data;
194 int mode;
195 {
196         int error = 0, unit = 0, uid;
197         SPL_INT(s);
198
199         uid = getuid();
200         unit = dev;
201
202         SPL_NET(s);
203
204         error = fr_ioctlswitch(unit, data, cmd, mode, uid, NULL);
205         if (error != -1) {
206                 SPL_X(s);
207                 return error;
208         }
209
210         SPL_X(s);
211         return error;
212 }
213
214
215 void fr_forgetifp(ifp)
216 void *ifp;
217 {
218         register frentry_t *f;
219
220         WRITE_ENTER(&ipf_mutex);
221         for (f = ipacct[0][fr_active]; (f != NULL); f = f->fr_next)
222                 if (f->fr_ifa == ifp)
223                         f->fr_ifa = (void *)-1;
224         for (f = ipacct[1][fr_active]; (f != NULL); f = f->fr_next)
225                 if (f->fr_ifa == ifp)
226                         f->fr_ifa = (void *)-1;
227         for (f = ipfilter[0][fr_active]; (f != NULL); f = f->fr_next)
228                 if (f->fr_ifa == ifp)
229                         f->fr_ifa = (void *)-1;
230         for (f = ipfilter[1][fr_active]; (f != NULL); f = f->fr_next)
231                 if (f->fr_ifa == ifp)
232                         f->fr_ifa = (void *)-1;
233 #ifdef  USE_INET6
234         for (f = ipacct6[0][fr_active]; (f != NULL); f = f->fr_next)
235                 if (f->fr_ifa == ifp)
236                         f->fr_ifa = (void *)-1;
237         for (f = ipacct6[1][fr_active]; (f != NULL); f = f->fr_next)
238                 if (f->fr_ifa == ifp)
239                         f->fr_ifa = (void *)-1;
240         for (f = ipfilter6[0][fr_active]; (f != NULL); f = f->fr_next)
241                 if (f->fr_ifa == ifp)
242                         f->fr_ifa = (void *)-1;
243         for (f = ipfilter6[1][fr_active]; (f != NULL); f = f->fr_next)
244                 if (f->fr_ifa == ifp)
245                         f->fr_ifa = (void *)-1;
246 #endif
247         RWLOCK_EXIT(&ipf_mutex);
248         fr_natsync(ifp);
249 }
250
251
252 #if defined(__sgi) && (IRIX < 60500)
253 static int no_output(ifp, m, s)
254 #else
255 # if TRU64 >= 1885
256 static int no_output (ifp, m, s, rt, cp)
257 char *cp;
258 # else
259 static int no_output(ifp, m, s, rt)
260 # endif
261 struct rtentry *rt;
262 #endif
263 struct ifnet *ifp;
264 struct mbuf *m;
265 struct sockaddr *s;
266 {
267         return 0;
268 }
269
270
271 #if defined(__sgi) && (IRIX < 60500)
272 static int write_output(ifp, m, s)
273 #else
274 # if TRU64 >= 1885
275 static int write_output (ifp, m, s, rt, cp)
276 char *cp;
277 # else
278 static int write_output(ifp, m, s, rt)
279 # endif
280 struct rtentry *rt;
281 #endif
282 struct ifnet *ifp;
283 struct mbuf *m;
284 struct sockaddr *s;
285 {
286         char fname[32];
287         mb_t *mb;
288         ip_t *ip;
289         int fd;
290
291         mb = (mb_t *)m;
292         ip = MTOD(mb, ip_t *);
293
294 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
295     (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
296     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
297         sprintf(fname, "/tmp/%s", ifp->if_xname);
298 #else
299         sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
300 #endif
301         fd = open(fname, O_WRONLY|O_APPEND);
302         if (fd == -1) {
303                 perror("open");
304                 return -1;
305         }
306         write(fd, (char *)ip, ntohs(ip->ip_len));
307         close(fd);
308         return 0;
309 }
310
311
312 static void fr_setifpaddr(ifp, addr)
313 struct ifnet *ifp;
314 char *addr;
315 {
316 #ifdef __sgi
317         struct in_ifaddr *ifa;
318 #else
319         struct ifaddr *ifa;
320 #endif
321
322 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
323         if (ifp->if_addrlist.tqh_first != NULL)
324 #else
325 # ifdef __sgi
326         if (ifp->in_ifaddr != NULL)
327 # else
328         if (ifp->if_addrlist != NULL)
329 # endif
330 #endif
331                 return;
332
333         ifa = (struct ifaddr *)malloc(sizeof(*ifa));
334 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
335         ifp->if_addrlist.tqh_first = ifa;
336 #else
337 # ifdef __sgi
338         ifp->in_ifaddr = ifa;
339 # else
340         ifp->if_addrlist = ifa;
341 # endif
342 #endif
343
344         if (ifa != NULL) {
345                 struct sockaddr_in *sin;
346
347 #ifdef __sgi
348                 sin = (struct sockaddr_in *)&ifa->ia_addr;
349 #else
350                 sin = (struct sockaddr_in *)&ifa->ifa_addr;
351 #endif
352                 sin->sin_addr.s_addr = inet_addr(addr);
353                 if (sin->sin_addr.s_addr == 0)
354                         abort();
355         }
356 }
357
358 struct ifnet *get_unit(name, v)
359 char *name;
360 int v;
361 {
362         struct ifnet *ifp, **ifpp, **old_ifneta;
363         char *addr;
364 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
365     (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
366     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
367
368         if (name == NULL)
369                 name = "anon0";
370
371         addr = strchr(name, '=');
372         if (addr != NULL)
373                 *addr++ = '\0';
374
375         for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
376                 if (!strcmp(name, ifp->if_xname)) {
377                         if (addr != NULL)
378                                 fr_setifpaddr(ifp, addr);
379                         return ifp;
380                 }
381         }
382 #else
383         char *s, ifname[LIFNAMSIZ+1];
384
385         if (name == NULL)
386                 name = "anon0";
387
388         addr = strchr(name, '=');
389         if (addr != NULL)
390                 *addr++ = '\0';
391
392         for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
393                 COPYIFNAME(v, ifp, ifname);
394                 if (!strcmp(name, ifname)) {
395                         if (addr != NULL)
396                                 fr_setifpaddr(ifp, addr);
397                         return ifp;
398                 }
399         }
400 #endif
401
402         if (!ifneta) {
403                 ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2);
404                 if (!ifneta)
405                         return NULL;
406                 ifneta[1] = NULL;
407                 ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp));
408                 if (!ifneta[0]) {
409                         free(ifneta);
410                         return NULL;
411                 }
412                 nifs = 1;
413         } else {
414                 old_ifneta = ifneta;
415                 nifs++;
416                 ifneta = (struct ifnet **)realloc(ifneta,
417                                                   (nifs + 1) * sizeof(ifp));
418                 if (!ifneta) {
419                         free(old_ifneta);
420                         nifs = 0;
421                         return NULL;
422                 }
423                 ifneta[nifs] = NULL;
424                 ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp));
425                 if (!ifneta[nifs - 1]) {
426                         nifs--;
427                         return NULL;
428                 }
429         }
430         ifp = ifneta[nifs - 1];
431
432 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
433         TAILQ_INIT(&ifp->if_addrlist);
434 #endif
435 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
436     (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
437     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
438         (void) strncpy(ifp->if_xname, name, sizeof(ifp->if_xname));
439 #else
440         for (s = name; *s && !ISDIGIT(*s); s++)
441                 ;
442         if (*s && ISDIGIT(*s)) {
443                 ifp->if_unit = atoi(s);
444                 ifp->if_name = (char *)malloc(s - name + 1);
445                 (void) strncpy(ifp->if_name, name, s - name);
446                 ifp->if_name[s - name] = '\0';
447         } else {
448                 ifp->if_name = strdup(name);
449                 ifp->if_unit = -1;
450         }
451 #endif
452         ifp->if_output = (void *)no_output;
453
454         if (addr != NULL) {
455                 fr_setifpaddr(ifp, addr);
456         }
457
458         return ifp;
459 }
460
461
462 char *get_ifname(ifp)
463 struct ifnet *ifp;
464 {
465         static char ifname[LIFNAMSIZ];
466
467 #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(linux) || \
468     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
469         sprintf(ifname, "%s", ifp->if_xname);
470 #else
471         sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit);
472 #endif
473         return ifname;
474 }
475
476
477
478 void init_ifp()
479 {
480         struct ifnet *ifp, **ifpp;
481         char fname[32];
482         int fd;
483
484 #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
485     (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \
486     (defined(__FreeBSD__) && (__FreeBSD_version >= 501113))
487         for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
488                 ifp->if_output = (void *)write_output;
489                 sprintf(fname, "/tmp/%s", ifp->if_xname);
490                 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
491                 if (fd == -1)
492                         perror("open");
493                 else
494                         close(fd);
495         }
496 #else
497
498         for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) {
499                 ifp->if_output = write_output;
500                 sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
501                 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
502                 if (fd == -1)
503                         perror("open");
504                 else
505                         close(fd);
506         }
507 #endif
508 }
509
510
511 int fr_fastroute(m, mpp, fin, fdp)
512 mb_t *m, **mpp;
513 fr_info_t *fin;
514 frdest_t *fdp;
515 {
516         struct ifnet *ifp = fdp->fd_ifp;
517         ip_t *ip = fin->fin_ip;
518         int error = 0;
519         frentry_t *fr;
520         void *sifp;
521
522         if (!ifp)
523                 return 0;       /* no routing table out here */
524
525         fr = fin->fin_fr;
526         ip->ip_sum = 0;
527
528         if (fin->fin_out == 0) {
529                 sifp = fin->fin_ifp;
530                 fin->fin_ifp = ifp;
531                 fin->fin_out = 1;
532                 (void) fr_acctpkt(fin, NULL);
533                 fin->fin_fr = NULL;
534                 if (!fr || !(fr->fr_flags & FR_RETMASK)) {
535                         u_32_t pass;
536
537                         (void) fr_checkstate(fin, &pass);
538                 }
539
540                 switch (fr_checknatout(fin, NULL))
541                 {
542                 case 0 :
543                         break;
544                 case 1 :
545                         ip->ip_sum = 0;
546                         break;
547                 case -1 :
548                         error = -1;
549                         goto done;
550                         break;
551                 }
552
553                 fin->fin_ifp = sifp;
554                 fin->fin_out = 0;
555         }
556
557 #if defined(__sgi) && (IRIX < 60500)
558         (*ifp->if_output)(ifp, (void *)ip, NULL);
559 # if TRU64 >= 1885
560         (*ifp->if_output)(ifp, (void *)m, NULL, 0, 0);
561 # else
562         (*ifp->if_output)(ifp, (void *)m, NULL, 0);
563 # endif
564 #endif
565 done:
566         return error;
567 }
568
569
570 int fr_send_reset(fin)
571 fr_info_t *fin;
572 {
573         verbose("- TCP RST sent\n");
574         return 0;
575 }
576
577
578 int fr_send_icmp_err(type, fin, dst)
579 int type;
580 fr_info_t *fin;
581 int dst;
582 {
583         verbose("- ICMP unreachable sent\n");
584         return 0;
585 }
586
587
588 void frsync(ifp)
589 void *ifp;
590 {
591         return;
592 }
593
594
595 void m_freem(m)
596 mb_t *m;
597 {
598         return;
599 }
600
601
602 void m_copydata(m, off, len, cp)
603 mb_t *m;
604 int off, len;
605 caddr_t cp;
606 {
607         bcopy((char *)m + off, cp, len);
608 }
609
610
611 int ipfuiomove(buf, len, rwflag, uio)
612 caddr_t buf;
613 int len, rwflag;
614 struct uio *uio;
615 {
616         int left, ioc, num, offset;
617         struct iovec *io;
618         char *start;
619
620         if (rwflag == UIO_READ) {
621                 left = len;
622                 ioc = 0;
623
624                 offset = uio->uio_offset;
625
626                 while ((left > 0) && (ioc < uio->uio_iovcnt)) {
627                         io = uio->uio_iov + ioc;
628                         num = io->iov_len;
629                         if (num > left)
630                                 num = left;
631                         start = (char *)io->iov_base + offset;
632                         if (start > (char *)io->iov_base + io->iov_len) {
633                                 offset -= io->iov_len;
634                                 ioc++;
635                                 continue;
636                         }
637                         bcopy(buf, start, num);
638                         uio->uio_resid -= num;
639                         uio->uio_offset += num;
640                         left -= num;
641                         if (left > 0)
642                                 ioc++;
643                 }
644                 if (left > 0)
645                         return EFAULT;
646         }
647         return 0;
648 }
649
650
651 u_32_t fr_newisn(fin)
652 fr_info_t *fin;
653 {
654         static int iss_seq_off = 0;
655         u_char hash[16];
656         u_32_t newiss;
657         MD5_CTX ctx;
658
659         /*
660          * Compute the base value of the ISS.  It is a hash
661          * of (saddr, sport, daddr, dport, secret).
662          */
663         MD5Init(&ctx);
664
665         MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src,
666                   sizeof(fin->fin_fi.fi_src));
667         MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst,
668                   sizeof(fin->fin_fi.fi_dst));
669         MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat));
670
671         /* MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); */
672
673         MD5Final(hash, &ctx);
674
675         memcpy(&newiss, hash, sizeof(newiss));
676
677         /*
678          * Now increment our "timer", and add it in to
679          * the computed value.
680          *
681          * XXX Use `addin'?
682          * XXX TCP_ISSINCR too large to use?
683          */
684         iss_seq_off += 0x00010000;
685         newiss += iss_seq_off;
686         return newiss;
687 }
688
689
690 /* ------------------------------------------------------------------------ */
691 /* Function:    fr_nextipid                                                 */
692 /* Returns:     int - 0 == success, -1 == error (packet should be droppped) */
693 /* Parameters:  fin(I) - pointer to packet information                      */
694 /*                                                                          */
695 /* Returns the next IPv4 ID to use for this packet.                         */
696 /* ------------------------------------------------------------------------ */
697 INLINE u_short fr_nextipid(fin)
698 fr_info_t *fin;
699 {
700         static u_short ipid = 0;
701         u_short id;
702
703         MUTEX_ENTER(&ipf_rw);
704         id = ipid++;
705         MUTEX_EXIT(&ipf_rw);
706
707         return id;
708 }
709
710
711 INLINE void fr_checkv4sum(fin)
712 fr_info_t *fin;
713 {
714         if (fr_checkl4sum(fin) == -1)
715                 fin->fin_flx |= FI_BAD;
716 }
717
718
719 #ifdef  USE_INET6
720 INLINE void fr_checkv6sum(fin)
721 fr_info_t *fin;
722 {
723         if (fr_checkl4sum(fin) == -1)
724                 fin->fin_flx |= FI_BAD;
725 }
726 #endif
727
728
729 /*
730  * See above for description, except that all addressing is in user space.
731  */
732 int copyoutptr(src, dst, size)
733 void *src, *dst;
734 size_t size;
735 {
736         caddr_t ca;
737
738         bcopy(dst, (char *)&ca, sizeof(ca));
739         bcopy(src, ca, size);
740         return 0;
741 }
742
743
744 /*
745  * See above for description, except that all addressing is in user space.
746  */
747 int copyinptr(src, dst, size)
748 void *src, *dst;
749 size_t size;
750 {
751         caddr_t ca;
752
753         bcopy(src, (char *)&ca, sizeof(ca));
754         bcopy(ca, dst, size);
755         return 0;
756 }
757
758
759 /*
760  * return the first IP Address associated with an interface
761  */
762 int fr_ifpaddr(v, atype, ifptr, inp, inpmask)
763 int v, atype;
764 void *ifptr;
765 struct in_addr *inp, *inpmask;
766 {
767         struct ifnet *ifp = ifptr;
768 #ifdef __sgi
769         struct in_ifaddr *ifa;
770 #else
771         struct ifaddr *ifa;
772 #endif
773
774 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
775         ifa = ifp->if_addrlist.tqh_first;
776 #else
777 # ifdef __sgi
778         ifa = (struct in_ifaddr *)ifp->in_ifaddr;
779 # else
780         ifa = ifp->if_addrlist;
781 # endif
782 #endif
783         if (ifa != NULL) {
784                 struct sockaddr_in *sin, mask;
785
786                 mask.sin_addr.s_addr = 0xffffffff;
787
788 #ifdef __sgi
789                 sin = (struct sockaddr_in *)&ifa->ia_addr;
790 #else
791                 sin = (struct sockaddr_in *)&ifa->ifa_addr;
792 #endif
793
794                 return fr_ifpfillv4addr(atype, sin, &mask, inp, inpmask);
795         }
796         return 0;
797 }
798
799
800 int ipfsync()
801 {
802         return 0;
803 }
804
805
806 #ifndef ipf_random
807 u_32_t ipf_random()
808 {
809         static int seeded = 0;
810
811         /*
812          * Choose a non-random seed so that "randomness" can be "tested."
813          */
814         if (seeded == 0) {
815                 srand(0);
816                 seeded = 1;
817         }
818         return rand();
819 }
820 #endif