Annotation of embedaddon/miniupnpd/ipf/ipfrdr.c, revision 1.1

1.1     ! misho       1: /* $Id: ipfrdr.c,v 1.11 2009/10/10 18:34:39 nanard Exp $ */
        !             2: /* MiniUPnP project
        !             3:  * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
        !             4:  * (c) 2007 Darren Reed
        !             5:  * This software is subject to the conditions detailed
        !             6:  * in the LICENCE file provided within the distribution */
        !             7: 
        !             8: #include <sys/param.h>
        !             9: #include <sys/types.h>
        !            10: #include <sys/file.h>
        !            11: /*
        !            12:  * This is a workaround for <sys/uio.h> troubles on FreeBSD, HPUX, OpenBSD.
        !            13:  * Needed here because on some systems <sys/uio.h> gets included by things
        !            14:  * like <sys/socket.h>
        !            15:  */
        !            16: #ifndef _KERNEL
        !            17: # define ADD_KERNEL
        !            18: # define _KERNEL
        !            19: # define KERNEL
        !            20: #endif
        !            21: #ifdef __OpenBSD__
        !            22: struct file;
        !            23: #endif
        !            24: #include <sys/uio.h>
        !            25: #ifdef ADD_KERNEL
        !            26: # undef _KERNEL
        !            27: # undef KERNEL
        !            28: #endif
        !            29: #include <sys/time.h>
        !            30: #include <sys/socket.h>
        !            31: #include <sys/syslog.h>
        !            32: #include <sys/ioctl.h>
        !            33: #include <net/if.h>
        !            34: #if __FreeBSD_version >= 300000
        !            35: # include <net/if_var.h>
        !            36: #endif
        !            37: #include <netinet/in.h>
        !            38: #include <netinet/in_systm.h>
        !            39: #include <netinet/ip.h>
        !            40: #include <netinet/ip_icmp.h>
        !            41: #ifndef        TCP_PAWS_IDLE   /* IRIX */
        !            42: # include <netinet/tcp.h>
        !            43: #endif
        !            44: #include <netinet/udp.h>
        !            45: 
        !            46: #include <arpa/inet.h>
        !            47: 
        !            48: #include <errno.h>
        !            49: #include <limits.h>
        !            50: #include <netdb.h>
        !            51: #include <stdlib.h>
        !            52: #include <fcntl.h>
        !            53: #include <syslog.h>
        !            54: #include <stddef.h>
        !            55: #include <stdio.h>
        !            56: #if !defined(__SVR4) && !defined(__svr4__) && defined(sun)
        !            57: # include <strings.h>
        !            58: #endif
        !            59: #include <string.h>
        !            60: #include <unistd.h>
        !            61: 
        !            62: #include "../config.h"
        !            63: #include "netinet/ipl.h"
        !            64: #include "netinet/ip_compat.h"
        !            65: #include "netinet/ip_fil.h"
        !            66: #include "netinet/ip_nat.h"
        !            67: #include "netinet/ip_state.h"
        !            68: 
        !            69: 
        !            70: #ifndef __P
        !            71: # ifdef __STDC__
        !            72: #  define      __P(x)  x
        !            73: # else
        !            74: #  define      __P(x)  ()
        !            75: # endif
        !            76: #endif
        !            77: #ifndef __STDC__
        !            78: # undef                const
        !            79: # define       const
        !            80: #endif
        !            81: 
        !            82: #ifndef        U_32_T
        !            83: # define       U_32_T  1
        !            84: # if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || \
        !            85:        defined(__sgi)
        !            86: typedef        u_int32_t       u_32_t;
        !            87: # else
        !            88: #  if defined(__alpha__) || defined(__alpha) || defined(_LP64)
        !            89: typedef unsigned int   u_32_t;
        !            90: #  else
        !            91: #   if SOLARIS2 >= 6
        !            92: typedef uint32_t       u_32_t;
        !            93: #   else
        !            94: typedef unsigned int   u_32_t;
        !            95: #   endif
        !            96: #  endif
        !            97: # endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ || __sgi */
        !            98: #endif /* U_32_T */
        !            99: 
        !           100: 
        !           101: #if defined(__NetBSD__) || defined(__OpenBSD__) ||                     \
        !           102:         (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) ||  \
        !           103:        SOLARIS || defined(__sgi) || defined(__osf__) || defined(linux)
        !           104: # include <stdarg.h>
        !           105: typedef        int     (* ioctlfunc_t) __P((int, ioctlcmd_t, ...));
        !           106: #else
        !           107: typedef        int     (* ioctlfunc_t) __P((dev_t, ioctlcmd_t, void *));
        !           108: #endif
        !           109: typedef        void    (* addfunc_t) __P((int, ioctlfunc_t, void *));
        !           110: typedef        int     (* copyfunc_t) __P((void *, void *, size_t));
        !           111: 
        !           112: 
        !           113: /*
        !           114:  * SunOS4
        !           115:  */
        !           116: #if defined(sun) && !defined(__SVR4) && !defined(__svr4__)
        !           117: extern int     ioctl __P((int, int, void *));
        !           118: #endif
        !           119: 
        !           120: #include "../upnpglobalvars.h"
        !           121: 
        !           122: /* group name */
        !           123: static const char group_name[] = "miniupnpd";
        !           124: 
        !           125: static int dev = -1;
        !           126: static int dev_ipl = -1;
        !           127: 
        !           128: /* IPFilter cannot store redirection descriptions, so we use our
        !           129:  * own structure to store them */
        !           130: struct rdr_desc {
        !           131:        struct rdr_desc * next;
        !           132:        unsigned short eport;
        !           133:        int proto;
        !           134:        char str[];
        !           135: };
        !           136: 
        !           137: /* pointer to the chained list where descriptions are stored */
        !           138: static struct rdr_desc * rdr_desc_list;
        !           139: 
        !           140: static void
        !           141: add_redirect_desc(unsigned short eport, int proto, const char * desc)
        !           142: {
        !           143:        struct rdr_desc * p;
        !           144:        size_t l;
        !           145:        
        !           146:        if (desc != NULL) {
        !           147:                l = strlen(desc) + 1;
        !           148:                p = malloc(sizeof(struct rdr_desc) + l);
        !           149:                if (p) {
        !           150:                        p->next = rdr_desc_list;
        !           151:                        p->eport = eport;
        !           152:                        p->proto = proto;
        !           153:                        memcpy(p->str, desc, l);
        !           154:                        rdr_desc_list = p;
        !           155:                }
        !           156:        }
        !           157: }
        !           158: 
        !           159: static void
        !           160: del_redirect_desc(unsigned short eport, int proto)
        !           161: {
        !           162:        struct rdr_desc * p, * last;
        !           163: 
        !           164:        last = NULL;
        !           165:        for (p = rdr_desc_list; p; p = p->next) {
        !           166:                if(p->eport == eport && p->proto == proto) {
        !           167:                        if (last == NULL)
        !           168:                                rdr_desc_list = p->next;
        !           169:                        else
        !           170:                                last->next = p->next;
        !           171:                        free(p);
        !           172:                        return;
        !           173:                }
        !           174:        }
        !           175: }
        !           176: 
        !           177: static void
        !           178: get_redirect_desc(unsigned short eport, int proto, char * desc, int desclen)
        !           179: {
        !           180:        struct rdr_desc * p;
        !           181:        
        !           182:        if (desc == NULL || desclen == 0)
        !           183:                return;
        !           184:        for (p = rdr_desc_list; p; p = p->next) {
        !           185:                if (p->eport == eport && p->proto == proto)
        !           186:                {
        !           187:                        strncpy(desc, p->str, desclen);
        !           188:                        return;
        !           189:                }
        !           190:        }
        !           191: }
        !           192: 
        !           193: int init_redirect(void)
        !           194: {
        !           195:        
        !           196:        dev = open(IPNAT_NAME, O_RDWR);
        !           197:        if (dev < 0) {
        !           198:                syslog(LOG_ERR, "open(\"%s\"): %m", IPNAT_NAME);
        !           199:                return -1;
        !           200:        }
        !           201:        dev_ipl = open(IPL_NAME, O_RDWR);
        !           202:        if (dev_ipl < 0) {
        !           203:                syslog(LOG_ERR, "open(\"%s\"): %m", IPL_NAME);
        !           204:                return -1;
        !           205:        }
        !           206:        return 0;
        !           207: }
        !           208: 
        !           209: void shutdown_redirect(void)
        !           210: {
        !           211:        
        !           212:        if (dev >= 0) {
        !           213:                close(dev);
        !           214:                dev = -1;
        !           215:        }
        !           216:        if (dev_ipl >= 0) {
        !           217:                close(dev_ipl);
        !           218:                dev = -1;
        !           219:        }
        !           220:        return;
        !           221: }
        !           222: 
        !           223: int
        !           224: add_redirect_rule2(const char * ifname, unsigned short eport,
        !           225:     const char * iaddr, unsigned short iport, int proto,
        !           226:     const char * desc)
        !           227: {
        !           228:        struct ipnat ipnat;
        !           229:        struct ipfobj obj;
        !           230:        int r;
        !           231: 
        !           232:        if (dev < 0) {
        !           233:                syslog(LOG_ERR, "%s not open", IPNAT_NAME);
        !           234:                return -1;
        !           235:        }
        !           236: 
        !           237:        memset(&obj, 0, sizeof(obj));
        !           238:        memset(&ipnat, 0, sizeof(ipnat));
        !           239: 
        !           240:        ipnat.in_redir = NAT_REDIRECT;
        !           241:        ipnat.in_p = proto;
        !           242:        if (proto == IPPROTO_TCP)
        !           243:                ipnat.in_flags = IPN_TCP;
        !           244:        if (proto == IPPROTO_UDP)
        !           245:                ipnat.in_flags = IPN_UDP;
        !           246:        ipnat.in_dcmp = FR_EQUAL;
        !           247:        ipnat.in_pmin = htons(eport);
        !           248:        ipnat.in_pmax = htons(eport);
        !           249:        ipnat.in_pnext = htons(iport);
        !           250:        ipnat.in_v = 4;
        !           251:        strlcpy(ipnat.in_tag.ipt_tag, group_name, IPFTAG_LEN);
        !           252: 
        !           253: #ifdef USE_IFNAME_IN_RULES
        !           254:        if (ifname) {
        !           255:                strlcpy(ipnat.in_ifnames[0], ifname, IFNAMSIZ);
        !           256:                strlcpy(ipnat.in_ifnames[1], ifname, IFNAMSIZ);
        !           257:        }
        !           258: #endif
        !           259: 
        !           260:        inet_pton(AF_INET, iaddr, &ipnat.in_in[0].in4);
        !           261:        ipnat.in_in[1].in4.s_addr = 0xffffffff;
        !           262: 
        !           263:        obj.ipfo_rev = IPFILTER_VERSION;
        !           264:        obj.ipfo_size = sizeof(ipnat);
        !           265:        obj.ipfo_ptr = &ipnat;
        !           266:        obj.ipfo_type = IPFOBJ_IPNAT;
        !           267: 
        !           268:        r = ioctl(dev, SIOCADNAT, &obj);
        !           269:        if (r == -1)
        !           270:                syslog(LOG_ERR, "ioctl(SIOCADNAT): %m");
        !           271:        else
        !           272:                add_redirect_desc(eport, proto, desc);
        !           273:        return r;
        !           274: }
        !           275: 
        !           276: /* get_redirect_rule()
        !           277:  * return value : 0 success (found)
        !           278:  * -1 = error or rule not found */
        !           279: int
        !           280: get_redirect_rule(const char * ifname, unsigned short eport, int proto,
        !           281:     char * iaddr, int iaddrlen, unsigned short * iport,
        !           282:     char * desc, int desclen,
        !           283:     u_int64_t * packets, u_int64_t * bytes)
        !           284: {
        !           285:        ipfgeniter_t iter;
        !           286:        ipfobj_t obj;
        !           287:        ipnat_t ipn;
        !           288:        int r;
        !           289: 
        !           290:        memset(&obj, 0, sizeof(obj));
        !           291:        obj.ipfo_rev = IPFILTER_VERSION;
        !           292:        obj.ipfo_type = IPFOBJ_GENITER;
        !           293:        obj.ipfo_size = sizeof(iter);
        !           294:        obj.ipfo_ptr = &iter;
        !           295: 
        !           296:        iter.igi_type = IPFGENITER_IPNAT;
        !           297: #if IPFILTER_VERSION > 4011300
        !           298:        iter.igi_nitems = 1;
        !           299: #endif
        !           300:        iter.igi_data = &ipn;
        !           301: 
        !           302:        if (dev < 0) {
        !           303:                syslog(LOG_ERR, "%s not open", IPNAT_NAME);
        !           304:                return -1;
        !           305:        }
        !           306: 
        !           307:        r = -1;
        !           308:        do {
        !           309:                if (ioctl(dev, SIOCGENITER, &obj) == -1) {
        !           310:                        syslog(LOG_ERR, "ioctl(dev, SIOCGENITER): %m");
        !           311:                        break;
        !           312:                }
        !           313:                if (eport == ntohs(ipn.in_pmin) &&
        !           314:                    eport == ntohs(ipn.in_pmax) &&
        !           315:                    strcmp(ipn.in_tag.ipt_tag, group_name) == 0 &&
        !           316:                    ipn.in_p == proto)
        !           317:                {
        !           318:                        strlcpy(desc, "", desclen);
        !           319:                        if (packets != NULL)
        !           320:                                *packets = 0;
        !           321:                        if (bytes != NULL)
        !           322:                                *bytes = 0;
        !           323:                        if (iport != NULL)
        !           324:                                *iport = ntohs(ipn.in_pnext);
        !           325:                        if (desc != NULL)
        !           326:                                get_redirect_desc(eport, proto, desc, desclen);
        !           327:                        inet_ntop(AF_INET, &ipn.in_in[0].in4, iaddr, iaddrlen);
        !           328:                        r = 0;
        !           329:                }
        !           330:        } while (ipn.in_next != NULL);
        !           331:        return r;
        !           332: }
        !           333: 
        !           334: 
        !           335: int
        !           336: get_redirect_rule_by_index(int index,
        !           337:     char * ifname, unsigned short * eport,
        !           338:     char * iaddr, int iaddrlen, unsigned short * iport,
        !           339:     int * proto, char * desc, int desclen,
        !           340:     u_int64_t * packets, u_int64_t * bytes)
        !           341: {
        !           342:        ipfgeniter_t iter;
        !           343:        ipfobj_t obj;
        !           344:        ipnat_t ipn;
        !           345:        int n, r;
        !           346: 
        !           347:        if (index < 0)
        !           348:                return -1;
        !           349: 
        !           350:        if (dev < 0) {
        !           351:                syslog(LOG_ERR, "%s not open", IPNAT_NAME);
        !           352:                return -1;
        !           353:        }
        !           354: 
        !           355:        memset(&obj, 0, sizeof(obj));
        !           356:        obj.ipfo_rev = IPFILTER_VERSION;
        !           357:        obj.ipfo_ptr = &iter;
        !           358:        obj.ipfo_size = sizeof(iter);
        !           359:        obj.ipfo_type = IPFOBJ_GENITER;
        !           360: 
        !           361:        iter.igi_type = IPFGENITER_IPNAT;
        !           362: #if IPFILTER_VERSION > 4011300
        !           363:        iter.igi_nitems = 1;
        !           364: #endif
        !           365:        iter.igi_data = &ipn;
        !           366: 
        !           367:        n = 0;
        !           368:        r = -1;
        !           369:        do {
        !           370:                if (ioctl(dev, SIOCGENITER, &obj) == -1) {
        !           371:                        syslog(LOG_ERR, "%s:ioctl(SIOCGENITER): %m",
        !           372:                            "get_redirect_rule_by_index");
        !           373:                        break;
        !           374:                }
        !           375: 
        !           376:                if (strcmp(ipn.in_tag.ipt_tag, group_name) != 0)
        !           377:                        continue;
        !           378: 
        !           379:                if (index == n++) {
        !           380:                        *proto = ipn.in_p;
        !           381:                        *eport = ntohs(ipn.in_pmax);
        !           382:                        *iport = ntohs(ipn.in_pnext);
        !           383: 
        !           384:                        if (ifname)
        !           385:                                strlcpy(ifname, ipn.in_ifnames[0], IFNAMSIZ);
        !           386:                        if (packets != NULL)
        !           387:                                *packets = 0;
        !           388:                        if (bytes != NULL)
        !           389:                                *bytes = 0;
        !           390:                        if (desc != NULL)
        !           391:                                get_redirect_desc(*eport, *proto, desc, desclen);
        !           392:                        inet_ntop(AF_INET, &ipn.in_in[0].in4, iaddr, iaddrlen);
        !           393:                        r = 0;
        !           394:                }
        !           395:        } while (ipn.in_next != NULL);
        !           396:        return r;
        !           397: }
        !           398: 
        !           399: static int
        !           400: real_delete_redirect_rule(const char * ifname, unsigned short eport, int proto)
        !           401: {
        !           402:        ipfgeniter_t iter;
        !           403:        ipfobj_t obj;
        !           404:        ipnat_t ipn;
        !           405:        int r;
        !           406: 
        !           407:        memset(&obj, 0, sizeof(obj));
        !           408:        obj.ipfo_rev = IPFILTER_VERSION;
        !           409:        obj.ipfo_type = IPFOBJ_GENITER;
        !           410:        obj.ipfo_size = sizeof(iter);
        !           411:        obj.ipfo_ptr = &iter;
        !           412: 
        !           413:        iter.igi_type = IPFGENITER_IPNAT;
        !           414: #if IPFILTER_VERSION > 4011300
        !           415:        iter.igi_nitems = 1;
        !           416: #endif
        !           417:        iter.igi_data = &ipn;
        !           418: 
        !           419:        if (dev < 0) {
        !           420:                syslog(LOG_ERR, "%s not open", IPNAT_NAME);
        !           421:                return -1;
        !           422:        }
        !           423: 
        !           424:        r = -1;
        !           425:        do {
        !           426:                if (ioctl(dev, SIOCGENITER, &obj) == -1) {
        !           427:                        syslog(LOG_ERR, "%s:ioctl(SIOCGENITER): %m",
        !           428:                            "delete_redirect_rule");
        !           429:                        break;
        !           430:                }
        !           431:                if (eport == ntohs(ipn.in_pmin) &&
        !           432:                    eport == ntohs(ipn.in_pmax) &&
        !           433:                    strcmp(ipn.in_tag.ipt_tag, group_name) == 0 &&
        !           434:                    ipn.in_p == proto)
        !           435:                {
        !           436:                        obj.ipfo_rev = IPFILTER_VERSION;
        !           437:                        obj.ipfo_size = sizeof(ipn);
        !           438:                        obj.ipfo_ptr = &ipn;
        !           439:                        obj.ipfo_type = IPFOBJ_IPNAT;
        !           440:                        r = ioctl(dev, SIOCRMNAT, &obj);
        !           441:                        if (r == -1)
        !           442:                                syslog(LOG_ERR, "%s:ioctl(SIOCRMNAT): %m",
        !           443:                                    "delete_redirect_rule");
        !           444:                        /* Delete the desc even if the above failed */
        !           445:                        del_redirect_desc(eport, proto);
        !           446:                        break;
        !           447:                }
        !           448:        } while (ipn.in_next != NULL);
        !           449:        return r;
        !           450: }
        !           451: 
        !           452: /* FIXME: For some reason, the iter isn't reset every other delete,
        !           453:  * so we attempt 2 deletes. */
        !           454: int
        !           455: delete_redirect_rule(const char * ifname, unsigned short eport, int proto)
        !           456: {
        !           457:        int r;
        !           458: 
        !           459:        r = real_delete_redirect_rule(ifname, eport, proto);
        !           460:        if (r == -1)
        !           461:                r = real_delete_redirect_rule(ifname, eport, proto);
        !           462:        return r;
        !           463: }
        !           464: 
        !           465: /* thanks to Seth Mos for this function */
        !           466: int
        !           467: add_filter_rule2(const char * ifname, const char * iaddr,
        !           468:     unsigned short eport, unsigned short iport,
        !           469:     int proto, const char * desc)
        !           470: {
        !           471:        ipfobj_t obj;
        !           472:        frentry_t fr;
        !           473:        fripf_t ipffr;
        !           474:        int r;
        !           475: 
        !           476:        if (dev_ipl < 0) {
        !           477:                syslog(LOG_ERR, "%s not open", IPL_NAME);
        !           478:                return -1;
        !           479:        }
        !           480: 
        !           481:        memset(&obj, 0, sizeof(obj));
        !           482:        memset(&fr, 0, sizeof(fr));
        !           483:        memset(&ipffr, 0, sizeof(ipffr));
        !           484: 
        !           485:        fr.fr_flags = FR_PASS|FR_KEEPSTATE|FR_QUICK|FR_INQUE;
        !           486:        if (GETFLAG(LOGPACKETSMASK))
        !           487:                fr.fr_flags |= FR_LOG|FR_LOGFIRST;
        !           488:        fr.fr_v = 4;
        !           489: 
        !           490:        fr.fr_type = FR_T_IPF;
        !           491:        fr.fr_dun.fru_ipf = &ipffr;
        !           492:        fr.fr_dsize = sizeof(ipffr);
        !           493:        fr.fr_isc = (void *)-1;
        !           494: 
        !           495:        fr.fr_proto = proto;
        !           496:        fr.fr_mproto = 0xff;
        !           497:        fr.fr_dcmp = FR_EQUAL;
        !           498:        fr.fr_dport = eport;
        !           499: #ifdef USE_IFNAME_IN_RULES
        !           500:        if (ifname)
        !           501:                strlcpy(fr.fr_ifnames[0], ifname, IFNAMSIZ);
        !           502: #endif
        !           503:        strlcpy(fr.fr_group, group_name, sizeof(fr.fr_group));
        !           504: 
        !           505:        if (proto == IPPROTO_TCP) {
        !           506:                fr.fr_tcpf = TH_SYN;
        !           507:                fr.fr_tcpfm = TH_SYN|TH_ACK|TH_RST|TH_FIN|TH_URG|TH_PUSH;
        !           508:        }
        !           509: 
        !           510:        inet_pton(AF_INET, iaddr, &fr.fr_daddr);
        !           511:        fr.fr_dmask = 0xffffffff;
        !           512: 
        !           513:        obj.ipfo_rev = IPFILTER_VERSION;
        !           514:        obj.ipfo_ptr = &fr;
        !           515:        obj.ipfo_size = sizeof(fr);
        !           516: 
        !           517:        r = ioctl(dev_ipl, SIOCINAFR, &obj);
        !           518:        if (r == -1) {
        !           519:                if (errno == ESRCH)
        !           520:                        syslog(LOG_ERR,
        !           521:                            "SIOCINAFR(missing 'head %s' rule?):%m",
        !           522:                            group_name);
        !           523:                else
        !           524:                        syslog(LOG_ERR, "SIOCINAFR:%m");
        !           525:        }
        !           526:        return r;
        !           527: }
        !           528: 
        !           529: int
        !           530: delete_filter_rule(const char * ifname, unsigned short eport, int proto)
        !           531: {
        !           532:        ipfobj_t wobj, dobj;
        !           533:        ipfruleiter_t rule;
        !           534:        u_long darray[1000];
        !           535:        u_long array[1000];
        !           536:        friostat_t fio;
        !           537:        frentry_t *fp;
        !           538:        int r;
        !           539: 
        !           540:        if (dev_ipl < 0) {
        !           541:                syslog(LOG_ERR, "%s not open", IPL_NAME);
        !           542:                return -1;
        !           543:        }
        !           544: 
        !           545:        wobj.ipfo_rev = IPFILTER_VERSION;
        !           546:        wobj.ipfo_type = IPFOBJ_IPFSTAT;
        !           547:        wobj.ipfo_size = sizeof(fio);
        !           548:        wobj.ipfo_ptr = &fio;
        !           549: 
        !           550:        if (ioctl(dev_ipl, SIOCGETFS, &wobj) == -1) {
        !           551:                syslog(LOG_ERR, "ioctl(SIOCGETFS): %m");
        !           552:                return -1;
        !           553:        }
        !           554: 
        !           555:        wobj.ipfo_rev = IPFILTER_VERSION;
        !           556:        wobj.ipfo_ptr = &rule;
        !           557:        wobj.ipfo_size = sizeof(rule);
        !           558:        wobj.ipfo_type = IPFOBJ_IPFITER;
        !           559: 
        !           560:        fp = (frentry_t *)array;
        !           561:        fp->fr_dun.fru_data = darray;
        !           562:        fp->fr_dsize = sizeof(darray);
        !           563: 
        !           564:        rule.iri_inout = 0;
        !           565:        rule.iri_active = fio.f_active;
        !           566: #if IPFILTER_VERSION > 4011300
        !           567:        rule.iri_nrules = 1;
        !           568:        rule.iri_v = 4;
        !           569: #endif
        !           570:        rule.iri_rule = fp;
        !           571:        strlcpy(rule.iri_group, group_name, sizeof(rule.iri_group));
        !           572: 
        !           573:        dobj.ipfo_rev = IPFILTER_VERSION;
        !           574:        dobj.ipfo_size = sizeof(*fp);
        !           575:        dobj.ipfo_type = IPFOBJ_FRENTRY;
        !           576: 
        !           577:        r = -1;
        !           578:        do {
        !           579:                memset(array, 0xff, sizeof(array));
        !           580: 
        !           581:                if (ioctl(dev_ipl, SIOCIPFITER, &wobj) == -1) {
        !           582:                        syslog(LOG_ERR, "ioctl(SIOCIPFITER): %m");
        !           583:                        break;
        !           584:                }
        !           585: 
        !           586:                if (fp->fr_data != NULL)
        !           587:                        fp->fr_data = (char *)fp + sizeof(*fp);
        !           588:                if ((fp->fr_type & ~FR_T_BUILTIN) == FR_T_IPF &&
        !           589:                    fp->fr_dport == eport &&
        !           590:                    fp->fr_proto == proto)
        !           591:                {
        !           592:                        dobj.ipfo_ptr = fp;
        !           593: 
        !           594:                        r = ioctl(dev_ipl, SIOCRMAFR, &dobj);
        !           595:                        if (r == -1)
        !           596:                                syslog(LOG_ERR, "ioctl(SIOCRMAFR): %m");
        !           597:                        break;
        !           598:                }
        !           599:        } while (fp->fr_next != NULL);
        !           600:        return r;
        !           601: }
        !           602: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>