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 ['custom', 'Custom URL', '', 'c']];
78 var opendns
= ['208.67.222.222', '208.67.220.220'];
85 s
= s
.trim().replace(/\n+/g, ' ');
86 if (r
= s
.match(/^(.*?): (.*)/)) {
87 r
[2] = r
[2].replace(/#RETRY (\d+) (\d+)/,
88 function(s
, min
, num
) {
89 return '<br><small>(' + ((num
>= 1) ? (num
+ '/3: ') : '') + 'Automatically retrying in ' + min
+ ' minutes)</small>';
92 return '<small>' + (new Date(r
[1])).toLocaleString() + ':</small><br>' + r
[2];
94 else if (s
.length
== 0) {
105 for (i
= s
.length
- 1; i
>= 0; --i
) {
112 function verifyFields(focused
, quiet
)
120 b
= E('_f_ddnsx_ip').value
== 'custom';
121 elem
.display(PR('_f_custom_ip'), b
);
122 if ((b
) && (!v_ip('_f_custom_ip', quiet
))) return 0;
124 if (!v_range('_ddnsx_refresh', quiet
, 0, 90)) return 0;
127 for (i
= 0; i
< 2; ++i
) {
128 data
= services
[E('_f_service' + i
).selectedIndex
] || services
[0];
129 enabled
= (data
[0] != '');
133 elem
.display(PR('url' + i
), (enabled
) && (data
[0] != 'custom'));
134 elem
.display('row_z' + i
, op
.z
);
136 elem
.display(PR('_f_hosttop' + i
), op
.t
);
137 elem
.display(PR('_f_user' + i
), op
.u
);
138 elem
.display(PR('_f_pass' + i
), op
.u
|| op
.p
);
139 elem
.display(PR('_f_host' + i
), op
.h
|| op
.j
);
140 elem
.display(PR('_f_cust' + i
), 'custmsg' + i
, op
.c
);
142 elem
.display(PR('_f_wild' + i
), op
.w
);
143 elem
.display(PR('_f_mx' + i
), op
.m
);
144 elem
.display(PR('_f_bmx' + i
), op
.b
);
145 elem
.display(PR('_f_opendns' + i
), op
.o
);
146 elem
.display(PR('_f_afraid' + i
), op
.a
);
147 elem
.display(PR('_f_ddnsx_save' + i
), op
.s
);
149 elem
.display(PR('_f_force' + i
), 'last-response' + i
, enabled
);
150 elem
.display('last-update' + i
, enabled
&& !op
.z
);
153 PR('_f_user' + i
).cells
[0].innerHTML
= data
[4] || 'Username';
154 PR('_f_pass' + i
).cells
[0].innerHTML
= data
[5] || 'Password';
155 PR('_f_host' + i
).cells
[0].innerHTML
= data
[6] || 'Hostname';
159 e
.innerHTML
= data
[2];
162 e
= E('_f_cust' + i
);
163 e
.value
= e
.value
.trim();
167 if (e
.value
.search(/http(s?):\/\/./) != 0) {
168 ferror
.set(e
, 'Expecting a URL -- http://... or https://...', quiet
)
172 if (!v_nodelim('_f_cust' + i
, quiet
, 'URL')) r
= 0;
173 else ferror
.clear(e
);
177 e
= E('_f_afraid' + i
);
178 e
.value
= e
.value
.trim();
179 if (e
.value
.match(/freedns\.afraid\.org\/dynamic\/update\.php\?([a-zA-Z0-9]+)/)) {
182 if (e
.value
.search(/^[A-Za-z0-9]+/) == -1) {
183 ferror
.set(e
, 'Invalid hash or URL', quiet
)
187 if (!v_nodelim('_f_afraid' + i
, quiet
, 'Token / URL')) r
= 0;
188 else ferror
.clear(e
);
192 if (((op
.u
) && (!v_length('_f_user' + i
, quiet
, 1) || !v_nodelim('_f_user' + i
, quiet
, 'Username'))) ||
193 (!v_length('_f_pass' + i
, quiet
, 1) || !v_nodelim('_f_pass' + i
, quiet
, 'Password')) ||
194 ((op
.m
) && (!v_nodelim('_f_mx' + i
, quiet
, 'MX'))) ||
195 ((op
.h
) && (!op
.o
) && (!v_length('_f_host' + i
, quiet
, 1) || !v_nodelim('_f_host' + i
, quiet
, 'Hostname'))) ||
196 ((op
.t
) && (!v_length('_f_hosttop' + i
, quiet
, 1) || !v_nodelim('_f_hosttop' + i
, quiet
, 'Hostname')))) {
203 // shouldn't do this twice, but...
204 if (E('_f_opendns0') == focused
) E('_f_opendns1').checked
= E('_f_opendns0').checked
;
205 if (E('_f_opendns1') == focused
) E('_f_opendns0').checked
= E('_f_opendns1').checked
;
207 if (E('_f_ddnsx_save0') == focused
) E('_f_ddnsx_save1').checked
= E('_f_ddnsx_save0').checked
;
208 if (E('_f_ddnsx_save1') == focused
) E('_f_ddnsx_save0').checked
= E('_f_ddnsx_save1').checked
;
221 if (!verifyFields(null, 0)) return;
224 fom
.ddnsx_save
.value
= (nvram
.ddnsx_save
== 1) ? 1 : 0;
226 fom
.ddnsx_ip
.value
= (E('_f_ddnsx_ip').value
== 'custom') ? E('_f_custom_ip').value
: E('_f_ddnsx_ip').value
;
229 for (i
= 0; i
< 2; ++i
) {
231 data
= services
[E('_f_service' + i
).selectedIndex
] || services
[0];
237 u = username/password
245 z = can't use client-given IP address
246 s = save state checkbox
257 custom url/afraid hash<
262 if ((op
.u
) || (op
.p
)) s
.push(E('_f_user' + i
).value
+ ':' + E('_f_pass' + i
).value
);
266 s
.push(E('_f_hosttop' + i
).value
);
268 else if ((op
.h
) || (op
.j
)) {
269 s
.push(E('_f_host' + i
).value
);
275 if (op
.w
) s
.push(E('_f_wild' + i
).checked
? 1 : 0);
277 if (op
.m
) s
.push(E('_f_mx' + i
).value
)
279 if (op
.b
) s
.push(E('_f_bmx' + i
).checked
? 1 : 0);
283 s
.push(E('_f_cust' + i
).value
);
286 s
.push(E('_f_afraid' + i
).value
);
293 fom
.ddnsx_save
.value
= E('_f_ddnsx_save' + i
).checked
? 1 : 0;
296 if (data
[0] == 'opendns') setopendns
= E('_f_opendns' + i
).checked
;
299 fom
['ddnsx' + i
].value
= s
;
300 fom
['ddnsx' + i
+ '_cache'].disabled
= (!E('_f_force' + i
).checked
) && (s
== nvram
['ddnsx' + i
]);
303 if (setopendns
!= -1) {
305 if (opendnsInUse
!= opendns
.length
) {
306 fom
.wan_dns
.value
= opendns
.join(' ');
307 fom
.wan_dns
.disabled
= 0;
308 fom
._service
.value
+= ',dns-restart';
312 // not set if partial, do not remove if partial
313 if (opendnsInUse
== opendns
.length
) {
314 a
= nvram
.wan_dns
.split(/\s+/);
316 for (i
= a
.length
- 1; i
>= 0; --i
) {
317 for (j
= opendns
.length
- 1; j
>= 0; --j
) {
318 if (a
[i
] == opendns
[j
]) {
324 fom
.wan_dns
.value
= a
.join(' ');
325 fom
.wan_dns
.disabled
= 0;
326 fom
._service
.value
+= ',dns-restart';
336 if ('<% psup("ddns-update"); %>' != 0) {
337 var e
= E('footer-msg');
338 e
.innerHTML
= 'DDNS update is running. Please refresh after a few seconds.';
339 e
.style
.visibility
= 'visible';
345 <body onload='init()'
>
346 <form id='_fom' method='post' action='tomato.cgi'
>
347 <table id='container' cellspacing=
0>
348 <tr><td colspan=
2 id='header'
>
349 <div class='title'
>Tomato
</div>
350 <div class='version'
>Version <%
version(); %></div>
352 <tr id='body'
><td id='navi'
><script type='text/javascript'
>navi()</script></td>
354 <div id='ident'
><%
ident(); %></div>
358 <input type='hidden' name='_nextpage' value='basic-ddns.asp'
>
359 <input type='hidden' name='_service' value='ddns-restart'
>
360 <input type='hidden' name='_nextwait' value='
10'
>
362 <input type='hidden' name='ddnsx0' value=''
>
363 <input type='hidden' name='ddnsx1' value=''
>
364 <input type='hidden' name='ddnsx0_cache' value='' disabled
>
365 <input type='hidden' name='ddnsx1_cache' value='' disabled
>
366 <input type='hidden' name='wan_dns' value='' disabled
>
367 <input type='hidden' name='ddnsx_ip' value=''
>
368 <input type='hidden' name='ddnsx_save' value=''
>
371 <div class='section-title'
>Dynamic DNS
</div>
372 <div class='section'
>
373 <script type='text/javascript'
>
375 a
= (s
!= '') && (s
.indexOf('@') != 0) && (s
!= '0.0.0.0') && (s
!= '1.1.1.1') && (s
!= '10.1.1.1');
376 createFieldTable('', [
377 { title
: 'IP address', name
: 'f_ddnsx_ip', type
: 'select',
379 ['', 'Use WAN IP Address ' + ddnsx_ip
+ ' (recommended)'],
380 ['@', 'Use External IP Address Checker (every 10 minutes)'],
381 ['0.0.0.0', 'Offline (0.0.0.0)'],
382 ['1.1.1.1', 'Offline (1.1.1.1)'],
383 ['10.1.1.1', 'Offline (10.1.1.1)'],
384 ['custom', 'Custom IP Address...']
386 value
: a
? 'custom' : nvram
.ddnsx_ip
},
387 { title
: 'Custom IP address', indent
: 2, name
: 'f_custom_ip', type
: 'text', maxlen
: 15, size
: 20,
388 value
: a
? nvram
.ddnsx_ip
: '', hidden
: !a
},
389 { 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) }
395 <script type='text/javascript'
>
396 a
= nvram
.wan_dns
.split(/\s+/);
397 for (i
= 0; i
< a
.length
; ++i
) {
398 for (j
= 0; j
< opendns
.length
; ++j
) {
399 if (a
[i
] == opendns
[j
]) ++opendnsInUse
;
403 if (nvram
.dns_addget
== 1) {
404 dns
= nvram
.wan_dns
+ ' ' + nvram
.wan_get_dns
;
406 else if (nvram
.wan_dns
!= '') {
410 dns
= nvram
.wan_get_dns
;
412 dns
= dns
.split(/\s+/);
413 for (i
= 0; i
< dns
.length
; ++i
) {
414 for (j
= 0; j
< opendns
.length
; ++j
) {
415 if (dns
[i
] == opendns
[j
]) {
416 dns
[i
] = '<i>' + dns
[i
] + '</i>';
421 dns
= dns
.join(', ');
423 for (i
= 0; i
< 2; ++i
) {
424 v
= nvram
['ddnsx' + i
].split('<');
425 if (v
.length
!= 7) v
= ['', '', '', 0, '', 0, ''];
428 if (u
.length
!= 2) u
= ['', ''];
431 W('<div class="section-title">Dynamic DNS ' + (i
+ 1) + '</div><div class="section">');
432 createFieldTable('', [
433 { title
: 'Service', name
: 'f_service' + i
, type
: 'select', options
: services
, value
: v
[0] },
434 { title
: 'URL', indent
: 2, text
: '<a href="" id="url' + i
+ '" target="tomato-ext-ddns"></a>', hidden
: 1 },
435 { title
: ' ', text
: '<small>* This service determines the IP address using its own method.</small>', hidden
: 1, rid
: 'row_z' + i
},
436 { title
: 'Hostname', name
: 'f_hosttop' + i
, type
: 'text', maxlen
: 96, size
: 35, value
: v
[2], hidden
: 1 },
437 { title
: 'Username', name
: 'f_user' + i
, type
: 'text', maxlen
: 64, size
: 35, value
: u
[0], hidden
: 1 },
438 { title
: 'Password', name
: 'f_pass' + i
, type
: 'password', maxlen
: 64, size
: 35, peekaboo
: 1, value
: u
[1], hidden
: 1 },
439 { title
: 'Hostname', name
: 'f_host' + i
, type
: 'text', maxlen
: 255, size
: 80, value
: v
[2], hidden
: 1 },
440 { title
: 'URL', name
: 'f_cust' + i
, type
: 'text', maxlen
: 255, size
: 80, value
: v
[6], hidden
: 1 },
441 { title
: ' ', text
: '(Use @IP for the current IP address)', rid
: ('custmsg' + i
), hidden
: 1 },
442 { title
: 'Wildcard', indent
: 2, name
: 'f_wild' + i
, type
: 'checkbox', value
: v
[3] != '0', hidden
: 1 },
443 { title
: 'MX', name
: 'f_mx' + i
, type
: 'text', maxlen
: 32, size
: 35, value
: v
[4], hidden
: 1 },
444 { title
: 'Backup MX', indent
: 2, name
: 'f_bmx' + i
, type
: 'checkbox', value
: v
[5] != '0', hidden
: 1 },
445 { title
: 'Use as DNS', name
: 'f_opendns' + i
, type
: 'checkbox', value
: (opendnsInUse
== opendns
.length
),
446 suffix
: '<br><small>(Current DNS: ' + dns
+ ')</small>', hidden
: 1 },
447 { title
: 'Token / URL', name
: 'f_afraid' + i
, type
: 'text', maxlen
: 255, size
: 80, value
: v
[6], hidden
: 1 },
448 { title
: 'Save state when IP changes (nvram commit)', name
: 'f_ddnsx_save' + i
, type
: 'checkbox', value
: nvram
.ddnsx_save
== '1', hidden
: 1 },
449 { title
: 'Force next update', name
: 'f_force' + i
, type
: 'checkbox', value
: 0, hidden
: 1 },
451 { title
: 'Last IP Address', custom
: msgLoc(ddnsx_last
[i
]), rid
: 'last-update' + i
, hidden
: 1 },
452 { title
: 'Last Result', custom
: msgLoc(ddnsx_msg
[i
]), rid
: 'last-response' + i
, hidden
: h
}
462 <tr><td id='footer' colspan=
2>
463 <span id='footer-msg'
></span>
464 <input type='button' value='Save' id='save-button' onclick='save()'
>
465 <input type='button' value='Cancel' id='cancel-button' onclick='reloadPage();'
>
468 <script type='text/javascript'
>verifyFields(null, 1);</script>