Handle hostnames with upper-case letters
[webmin.git] / ipfilter / edit_nat.cgi
1 #!/usr/local/bin/perl
2 # Display a form for editing or creating a NAT rule
3
4 require './ipfilter-lib.pl';
5 &ReadParse();
6 $rules = &get_ipnat_config();
7
8 if ($in{'delsel'}) {
9         # Special case - deleting selected rules
10         @nums = sort { $b cmp $a } split(/\0/, $in{'d'});
11         if (@nums) {
12                 &lock_file($rules->[$nums[0]]->{'file'});
13                 foreach $n (@nums) {
14                         &delete_rule($rules->[$n]);
15                         }
16                 &flush_file_lines();
17                 &unlock_file($rules->[$nums[0]]->{'file'});
18                 &webmin_log("delsel", "nat", undef,
19                             { 'count' => scalar(@nums) });
20                 }
21         &redirect("");
22         exit;
23         }
24
25 if ($in{'newmap'} || $in{'newrdr'}) {
26         &ui_print_header(undef, $text{'nat_title1'}, "");
27         $rdr = $in{'newrdr'} ? 1 : 0;
28         $rule = { 'action' => $rdr ? 'rdr' : 'map',
29                   'active' => 1,
30                   'toip' => '0.0.0.0', 'tomask' => 32 };
31         }
32 else {
33         $rule = $rules->[$in{'idx'}];
34         &ui_print_header(undef, $text{'nat_title2'}, "");
35         $rdr = $rule->{'action'} eq 'rdr' ? 1 : 0;
36         }
37
38 if (!$rdr) {
39         # Javascript for disabling fields
40         print <<EOF;
41 <script>
42 function from_change(dis)
43 {
44 var f = document.forms[0];
45 for(i=0; i<f.elements.length; i++) {
46         e = f.elements[i];
47         if (e.name.substring(0, 4) == "from" &&
48             e.name != "frommode" && e.name != "fromip" &&
49             e.name != "frommask") {
50                 e.disabled = dis;
51                 }
52         }
53 }
54 </script>
55 EOF
56         }
57
58 print &ui_form_start("save_nat.cgi", "post");
59 print &ui_hidden("new", $in{'newmap'} || $in{'newrdr'}),"\n";
60 print &ui_hidden("idx", $in{'idx'}),"\n";
61 print &ui_hidden("before", $in{'before'}),"\n";
62 print &ui_hidden("after", $in{'after'}),"\n";
63 @tds = ( "width=20%", undef );
64
65 print &ui_table_start($text{'nat_header1'}, "width=100%", 2);
66
67 # Comment
68 print &ui_table_row($text{'edit_cmt'},
69                     $rule->{'cmt'} =~ /\n/ ? 
70                         &ui_textarea("cmt", $rule->{'cmt'}, 3, 50) :
71                         &ui_textbox("cmt", $rule->{'cmt'}, 50),
72                     undef, \@tds);
73
74 # Enabled
75 print &ui_table_row($text{'edit_active'},
76                     &ui_radio("active", $rule->{'active'} ? 1 : 0,
77                               [ [ 1, $text{'edit_active1'} ],
78                                 [ 0, $text{'edit_active0'} ] ]));
79
80 # NAT mode
81 if ($rdr) {
82         print &ui_table_row($text{'nat_action'},
83                             $text{'action_rdr'});
84         print &ui_hidden("action", "rdr"),"\n";
85         }
86 else {
87         print &ui_table_row($text{'nat_action'},
88                     &ui_select("action", $rule->{'action'},
89                                [ [ "map", $text{'action_map'} ],
90                                  [ "bimap", $text{'action_bimap'} ],
91                                  [ "map-block", $text{'action_map-block'} ] ]));
92         }
93 print &ui_table_end(),"<p>\n";
94
95 if (!$rdr) {
96         # Show section for source
97         print &ui_table_start($text{'nat_header2'}, "width=100%", 2);
98
99         # NAT interface
100         print &ui_table_row($text{'nat_iface'},
101                             &interface_choice("iface", $rule->{'iface'}, 1));
102
103         # Source mode and address
104         print &ui_table_row($text{'nat_frommode'},
105             &ui_radio("frommode", $rule->{'from'} ? 1 : 0,
106                       [ [ 0, &text('nat_frommode0',
107                                    &ipmask_input("from"))."<br>",
108                              "onClick='from_change(true)'" ],
109                         [ 1, $text{'nat_frommode1'},
110                              "onClick='from_change(false)'" ] ]));
111         ($ft, $pt) = &object_input($rule, "from");
112         print &ui_table_row($text{'edit_from'}, $ft);
113         print &ui_table_row($text{'edit_portfrom'}, $pt);
114         ($ft, $pt) = &object_input($rule, "fromto");
115         print &ui_table_row($text{'edit_to'}, $ft);
116         print &ui_table_row($text{'edit_portto'}, $pt);
117
118         print &ui_table_end(),"<p>\n";
119
120         # Show section for destination
121         print &ui_table_start($text{'nat_header3'}, "width=100%", 2);
122
123         # Destination address
124         print &ui_table_row($text{'nat_tomode'},
125              &ui_radio("tomode", $rule->{'tostart'} ? 1 :
126                                  $rule->{'toip'} eq '0.0.0.0' &&
127                                   $rule->{'tomask'} == 32 ? 2 : 0,
128                       [ [ 2, $text{'nat_tomode2'}."<br>" ],
129                         [ 0, &text('nat_tomode0',
130                                    &ipmask_input("to"))."<br>" ],
131                         [ 1, &text('nat_tomode1',
132                            &ui_textbox("tostart", $rule->{'tostart'}, 15),
133                            &ui_textbox("toend", $rule->{'toend'}, 15)) ] ]));
134
135         # Port mapping
136         print &ui_table_row($text{'nat_portmap'},
137                 &ui_radio("portmapmode", $rule->{'portmap'} ? 1 : 0,
138                   [ [ 0, $text{'nat_portmap0'}."<br>" ],
139                     [ 1, &text('nat_portmap1',
140                         &protocol_input("portmap", $rule->{'portmap'}, 0, 1),
141                         &ui_checkbox("portmapnoauto", 1,"",
142                                      $rule->{'portmapfrom'}),
143                         &ui_textbox("portmapfrom", $rule->{'portmapfrom'}, 5),
144                         &ui_textbox("portmapto", $rule->{'portmapto'}, 5)) ] ]));
145
146         # Proxy mapping
147         print &ui_table_row($text{'nat_proxy'},
148                 &ui_radio("proxymode", $rule->{'proxyport'} ? 1 : 0,
149                   [ [ 0, $text{'nat_proxy0'}."<br>" ],
150                     [ 1, &text('nat_proxy1',
151                           &ui_textbox("proxyport", $rule->{'proxyport'}, 5),
152                           &ui_textbox("proxyname", $rule->{'proxyname'}, 5),
153                           &protocol_input("proxyproto",
154                                           $rule->{'proxyproto'}, 0, 0)) ] ]));
155
156         print &ui_table_end(),"<p>\n";
157
158         # Show section for other options
159         print &ui_table_start($text{'nat_header4'}, "width=100%", 2);
160         print "<table>\n";
161
162         print "<tr> <td>",&ui_checkbox("proto", 1, $text{'nat_proto'},
163                                        $rule->{'proto'}),"</td>\n";
164         print "<td>",&protocol_input("protoproto", $rule->{'proto'}, 0, 1),
165               "</td> </tr>\n";
166
167         print "<tr> <td colspan=2>",&ui_checkbox("frag", 1, $text{'nat_frag'},
168                                        $rule->{'frag'}),"</td> </tr>\n";
169
170         print "<tr> <td>",&ui_checkbox("mssclamp", 1, $text{'nat_clampmss'},
171                                        $rule->{'mssclamp'}),"</td>\n";
172         print "<td>",&ui_textbox("mss", $rule->{'mssclamp'}, 5)," ",
173               "$text{'nat_bytes'}</td> </tr>\n";
174
175         # Proxy mapping
176         print "<tr> <td>",&ui_checkbox("oproxy", 1, $text{'nat_oproxy'},
177                                        $rule->{'oproxyport'}),"</td>\n";
178         print "<td>",&text('nat_oproxy1',
179                           &ui_textbox("oproxyport", $rule->{'oproxyport'}, 5),
180                           &ui_textbox("oproxyname", $rule->{'oproxyname'}, 5),
181                           &protocol_input("oproxyproto",
182                                           $rule->{'oproxyproto'}, 0, 0)),"</td> </tr>\n";
183
184         print &ui_table_end();
185         }
186 else {
187         # Show section for source
188         print &ui_table_start($text{'nat_header5'}, "width=100%", 2);
189
190         # NAT interface
191         print &ui_table_row($text{'nat_iface'},
192                             &interface_choice("iface", $rule->{'iface'}, 1));
193
194         # Packets to redirect
195         print &ui_table_row($text{'nat_redir'},
196                             &ipmask_input("from"));
197
198         # Destination ports
199         print &ui_table_row($text{'nat_dports'},
200             &ui_radio("dportsmode", $rule->{'dport2'} ? 1 : 0,
201                       [ [ 0, &text('nat_dports0',
202                            &ui_textbox("dport", $rule->{'dport1'}, 10)) ],
203                         [ 1, &text('nat_dports1',
204                            &ui_textbox("dport1", $rule->{'dport1'}, 10),
205                            &ui_textbox("dport2", $rule->{'dport2'}, 10)) ] ]));
206
207         print &ui_table_row($text{'nat_rdrproto'},
208                 &protocol_input("rprproto",  $rule->{'rdrproto'}, 0, 1));
209
210         print &ui_table_end(),"<p>\n";
211
212         # Show section for destination
213         print &ui_table_start($text{'nat_header6'}, "width=100%", 2);
214
215         print &ui_table_row($text{'nat_rdrip'},
216             &ui_textarea("rdrip", join("\n", @{$rule->{'rdrip'}}), 3, 50));
217
218         print &ui_table_row($text{'nat_rdrport'},
219                 &ui_textbox("rdrport", $rule->{'rdrport'}, 10));
220
221         print &ui_table_end(),"<p>\n";
222
223         # Show section for other options
224         print &ui_table_start($text{'nat_header4'}, "width=100%", 2);
225         print "<table>\n";
226
227         print "<tr> <td colspan=2>",&ui_checkbox("round-robin", 1,
228                                                  $text{'nat_robin'},
229                                        $rule->{'round-robin'}),"</td> </tr>\n";
230
231         print "<tr> <td colspan=2>",&ui_checkbox("frag", 1, $text{'nat_frag'},
232                                        $rule->{'frag'}),"</td> </tr>\n";
233
234         print "<tr> <td>",&ui_checkbox("mssclamp", 1, $text{'nat_clampmss'},
235                                        $rule->{'mssclamp'}),"</td>\n";
236         print "<td>",&ui_textbox("mss", $rule->{'mssclamp'}, 5)," ",
237               "$text{'nat_bytes'}</td> </tr>\n";
238
239         print &ui_table_end();
240         }
241
242 if ($in{'newmap'} || $in{'newrdr'}) {
243         print &ui_form_end([ [ 'create', $text{'create'} ] ], "100%");
244         }
245 else {
246         print &ui_form_end([ [ 'save', $text{'save'} ],
247                              [ 'delete', $text{'delete'} ] ], "100%");
248         }
249 if (!$rdr) {
250         $dis = $rule->{'from'} ? "false" : "true";
251         print "<script>from_change($dis);</script>\n";
252         }
253 &ui_print_footer("", $text{'index_return'});
254
255 # ipmask_input(prefix)
256 sub ipmask_input
257 {
258 local ($pfx) = @_;
259 return &ui_textbox($pfx."ip", $rule->{$pfx."ip"}, 15)." / ".
260        &ui_textbox($pfx."mask", $rule->{$pfx."mask"}, 15);
261 }
262