Merge branch 'Toastman-RT' into Toastman-VLAN
[tomato.git] / release / src / router / www / basic-static.asp
blobb72c05cc6d0187031b21f0ce9d8619a1276b6bb5
1 <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
2 <!--
3 Tomato GUI
4 Copyright (C) 2006-2010 Jonathan Zarate
5 http://www.polarcloud.com/tomato/
7 For use with Tomato Firmware only.
8 No part of this file may be used without permission.
9 -->
10 <html>
11 <head>
12 <meta http-equiv='content-type' content='text/html;charset=utf-8'>
13 <meta name='robots' content='noindex,nofollow'>
14 <title>[<% ident(); %>] Basic: Static DHCP</title>
15 <link rel='stylesheet' type='text/css' href='tomato.css'>
16 <link rel='stylesheet' type='text/css' href='color.css'>
17 <script type='text/javascript' src='tomato.js'></script>
19 <!-- / / / -->
20 <style type='text/css'>
21 #bs-grid {
22 width: 600px;
24 #bs-grid .co1,
25 #bs-grid .co2 {
26 width: 130px;
28 #bs-grid .co3 {
29 width: 340px;
31 </style>
33 <script type='text/javascript' src='debug.js'></script>
35 <script type='text/javascript'>
37 // <% nvram("lan_ipaddr,lan_netmask,dhcpd_static,dhcpd_startip,arpbind_enable,arpbind_only"); %>
39 if (nvram.lan_ipaddr.match(/^(\d+\.\d+\.\d+)\.(\d+)$/)) ipp = RegExp.$1 + '.';
40 else ipp = '?.?.?.';
42 autonum = aton(nvram.lan_ipaddr) & aton(nvram.lan_netmask);
44 var sg = new TomatoGrid();
46 sg.exist = function(f, v)
48 var data = this.getAllData();
49 for (var i = 0; i < data.length; ++i) {
50 if (data[i][f] == v) return true;
52 return false;
55 sg.existMAC = function(mac)
57 if (isMAC0(mac)) return false;
58 return this.exist(0, mac) || this.exist(1, mac);
61 sg.existName = function(name)
63 return this.exist(3, name);
66 sg.inStatic = function(n)
68 return this.exist(2, n);
71 sg.dataToView = function(data) {
72 var v = [];
74 var s = data[0];
75 if (!isMAC0(data[1])) s += '<br>' + data[1];
76 v.push(s);
78 for (var i = 2; i < data.length; ++i)
79 v.push(escapeHTML('' + data[i]));
81 return v;
84 sg.sortCompare = function(a, b) {
85 var da = a.getRowData();
86 var db = b.getRowData();
87 var r = 0;
88 switch (this.sortColumn) {
89 case 0:
90 r = cmpText(da[0], db[0]);
91 break;
92 case 1:
93 r = cmpIP(da[2], db[2]);
94 break;
96 if (r == 0) r = cmpText(da[3], db[3]);
97 return this.sortAscending ? r : -r;
100 sg.verifyFields = function(row, quiet)
102 var f, s, i;
104 f = fields.getAll(row);
106 if (!v_macz(f[0], quiet)) return 0;
107 if (!v_macz(f[1], quiet)) return 0;
108 if (isMAC0(f[0].value)) {
109 f[0].value = f[1].value;
110 f[1].value = '00:00:00:00:00:00';
112 else if (f[0].value == f[1].value) {
113 f[1].value = '00:00:00:00:00:00';
115 else if ((!isMAC0(f[1].value)) && (f[0].value > f[1].value)) {
116 s = f[1].value;
117 f[1].value = f[0].value;
118 f[0].value = s;
120 for (i = 0; i < 2; ++i) {
121 if (this.existMAC(f[i].value)) {
122 ferror.set(f[i], 'Duplicate MAC address', quiet);
123 return 0;
127 if (f[2].value.indexOf('.') == -1) {
128 s = parseInt(f[2].value, 10)
129 if (isNaN(s) || (s <= 0) || (s >= 255)) {
130 ferror.set(f[2], 'Invalid IP address', quiet);
131 return 0;
133 f[2].value = ipp + s;
136 if ((!isMAC0(f[0].value)) && (this.inStatic(f[2].value))) {
137 ferror.set(f[2], 'Duplicate IP address', quiet);
138 return 0;
141 if (!v_hostname(f[3], quiet, 5)) return 0;
142 if (!v_nodelim(f[3], quiet, 'Hostname', 1)) return 0;
143 s = f[3].value;
144 if (s.length > 0) {
145 if (this.existName(s)) {
146 ferror.set(f[3], 'Duplicate name.', quiet);
147 return 0;
151 if (isMAC0(f[0].value)) {
152 if (s == '') {
153 s = 'Both MAC address and name fields must not be empty.';
154 ferror.set(f[0], s, 1);
155 ferror.set(f[3], s, quiet);
156 return 0;
160 return 1;
163 sg.resetNewEditor = function() {
164 var f, c, n;
166 f = fields.getAll(this.newEditor);
167 ferror.clearAll(f);
169 if ((c = cookie.get('addstatic')) != null) {
170 cookie.set('addstatic', '', 0);
171 c = c.split(',');
172 if (c.length == 3) {
173 f[0].value = c[0];
174 f[1].value = '00:00:00:00:00:00';
175 f[2].value = c[1];
176 f[3].value = c[2];
177 return;
181 f[0].value = '00:00:00:00:00:00';
182 f[1].value = '00:00:00:00:00:00';
183 f[3].value = '';
185 n = 10;
186 do {
187 if (--n < 0) {
188 f[2].value = '';
189 return;
191 autonum++;
192 } while (((c = fixIP(ntoa(autonum), 1)) == null) || (c == nvram.lan_ipaddr) || (this.inStatic(c)));
194 f[2].value = c;
197 sg.setup = function()
199 this.init('bs-grid', 'sort', 250, [
200 { multi: [ { type: 'text', maxlen: 17 }, { type: 'text', maxlen: 17 } ] },
201 { type: 'text', maxlen: 15 },
202 { type: 'text', maxlen: 63 } ] );
204 this.headerSet(['MAC Address', 'IP Address', 'Hostname']);
205 var s = nvram.dhcpd_static.split('>');
206 for (var i = 0; i < s.length; ++i) {
207 var t = s[i].split('<');
208 if (t.length == 3) {
209 var d = t[0].split(',');
210 this.insertData(-1, [d[0], (d.length >= 2) ? d[1] : '00:00:00:00:00:00',
211 (t[1].indexOf('.') == -1) ? (ipp + t[1]) : t[1], t[2]]);
214 this.sort(2);
215 this.showNewEditor();
216 this.resetNewEditor();
219 function toggleFiltersVisibility(){
220 if(E('staticarp').style.display=='')
221 E('staticarp').style.display='none';
222 else
223 E('staticarp').style.display='';
226 function verifyFields(focused, quiet)
228 var j = E('_f_arpbind_enable').checked;
229 E('_f_arpbind_only').disabled = !j;
231 return 1;
234 function save()
236 if (sg.isEditing()) return;
238 var data = sg.getAllData();
239 var sdhcp = '';
240 var i;
242 for (i = 0; i < data.length; ++i) {
243 var d = data[i];
244 sdhcp += d[0];
245 if (!isMAC0(d[1])) sdhcp += ',' + d[1];
246 sdhcp += '<' + d[2] + '<' + d[3] + '>';
249 var fom = E('_fom');
250 fom.dhcpd_static.value = sdhcp;
251 fom.arpbind_enable.value = E('_f_arpbind_enable').checked ? 1 : 0;
252 fom.arpbind_only.value = E('_f_arpbind_only').checked ? 1 : 0;
253 form.submit(fom, 1);
256 function init()
258 sg.recolor();
260 </script>
261 </head>
262 <body onload='init()'>
263 <form id='_fom' method='post' action='tomato.cgi'>
264 <table id='container' cellspacing=0>
265 <tr><td colspan=2 id='header'>
266 <div class='title'>Tomato</div>
267 <div class='version'>Version <% version(); %></div>
268 </td></tr>
269 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
270 <td id='content'>
271 <div id='ident'><% ident(); %></div>
273 <!-- / / / -->
275 <input type='hidden' name='_nextpage' value='basic-static.asp'>
276 <input type='hidden' name='_service' value='dhcpd-restart,arpbind-restart'>
277 <input type='hidden' name='dhcpd_static'>
279 <input type='hidden' name='arpbind_enable'>
280 <input type='hidden' name='arpbind_only'>
282 <div class='section-title'>Static DHCP</div>
283 <div class='section'>
284 <table class='tomato-grid' id='bs-grid'></table>
285 </div>
287 <div>
288 <small>
289 <ul>
290 <li>To specify multiple hostnames per device, separate them with spaces.<br>
291 </ul>
292 </small>
293 </div>
295 <br>
296 <div class='section-title'>Static ARP <small><i><a href='javascript:toggleFiltersVisibility();'>(Toggle Visibility)</a></i></small></div>
297 <div class='section' id='staticarp' style='display:none'>
298 <script type='text/javascript'>
299 createFieldTable('', [
300 { title: 'Enable static ARP', name: 'f_arpbind_enable', type: 'checkbox', value: nvram.arpbind_enable != '0' },
301 { title: 'Restrict unlisted machines', name: 'f_arpbind_only', type: 'checkbox', value: nvram.arpbind_only != '0' }
303 </script>
304 </div>
306 <div>
307 <small>
308 <ul>
309 <li>Static ARP only works if there's one MAC address per IP. You can't enter two MAC addresses in the above table.<br>
310 </ul>
311 </small>
312 </div>
314 <br>
315 <br>
316 <br>
318 <div>
319 <ul>
320 <b>When using "Restrict unlisted machines"</b>
321 </ul>
322 </div>
324 <div>
325 <small>
326 <ul>
327 <li> DHCP should issue a "range" with only 1 IP address, preferably the administrator's IP - e.g. 192.168.1.100-100.<br>
328 <li> You <b>MUST</b> enter your own (administrator) IP and MAC into the table, or you may be locked out of the router.<br>
329 <li> You must add the IP/MAC address of all your access point(s) etc. to the table.<br>
330 <li> All listed IP's will now show as "active" in the WOL table.<br>
331 </ul>
332 </small>
334 </div>
336 <!-- / / / -->
338 </td></tr>
339 <tr><td id='footer' colspan=2>
340 <span id='footer-msg'></span>
341 <input type='button' value='Save' id='save-button' onclick='save()'>
342 <input type='button' value='Cancel' id='cancel-button' onclick='javascript:reloadPage();'>
343 </td></tr>
344 </table>
345 </form>
346 <script type='text/javascript'>sg.setup();verifyFields(null, 1);</script>
347 </body>
348 </html>