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(); %>] 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
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, 'Domain <small>(optional)</small>'],
63 ['minidns', 'miniDNS', 'http://www.minidns.net/', 'uh'],
64 ['enom', 'eNom', 'http://www.enom.com/', 'ut', 'Domain'],
65 ['afraid', 'FreeDNS (afraid.org)', 'http://freedns.afraid.org/', 'az'],
66 ['heipv6tb', 'HE.net IPv6 Tunnel Broker', 'http://www.tunnelbroker.net/', 'uh', 'User ID <small>(not your username)</small>', null, 'Global Tunnel ID'],
67 ['ieserver', 'ieServer.net', 'http://www.ieserver.net/', 'uhz', 'Username / Hostname', null, 'Domain'],
68 ['namecheap', 'namecheap', 'http://www.namecheap.com/', 'ut', 'Domain'],
69 ['noip', 'No-IP.com', 'http://www.no-ip.com/', 'uh', 'Email Address', null, 'Hostname / Group'],
70 ['opendns', 'OpenDNS', 'http://www.opendns.com/', 'uhoz', null, null, 'Network <small>(optional)</small>'],
71 ['tzo', 'TZO', 'http://www.tzo.com/', 'uh', 'Email Address', 'Password'],
72 ['zoneedit', 'ZoneEdit', 'http://www.zoneedit.com/', 'uh'],
73 ['szoneedit', 'ZoneEdit (https)', 'http://www.zoneedit.com/', 'uh'],
74 ['pairnic', 'pairNIC', 'http://www.pairnic.com/', 'uh'],
75 ['spairnic', 'pairNIC (https)', 'http://www.pairnic.com/', 'uh'],
76 ['ovh', 'OVH', 'http://www.ovh.com/', 'uh'],
77 ['sovh', 'OVH (https)', 'https://www.ovh.com/', 'uh'],
78 ['schangeip', 'ChangeIP (https)', 'https://www.changeip.com/', 'uh'],
79 ['custom', 'Custom URL', '', 'c']];
81 var opendns
= ['208.67.222.222', '208.67.220.220'];
88 s
= s
.trim().replace(/\n+/g, ' ');
89 if (r
= s
.match(/^(.*?): (.*)/)) {
90 r
[2] = r
[2].replace(/#RETRY (\d+) (\d+)/,
91 function(s
, min
, num
) {
92 return '<br><small>(' + ((num
>= 1) ? (num
+ '/3: ') : '') + 'Automatically retrying in ' + min
+ ' minutes)</small>';
95 return '<small>' + (new Date(r
[1])).toLocaleString() + ':</small><br>' + r
[2];
97 else if (s
.length
== 0) {
108 for (i
= s
.length
- 1; i
>= 0; --i
) {
115 function verifyFields(focused
, quiet
)
123 b
= E('_f_ddnsx_ip').value
== 'custom';
124 elem
.display(PR('_f_custom_ip'), b
);
125 if ((b
) && (!v_ip('_f_custom_ip', quiet
))) return 0;
127 if (!v_range('_ddnsx_refresh', quiet
, 0, 90)) return 0;
130 for (i
= 0; i
< 2; ++i
) {
131 data
= services
[E('_f_service' + i
).selectedIndex
] || services
[0];
132 enabled
= (data
[0] != '');
136 elem
.display(PR('url' + i
), (enabled
) && (data
[0] != 'custom'));
137 elem
.display('row_z' + i
, op
.z
);
139 elem
.display(PR('_f_hosttop' + i
), op
.t
);
140 elem
.display(PR('_f_user' + i
), op
.u
);
141 elem
.display(PR('_f_pass' + i
), op
.u
|| op
.p
);
142 elem
.display(PR('_f_host' + i
), op
.h
|| op
.j
);
143 elem
.display(PR('_f_cust' + i
), op
.c
);
145 elem
.display(PR('_f_wild' + i
), op
.w
);
146 elem
.display(PR('_f_mx' + i
), op
.m
);
147 elem
.display(PR('_f_bmx' + i
), op
.b
);
148 elem
.display(PR('_f_opendns' + i
), op
.o
);
149 elem
.display(PR('_f_afraid' + i
), op
.a
);
150 elem
.display(PR('_f_ddnsx_save' + i
), op
.s
);
152 elem
.display(PR('_f_force' + i
), 'last-response' + i
, enabled
);
153 elem
.display('last-update' + i
, enabled
&& !op
.z
);
156 PR('_f_user' + i
).cells
[0].innerHTML
= data
[4] || 'Username';
157 PR('_f_pass' + i
).cells
[0].innerHTML
= data
[5] || 'Password';
158 PR('_f_host' + i
).cells
[0].innerHTML
= data
[6] || 'Hostname';
162 e
.innerHTML
= data
[2];
165 e
= E('_f_cust' + i
);
166 e
.value
= e
.value
.trim();
170 if (e
.value
.search(/http(s?):\/\/./) != 0) {
171 ferror
.set(e
, 'Expecting a URL -- http://... or https://...', quiet
);
175 if (!v_nodelim('_f_cust' + i
, quiet
, 'URL')) r
= 0;
176 else ferror
.clear(e
);
180 e
= E('_f_afraid' + i
);
181 e
.value
= e
.value
.trim();
182 if (e
.value
.match(/freedns\.afraid\.org\/dynamic\/update\.php\?([a-zA-Z0-9]+)/)) {
185 if (e
.value
.search(/^[A-Za-z0-9]+/) == -1) {
186 ferror
.set(e
, 'Invalid hash or URL', quiet
);
190 if (!v_nodelim('_f_afraid' + i
, quiet
, 'Token / URL')) r
= 0;
191 else ferror
.clear(e
);
195 if (((op
.u
) && (!v_length('_f_user' + i
, quiet
, 1) || !v_nodelim('_f_user' + i
, quiet
, 'Username'))) ||
196 (!v_length('_f_pass' + i
, quiet
, 1) || !v_nodelim('_f_pass' + i
, quiet
, 'Password')) ||
197 ((op
.m
) && (!v_nodelim('_f_mx' + i
, quiet
, 'MX'))) ||
198 ((op
.h
) && (!op
.o
) && (!v_length('_f_host' + i
, quiet
, 1) || !v_nodelim('_f_host' + i
, quiet
, 'Hostname'))) ||
199 ((op
.t
) && (!v_length('_f_hosttop' + i
, quiet
, 1) || !v_nodelim('_f_hosttop' + i
, quiet
, 'Hostname')))) {
206 // shouldn't do this twice, but...
207 if (E('_f_opendns0') == focused
) E('_f_opendns1').checked
= E('_f_opendns0').checked
;
208 if (E('_f_opendns1') == focused
) E('_f_opendns0').checked
= E('_f_opendns1').checked
;
210 if (E('_f_ddnsx_save0') == focused
) E('_f_ddnsx_save1').checked
= E('_f_ddnsx_save0').checked
;
211 if (E('_f_ddnsx_save1') == focused
) E('_f_ddnsx_save0').checked
= E('_f_ddnsx_save1').checked
;
224 if (!verifyFields(null, 0)) return;
227 fom
.ddnsx_save
.value
= (nvram
.ddnsx_save
== 1) ? 1 : 0;
229 fom
.ddnsx_ip
.value
= (E('_f_ddnsx_ip').value
== 'custom') ? E('_f_custom_ip').value
: E('_f_ddnsx_ip').value
;
232 for (i
= 0; i
< 2; ++i
) {
234 data
= services
[E('_f_service' + i
).selectedIndex
] || services
[0];
240 u = username/password
248 z = can't use client-given IP address
249 s = save state checkbox
260 custom url/afraid hash<
265 if ((op
.u
) || (op
.p
)) s
.push(E('_f_user' + i
).value
+ ':' + E('_f_pass' + i
).value
);
269 s
.push(E('_f_hosttop' + i
).value
);
271 else if ((op
.h
) || (op
.j
)) {
272 s
.push(E('_f_host' + i
).value
);
278 if (op
.w
) s
.push(E('_f_wild' + i
).checked
? 1 : 0);
280 if (op
.m
) s
.push(E('_f_mx' + i
).value
)
282 if (op
.b
) s
.push(E('_f_bmx' + i
).checked
? 1 : 0);
286 s
.push(E('_f_cust' + i
).value
);
289 s
.push(E('_f_afraid' + i
).value
);
296 fom
.ddnsx_save
.value
= E('_f_ddnsx_save' + i
).checked
? 1 : 0;
299 if (data
[0] == 'opendns') setopendns
= E('_f_opendns' + i
).checked
;
302 fom
['ddnsx' + i
].value
= s
;
303 fom
['ddnsx' + i
+ '_cache'].disabled
= (!E('_f_force' + i
).checked
) && (s
== nvram
['ddnsx' + i
]);
306 if (setopendns
!= -1) {
308 if (opendnsInUse
!= opendns
.length
) {
309 fom
.wan_dns
.value
= opendns
.join(' ');
310 fom
.wan_dns
.disabled
= 0;
311 fom
._service
.value
+= ',dns-restart';
315 // not set if partial, do not remove if partial
316 if (opendnsInUse
== opendns
.length
) {
317 a
= nvram
.wan_dns
.split(/\s+/);
319 for (i
= a
.length
- 1; i
>= 0; --i
) {
320 for (j
= opendns
.length
- 1; j
>= 0; --j
) {
321 if (a
[i
] == opendns
[j
]) {
327 fom
.wan_dns
.value
= a
.join(' ');
328 fom
.wan_dns
.disabled
= 0;
329 fom
._service
.value
+= ',dns-restart';
339 if ('<% psup("ddns-update"); %>' != 0) {
340 var e
= E('footer-msg');
341 e
.innerHTML
= 'DDNS update is running. Please refresh after a few seconds.';
342 e
.style
.visibility
= 'visible';
348 <body onload='init()'
>
349 <form id='_fom' method='post' action='tomato.cgi'
>
350 <table id='container' cellspacing=
0>
351 <tr><td colspan=
2 id='header'
>
352 <div class='title'
>Tomato
</div>
353 <div class='version'
>Version <%
version(); %></div>
355 <tr id='body'
><td id='navi'
><script type='text/javascript'
>navi()</script></td>
357 <div id='ident'
><%
ident(); %></div>
361 <input type='hidden' name='_nextpage' value='basic-ddns.asp'
>
362 <input type='hidden' name='_service' value='ddns-restart'
>
363 <input type='hidden' name='_nextwait' value='
10'
>
365 <input type='hidden' name='ddnsx0' value=''
>
366 <input type='hidden' name='ddnsx1' value=''
>
367 <input type='hidden' name='ddnsx0_cache' value='' disabled
>
368 <input type='hidden' name='ddnsx1_cache' value='' disabled
>
369 <input type='hidden' name='wan_dns' value='' disabled
>
370 <input type='hidden' name='ddnsx_ip' value=''
>
371 <input type='hidden' name='ddnsx_save' value=''
>
374 <div class='section-title'
>Dynamic DNS
</div>
375 <div class='section'
>
376 <script type='text/javascript'
>
378 a
= (s
!= '') && (s
.indexOf('@') != 0) && (s
!= '0.0.0.0') && (s
!= '1.1.1.1') && (s
!= '10.1.1.1');
379 createFieldTable('', [
380 { title
: 'IP address', name
: 'f_ddnsx_ip', type
: 'select',
382 ['', 'Use WAN IP Address ' + ddnsx_ip
+ ' (recommended)'],
383 ['@', 'Use External IP Address Checker (every 10 minutes)'],
384 ['0.0.0.0', 'Offline (0.0.0.0)'],
385 ['1.1.1.1', 'Offline (1.1.1.1)'],
386 ['10.1.1.1', 'Offline (10.1.1.1)'],
387 ['custom', 'Custom IP Address...']
389 value
: a
? 'custom' : nvram
.ddnsx_ip
},
390 { title
: 'Custom IP address', indent
: 2, name
: 'f_custom_ip', type
: 'text', maxlen
: 15, size
: 20,
391 value
: a
? nvram
.ddnsx_ip
: '', hidden
: !a
},
392 { title
: 'Auto refresh every', name
: 'ddnsx_refresh', type
: 'text', maxlen
: 8, size
: 8, suffix
: '<small> days (0 = disable)</small>', value
: fixInt(nvram
.ddnsx_refresh
, 0, 90, 28) }
398 <script type='text/javascript'
>
399 a
= nvram
.wan_dns
.split(/\s+/);
400 for (i
= 0; i
< a
.length
; ++i
) {
401 for (j
= 0; j
< opendns
.length
; ++j
) {
402 if (a
[i
] == opendns
[j
]) ++opendnsInUse
;
406 if (nvram
.dns_addget
== 1) {
407 dns
= nvram
.wan_dns
+ ' ' + nvram
.wan_get_dns
;
409 else if (nvram
.wan_dns
!= '') {
413 dns
= nvram
.wan_get_dns
;
415 dns
= dns
.split(/\s+/);
416 for (i
= 0; i
< dns
.length
; ++i
) {
417 for (j
= 0; j
< opendns
.length
; ++j
) {
418 if (dns
[i
] == opendns
[j
]) {
419 dns
[i
] = '<i>' + dns
[i
] + '</i>';
424 dns
= dns
.join(', ');
426 for (i
= 0; i
< 2; ++i
) {
427 v
= nvram
['ddnsx' + i
].split('<');
428 if (v
.length
!= 7) v
= ['', '', '', 0, '', 0, ''];
431 if (u
.length
!= 2) u
= ['', ''];
434 W('<div class="section-title">Dynamic DNS ' + (i
+ 1) + '</div><div class="section">');
435 createFieldTable('', [
436 { title
: 'Service', name
: 'f_service' + i
, type
: 'select', options
: services
, value
: v
[0] },
437 { title
: 'URL', indent
: 2, text
: '<a href="" id="url' + i
+ '" target="tomato-ext-ddns"></a>', hidden
: 1 },
438 { title
: ' ', text
: '<small>* This service determines the IP address using its own method.</small>', hidden
: 1, rid
: 'row_z' + i
},
439 { title
: 'Hostname', name
: 'f_hosttop' + i
, type
: 'text', maxlen
: 96, size
: 35, value
: v
[2], hidden
: 1 },
440 { title
: 'Username', name
: 'f_user' + i
, type
: 'text', maxlen
: 64, size
: 35, value
: u
[0], hidden
: 1 },
441 { title
: 'Password', name
: 'f_pass' + i
, type
: 'password', maxlen
: 64, size
: 35, peekaboo
: 1, value
: u
[1], hidden
: 1 },
442 { title
: 'Hostname', name
: 'f_host' + i
, type
: 'text', maxlen
: 255, size
: 80, value
: v
[2], hidden
: 1 },
443 { title
: 'URL', name
: 'f_cust' + i
, type
: 'text', maxlen
: 255, size
: 80, value
: v
[6], hidden
: 1 },
444 { title
: 'Wildcard', indent
: 2, name
: 'f_wild' + i
, type
: 'checkbox', value
: v
[3] != '0', hidden
: 1 },
445 { title
: 'MX', name
: 'f_mx' + i
, type
: 'text', maxlen
: 32, size
: 35, value
: v
[4], hidden
: 1 },
446 { title
: 'Backup MX', indent
: 2, name
: 'f_bmx' + i
, type
: 'checkbox', value
: v
[5] != '0', hidden
: 1 },
447 { title
: 'Use as DNS', name
: 'f_opendns' + i
, type
: 'checkbox', value
: (opendnsInUse
== opendns
.length
),
448 suffix
: '<br><small>(Current DNS: ' + dns
+ ')</small>', hidden
: 1 },
449 { title
: 'Token / URL', name
: 'f_afraid' + i
, type
: 'text', maxlen
: 255, size
: 80, value
: v
[6], hidden
: 1 },
450 { title
: 'Save state when IP changes (nvram commit)', name
: 'f_ddnsx_save' + i
, type
: 'checkbox', value
: nvram
.ddnsx_save
== '1', hidden
: 1 },
451 { title
: 'Force next update', name
: 'f_force' + i
, type
: 'checkbox', value
: 0, hidden
: 1 },
453 { title
: 'Last IP Address', custom
: msgLoc(ddnsx_last
[i
]), rid
: 'last-update' + i
, hidden
: 1 },
454 { title
: 'Last Result', custom
: msgLoc(ddnsx_msg
[i
]), rid
: 'last-response' + i
, hidden
: h
}
462 <div class='section-title'
>Notes
</div>
463 <div class='section'
>
465 <li><b>URL
</b> - Use
<code>@IP
</code> in an HTTP parameter/argument to refer to the current WAN IP address.
</li>
472 <tr><td id='footer' colspan=
2>
473 <span id='footer-msg'
></span>
474 <input type='button' value='Save' id='save-button' onclick='save()'
>
475 <input type='button' value='Cancel' id='cancel-button' onclick='reloadPage();'
>
478 <script type='text/javascript'
>verifyFields(null, 1);</script>