1 /* tables.c is Copyright (c) 2014 Sven Falempin All Rights Reserved.
3 Author's email: sfalempin@citypassenger.com
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; version 2 dated June, 1991, or
8 (at your option) version 3 dated 29 June, 2007.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #if defined(HAVE_IPSET) && defined(HAVE_BSD_NETWORK)
27 #include <sys/types.h>
28 #include <sys/ioctl.h>
31 #include <netinet/in.h>
32 #include <net/pfvar.h>
38 #define UNUSED(x) (void)(x)
40 static char *pf_device
= "/dev/pf";
43 static char *pfr_strerror(int errnum
)
48 return "Table does not exist";
50 return "Anchor or Ruleset does not exist";
52 return strerror(errnum
);
56 static int pfr_add_tables(struct pfr_table
*tbl
, int size
, int *nadd
, int flags
)
58 struct pfioc_table io
;
60 if (size
< 0 || (size
&& tbl
== NULL
))
65 bzero(&io
, sizeof io
);
66 io
.pfrio_flags
= flags
;
67 io
.pfrio_buffer
= tbl
;
68 io
.pfrio_esize
= sizeof(*tbl
);
70 if (ioctl(dev
, DIOCRADDTABLES
, &io
))
73 *nadd
= io
.pfrio_nadd
;
77 static int fill_addr(const struct all_addr
*ipaddr
, int flags
, struct pfr_addr
* addr
) {
78 if ( !addr
|| !ipaddr
)
80 my_syslog(LOG_ERR
, _("error: fill_addr missused"));
83 bzero(addr
, sizeof(*addr
));
87 addr
->pfra_af
= AF_INET6
;
88 addr
->pfra_net
= 0x80;
89 memcpy(&(addr
->pfra_ip6addr
), &(ipaddr
->addr
), sizeof(struct in6_addr
));
94 addr
->pfra_af
= AF_INET
;
95 addr
->pfra_net
= 0x20;
96 addr
->pfra_ip4addr
.s_addr
= ipaddr
->addr
.addr4
.s_addr
;
101 /*****************************************************************************/
103 void ipset_init(void)
105 dev
= open( pf_device
, O_RDWR
);
108 err(1, "%s", pf_device
);
109 die (_("failed to access pf devices: %s"), NULL
, EC_MISC
);
113 int add_to_ipset(const char *setname
, const struct all_addr
*ipaddr
,
114 int flags
, int remove
)
116 struct pfr_addr addr
;
117 struct pfioc_table io
;
118 struct pfr_table table
;
123 my_syslog(LOG_ERR
, _("warning: no opened pf devices %s"), pf_device
);
127 bzero(&table
, sizeof(struct pfr_table
));
128 table
.pfrt_flags
|= PFR_TFLAG_PERSIST
;
129 if ( strlen(setname
) >= PF_TABLE_NAME_SIZE
)
131 my_syslog(LOG_ERR
, _("error: cannot use table name %s"), setname
);
132 errno
= ENAMETOOLONG
;
136 if ( strlcpy(table
.pfrt_name
, setname
,
137 sizeof(table
.pfrt_name
)) >= sizeof(table
.pfrt_name
))
139 my_syslog(LOG_ERR
, _("error: cannot strlcpy table name %s"), setname
);
143 if ((rc
= pfr_add_tables(&table
, 1, &n
, 0)))
145 my_syslog(LOG_WARNING
, _("warning: pfr_add_tables: %s(%d)"),
146 pfr_strerror(errno
),rc
);
149 table
.pfrt_flags
&= ~PFR_TFLAG_PERSIST
;
151 my_syslog(LOG_INFO
, _("info: table created"));
153 fill_addr(ipaddr
,flags
,&addr
);
154 bzero(&io
, sizeof(io
));
156 io
.pfrio_table
= table
;
157 io
.pfrio_buffer
= &addr
;
158 io
.pfrio_esize
= sizeof(addr
);
160 if (ioctl(dev
, ( remove
? DIOCRDELADDRS
: DIOCRADDADDRS
), &io
))
162 my_syslog(LOG_WARNING
, _("warning: DIOCR%sADDRS: %s"), ( remove
? "DEL" : "ADD" ), pfr_strerror(errno
));
166 my_syslog(LOG_INFO
, _("%d addresses %s"),
167 io
.pfrio_nadd
, ( remove
? "removed" : "added" ));
169 return io
.pfrio_nadd
;