3 /* using prototype.js */
7 /* a is assumed to be a 4-items array text.split('.') */
8 function arr_to_int (as) {
9 /*a=as.map(parseInt);*/
10 a=as.map( function (x) { return parseInt(x) & 0xff;} );
11 return (a[0]<<24) | (a[1]<<16) | (a[2]<<8) | a[3];
13 function int_to_arr (n) {
15 a[0]=(n&0xff000000)>>>24;
16 a[1]=(n&0x00ff0000)>>>16;
17 a[2]=(n&0x0000ff00)>>>8;
18 a[3]=(n&0x000000ff)>>>0;
22 function int_to_bits (n) {
24 for (var i=0; i<32; i++) {
31 function mask (masklen) {
32 return ( 0xffffffff<<(32-masklen));
35 // input is the user-typed text
36 // return the number of bits in the mask (like 24 for a /24) or -1 if the mask is wrong
37 function get_masklen (netmask) {
38 var a = netmask.split('.');
39 if ( IPCheckerAtom (netmask,'netmask')) return -1;
40 var n = arr_to_int (a);
41 var bits = int_to_bits (n);
43 while (bits[masklen] && masklen<32 ) masklen++;
44 // masklen holds the number of consecutive bits; just need to check
45 var n_mask = mask(masklen);
46 return (n == n_mask) ? masklen : -1;
49 // returns network and broadcast from ip and masklen
50 function get_derived (n,masklen) {
51 var n_mask = mask(masklen);
53 r[0]=int_to_arr(n&n_mask).join(".");
54 r[1]=int_to_arr(n|~n_mask).join(".");
58 function same_subnet (ip1,ip2,masklen) {
59 var n1=arr_to_int(ip1.split("."));
60 var n2=arr_to_int(ip2.split("."));
61 return (n1&mask(masklen)) == (n2 & mask(masklen));
64 //////////////////// basic chackers
65 function IPCheckerAtom (ip,id) {
66 if ( ! ip ) return "Empty field " + id;
68 if ( ip_a.length != 4) return "Invalid IP (" + id + ") "+ ip;
69 for (var i=0; i<4; i++) if (ip_a[i]<0 || ip_a[i]>256) return "Invalid IP (" + id + ") "+ ip;
73 function IPCheckerSilent (id) { return IPCheckerAtom ( $(id).value, id); }
75 function netmaskCheckerSilent (id) {
76 var netmask=$(id).value;
77 var check_ip = IPCheckerAtom (netmask,'netmask');
78 if (check_ip) return check_ip;
79 var masklen = get_masklen (netmask);
80 if (masklen <= 0) return "Invalid netmask " + netmask;
84 // focus on the field to check, other ones checked already
85 function subnetChecker(id, optional) {
86 var error= subnetCheckerSilent($(id).value);
88 Form.Element.focus($(id));
93 function subnetCheckerSilent (id, optional) {
95 var subnet=$(id).value;
96 // skip this field if optional
97 if (optional && (subnet=="")) return "";
98 var check_ip = IPCheckerAtom (subnet,id);
99 if (check_ip) return check_ip;
101 var masklen = get_masklen ($('netmask').value);
102 if (masklen < 0) return "Could not check " + id;
104 var ip=$('ip').value;
106 if ( ! same_subnet (ip,subnet,masklen) )
107 return id + ' ' + subnet + ' is not in the /' + masklen + ' subnet range';
112 function macChecker(id, optional) {
113 var error= macCheckerSilent($(id).value);
115 Form.Element.focus($(id));
120 function macCheckerSilent(macAdd) {
121 var RegExPattern = /^[0-9a-fA-F:]+$/;
123 if (!(macAdd.match(RegExPattern)) || macAdd.length != 17) {
124 return "Invalid MAC Address";
131 // updates broadcast & network from IP and netmask, as long as they are reasonably set
132 function networkHelper () {
133 var ip=$('ip').value;
134 var netmask=$('netmask').value;
136 /* don't trigger if the input does not make sense */
137 if (IPCheckerAtom (ip,'ip')) return;
138 if (IPCheckerAtom (netmask,'netmask')) return;
141 var masklen=get_masklen (netmask);
142 if (masklen <= 0) return;
144 var ip_a = ip.split('.');
145 var ip_n=arr_to_int(ip_a);
146 var derived = get_derived(ip_n,masklen);
148 $('network').value=derived[0];
149 $('broadcast').value=derived[1];
152 // disable/enable input fields according to the selected method
153 function updateMethodFields() {
154 var method=$('method');
155 var index = method.selectedIndex;
156 var selectedText = method[index].text;
157 var is_static = selectedText == 'Static';
158 var is_tap = selectedText == 'TUN/TAP';
160 $('netmask').disabled= !is_static;
161 $('network').disabled= !is_static;
162 $('gateway').disabled= !is_static && !is_tap;
163 $('broadcast').disabled= !is_static;
164 $('dns1').disabled= !is_static;
165 $('dns2').disabled= !is_static;
168 // check inputs and prevent submit in case s/t is wrong
169 function interfaceSubmit () {
171 var method=$('method');
172 var index = method.selectedIndex;
173 var selectedText = method[index].text;
174 var is_static = selectedText == 'Static';
175 var is_tap = selectedText == 'TUN/TAP';
180 error = IPCheckerSilent ('ip'); if (error) errors += error + "\n" ;
181 if ( ! $('netmask').disabled ) { error = netmaskCheckerSilent ('netmask'); if (error) errors += error + "\n" ; }
182 if ( ! $('network').disabled ) { error = IPCheckerSilent ('network'); if (error) errors += error + "\n" ; }
183 if ( ! $('gateway').disabled ) { error = subnetCheckerSilent ('gateway',false); if (error) errors += error + "\n" ; }
184 if ( ! $('broadcast').disabled ) { error = subnetCheckerSilent ('broadcast',false); if (error) errors += error + "\n" ; }
186 if ( ! errors.length) {
189 alert("-- Cannot create interface --\n" + errors);
194 function updateVirtualArea () {
195 var is_virtual=$('virtual').checked;
196 $('ifname').disabled = ! is_virtual;
197 $('alias').disabled = ! is_virtual;
200 Event.observe(window, 'load', updateMethodFields);
201 Event.observe(window, 'load', updateVirtualArea);