Annotation of embedaddon/dnsmasq/src/tables.c, revision 1.1.1.1
1.1 misho 1: /* tables.c is Copyright (c) 2014 Sven Falempin All Rights Reserved.
2:
3: Author's email: sfalempin@citypassenger.com
4:
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.
9:
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.
14:
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/>.
17: */
18:
19: #include "dnsmasq.h"
20:
21: #if defined(HAVE_IPSET) && defined(HAVE_BSD_NETWORK)
22:
23: #ifndef __FreeBSD__
24: #include <string.h>
25: #endif
26:
27: #include <sys/types.h>
28: #include <sys/ioctl.h>
29:
30: #include <net/if.h>
31: #include <netinet/in.h>
32: #include <net/pfvar.h>
33:
34: #include <err.h>
35: #include <errno.h>
36: #include <fcntl.h>
37:
38: #define UNUSED(x) (void)(x)
39:
40: static char *pf_device = "/dev/pf";
41: static int dev = -1;
42:
43: static char *pfr_strerror(int errnum)
44: {
45: switch (errnum)
46: {
47: case ESRCH:
48: return "Table does not exist";
49: case ENOENT:
50: return "Anchor or Ruleset does not exist";
51: default:
52: return strerror(errnum);
53: }
54: }
55:
56: static int pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
57: {
58: struct pfioc_table io;
59:
60: if (size < 0 || (size && tbl == NULL))
61: {
62: errno = EINVAL;
63: return (-1);
64: }
65: bzero(&io, sizeof io);
66: io.pfrio_flags = flags;
67: io.pfrio_buffer = tbl;
68: io.pfrio_esize = sizeof(*tbl);
69: io.pfrio_size = size;
70: if (ioctl(dev, DIOCRADDTABLES, &io))
71: return (-1);
72: if (nadd != NULL)
73: *nadd = io.pfrio_nadd;
74: return (0);
75: }
76:
77: static int fill_addr(const struct all_addr *ipaddr, int flags, struct pfr_addr* addr) {
78: if ( !addr || !ipaddr)
79: {
80: my_syslog(LOG_ERR, _("error: fill_addr missused"));
81: return -1;
82: }
83: bzero(addr, sizeof(*addr));
84: #ifdef HAVE_IPV6
85: if (flags & F_IPV6)
86: {
87: addr->pfra_af = AF_INET6;
88: addr->pfra_net = 0x80;
89: memcpy(&(addr->pfra_ip6addr), &(ipaddr->addr), sizeof(struct in6_addr));
90: }
91: else
92: #endif
93: {
94: addr->pfra_af = AF_INET;
95: addr->pfra_net = 0x20;
96: addr->pfra_ip4addr.s_addr = ipaddr->addr.addr4.s_addr;
97: }
98: return 1;
99: }
100:
101: /*****************************************************************************/
102:
103: void ipset_init(void)
104: {
105: dev = open( pf_device, O_RDWR);
106: if (dev == -1)
107: {
108: err(1, "%s", pf_device);
109: die (_("failed to access pf devices: %s"), NULL, EC_MISC);
110: }
111: }
112:
113: int add_to_ipset(const char *setname, const struct all_addr *ipaddr,
114: int flags, int remove)
115: {
116: struct pfr_addr addr;
117: struct pfioc_table io;
118: struct pfr_table table;
119: int n = 0, rc = 0;
120:
121: if ( dev == -1 )
122: {
123: my_syslog(LOG_ERR, _("warning: no opened pf devices %s"), pf_device);
124: return -1;
125: }
126:
127: bzero(&table, sizeof(struct pfr_table));
128: table.pfrt_flags |= PFR_TFLAG_PERSIST;
129: if ( strlen(setname) >= PF_TABLE_NAME_SIZE )
130: {
131: my_syslog(LOG_ERR, _("error: cannot use table name %s"), setname);
132: errno = ENAMETOOLONG;
133: return -1;
134: }
135:
136: if ( strlcpy(table.pfrt_name, setname,
137: sizeof(table.pfrt_name)) >= sizeof(table.pfrt_name))
138: {
139: my_syslog(LOG_ERR, _("error: cannot strlcpy table name %s"), setname);
140: return -1;
141: }
142:
143: if ((rc = pfr_add_tables(&table, 1, &n, 0)))
144: {
145: my_syslog(LOG_WARNING, _("warning: pfr_add_tables: %s(%d)"),
146: pfr_strerror(errno),rc);
147: return -1;
148: }
149: table.pfrt_flags &= ~PFR_TFLAG_PERSIST;
150: if (n)
151: my_syslog(LOG_INFO, _("info: table created"));
152:
153: fill_addr(ipaddr,flags,&addr);
154: bzero(&io, sizeof(io));
155: io.pfrio_flags = 0;
156: io.pfrio_table = table;
157: io.pfrio_buffer = &addr;
158: io.pfrio_esize = sizeof(addr);
159: io.pfrio_size = 1;
160: if (ioctl(dev, ( remove ? DIOCRDELADDRS : DIOCRADDADDRS ), &io))
161: {
162: my_syslog(LOG_WARNING, _("warning: DIOCR%sADDRS: %s"), ( remove ? "DEL" : "ADD" ), pfr_strerror(errno));
163: return -1;
164: }
165:
166: my_syslog(LOG_INFO, _("%d addresses %s"),
167: io.pfrio_nadd, ( remove ? "removed" : "added" ));
168:
169: return io.pfrio_nadd;
170: }
171:
172:
173: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>