]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/ipfilter/netinet/ip_rules.c
MFV r308265: Update tzdata to 2016i.
[FreeBSD/FreeBSD.git] / sys / contrib / ipfilter / netinet / ip_rules.c
1 /*      $FreeBSD$       */
2
3 /*
4 * Copyright (C) 2012 by Darren Reed.
5 *
6 * Redistribution and use in source and binary forms are permitted
7 * provided that this notice is preserved and due credit is given
8 * to the original author and the contributors.
9 */
10
11 #include <sys/param.h>
12 #include <sys/types.h>
13 #include <sys/time.h>
14 #include <sys/socket.h>
15 #if defined(__FreeBSD_version) && (__FreeBSD_version >= 40000)
16 # if defined(_KERNEL)
17 #  include <sys/libkern.h>
18 # else
19 #  include <sys/unistd.h>
20 # endif
21 #endif
22 #if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 399000000)
23 #else
24 # if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__sgi)
25 #  include <sys/systm.h>
26 # endif
27 #endif
28 #include <sys/errno.h>
29 #include <sys/param.h>
30 #if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux)
31 # include <sys/mbuf.h>
32 #endif
33 #if defined(__FreeBSD__) && (__FreeBSD_version > 220000)
34 # include <sys/sockio.h>
35 #if defined(__FreeBSD_version) && (__FreeBSD_version >= 800000) && defined(_KERNEL)
36 #include <net/vnet.h>
37 #else
38 #define CURVNET_SET(arg)
39 #define CURVNET_RESTORE()
40 #define VNET_DEFINE(_t, _v)     _t _v
41 #define VNET_DECLARE(_t, _v)    extern _t _v
42 #define VNET(arg)       arg
43 #endif
44 #else
45 # include <sys/ioctl.h>
46 #endif /* FreeBSD */
47 #include <net/if.h>
48 #include <netinet/in.h>
49 #include <netinet/in_systm.h>
50 #include <netinet/ip.h>
51 #include <netinet/tcp.h>
52 #include "netinet/ip_compat.h"
53 #include "netinet/ip_fil.h"
54
55 #include "netinet/ip_rules.h"
56
57 #ifndef _KERNEL
58 # include <string.h>
59 #endif /* _KERNEL */
60
61 #ifdef IPFILTER_COMPILED
62
63 VNET_DECLARE(ipf_main_softc_t, ipfmain);
64 #define V_ipfmain               VNET(ipfmain)
65
66
67 static u_long in_rule__0[] = {
68 0, 0, 0, 0, 0, 0, 0, 0x8070d88, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0x1b0, 0x1, 0, 0, 0, 0x2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x40000000, 0x8002, 0, 0, 0, 0xffff, 0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0
69 };
70
71 static u_long out_rule__0[] = {
72 0, 0, 0, 0, 0, 0, 0, 0x8070d88, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0x1b0, 0x1, 0, 0, 0, 0x3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x40000000, 0x4002, 0, 0, 0, 0xffff, 0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0
73 };
74
75 frentry_t *ipf_rules_in_[1] = {
76         (frentry_t *)&in_rule__0
77 };
78
79 /* XXX  This file (ip_rules.c) is not part of the ipfilter tarball, it is
80    XXX  generated by the ipfilter build process. Unfortunately the build
81    XXX  process did not generate the following lines so they are added
82    XXX  by hand here. This is a bit of a hack but it works for now. Future
83    XXX  imports/merges of ipfilter may generate this so the following will
84    XXX  need to be removed following some future merge.
85    XXX  */
86 frentry_t *ipf_rules_out_[1] = {
87         (frentry_t *)&out_rule__0
88 };
89
90 frentry_t *ipfrule_match_in_(fin, passp)
91 fr_info_t *fin;
92 u_32_t *passp;
93 {
94         frentry_t *fr = NULL;
95
96         fr = (frentry_t *)&in_rule__0;
97         return fr;
98 }
99
100 frentry_t *ipfrule_match_out_(fin, passp)
101 fr_info_t *fin;
102 u_32_t *passp;
103 {
104         frentry_t *fr = NULL;
105
106         fr = (frentry_t *)&out_rule__0;
107         return fr;
108 }
109 static frentry_t ipfrule_out_;
110
111 int ipfrule_add_out_()
112 {
113         int i, j, err = 0, max;
114         frentry_t *fp;
115
116         max = sizeof(ipf_rules_out_)/sizeof(frentry_t *);
117         for (i = 0; i < max; i++) {
118                 fp = ipf_rules_out_[i];
119                 fp->fr_next = NULL;
120                 for (j = i + 1; j < max; j++)
121                         if (strncmp(fp->fr_names + fp->fr_group,
122                                     ipf_rules_out_[j]->fr_names +
123                                     ipf_rules_out_[j]->fr_group,
124                                     FR_GROUPLEN) == 0) {
125                                 if (ipf_rules_out_[j] != NULL)
126                                         ipf_rules_out_[j]->fr_pnext =
127                                             &fp->fr_next;
128                                 fp->fr_pnext = &ipf_rules_out_[j];
129                                 fp->fr_next = ipf_rules_out_[j];
130                                 break;
131                         }
132         }
133
134         fp = &ipfrule_out_;
135         bzero((char *)fp, sizeof(*fp));
136         fp->fr_type = FR_T_CALLFUNC_BUILTIN;
137         fp->fr_flags = FR_OUTQUE|FR_NOMATCH;
138         fp->fr_data = (void *)ipf_rules_out_[0];
139         fp->fr_dsize = sizeof(ipf_rules_out_[0]);
140         fp->fr_family = AF_INET;
141         fp->fr_func = (ipfunc_t)ipfrule_match_out_;
142         err = frrequest(&V_ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp,
143                         V_ipfmain.ipf_active, 0);
144         return err;
145 }
146
147
148 int ipfrule_remove_out_()
149 {
150         int err = 0, i;
151         frentry_t *fp;
152
153         /*
154          * Try to remove the outbound rule.
155          */
156         if (ipfrule_out_.fr_ref > 0) {
157                 err = EBUSY;
158         } else {
159                 i = sizeof(ipf_rules_out_)/sizeof(frentry_t *) - 1;
160                 for (; i >= 0; i--) {
161                         fp = ipf_rules_out_[i];
162                         if (fp->fr_ref > 1) {
163                                 err = EBUSY;
164                                 break;
165                         }
166                 }
167         }
168         if (err == 0)
169                 err = frrequest(&V_ipfmain, IPL_LOGIPF, SIOCDELFR,
170                                 (caddr_t)&ipfrule_out_,
171                                 V_ipfmain.ipf_active, 0);
172         if (err)
173                 return err;
174
175
176         return err;
177 }
178 static frentry_t ipfrule_in_;
179
180 int ipfrule_add_in_()
181 {
182         int i, j, err = 0, max;
183         frentry_t *fp;
184
185         max = sizeof(ipf_rules_in_)/sizeof(frentry_t *);
186         for (i = 0; i < max; i++) {
187                 fp = ipf_rules_in_[i];
188                 fp->fr_next = NULL;
189                 for (j = i + 1; j < max; j++)
190                         if (strncmp(fp->fr_names + fp->fr_group,
191                                     ipf_rules_in_[j]->fr_names +
192                                     ipf_rules_in_[j]->fr_group,
193                                     FR_GROUPLEN) == 0) {
194                                 if (ipf_rules_in_[j] != NULL)
195                                         ipf_rules_in_[j]->fr_pnext =
196                                             &fp->fr_next;
197                                 fp->fr_pnext = &ipf_rules_in_[j];
198                                 fp->fr_next = ipf_rules_in_[j];
199                                 break;
200                         }
201         }
202
203         fp = &ipfrule_in_;
204         bzero((char *)fp, sizeof(*fp));
205         fp->fr_type = FR_T_CALLFUNC_BUILTIN;
206         fp->fr_flags = FR_INQUE|FR_NOMATCH;
207         fp->fr_data = (void *)ipf_rules_in_[0];
208         fp->fr_dsize = sizeof(ipf_rules_in_[0]);
209         fp->fr_family = AF_INET;
210         fp->fr_func = (ipfunc_t)ipfrule_match_in_;
211         err = frrequest(&V_ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp,
212                         V_ipfmain.ipf_active, 0);
213         return err;
214 }
215
216
217 int ipfrule_remove_in_()
218 {
219         int err = 0, i;
220         frentry_t *fp;
221
222         /*
223          * Try to remove the inbound rule.
224          */
225         if (ipfrule_in_.fr_ref > 0) {
226                 err = EBUSY;
227         } else {
228                 i = sizeof(ipf_rules_in_)/sizeof(frentry_t *) - 1;
229                 for (; i >= 0; i--) {
230                         fp = ipf_rules_in_[i];
231                         if (fp->fr_ref > 1) {
232                                 err = EBUSY;
233                                 break;
234                         }
235                 }
236         }
237         if (err == 0)
238                 err = frrequest(&V_ipfmain, IPL_LOGIPF, SIOCDELFR,
239                                 (caddr_t)&ipfrule_in_,
240                                 V_ipfmain.ipf_active, 0);
241         if (err)
242                 return err;
243
244
245         return err;
246 }
247
248 int ipfrule_add()
249 {
250         int err;
251
252         err = ipfrule_add_out_();
253         if (err != 0)
254                 return err;
255         err = ipfrule_add_in_();
256         if (err != 0)
257                 return err;
258         return 0;
259 }
260
261
262 int ipfrule_remove()
263 {
264         int err;
265
266         err = ipfrule_remove_out_();
267         if (err != 0)
268                 return err;
269         err = ipfrule_remove_in_();
270         if (err != 0)
271                 return err;
272         return 0;
273 }
274 #endif /* IPFILTER_COMPILED */