make 'mac' field on an interface editable.
[plewww.git] / planetlab / nodes / interface.js
1 /* $Id$ */
2
3 /* using prototype.js */
4
5 /* disable/enable input fields according to the selected method */
6 function updateMethodFields() {
7   var method=$('method');
8   var index = method.selectedIndex;
9   var selectedText = method[index].text;
10
11   var is_static = selectedText == 'Static';
12   var is_tap = selectedText == 'TUN/TAP';
13
14   $('netmask').disabled= !is_static;
15   $('network').disabled= !is_static;
16   $('gateway').disabled= !is_static && !is_tap;
17   $('broadcast').disabled= !is_static;
18   $('dns1').disabled= !is_static;
19   $('dns2').disabled= !is_static;
20 }
21
22 /* updates broadcast & network from IP and netmask, as long as they are reasonably set */
23
24 /* a is assumed to be a 4-items array text.split('.') */
25 function arr_to_int (as) {
26   /*a=as.map(parseInt);*/
27   a=as.map( function (x) { return parseInt(x) & 0xff;} );
28   return (a[0]<<24) | (a[1]<<16) | (a[2]<<8) | a[3];
29 }
30 function int_to_arr (n) {
31   var a=[];
32   a[0]=(n&0xff000000)>>>24;
33   a[1]=(n&0x00ff0000)>>>16;
34   a[2]=(n&0x0000ff00)>>>8;
35   a[3]=(n&0x000000ff)>>>0;
36   return a;
37 }
38
39 function int_to_bits (n) {
40   var a=[];
41   for (var i=0; i<32; i++) {
42     a[31-i]=n&1;
43     n=n>>>1;
44   }
45   return a;
46 }
47
48 function mask (masklen) {
49   return ( 0xffffffff<<(32-masklen));
50 }
51
52 // input is the user-typed text
53 // return the number of bits in the mask (like 24 for a /24) or -1 if the mask is wrong
54 function get_masklen (nm) {
55   var a = nm.split('.');
56   if ( 4 != a.length ) return -1;
57   var n = arr_to_int (a);
58   var bits = int_to_bits (n);
59   var masklen=0;
60   while (bits[masklen] && masklen<32 ) masklen++;
61   // masklen holds the number of consecutive bits; just need to check
62   var n_mask = mask(masklen);
63   return (n == n_mask) ? masklen : -1;
64 }
65
66
67 // returns network and broadcast from ip and masklen
68 function get_derived (n,masklen) {
69   var n_mask = mask(masklen);
70   var r=[];
71   r[0]=int_to_arr(n&n_mask).join(".");
72   r[1]=int_to_arr(n|~n_mask).join(".");
73   return r;
74 }
75
76 function same_subnet (ip1,ip2,masklen) {
77   var n1=arr_to_int(ip1.split("."));
78   var n2=arr_to_int(ip2.split("."));
79   return (n1&mask(masklen)) == (n2 & mask(masklen));
80 }
81
82 function networkHelper () {
83   window.console.log('networkHelper');
84   var ip=$('ip').value;
85   var nm=$('netmask').value;
86
87   var ip_a = ip.split('.');
88   var nm_a = ip.split('.');
89   
90   /* don't trigger if the input does not make sense */
91   if (ip_a.length != 4) return; 
92   if (ip_a[3] == "") return;
93   if (nm_a.length != 4) return; 
94   if (nm_a[3] == "") return;
95   
96   /*check netmask*/
97   var masklen=get_masklen (nm);
98   if (masklen < 0) return;
99
100   var ip_n=arr_to_int(ip_a);
101   var derived = get_derived(ip_n,masklen);
102
103   $('network').value=derived[0];
104   $('broadcast').value=derived[1];
105 }
106
107 function macChecker(id, optional) {
108   var error= macCheckerSilent($(id).value);
109   if (error) {
110     Form.Element.focus($(id));
111     alert(error);
112   }
113 }
114
115 function macCheckerSilent(macAdd) {
116         var RegExPattern = /^[0-9a-fA-F:]+$/;
117  
118         if (!(macAdd.match(RegExPattern)) || macAdd.length != 17) 
119         {
120                 return "Invalid MAC Address";
121         } else {
122                 return "";
123         }
124 }
125
126 /* check one */
127 function subnetChecker (id, optional) {
128   var error= subnetCheckerSilent([id,optional]);
129   if (error) {
130     Form.Element.focus($(id));
131     alert(error);
132   }
133 }
134
135 function subnetCheckerSilent (args) {
136   
137   id=args[0];
138   optional=args[1];
139
140   var ip2=$(id).value;
141   if (optional && (ip2=="")) return "";
142   if ( ip2.split(".").length != 4) return "Inconsistent value for " + id;
143
144   var masklen = get_masklen ($('netmask').value);
145   if (masklen < 0) return "Inconsistent netmask";
146
147   var ip=$('ip').value;
148   if ( ip.split(".").length != 4) return "Inconsistent IP";
149
150   if ( ! same_subnet (ip,ip2,masklen) ) 
151     return id + ' ' + ip2 + ' is not in the /' + masklen + ' subnet range';
152   
153   return "";
154 }
155
156 function interfaceSubmit () {
157   alert ('submitting');
158   // get error strings, and remove the empty ones
159   // dns2 is optional
160   var errors=['gateway','dns1','dns2'].zip ([true,true,false],subnetCheckerSilent).reject( function (s) {return s.length==0;} );
161   if ( ! errors.length)
162     $('ip').up('form').submit();
163   else
164     alert(errors.join("\n"));
165 }