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 ['custom', 'Custom URL', '', 'c']];
76 var opendns
= ['208.67.222.222', '208.67.220.220'];
83 s
= s
.trim().replace(/\n+/g, ' ');
84 if (r
= s
.match(/^(.*?): (.*)/)) {
85 r
[2] = r
[2].replace(/#RETRY (\d+) (\d+)/,
86 function(s
, min
, num
) {
87 return '<br><small>(' + ((num
>= 1) ? (num
+ '/3: ') : '') + 'Automatically retrying in ' + min
+ ' minutes)</small>';
90 return '<small>' + (new Date(r
[1])).toLocaleString() + ':</small><br>' + r
[2];
92 else if (s
.length
== 0) {
103 for (i
= s
.length
- 1; i
>= 0; --i
) {
110 function verifyFields(focused
, quiet
)
118 b
= E('_f_ddnsx_ip').value
== 'custom';
119 elem
.display(PR('_f_custom_ip'), b
);
120 if ((b
) && (!v_ip('_f_custom_ip', quiet
))) return 0;
122 if (!v_range('_ddnsx_refresh', quiet
, 0, 90)) return 0;
125 for (i
= 0; i
< 2; ++i
) {
126 data
= services
[E('_f_service' + i
).selectedIndex
] || services
[0];
127 enabled
= (data
[0] != '');
131 elem
.display(PR('url' + i
), (enabled
) && (data
[0] != 'custom'));
132 elem
.display('row_z' + i
, op
.z
);
134 elem
.display(PR('_f_hosttop' + i
), op
.t
);
135 elem
.display(PR('_f_user' + i
), op
.u
);
136 elem
.display(PR('_f_pass' + i
), op
.u
|| op
.p
);
137 elem
.display(PR('_f_host' + i
), op
.h
|| op
.j
);
138 elem
.display(PR('_f_cust' + i
), 'custmsg' + i
, op
.c
);
140 elem
.display(PR('_f_wild' + i
), op
.w
);
141 elem
.display(PR('_f_mx' + i
), op
.m
);
142 elem
.display(PR('_f_bmx' + i
), op
.b
);
143 elem
.display(PR('_f_opendns' + i
), op
.o
);
144 elem
.display(PR('_f_afraid' + i
), op
.a
);
145 elem
.display(PR('_f_ddnsx_save' + i
), op
.s
);
147 elem
.display(PR('_f_force' + i
), 'last-response' + i
, enabled
);
148 elem
.display('last-update' + i
, enabled
&& !op
.z
);
151 PR('_f_user' + i
).cells
[0].innerHTML
= data
[4] || 'Username';
152 PR('_f_pass' + i
).cells
[0].innerHTML
= data
[5] || 'Password';
153 PR('_f_host' + i
).cells
[0].innerHTML
= data
[6] || 'Hostname';
157 e
.innerHTML
= data
[2];
160 e
= E('_f_cust' + i
);
161 e
.value
= e
.value
.trim();
165 if (e
.value
.search(/http(s?):\/\/./) != 0) {
166 ferror
.set(e
, 'Expecting a URL -- http://... or https://...', quiet
)
170 if (!v_nodelim('_f_cust' + i
, quiet
, 'URL')) r
= 0;
171 else ferror
.clear(e
);
175 e
= E('_f_afraid' + i
);
176 e
.value
= e
.value
.trim();
177 if (e
.value
.match(/freedns\.afraid\.org\/dynamic\/update\.php\?([a-zA-Z0-9]+)/)) {
180 if (e
.value
.search(/^[A-Za-z0-9]+/) == -1) {
181 ferror
.set(e
, 'Invalid hash or URL', quiet
)
185 if (!v_nodelim('_f_afraid' + i
, quiet
, 'Token / URL')) r
= 0;
186 else ferror
.clear(e
);
190 if (((op
.u
) && (!v_length('_f_user' + i
, quiet
, 1) || !v_nodelim('_f_user' + i
, quiet
, 'Username'))) ||
191 (!v_length('_f_pass' + i
, quiet
, 1) || !v_nodelim('_f_pass' + i
, quiet
, 'Password')) ||
192 ((op
.m
) && (!v_nodelim('_f_mx' + i
, quiet
, 'MX'))) ||
193 ((op
.h
) && (!op
.o
) && (!v_length('_f_host' + i
, quiet
, 1) || !v_nodelim('_f_host' + i
, quiet
, 'Hostname'))) ||
194 ((op
.t
) && (!v_length('_f_hosttop' + i
, quiet
, 1) || !v_nodelim('_f_hosttop' + i
, quiet
, 'Hostname')))) {
201 // shouldn't do this twice, but...
202 if (E('_f_opendns0') == focused
) E('_f_opendns1').checked
= E('_f_opendns0').checked
;
203 if (E('_f_opendns1') == focused
) E('_f_opendns0').checked
= E('_f_opendns1').checked
;
205 if (E('_f_ddnsx_save0') == focused
) E('_f_ddnsx_save1').checked
= E('_f_ddnsx_save0').checked
;
206 if (E('_f_ddnsx_save1') == focused
) E('_f_ddnsx_save0').checked
= E('_f_ddnsx_save1').checked
;
219 if (!verifyFields(null, 0)) return;
222 fom
.ddnsx_save
.value
= (nvram
.ddnsx_save
== 1) ? 1 : 0;
224 fom
.ddnsx_ip
.value
= (E('_f_ddnsx_ip').value
== 'custom') ? E('_f_custom_ip').value
: E('_f_ddnsx_ip').value
;
227 for (i
= 0; i
< 2; ++i
) {
229 data
= services
[E('_f_service' + i
).selectedIndex
] || services
[0];
235 u = username/password
243 z = can't use client-given IP address
244 s = save state checkbox
255 custom url/afraid hash<
260 if ((op
.u
) || (op
.p
)) s
.push(E('_f_user' + i
).value
+ ':' + E('_f_pass' + i
).value
);
264 s
.push(E('_f_hosttop' + i
).value
);
266 else if ((op
.h
) || (op
.j
)) {
267 s
.push(E('_f_host' + i
).value
);
273 if (op
.w
) s
.push(E('_f_wild' + i
).checked
? 1 : 0);
275 if (op
.m
) s
.push(E('_f_mx' + i
).value
)
277 if (op
.b
) s
.push(E('_f_bmx' + i
).checked
? 1 : 0);
281 s
.push(E('_f_cust' + i
).value
);
284 s
.push(E('_f_afraid' + i
).value
);
291 fom
.ddnsx_save
.value
= E('_f_ddnsx_save' + i
).checked
? 1 : 0;
294 if (data
[0] == 'opendns') setopendns
= E('_f_opendns' + i
).checked
;
297 fom
['ddnsx' + i
].value
= s
;
298 fom
['ddnsx' + i
+ '_cache'].disabled
= (!E('_f_force' + i
).checked
) && (s
== nvram
['ddnsx' + i
]);
301 if (setopendns
!= -1) {
303 if (opendnsInUse
!= opendns
.length
) {
304 fom
.wan_dns
.value
= opendns
.join(' ');
305 fom
.wan_dns
.disabled
= 0;
306 fom
._service
.value
+= ',dns-restart';
310 // not set if partial, do not remove if partial
311 if (opendnsInUse
== opendns
.length
) {
312 a
= nvram
.wan_dns
.split(/\s+/);
314 for (i
= a
.length
- 1; i
>= 0; --i
) {
315 for (j
= opendns
.length
- 1; j
>= 0; --j
) {
316 if (a
[i
] == opendns
[j
]) {
322 fom
.wan_dns
.value
= a
.join(' ');
323 fom
.wan_dns
.disabled
= 0;
324 fom
._service
.value
+= ',dns-restart';
334 if ('<% psup("ddns-update"); %>' != 0) {
335 var e
= E('footer-msg');
336 e
.innerHTML
= 'DDNS update is running. Please refresh after a few seconds.';
337 e
.style
.visibility
= 'visible';
343 <body onload='init()'
>
344 <form id='_fom' method='post' action='tomato.cgi'
>
345 <table id='container' cellspacing=
0>
346 <tr><td colspan=
2 id='header'
>
347 <div class='title'
>Tomato
</div>
348 <div class='version'
>Version <%
version(); %></div>
350 <tr id='body'
><td id='navi'
><script type='text/javascript'
>navi()</script></td>
352 <div id='ident'
><%
ident(); %></div>
356 <input type='hidden' name='_nextpage' value='basic-ddns.asp'
>
357 <input type='hidden' name='_service' value='ddns-restart'
>
358 <input type='hidden' name='_nextwait' value='
10'
>
360 <input type='hidden' name='ddnsx0' value=''
>
361 <input type='hidden' name='ddnsx1' value=''
>
362 <input type='hidden' name='ddnsx0_cache' value='' disabled
>
363 <input type='hidden' name='ddnsx1_cache' value='' disabled
>
364 <input type='hidden' name='wan_dns' value='' disabled
>
365 <input type='hidden' name='ddnsx_ip' value=''
>
366 <input type='hidden' name='ddnsx_save' value=''
>
369 <div class='section-title'
>Dynamic DNS
</div>
370 <div class='section'
>
371 <script type='text/javascript'
>
373 a
= (s
!= '') && (s
.indexOf('@') != 0) && (s
!= '0.0.0.0') && (s
!= '1.1.1.1') && (s
!= '10.1.1.1');
374 createFieldTable('', [
375 { title
: 'IP address', name
: 'f_ddnsx_ip', type
: 'select',
377 ['', 'Use WAN IP Address ' + ddnsx_ip
+ ' (recommended)'],
378 ['@', 'Use External IP Address Checker (every 10 minutes)'],
379 ['0.0.0.0', 'Offline (0.0.0.0)'],
380 ['1.1.1.1', 'Offline (1.1.1.1)'],
381 ['10.1.1.1', 'Offline (10.1.1.1)'],
382 ['custom', 'Custom IP Address...']
384 value
: a
? 'custom' : nvram
.ddnsx_ip
},
385 { title
: 'Custom IP address', indent
: 2, name
: 'f_custom_ip', type
: 'text', maxlen
: 15, size
: 20,
386 value
: a
? nvram
.ddnsx_ip
: '', hidden
: !a
},
387 { title
: 'Auto refresh every', name
: 'ddnsx_refresh', type
: 'text', maxlen
: 8, size
: 8, suffix
: ' days <small>(0 = disable)</small>', value
: fixInt(nvram
.ddnsx_refresh
, 0, 90, 28) }
393 <script type='text/javascript'
>
394 a
= nvram
.wan_dns
.split(/\s+/);
395 for (i
= 0; i
< a
.length
; ++i
) {
396 for (j
= 0; j
< opendns
.length
; ++j
) {
397 if (a
[i
] == opendns
[j
]) ++opendnsInUse
;
401 if (nvram
.dns_addget
== 1) {
402 dns
= nvram
.wan_dns
+ ' ' + nvram
.wan_get_dns
;
404 else if (nvram
.wan_dns
!= '') {
408 dns
= nvram
.wan_get_dns
;
410 dns
= dns
.split(/\s+/);
411 for (i
= 0; i
< dns
.length
; ++i
) {
412 for (j
= 0; j
< opendns
.length
; ++j
) {
413 if (dns
[i
] == opendns
[j
]) {
414 dns
[i
] = '<i>' + dns
[i
] + '</i>';
419 dns
= dns
.join(', ');
421 for (i
= 0; i
< 2; ++i
) {
422 v
= nvram
['ddnsx' + i
].split('<');
423 if (v
.length
!= 7) v
= ['', '', '', 0, '', 0, ''];
426 if (u
.length
!= 2) u
= ['', ''];
429 W('<div class="section-title">Dynamic DNS ' + (i
+ 1) + '</div><div class="section">');
430 createFieldTable('', [
431 { title
: 'Service', name
: 'f_service' + i
, type
: 'select', options
: services
, value
: v
[0] },
432 { title
: 'URL', indent
: 2, text
: '<a href="" id="url' + i
+ '" target="tomato-ext-ddns"></a>', hidden
: 1 },
433 { title
: ' ', text
: '<small>* This service determines the IP address using its own method.</small>', hidden
: 1, rid
: 'row_z' + i
},
434 { title
: 'Hostname', name
: 'f_hosttop' + i
, type
: 'text', maxlen
: 96, size
: 35, value
: v
[2], hidden
: 1 },
435 { title
: 'Username', name
: 'f_user' + i
, type
: 'text', maxlen
: 64, size
: 35, value
: u
[0], hidden
: 1 },
436 { title
: 'Password', name
: 'f_pass' + i
, type
: 'password', maxlen
: 64, size
: 35, peekaboo
: 1, value
: u
[1], hidden
: 1 },
437 { title
: 'Hostname', name
: 'f_host' + i
, type
: 'text', maxlen
: 255, size
: 80, value
: v
[2], hidden
: 1 },
438 { title
: 'URL', name
: 'f_cust' + i
, type
: 'text', maxlen
: 255, size
: 80, value
: v
[6], hidden
: 1 },
439 { title
: ' ', text
: '(Use @IP for the current IP address)', rid
: ('custmsg' + i
), hidden
: 1 },
440 { title
: 'Wildcard', indent
: 2, name
: 'f_wild' + i
, type
: 'checkbox', value
: v
[3] != '0', hidden
: 1 },
441 { title
: 'MX', name
: 'f_mx' + i
, type
: 'text', maxlen
: 32, size
: 35, value
: v
[4], hidden
: 1 },
442 { title
: 'Backup MX', indent
: 2, name
: 'f_bmx' + i
, type
: 'checkbox', value
: v
[5] != '0', hidden
: 1 },
443 { title
: 'Use as DNS', name
: 'f_opendns' + i
, type
: 'checkbox', value
: (opendnsInUse
== opendns
.length
),
444 suffix
: '<br><small>(Current DNS: ' + dns
+ ')</small>', hidden
: 1 },
445 { title
: 'Token / URL', name
: 'f_afraid' + i
, type
: 'text', maxlen
: 255, size
: 80, value
: v
[6], hidden
: 1 },
446 { title
: 'Save state when IP changes (nvram commit)', name
: 'f_ddnsx_save' + i
, type
: 'checkbox', value
: nvram
.ddnsx_save
== '1', hidden
: 1 },
447 { title
: 'Force next update', name
: 'f_force' + i
, type
: 'checkbox', value
: 0, hidden
: 1 },
449 { title
: 'Last IP Address', custom
: msgLoc(ddnsx_last
[i
]), rid
: 'last-update' + i
, hidden
: 1 },
450 { title
: 'Last Result', custom
: msgLoc(ddnsx_msg
[i
]), rid
: 'last-response' + i
, hidden
: h
}
460 <tr><td id='footer' colspan=
2>
461 <span id='footer-msg'
></span>
462 <input type='button' value='Save' id='save-button' onclick='save()'
>
463 <input type='button' value='Cancel' id='cancel-button' onclick='reloadPage();'
>
466 <script type='text/javascript'
>verifyFields(null, 1);</script>