1 <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML
4.0//EN'
>
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.
12 <meta http-equiv='content-type' content='text/html;charset=utf-
8'
>
13 <meta name='robots' content='noindex,nofollow'
>
14 <title>[<%
ident(); %>] <% translate(
"Basic"); %
>: DDNS
</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>
21 <script type='text/javascript' src='debug.js'
></script>
23 <script type='text/javascript'
>
25 // <% nvram("ddnsx0,ddnsx1,ddnsx_ip,wan_dns,wan_get_dns,dns_addget,ddnsx_refresh,ddnsx_save"); %>
34 j = hostname (optional)
41 z = can't use client-given IP address
42 s = save state checkbox
47 ['', '<% translate("None"); %>', '', ''],
48 ['3322', '3322', 'http://www.3322.org/', 'uhwmb'],
49 ['3322-static', '3322 - Static', 'http://www.3322.org/', 'uhwmb'],
50 ['dnsexit', 'DNS Exit', 'http://www.dnsexit.com/', 'uh'],
51 ['dnsomatic', 'DNS-O-Matic', 'http://www.dnsomatic.com/', 'uj'],
52 ['dyndns', 'DynDNS - Dynamic', 'http://www.dyndns.com/', 'uhwmbs'],
53 ['dyndns-static', 'DynDNS - Static', 'http://www.dyndns.com/', 'uhwmbs'],
54 ['dyndns-custom', 'DynDNS - Custom', 'http://www.dyndns.com/', 'uhwmbs'],
55 ['sdyndns', 'DynDNS (https) - Dynamic', 'http://www.dyndns.com/', 'uhwmbs'],
56 ['sdyndns-static', 'DynDNS (https) - Static', 'http://www.dyndns.com/', 'uhwmbs'],
57 ['sdyndns-custom', 'DynDNS (https) - Custom', 'http://www.dyndns.com/', 'uhwmbs'],
58 ['dyns', 'DyNS', 'http://www.dyns.cx/', 'uh'],
59 ['easydns', 'easyDNS', 'http://www.easydns.com/', 'uhwm'],
60 ['seasydns', 'easyDNS (https)', 'http://www.easydns.com/', 'uhwm'],
61 ['editdns', 'EditDNS', 'http://www.editdns.net/', 'tpz'],
62 ['everydns', 'EveryDNS', 'http://www.everydns.net/', 'uj', null, null, '<% translate("Domain"); %> <small>(<% translate("optional"); %>)</small>'],
63 ['enom', 'eNom', 'http://www.enom.com/', 'ut', '<% translate("Domain"); %>'],
64 ['afraid', 'FreeDNS (afraid.org)', 'http://freedns.afraid.org/', 'az'],
65 ['heipv6tb', 'HE.net IPv6 Tunnel Broker', 'http://www.tunnelbroker.net/', 'uh', '<% translate("User ID"); %> <small>(<% translate("not your username"); %>)</small>', null, '<% translate("Global Tunnel ID"); %>'],
66 ['ieserver', 'ieServer.net', 'http://www.ieserver.net/', 'uhz', '<% translate("Username / Hostname"); %>', null, '<% translate("Domain"); %>'],
67 ['namecheap', 'namecheap', 'http://www.namecheap.com/', 'ut', '<% translate("Domain"); %>'],
68 ['noip', 'No-IP.com', 'http://www.no-ip.com/', 'uh', '<% translate("Email Address"); %>', null, '<% translate("Hostname / Group"); %>'],
69 ['opendns', 'OpenDNS', 'http://www.opendns.com/', 'uhoz', null, null, '<% translate("Network"); %> <small>(<% translate("optional"); %>)</small>'],
70 ['tzo', 'TZO', 'http://www.tzo.com/', 'uh', '<% translate("Email Address"); %>', '<% translate("Password"); %>'],
71 ['zoneedit', 'ZoneEdit', 'http://www.zoneedit.com/', 'uh'],
72 ['szoneedit', 'ZoneEdit (https)', 'http://www.zoneedit.com/', 'uh'],
73 ['custom', '<% translate("Custom URL"); %>', '', 'c']];
75 var opendns
= ['208.67.222.222', '208.67.220.220'];
82 s
= s
.trim().replace(/\n+/g, ' ');
83 if (r
= s
.match(/^(.*?): (.*)/)) {
84 r
[2] = r
[2].replace(/#RETRY (\d+) (\d+)/,
85 function(s
, min
, num
) {
86 return '<br><small>(' + ((num
>= 1) ? (num
+ '/3: ') : '') + '<% translate("Automatically retrying in"); %> ' + min
+ ' <% translate("minutes"); %>)</small>';
89 return '<small>' + (new Date(r
[1])).toLocaleString() + ':</small><br>' + r
[2];
91 else if (s
.length
== 0) {
102 for (i
= s
.length
- 1; i
>= 0; --i
) {
109 function verifyFields(focused
, quiet
)
117 b
= E('_f_ddnsx_ip').value
== 'custom';
118 elem
.display(PR('_f_custom_ip'), b
);
119 if ((b
) && (!v_ip('_f_custom_ip', quiet
))) return 0;
121 if (!v_range('_ddnsx_refresh', quiet
, 0, 90)) return 0;
124 for (i
= 0; i
< 2; ++i
) {
125 data
= services
[E('_f_service' + i
).selectedIndex
] || services
[0];
126 enabled
= (data
[0] != '');
130 elem
.display(PR('url' + i
), (enabled
) && (data
[0] != 'custom'));
131 elem
.display('row_z' + i
, op
.z
);
133 elem
.display(PR('_f_hosttop' + i
), op
.t
);
134 elem
.display(PR('_f_user' + i
), op
.u
);
135 elem
.display(PR('_f_pass' + i
), op
.u
|| op
.p
);
136 elem
.display(PR('_f_host' + i
), op
.h
|| op
.j
);
137 elem
.display(PR('_f_cust' + i
), 'custmsg' + i
, op
.c
);
139 elem
.display(PR('_f_wild' + i
), op
.w
);
140 elem
.display(PR('_f_mx' + i
), op
.m
);
141 elem
.display(PR('_f_bmx' + i
), op
.b
);
142 elem
.display(PR('_f_opendns' + i
), op
.o
);
143 elem
.display(PR('_f_afraid' + i
), op
.a
);
144 elem
.display(PR('_f_ddnsx_save' + i
), op
.s
);
146 elem
.display(PR('_f_force' + i
), 'last-response' + i
, enabled
);
147 elem
.display('last-update' + i
, enabled
&& !op
.z
);
150 PR('_f_user' + i
).cells
[0].innerHTML
= data
[4] || 'Username';
151 PR('_f_pass' + i
).cells
[0].innerHTML
= data
[5] || 'Password';
152 PR('_f_host' + i
).cells
[0].innerHTML
= data
[6] || 'Hostname';
156 e
.innerHTML
= data
[2];
159 e
= E('_f_cust' + i
);
160 e
.value
= e
.value
.trim();
164 if (e
.value
.search(/http(s?):\/\/./) != 0) {
165 ferror
.set(e
, '<% translate("Expecting a URL -- http://... or https://..."); %>', quiet
)
169 if (!v_nodelim('_f_cust' + i
, quiet
, 'URL')) r
= 0;
170 else ferror
.clear(e
);
174 e
= E('_f_afraid' + i
);
175 e
.value
= e
.value
.trim();
176 if (e
.value
.match(/freedns\.afraid\.org\/dynamic\/update\.php\?([a-zA-Z0-9]+)/)) {
179 if (e
.value
.search(/^[A-Za-z0-9]+/) == -1) {
180 ferror
.set(e
, '<% translate("Invalid hash or URL"); %>', quiet
)
184 if (!v_nodelim('_f_afraid' + i
, quiet
, 'Token / URL')) r
= 0;
185 else ferror
.clear(e
);
189 if (((op
.u
) && (!v_length('_f_user' + i
, quiet
, 1) || !v_nodelim('_f_user' + i
, quiet
, 'Username'))) ||
190 (!v_length('_f_pass' + i
, quiet
, 1) || !v_nodelim('_f_pass' + i
, quiet
, 'Password')) ||
191 ((op
.m
) && (!v_nodelim('_f_mx' + i
, quiet
, 'MX'))) ||
192 ((op
.h
) && (!op
.o
) && (!v_length('_f_host' + i
, quiet
, 1) || !v_nodelim('_f_host' + i
, quiet
, 'Hostname'))) ||
193 ((op
.t
) && (!v_length('_f_hosttop' + i
, quiet
, 1) || !v_nodelim('_f_hosttop' + i
, quiet
, 'Hostname')))) {
200 // shouldn't do this twice, but...
201 if (E('_f_opendns0') == focused
) E('_f_opendns1').checked
= E('_f_opendns0').checked
;
202 if (E('_f_opendns1') == focused
) E('_f_opendns0').checked
= E('_f_opendns1').checked
;
204 if (E('_f_ddnsx_save0') == focused
) E('_f_ddnsx_save1').checked
= E('_f_ddnsx_save0').checked
;
205 if (E('_f_ddnsx_save1') == focused
) E('_f_ddnsx_save0').checked
= E('_f_ddnsx_save1').checked
;
218 if (!verifyFields(null, 0)) return;
221 fom
.ddnsx_save
.value
= (nvram
.ddnsx_save
== 1) ? 1 : 0;
223 fom
.ddnsx_ip
.value
= (E('_f_ddnsx_ip').value
== 'custom') ? E('_f_custom_ip').value
: E('_f_ddnsx_ip').value
;
226 for (i
= 0; i
< 2; ++i
) {
228 data
= services
[E('_f_service' + i
).selectedIndex
] || services
[0];
234 u = username/password
242 z = can't use client-given IP address
243 s = save state checkbox
254 custom url/afraid hash<
259 if ((op
.u
) || (op
.p
)) s
.push(E('_f_user' + i
).value
+ ':' + E('_f_pass' + i
).value
);
263 s
.push(E('_f_hosttop' + i
).value
);
265 else if ((op
.h
) || (op
.j
)) {
266 s
.push(E('_f_host' + i
).value
);
272 if (op
.w
) s
.push(E('_f_wild' + i
).checked
? 1 : 0);
274 if (op
.m
) s
.push(E('_f_mx' + i
).value
)
276 if (op
.b
) s
.push(E('_f_bmx' + i
).checked
? 1 : 0);
280 s
.push(E('_f_cust' + i
).value
);
283 s
.push(E('_f_afraid' + i
).value
);
290 fom
.ddnsx_save
.value
= E('_f_ddnsx_save' + i
).checked
? 1 : 0;
293 if (data
[0] == 'opendns') setopendns
= E('_f_opendns' + i
).checked
;
296 fom
['ddnsx' + i
].value
= s
;
297 fom
['ddnsx' + i
+ '_cache'].disabled
= (!E('_f_force' + i
).checked
) && (s
== nvram
['ddnsx' + i
]);
300 if (setopendns
!= -1) {
302 if (opendnsInUse
!= opendns
.length
) {
303 fom
.wan_dns
.value
= opendns
.join(' ');
304 fom
.wan_dns
.disabled
= 0;
305 fom
._service
.value
+= ',dns-restart';
309 // not set if partial, do not remove if partial
310 if (opendnsInUse
== opendns
.length
) {
311 a
= nvram
.wan_dns
.split(/\s+/);
313 for (i
= a
.length
- 1; i
>= 0; --i
) {
314 for (j
= opendns
.length
- 1; j
>= 0; --j
) {
315 if (a
[i
] == opendns
[j
]) {
321 fom
.wan_dns
.value
= a
.join(' ');
322 fom
.wan_dns
.disabled
= 0;
323 fom
._service
.value
+= ',dns-restart';
333 if ('<% psup("ddns-update"); %>' != 0) {
334 var e
= E('footer-msg');
335 e
.innerHTML
= '<% translate("DDNS update is running. Please refresh after a few seconds"); %>.';
336 e
.style
.visibility
= 'visible';
342 <body onload='init()'
>
343 <form id='_fom' method='post' action='tomato.cgi'
>
344 <table id='container' cellspacing=
0>
345 <tr><td colspan=
2 id='header'
>
346 <div class='title'
>Tomato
</div>
347 <div class='version'
><%
translate("Version"); %> <% version(); %
></div>
349 <tr id='body'
><td id='navi'
><script type='text/javascript'
>navi()</script></td>
351 <div id='ident'
><%
ident(); %></div>
355 <input type='hidden' name='_nextpage' value='basic-ddns.asp'
>
356 <input type='hidden' name='_service' value='ddns-restart'
>
357 <input type='hidden' name='_nextwait' value='
10'
>
359 <input type='hidden' name='ddnsx0' value=''
>
360 <input type='hidden' name='ddnsx1' value=''
>
361 <input type='hidden' name='ddnsx0_cache' value='' disabled
>
362 <input type='hidden' name='ddnsx1_cache' value='' disabled
>
363 <input type='hidden' name='wan_dns' value='' disabled
>
364 <input type='hidden' name='ddnsx_ip' value=''
>
365 <input type='hidden' name='ddnsx_save' value=''
>
368 <div class='section-title'
><%
translate("Dynamic DNS"); %></div>
369 <div class='section'
>
370 <script type='text/javascript'
>
372 a
= (s
!= '') && (s
.indexOf('@') != 0) && (s
!= '0.0.0.0') && (s
!= '1.1.1.1') && (s
!= '10.1.1.1');
373 createFieldTable('', [
374 { title
: '<% translate("IP address"); %>', name
: 'f_ddnsx_ip', type
: 'select',
376 ['', '<% translate("Use WAN IP Address"); %> ' + ddnsx_ip
+ ' (<% translate("recommended"); %>)'],
377 ['@', '<% translate("Use External IP Address Checker (every 10 minutes)"); %>'],
378 ['0.0.0.0', '<% translate("Offline"); %> (0.0.0.0)'],
379 ['1.1.1.1', '<% translate("Offline"); %> (1.1.1.1)'],
380 ['10.1.1.1', '<% translate("Offline"); %> (10.1.1.1)'],
381 ['<% translate("custom"); %>', '<% translate("Custom IP Address"); %>...']
383 value
: a
? 'custom' : nvram
.ddnsx_ip
},
384 { title
: '<% translate("Custom IP address"); %>', indent
: 2, name
: 'f_custom_ip', type
: 'text', maxlen
: 15, size
: 20,
385 value
: a
? nvram
.ddnsx_ip
: '', hidden
: !a
},
386 { title
: '<% translate("Auto refresh every"); %>', name
: 'ddnsx_refresh', type
: 'text', maxlen
: 8, size
: 8, suffix
: ' <% translate("days"); %> <small>("0 = <% translate("disable"); %>")</small>', value
: fixInt(nvram
.ddnsx_refresh
, 0, 90, 28) }
392 <script type='text/javascript'
>
393 a
= nvram
.wan_dns
.split(/\s+/);
394 for (i
= 0; i
< a
.length
; ++i
) {
395 for (j
= 0; j
< opendns
.length
; ++j
) {
396 if (a
[i
] == opendns
[j
]) ++opendnsInUse
;
400 if (nvram
.dns_addget
== 1) {
401 dns
= nvram
.wan_dns
+ ' ' + nvram
.wan_get_dns
;
403 else if (nvram
.wan_dns
!= '') {
407 dns
= nvram
.wan_get_dns
;
409 dns
= dns
.split(/\s+/);
410 for (i
= 0; i
< dns
.length
; ++i
) {
411 for (j
= 0; j
< opendns
.length
; ++j
) {
412 if (dns
[i
] == opendns
[j
]) {
413 dns
[i
] = '<i>' + dns
[i
] + '</i>';
418 dns
= dns
.join(', ');
420 for (i
= 0; i
< 2; ++i
) {
421 v
= nvram
['ddnsx' + i
].split('<');
422 if (v
.length
!= 7) v
= ['', '', '', 0, '', 0, ''];
425 if (u
.length
!= 2) u
= ['', ''];
428 W('<div class="section-title"><% translate("Dynamic DNS"); %> ' + (i
+ 1) + '</div><div class="section">');
429 createFieldTable('', [
430 { title
: '<% translate("Service"); %>', name
: 'f_service' + i
, type
: 'select', options
: services
, value
: v
[0] },
431 { title
: 'URL', indent
: 2, text
: '<a href="" id="url' + i
+ '" target="tomato-ext-ddns"></a>', hidden
: 1 },
432 { title
: ' ', text
: '<small>* <% translate("This service determines the IP address using its own method"); %>.</small>', hidden
: 1, rid
: 'row_z' + i
},
433 { title
: '<% translate("Hostname"); %>', name
: 'f_hosttop' + i
, type
: 'text', maxlen
: 96, size
: 35, value
: v
[2], hidden
: 1 },
434 { title
: '<% translate("Username"); %>', name
: 'f_user' + i
, type
: 'text', maxlen
: 64, size
: 35, value
: u
[0], hidden
: 1 },
435 { title
: '<% translate("Password"); %>', name
: 'f_pass' + i
, type
: 'password', maxlen
: 64, size
: 35, peekaboo
: 1, value
: u
[1], hidden
: 1 },
436 { title
: '<% translate("Hostname"); %>', name
: 'f_host' + i
, type
: 'text', maxlen
: 255, size
: 80, value
: v
[2], hidden
: 1 },
437 { title
: 'URL', name
: 'f_cust' + i
, type
: 'text', maxlen
: 255, size
: 80, value
: v
[6], hidden
: 1 },
438 { title
: ' ', text
: '(Use @IP for the current IP address)', rid
: ('custmsg' + i
), hidden
: 1 },
439 { title
: '<% translate("Wildcard"); %>', indent
: 2, name
: 'f_wild' + i
, type
: 'checkbox', value
: v
[3] != '0', hidden
: 1 },
440 { title
: 'MX', name
: 'f_mx' + i
, type
: 'text', maxlen
: 32, size
: 35, value
: v
[4], hidden
: 1 },
441 { title
: '<% translate("Backup MX"); %>', indent
: 2, name
: 'f_bmx' + i
, type
: 'checkbox', value
: v
[5] != '0', hidden
: 1 },
442 { title
: '<% translate("Use as DNS"); %>', name
: 'f_opendns' + i
, type
: 'checkbox', value
: (opendnsInUse
== opendns
.length
),
443 suffix
: '<br><small>(<% translate("Current DNS"); %>: ' + dns
+ ')</small>', hidden
: 1 },
444 { title
: '<% translate("Token / URL"); %>', name
: 'f_afraid' + i
, type
: 'text', maxlen
: 255, size
: 80, value
: v
[6], hidden
: 1 },
445 { title
: '<% translate("Save state when IP changes"); %> (nvram commit)', name
: 'f_ddnsx_save' + i
, type
: 'checkbox', value
: nvram
.ddnsx_save
== '1', hidden
: 1 },
446 { title
: '<% translate("Force next update"); %>', name
: 'f_force' + i
, type
: 'checkbox', value
: 0, hidden
: 1 },
448 { title
: '<% translate("Last IP Address"); %>', custom
: msgLoc(ddnsx_last
[i
]), rid
: 'last-update' + i
, hidden
: 1 },
449 { title
: '<% translate("Last Result"); %>', custom
: msgLoc(ddnsx_msg
[i
]), rid
: 'last-response' + i
, hidden
: h
}
459 <tr><td id='footer' colspan=
2>
460 <span id='footer-msg'
></span>
461 <input type='button' value='<%
translate("Save"); %>' id='save-button' onclick='save()'
>
462 <input type='button' value='<%
translate("Cancel"); %>' id='cancel-button' onclick='reloadPage();'
>
465 <script type='text/javascript'
>verifyFields(null, 1);</script>