00001
00002
00003
00004
00005
00006
00007
00008 #include "wvipfirewall.h"
00009 #include "wvinterface.h"
00010 #include <unistd.h>
00011
00012
00013 bool WvIPFirewall::enable = false, WvIPFirewall::ignore_errors = true;
00014
00015
00016 WvIPFirewall::WvIPFirewall() : log("Firewall", WvLog::Debug2)
00017 {
00018
00019
00020 }
00021
00022
00023 WvIPFirewall::~WvIPFirewall()
00024 {
00025 zap();
00026 }
00027
00028
00029 WvString WvIPFirewall::port_command(const char *cmd, const char *proto,
00030 const WvIPPortAddr &addr)
00031 {
00032 WvIPAddr ad(addr), none;
00033
00034 return WvString("iptables %s Services -j ACCEPT -p %s "
00035 "%s --dport %s "
00036 "%s",
00037 cmd, proto,
00038 ad == none ? WvString("") : WvString("-d %s", ad),
00039 addr.port,
00040 shutup());
00041 }
00042
00043
00044 WvString WvIPFirewall::redir_command(const char *cmd, const WvIPPortAddr &src,
00045 int dstport)
00046 {
00047 WvIPAddr ad(src), none;
00048
00049 return WvString("iptables -t nat %s TProxy "
00050 "-p tcp %s --dport %s "
00051 "-j REDIRECT --to-ports %s "
00052 "%s",
00053 cmd,
00054 ad == none ? WvString("") : WvString("-d %s", ad),
00055 src.port, dstport,
00056 shutup());
00057 }
00058
00059 WvString WvIPFirewall::forward_command(const char *cmd,
00060 const char *proto,
00061 const WvIPPortAddr &src,
00062 const WvIPPortAddr &dst, bool snat)
00063 {
00064 WvIPAddr srcaddr(src), dstaddr(dst), zero;
00065 WvString haveiface(""), haveoface("");
00066 if (!(srcaddr == zero))
00067 {
00068 haveiface.append("-d ");
00069 haveiface.append((WvString)srcaddr);
00070 }
00071
00072 WvString retval;
00073
00074 if ((dst == WvIPAddr("127.0.0.1")) || (dst == zero))
00075 {
00076 retval.append("iptables -t nat %s FASTFORWARD -p %s --dport %s %s "
00077 "-j REDIRECT --to-port %s %s \n",
00078 cmd, proto, src.port, haveiface, dst.port, shutup());
00079 }
00080 else
00081 {
00082 haveoface.append("-d ");
00083 haveoface.append((WvString)dstaddr);
00084
00085 retval.append("iptables -t nat %s FASTFORWARD -p %s --dport %s %s "
00086 "-j DNAT --to-destination %s "
00087 "%s \n", cmd, proto, src.port, haveiface, dst, shutup());
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 retval.append("iptables -t mangle %s FASTFORWARD -p %s --dport %s "
00099 "-j MARK --set-mark %s %s %s\n", cmd, proto, src.port,
00100 snat ? "0xFA58" : "0xFA57", haveiface, shutup());
00101
00102
00103 retval.append("iptables %s FFASTFORWARD -j ACCEPT -p %s "
00104 "--dport %s -m mark --mark %s %s %s\n", cmd, proto, dst.port,
00105 snat ? "0xFA58" : "0xFA57", haveoface, shutup());
00106
00107 return retval;
00108 }
00109
00110 WvString WvIPFirewall::redir_port_range_command(const char *cmd,
00111 const WvIPPortAddr &src_min, const WvIPPortAddr &src_max, int dstport)
00112 {
00113 WvIPAddr ad(src_min), none;
00114
00115 return WvString("iptables -t nat %s TProxy "
00116 "-p tcp %s --dport %s:%s "
00117 "-j REDIRECT --to-ports %s "
00118 "%s",
00119 cmd,
00120 ad == none ? WvString("") : WvString("-d %s", ad),
00121 src_min.port == 0? WvString(""): WvString(src_min.port),
00122 src_max.port == 0? WvString(""): WvString(src_max.port),
00123 dstport,
00124 shutup());
00125 }
00126
00127 WvString WvIPFirewall::redir_all_command(const char *cmd, int dstport)
00128 {
00129 return WvString("iptables -t nat %s TProxy "
00130 "-p tcp "
00131 "-j REDIRECT --to-ports %s "
00132 "%s",
00133 cmd,
00134 dstport,
00135 shutup());
00136 }
00137
00138 WvString WvIPFirewall::proto_command(const char *cmd, const char *proto)
00139 {
00140 return WvString("iptables %s Services -p %s -j ACCEPT "
00141 "%s",
00142 cmd, proto, shutup());
00143 }
00144
00145
00146 void WvIPFirewall::add_port(const WvIPPortAddr &addr)
00147 {
00148 addrs.append(new WvIPPortAddr(addr), true);
00149 WvString s(port_command("-A", "tcp", addr)),
00150 s2(port_command("-A", "udp", addr));
00151 if (enable)
00152 {
00153 system(s);
00154 system(s2);
00155 }
00156 }
00157
00158
00159
00160 void WvIPFirewall::del_port(const WvIPPortAddr &addr)
00161 {
00162 WvIPPortAddrList::Iter i(addrs);
00163 for (i.rewind(); i.next(); )
00164 {
00165 if (*i == addr)
00166 {
00167 WvString s(port_command("-D", "tcp", addr)),
00168 s2(port_command("-D", "udp", addr));
00169 if (enable)
00170 {
00171 system(s);
00172 system(s2);
00173 }
00174 return;
00175 }
00176 }
00177 }
00178
00179 void WvIPFirewall::add_forward(const WvIPPortAddr &src,
00180 const WvIPPortAddr &dst, bool snat)
00181 {
00182 ffwds.append(new FFwd(src, dst, snat), true);
00183 WvString s(forward_command("-A", "tcp", src, dst, snat)),
00184 s2(forward_command("-A", "udp", src, dst, snat));
00185
00186 log("Add Forwards (%s):\n%s\n%s\n", enable, s, s2);
00187
00188 if (enable)
00189 {
00190 system(s);
00191 system(s2);
00192 }
00193 }
00194
00195 void WvIPFirewall::del_forward(const WvIPPortAddr &src,
00196 const WvIPPortAddr &dst, bool snat)
00197 {
00198 FFwdList::Iter i(ffwds);
00199 for (i.rewind(); i.next();)
00200 {
00201 if (i->src == src && i->dst == dst && i->snat == snat)
00202 {
00203 WvString s(forward_command("-D", "tcp", src, dst, snat)),
00204 s2(forward_command("-D", "udp", src, dst, snat));
00205
00206 log("Delete Forward (%s):\n%s\n%s\n", enable, s, s2);
00207
00208 if (enable)
00209 {
00210 system(s);
00211 system(s2);
00212 }
00213 }
00214 }
00215 }
00216
00217 void WvIPFirewall::add_redir(const WvIPPortAddr &src, int dstport)
00218 {
00219 redirs.append(new Redir(src, dstport), true);
00220 WvString s(redir_command("-A", src, dstport));
00221 if (enable) system(s);
00222 }
00223
00224
00225 void WvIPFirewall::del_redir(const WvIPPortAddr &src, int dstport)
00226 {
00227 RedirList::Iter i(redirs);
00228 for (i.rewind(); i.next(); )
00229 {
00230 if (i->src == src && i->dstport == dstport)
00231 {
00232 WvString s(redir_command("-D", src, dstport));
00233 if (enable) system(s);
00234 return;
00235 }
00236 }
00237 }
00238
00239 void WvIPFirewall::add_redir_all(int dstport)
00240 {
00241 redir_alls.append(new RedirAll(dstport), true);
00242 WvString s(redir_all_command("-A", dstport));
00243 if (enable) system(s);
00244 }
00245
00246
00247 void WvIPFirewall::del_redir_all(int dstport)
00248 {
00249 RedirAllList::Iter i(redir_alls);
00250 for (i.rewind(); i.next(); )
00251 {
00252 if (i->dstport == dstport)
00253 {
00254 WvString s(redir_all_command("-D", dstport));
00255 if (enable) system(s);
00256 return;
00257 }
00258 }
00259 }
00260
00261 void WvIPFirewall::add_redir_port_range(const WvIPPortAddr &src_min,
00262 const WvIPPortAddr &src_max, int dstport)
00263 {
00264 redir_port_ranges.append(new RedirPortRange(src_min, src_max, dstport), true);
00265 WvString s(redir_port_range_command("-A", src_min, src_max, dstport));
00266 if (enable) system(s);
00267 }
00268
00269
00270 void WvIPFirewall::del_redir_port_range(const WvIPPortAddr &src_min,
00271 const WvIPPortAddr &src_max, int dstport)
00272 {
00273 RedirPortRangeList::Iter i(redir_port_ranges);
00274 for (i.rewind(); i.next(); )
00275 {
00276 if (i->src_min == src_min && i->src_max == src_max
00277 && i->dstport == dstport)
00278 {
00279 WvString s(redir_port_range_command("-D", src_min, src_max, dstport));
00280 if (enable) system(s);
00281 return;
00282 }
00283 }
00284 }
00285
00286
00287 void WvIPFirewall::add_proto(WvStringParm proto)
00288 {
00289 protos.append(new WvString(proto), true);
00290 WvString s(proto_command("-A", proto));
00291 if (enable) system(s);
00292 }
00293
00294
00295 void WvIPFirewall::del_proto(WvStringParm proto)
00296 {
00297 WvStringList::Iter i(protos);
00298 for (i.rewind(); i.next(); )
00299 {
00300 if (*i == proto)
00301 {
00302 WvString s(proto_command("-D", proto));
00303 if (enable) system(s);
00304 return;
00305 }
00306 }
00307 }
00308
00309
00310
00311 void WvIPFirewall::zap()
00312 {
00313 WvIPPortAddrList::Iter i(addrs);
00314 for (i.rewind(); i.next(); )
00315 {
00316 del_port(*i);
00317 i.xunlink();
00318 }
00319
00320 FFwdList::Iter ifwd(ffwds);
00321 for (ifwd.rewind(); ifwd.next();)
00322 {
00323 del_forward(ifwd->src, ifwd->dst, ifwd->snat);
00324 ifwd.xunlink();
00325 }
00326
00327 RedirList::Iter i2(redirs);
00328 for (i2.rewind(); i2.next(); )
00329 {
00330 del_redir(i2->src, i2->dstport);
00331 i2.xunlink();
00332 }
00333
00334 RedirAllList::Iter i2_5(redir_alls);
00335 for (i2_5.rewind(); i2_5.next(); )
00336 {
00337 del_redir_all(i2_5->dstport);
00338 i2_5.xunlink();
00339 }
00340
00341 RedirPortRangeList::Iter port_range(redir_port_ranges);
00342 for (port_range.rewind(); port_range.next(); )
00343 {
00344 del_redir_port_range(port_range->src_min, port_range->src_max,
00345 port_range->dstport);
00346 port_range.xunlink();
00347 }
00348
00349 WvStringList::Iter i3(protos);
00350 for (i3.rewind(); i3.next(); )
00351 {
00352 del_proto(*i3);
00353 i3.xunlink();
00354 }
00355 }