]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/contrib/ipfilter/netinet/ip_rules.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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 #else
36 # include <sys/ioctl.h>
37 #endif /* FreeBSD */
38 #include <net/if.h>
39 #include <netinet/in.h>
40 #include <netinet/in_systm.h>
41 #include <netinet/ip.h>
42 #include <netinet/tcp.h>
43 #include "netinet/ip_compat.h"
44 #include "netinet/ip_fil.h"
45
46 #include "netinet/ip_rules.h"
47
48 #ifndef _KERNEL
49 # include <string.h>
50 #endif /* _KERNEL */
51
52 #ifdef IPFILTER_COMPILED
53
54 extern ipf_main_softc_t ipfmain;
55
56
57 static u_long in_rule__0[] = {
58 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
59 };
60
61 static u_long out_rule__0[] = {
62 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
63 };
64
65 frentry_t *ipf_rules_in_[1] = {
66         (frentry_t *)&in_rule__0
67 };
68
69 /* XXX  This file (ip_rules.c) is not part of the ipfilter tarball, it is
70    XXX  generated by the ipfilter build process. Unfortunately the build
71    XXX  process did not generate the following lines so they are added
72    XXX  by hand here. This is a bit of a hack but it works for now. Future
73    XXX  imports/merges of ipfilter may generate this so the following will
74    XXX  need to be removed following some future merge.
75    XXX  */
76 frentry_t *ipf_rules_out_[1] = {
77         (frentry_t *)&out_rule__0
78 };
79
80 frentry_t *ipfrule_match_in_(fin, passp)
81 fr_info_t *fin;
82 u_32_t *passp;
83 {
84         frentry_t *fr = NULL;
85
86         fr = (frentry_t *)&in_rule__0;
87         return fr;
88 }
89
90 frentry_t *ipfrule_match_out_(fin, passp)
91 fr_info_t *fin;
92 u_32_t *passp;
93 {
94         frentry_t *fr = NULL;
95
96         fr = (frentry_t *)&out_rule__0;
97         return fr;
98 }
99 static frentry_t ipfrule_out_;
100
101 int ipfrule_add_out_()
102 {
103         int i, j, err = 0, max;
104         frentry_t *fp;
105
106         max = sizeof(ipf_rules_out_)/sizeof(frentry_t *);
107         for (i = 0; i < max; i++) {
108                 fp = ipf_rules_out_[i];
109                 fp->fr_next = NULL;
110                 for (j = i + 1; j < max; j++)
111                         if (strncmp(fp->fr_names + fp->fr_group,
112                                     ipf_rules_out_[j]->fr_names +
113                                     ipf_rules_out_[j]->fr_group,
114                                     FR_GROUPLEN) == 0) {
115                                 if (ipf_rules_out_[j] != NULL)
116                                         ipf_rules_out_[j]->fr_pnext =
117                                             &fp->fr_next;
118                                 fp->fr_pnext = &ipf_rules_out_[j];
119                                 fp->fr_next = ipf_rules_out_[j];
120                                 break;
121                         }
122         }
123
124         fp = &ipfrule_out_;
125         bzero((char *)fp, sizeof(*fp));
126         fp->fr_type = FR_T_CALLFUNC_BUILTIN;
127         fp->fr_flags = FR_OUTQUE|FR_NOMATCH;
128         fp->fr_data = (void *)ipf_rules_out_[0];
129         fp->fr_dsize = sizeof(ipf_rules_out_[0]);
130         fp->fr_family = AF_INET;
131         fp->fr_func = (ipfunc_t)ipfrule_match_out_;
132         err = frrequest(&ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp,
133                         ipfmain.ipf_active, 0);
134         return err;
135 }
136
137
138 int ipfrule_remove_out_()
139 {
140         int err = 0, i;
141         frentry_t *fp;
142
143         /*
144          * Try to remove the outbound rule.
145          */
146         if (ipfrule_out_.fr_ref > 0) {
147                 err = EBUSY;
148         } else {
149                 i = sizeof(ipf_rules_out_)/sizeof(frentry_t *) - 1;
150                 for (; i >= 0; i--) {
151                         fp = ipf_rules_out_[i];
152                         if (fp->fr_ref > 1) {
153                                 err = EBUSY;
154                                 break;
155                         }
156                 }
157         }
158         if (err == 0)
159                 err = frrequest(&ipfmain, IPL_LOGIPF, SIOCDELFR,
160                                 (caddr_t)&ipfrule_out_,
161                                 ipfmain.ipf_active, 0);
162         if (err)
163                 return err;
164
165
166         return err;
167 }
168 static frentry_t ipfrule_in_;
169
170 int ipfrule_add_in_()
171 {
172         int i, j, err = 0, max;
173         frentry_t *fp;
174
175         max = sizeof(ipf_rules_in_)/sizeof(frentry_t *);
176         for (i = 0; i < max; i++) {
177                 fp = ipf_rules_in_[i];
178                 fp->fr_next = NULL;
179                 for (j = i + 1; j < max; j++)
180                         if (strncmp(fp->fr_names + fp->fr_group,
181                                     ipf_rules_in_[j]->fr_names +
182                                     ipf_rules_in_[j]->fr_group,
183                                     FR_GROUPLEN) == 0) {
184                                 if (ipf_rules_in_[j] != NULL)
185                                         ipf_rules_in_[j]->fr_pnext =
186                                             &fp->fr_next;
187                                 fp->fr_pnext = &ipf_rules_in_[j];
188                                 fp->fr_next = ipf_rules_in_[j];
189                                 break;
190                         }
191         }
192
193         fp = &ipfrule_in_;
194         bzero((char *)fp, sizeof(*fp));
195         fp->fr_type = FR_T_CALLFUNC_BUILTIN;
196         fp->fr_flags = FR_INQUE|FR_NOMATCH;
197         fp->fr_data = (void *)ipf_rules_in_[0];
198         fp->fr_dsize = sizeof(ipf_rules_in_[0]);
199         fp->fr_family = AF_INET;
200         fp->fr_func = (ipfunc_t)ipfrule_match_in_;
201         err = frrequest(&ipfmain, IPL_LOGIPF, SIOCADDFR, (caddr_t)fp,
202                         ipfmain.ipf_active, 0);
203         return err;
204 }
205
206
207 int ipfrule_remove_in_()
208 {
209         int err = 0, i;
210         frentry_t *fp;
211
212         /*
213          * Try to remove the inbound rule.
214          */
215         if (ipfrule_in_.fr_ref > 0) {
216                 err = EBUSY;
217         } else {
218                 i = sizeof(ipf_rules_in_)/sizeof(frentry_t *) - 1;
219                 for (; i >= 0; i--) {
220                         fp = ipf_rules_in_[i];
221                         if (fp->fr_ref > 1) {
222                                 err = EBUSY;
223                                 break;
224                         }
225                 }
226         }
227         if (err == 0)
228                 err = frrequest(&ipfmain, IPL_LOGIPF, SIOCDELFR,
229                                 (caddr_t)&ipfrule_in_,
230                                 ipfmain.ipf_active, 0);
231         if (err)
232                 return err;
233
234
235         return err;
236 }
237
238 int ipfrule_add()
239 {
240         int err;
241
242         err = ipfrule_add_out_();
243         if (err != 0)
244                 return err;
245         err = ipfrule_add_in_();
246         if (err != 0)
247                 return err;
248         return 0;
249 }
250
251
252 int ipfrule_remove()
253 {
254         int err;
255
256         err = ipfrule_remove_out_();
257         if (err != 0)
258                 return err;
259         err = ipfrule_remove_in_();
260         if (err != 0)
261                 return err;
262         return 0;
263 }
264 #endif /* IPFILTER_COMPILED */