├── .gitignore ├── Gruntfile.js ├── LICENSE ├── README.md ├── dist └── networksim.min.js ├── examples └── data01.json ├── img ├── 64 │ ├── add.png │ ├── computer.png │ ├── delete.png │ ├── edit.png │ ├── envelope-DHCP.png │ ├── envelope-DNS.png │ ├── envelope-HTTP.png │ ├── envelope-ICMP.png │ ├── i18n.png │ ├── inspect.png │ ├── link.png │ ├── minus.png │ ├── playpause.png │ ├── plus.png │ ├── right-arrow.png │ ├── router2.png │ ├── save.png │ ├── server_dhcp.png │ ├── server_dns.png │ ├── server_web.png │ ├── switch.png │ └── upload.png ├── add.png ├── computer.png ├── delete.png ├── edit.png ├── envelope-DHCP.png ├── envelope-DNS.png ├── envelope-HTTP.png ├── envelope-ICMP.png ├── envelope.png ├── fondo boton.png ├── i18n.png ├── inspect.png ├── link.png ├── minus.png ├── minus.png~ ├── playpause.png ├── playpause.png~ ├── plus.png ├── right-arrow.png ├── router.png ├── save.png ├── server_dhcp.png ├── server_dns.png ├── server_web.png ├── switch.png └── upload.png ├── js ├── .directory ├── AnimationControls.js ├── Connectable.js ├── Connector.js ├── DHCPClient.js ├── DHCPServer.js ├── DNSClient.js ├── DNSServer.js ├── Drawable.js ├── GatewayManager.js ├── Globals.js ├── HTTPClient.js ├── HTTPServer.js ├── Host.js ├── IPInfo.js ├── ImageLoader.js ├── Link.js ├── Message.js ├── Network.js ├── TrafficManager.js ├── UIClickable.js ├── UILine.js ├── UIManager.js ├── UIMenu.js ├── UIRectangle.js ├── UITable.js ├── UITranslation.js ├── UIWindow.js ├── i18n │ ├── .directory │ ├── en_GB.js │ ├── es_ES.js │ └── eu_ES.js └── simulator.js ├── materials ├── design │ └── design.xmi ├── ideas │ ├── info.txt │ └── rerouting.txt └── snapshots │ ├── snapshot01.png │ ├── snapshot02.png │ ├── snapshot03.png │ ├── snapshot04.png │ ├── snapshot05.png │ ├── snapshot06.png │ ├── snapshot07.png │ ├── snapshot08.png │ ├── snapshot09.png │ ├── snapshot10.png │ ├── snapshot11.png │ ├── snapshot12.png │ ├── snapshot13.png │ ├── snapshot14.png │ ├── snapshot15.png │ ├── snapshot16.png │ └── snapshot17.png ├── notes.txt ├── package.json ├── simulator.html ├── simulator01.html ├── simulatordev.html └── simulatorteacher.html /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | 3 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt){ 2 | 3 | grunt.initConfig({ 4 | pkg: grunt.file.readJSON('package.json'), 5 | uglify: { 6 | options: { 7 | mangle: true 8 | }, 9 | my_target: { 10 | files: { 11 | 'dist/networksim.min.js': ['js/**/*.js'] 12 | } 13 | } 14 | } 15 | }); 16 | 17 | grunt.loadNpmTasks('grunt-contrib-uglify'); 18 | grunt.registerTask('default', ['uglify']); 19 | 20 | }; 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NetworkSimulator 2 | Educational Network Simulator Project 3 | 4 | Check out the project's webpage at: http://projects.bardok.net/educational-network-simulator/ 5 | 6 | (c) 2015 Jorge García Ochoa de Aspuru 7 | 8 | bardok@gmail.com 9 | 10 | @bardok 11 | 12 | This project is covered by GPLv3 license. 13 | -------------------------------------------------------------------------------- /img/64/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/add.png -------------------------------------------------------------------------------- /img/64/computer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/computer.png -------------------------------------------------------------------------------- /img/64/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/delete.png -------------------------------------------------------------------------------- /img/64/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/edit.png -------------------------------------------------------------------------------- /img/64/envelope-DHCP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/envelope-DHCP.png -------------------------------------------------------------------------------- /img/64/envelope-DNS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/envelope-DNS.png -------------------------------------------------------------------------------- /img/64/envelope-HTTP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/envelope-HTTP.png -------------------------------------------------------------------------------- /img/64/envelope-ICMP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/envelope-ICMP.png -------------------------------------------------------------------------------- /img/64/i18n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/i18n.png -------------------------------------------------------------------------------- /img/64/inspect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/inspect.png -------------------------------------------------------------------------------- /img/64/link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/link.png -------------------------------------------------------------------------------- /img/64/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/minus.png -------------------------------------------------------------------------------- /img/64/playpause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/playpause.png -------------------------------------------------------------------------------- /img/64/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/plus.png -------------------------------------------------------------------------------- /img/64/right-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/right-arrow.png -------------------------------------------------------------------------------- /img/64/router2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/router2.png -------------------------------------------------------------------------------- /img/64/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/save.png -------------------------------------------------------------------------------- /img/64/server_dhcp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/server_dhcp.png -------------------------------------------------------------------------------- /img/64/server_dns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/server_dns.png -------------------------------------------------------------------------------- /img/64/server_web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/server_web.png -------------------------------------------------------------------------------- /img/64/switch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/switch.png -------------------------------------------------------------------------------- /img/64/upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/64/upload.png -------------------------------------------------------------------------------- /img/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/add.png -------------------------------------------------------------------------------- /img/computer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/computer.png -------------------------------------------------------------------------------- /img/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/delete.png -------------------------------------------------------------------------------- /img/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/edit.png -------------------------------------------------------------------------------- /img/envelope-DHCP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/envelope-DHCP.png -------------------------------------------------------------------------------- /img/envelope-DNS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/envelope-DNS.png -------------------------------------------------------------------------------- /img/envelope-HTTP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/envelope-HTTP.png -------------------------------------------------------------------------------- /img/envelope-ICMP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/envelope-ICMP.png -------------------------------------------------------------------------------- /img/envelope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/envelope.png -------------------------------------------------------------------------------- /img/fondo boton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/fondo boton.png -------------------------------------------------------------------------------- /img/i18n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/i18n.png -------------------------------------------------------------------------------- /img/inspect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/inspect.png -------------------------------------------------------------------------------- /img/link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/link.png -------------------------------------------------------------------------------- /img/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/minus.png -------------------------------------------------------------------------------- /img/minus.png~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/minus.png~ -------------------------------------------------------------------------------- /img/playpause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/playpause.png -------------------------------------------------------------------------------- /img/playpause.png~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/playpause.png~ -------------------------------------------------------------------------------- /img/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/plus.png -------------------------------------------------------------------------------- /img/right-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/right-arrow.png -------------------------------------------------------------------------------- /img/router.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/router.png -------------------------------------------------------------------------------- /img/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/save.png -------------------------------------------------------------------------------- /img/server_dhcp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/server_dhcp.png -------------------------------------------------------------------------------- /img/server_dns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/server_dns.png -------------------------------------------------------------------------------- /img/server_web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/server_web.png -------------------------------------------------------------------------------- /img/switch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/switch.png -------------------------------------------------------------------------------- /img/upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/img/upload.png -------------------------------------------------------------------------------- /js/.directory: -------------------------------------------------------------------------------- 1 | [Dolphin] 2 | HeaderColumnWidths=182,87,95 3 | Timestamp=2018,3,4,16,28,25 4 | Version=4 5 | ViewMode=1 6 | -------------------------------------------------------------------------------- /js/AnimationControls.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | var AnimationControls = 15 | { 16 | MSG_ADVANCE_PRE: 0, 17 | MSG_ADVANCE: 2, 18 | controlsWindow: null, 19 | setSpeed: function(multiplier) 20 | { 21 | this.MSG_ADVANCE *= multiplier; 22 | if (this.MSG_ADVANCE > 16) 23 | { 24 | this.MSG_ADVANCE = 16; 25 | } 26 | else if (this.MSG_ADVANCE < 0.125) 27 | { 28 | this.MSG_ADVANCE = 0.125; 29 | } 30 | }, 31 | playPause: function() 32 | { 33 | var tmp = this.MSG_ADVANCE; 34 | this.MSG_ADVANCE = this.MSG_ADVANCE_PRE; 35 | this.MSG_ADVANCE_PRE = tmp; 36 | } 37 | }; 38 | 39 | function createControlsWindow() 40 | { 41 | AnimationControls.controlsWindow = new UIWindow("controlswindow", "Animation Controls", 200, 50,false,1.0); 42 | var pos = AnimationControls.controlsWindow.getPos(); 43 | AnimationControls.controlsWindow.setPos(pos.x, 5); 44 | 45 | var controls = 'Slow'; 46 | controls += 'Play/Pause'; 47 | controls += 'Fast'; 48 | 49 | AnimationControls.controlsWindow.setControls(controls); 50 | 51 | AnimationControls.controlsWindow.render(); 52 | } -------------------------------------------------------------------------------- /js/Connectable.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | var Connectable = function(c_owner, macmode, ipmode, limitbroadcast, performNAT) 15 | { 16 | this.id = getNextID(); 17 | var connectors = []; 18 | var macaddresses = []; 19 | var ipinfos = []; 20 | var macmode = macmode; 21 | var ipmode = ipmode; 22 | var trafficManager = null; 23 | var ARPtable = []; 24 | var addressingTable = []; 25 | var performNAT = performNAT; 26 | var gateways = null; 27 | 28 | var _self = this; 29 | var owner = c_owner; 30 | 31 | this.save = function() 32 | { 33 | var result = {}; 34 | result.version = 1; 35 | result.id = this.id; 36 | result.connectors = []; 37 | result.macaddresses = []; 38 | result.ipinfos = []; 39 | result.macmode = macmode; 40 | result.ipmode = ipmode; 41 | result.trafficManager = trafficManager.save(); 42 | result.gateways = gateways.save(); 43 | result.performNAT = performNAT; 44 | 45 | for (var i = 0; i < connectors.length; i++) 46 | { 47 | result.connectors.push(connectors[i].save()); 48 | } 49 | 50 | result.macaddresses = macaddresses; 51 | 52 | for (var i = 0; i < ipinfos.length; i++) 53 | { 54 | result.ipinfos.push(ipinfos[i].save()); 55 | } 56 | 57 | return result; 58 | }; 59 | 60 | this.load = function(data) 61 | { 62 | this.id = data.id; 63 | for (var i = 0; i < data.connectors.length; i++) 64 | { 65 | connectors[i].load(data.connectors[i]); 66 | } 67 | macaddresses = data.macaddresses; 68 | for (var i = 0; i < data.ipinfos.length; i++) 69 | { 70 | ipinfos[i].load(data.ipinfos[i]); 71 | } 72 | macmode = data.macmode; 73 | ipmode = data.ipmode; 74 | if (typeof data.performNAT !== 'undefined') 75 | { 76 | this.setPerformNAT(data.performNAT); 77 | } 78 | trafficManager.load(data.trafficManager); 79 | gateways.load(data.gateways ? data.gateways : null); 80 | }; 81 | 82 | this.updateAddressing = function(mac, ifacepos) 83 | { 84 | addressingTable[mac] = ifacepos; 85 | }; 86 | 87 | /*this.getDstMAC = function(ifacepos, ip) 88 | { 89 | var result = null; 90 | 91 | // Si es broadcast 92 | if (ip == "255.255.255.255") 93 | { 94 | result = "FF:FF:FF:FF:FF:FF"; 95 | } 96 | // Si es de mi red, pido la MAC de esa IP 97 | else if (this.getIPInfo(ifacepos).sameNetwork(ip)) 98 | { 99 | result = this.getMACforIP(ip); 100 | } 101 | // Si no es de mi red, pido la MAC de la IP de mi GW 102 | else 103 | { 104 | result = this.getMACforIP(this.getIPInfo(ifacepos).getGateway()); 105 | } 106 | return result; 107 | };*/ 108 | 109 | this.isInMyNetworks = function(ip) 110 | { 111 | var result = false; 112 | var i = 0; 113 | 114 | while ((result === false) && (i < connectors.length)) 115 | { 116 | var ipinfo = this.getIPInfo(i); 117 | if (ipinfo.getIPv4() != null) 118 | { 119 | result = ipinfo.sameNetwork(ip); 120 | i++; 121 | } 122 | } 123 | 124 | return result; 125 | }; 126 | 127 | this.getDstMAC = function(ip) 128 | { 129 | var result = null; 130 | 131 | // Si es broadcast 132 | if (ip == "255.255.255.255") 133 | { 134 | result = "FF:FF:FF:FF:FF:FF"; 135 | } 136 | // Si es de la red de alguna de mis interfaces, pido la MAC de esa IP 137 | else if (this.isInMyNetworks(ip)) 138 | { 139 | result = this.findMACforIP(ip, null); 140 | } 141 | // Si no es de mi red, pido la MAC de la IP del GW de esa IP. 142 | else 143 | { 144 | result = this.findMACforIP(gateways.getGatewayForIP(ip, null)); 145 | } 146 | return result; 147 | }; 148 | 149 | this.findMACforIP = function(ip, exclude) 150 | { 151 | var result = null; 152 | if (ip !== null) 153 | { 154 | var i = 0; 155 | while ((result === null) && (i < connectors.length)) 156 | { 157 | if (connectors[i] !== exclude) 158 | { 159 | var c = connectors[i].getConnectedConnector(); 160 | if (c !== null) 161 | { 162 | // Si el conector no tiene IP, o es de la misma subred que la ip solicitada... 163 | var nextip = c.getIPInfo(); 164 | if ((nextip === null) || nextip.sameNetwork(ip)) 165 | { 166 | result = c.whoHas(ip); 167 | if (result !== null) 168 | { 169 | ARPtable[ip] = result; 170 | addressingTable[result] = i; 171 | } 172 | } 173 | } 174 | } 175 | i++; 176 | } 177 | } 178 | return result; 179 | }; 180 | 181 | function addNewMAC() 182 | { 183 | var chars = "0123456789ABCDEF"; 184 | var mac = ""; 185 | 186 | for (var i = 0; i < 12; i++) 187 | { 188 | mac += chars.charAt(Math.floor(Math.random() * chars.length)); 189 | if ((i % 2 == 1) && (i !== 11)) 190 | { 191 | mac += ":"; 192 | } 193 | } 194 | 195 | macaddresses.push(mac); 196 | } 197 | 198 | function addNewIPInfo() 199 | { 200 | ipinfos.push(new IPInfo()); 201 | } 202 | 203 | function init() 204 | { 205 | trafficManager = new TrafficManager(_self, limitbroadcast, performNAT); 206 | gateways = new GatewayManager(_self); 207 | if (macmode === MACMODE_SHARED) 208 | { 209 | addNewMAC(); 210 | } 211 | if (ipmode === IPMODE_SHARED) 212 | { 213 | addNewIPInfo(); 214 | } 215 | } 216 | 217 | this.getTrafficManager = function() 218 | { 219 | return trafficManager; 220 | }; 221 | 222 | this.getGatewayManager = function() 223 | { 224 | return gateways; 225 | }; 226 | 227 | this.addConnector = function(connector) { 228 | connectors.push(connector); 229 | if (macmode === MACMODE_UNIQUE) 230 | { 231 | addNewMAC(); 232 | } 233 | if (ipmode === IPMODE_UNIQUE) 234 | { 235 | addNewIPInfo(); 236 | } 237 | }; 238 | 239 | this.removeConnector = function(pos) { 240 | connectors.slice(pos, 1); 241 | }; 242 | 243 | this.getConnector = function(pos) { 244 | return connectors[pos]; 245 | }; 246 | 247 | this.getConnectorNumber = function() { 248 | return connectors.length; 249 | }; 250 | 251 | this.getOwner = function() 252 | { 253 | return owner; 254 | }; 255 | 256 | this.getMAC = function(pos) 257 | { 258 | var result = null; 259 | if (pos < macaddresses.length) 260 | { 261 | if (macmode === MACMODE_SHARED) 262 | { 263 | pos = 0; 264 | } 265 | result = macaddresses[pos]; 266 | } 267 | return result; 268 | } 269 | 270 | this.getIPInfo = function(pos) 271 | { 272 | var result = null; 273 | if (pos < ipinfos.length) 274 | { 275 | if (ipmode === IPMODE_SHARED) 276 | { 277 | pos = 0; 278 | } 279 | result = ipinfos[pos]; 280 | } 281 | return result; 282 | } 283 | 284 | this.getFirstFreeConnector = function() 285 | { 286 | var result = false; 287 | var i = 0; 288 | while (result === false && i < connectors.length) 289 | { 290 | if (!connectors[i].isConnected()) 291 | { 292 | result = connectors[i]; 293 | } 294 | else 295 | { 296 | i++; 297 | } 298 | } 299 | 300 | return result; 301 | }; 302 | 303 | this.compatibleIP = function(ip, allowBroadcast) 304 | { 305 | // Broadcast o alguna de las IPs de la lista 306 | var result = allowBroadcast && this.compatibleBroadcastIP(ip); 307 | 308 | if (!result) 309 | { 310 | var i = 0; 311 | while (!result && i < ipinfos.length) 312 | { 313 | result = ipinfos[i].getIPv4() === ip; 314 | i++; 315 | } 316 | } 317 | 318 | return result; 319 | }; 320 | 321 | this.compatibleBroadcastIP = function(ip) 322 | { 323 | // En esta versión sólo aceptamos ésta dir de Broadcast 324 | return ip === "255.255.255.255"; 325 | }; 326 | 327 | this.compatibleMAC = function(mac, allowBroadcast) 328 | { 329 | // Broadcast o alguna de las MACs de la lista 330 | var result = allowBroadcast && this.compatibleBroadcastMAC(mac); 331 | 332 | if (!result) 333 | { 334 | var i = 0; 335 | while (!result && i < macaddresses.length) 336 | { 337 | result = macaddresses[i] === mac; 338 | i++; 339 | } 340 | } 341 | 342 | return result; 343 | }; 344 | 345 | this.compatibleBroadcastMAC = function(mac) 346 | { 347 | // En esta versión sólo aceptamos ésta dir de Broadcast 348 | return mac === "FF:FF:FF:FF:FF:FF"; 349 | }; 350 | 351 | this.getConnectorPos = function(connector) 352 | { 353 | return connectors.indexOf(connector); 354 | }; 355 | 356 | this.getIpMode = function() 357 | { 358 | return ipmode; 359 | }; 360 | 361 | this.getSenderConnectorForMAC = function(mac) 362 | { 363 | var result = null; 364 | 365 | if (mac in addressingTable) 366 | { 367 | result = connectors[addressingTable[mac]]; 368 | } 369 | 370 | return result; 371 | }; 372 | 373 | this.findConnector = function(id) 374 | { 375 | var result = null; 376 | var i = 0; 377 | while ((result === null) && (i < connectors.length)) 378 | { 379 | if (connectors[i].id === id) 380 | { 381 | result = connectors[i]; 382 | } 383 | i++; 384 | } 385 | 386 | return result; 387 | }; 388 | 389 | this.getPerformNAT = function() 390 | { 391 | return performNAT; 392 | }; 393 | 394 | this.setPerformNAT = function(pnat) 395 | { 396 | performNAT = pnat; 397 | trafficManager.setPerformNAT(pnat); 398 | }; 399 | 400 | init(); 401 | }; 402 | -------------------------------------------------------------------------------- /js/Connector.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | var Connector = function(connectable) 15 | { 16 | this.id = getNextID(); 17 | var connectable = connectable; 18 | var link = null; 19 | var _self = this; 20 | 21 | this.save = function() 22 | { 23 | var result = {}; 24 | result.version = 1; 25 | result.id = this.id; 26 | 27 | return result; 28 | }; 29 | 30 | this.load = function(data) 31 | { 32 | this.id = data.id; 33 | }; 34 | 35 | function init() { 36 | connectable.addConnector(_self); 37 | } 38 | 39 | this.setLink = function(l) { 40 | link = l; 41 | }; 42 | 43 | this.getLink = function() 44 | { 45 | return link; 46 | }; 47 | 48 | this.send = function(message) 49 | { 50 | if ((link != null) && (message.canSend())) 51 | { 52 | link.addMessage(_self, message); 53 | } 54 | }; 55 | 56 | this.receive = function(message) 57 | { 58 | connectable.getTrafficManager().proccess(this, message); 59 | }; 60 | 61 | this.getConnectable = function() 62 | { 63 | return connectable; 64 | }; 65 | 66 | this.isConnected = function() 67 | { 68 | return link !== null; 69 | }; 70 | 71 | this.getConnectedConnector = function() 72 | { 73 | var result = null; 74 | if (this.isConnected()) 75 | { 76 | result = (link.getConnector1() !== this) ? link.getConnector1() : link.getConnector2(); 77 | } 78 | return result; 79 | }; 80 | 81 | this.getDescription = function() 82 | { 83 | var result = ""; 84 | var cpos = connectable.getConnectorPos(this); 85 | 86 | if (connectable.getOwner().getType() === "router") 87 | { 88 | result += (cpos === ROUTER_LAN) ? "LAN" : "WAN"; 89 | result += ": "; 90 | } 91 | 92 | var ipinfo = connectable.getIPInfo(cpos); 93 | if ((ipinfo !== null) && (ipinfo.getIPv4() !== null)) 94 | { 95 | result += ipinfo.getIPv4(); 96 | } 97 | 98 | return result; 99 | }; 100 | 101 | this.whoHas = function(ip) 102 | { 103 | var result = null; 104 | var pos = connectable.getConnectorPos(this); 105 | var ipinfo = connectable.getIPInfo(pos); 106 | if ((ipinfo !== null) && (ipinfo.getIPv4() === ip)) 107 | { 108 | result = connectable.getMAC(pos); 109 | } 110 | else 111 | { 112 | result = connectable.findMACforIP(ip, this); 113 | } 114 | 115 | return result; 116 | }; 117 | 118 | this.getIPInfo = function() 119 | { 120 | var result = null; 121 | switch (connectable.getIpMode()) 122 | { 123 | case IPMODE_NOIP: 124 | result = null; 125 | break; 126 | case IPMODE_UNIQUE: 127 | var pos = connectable.getConnectorPos(this); 128 | result = connectable.getIPInfo(pos); 129 | break; 130 | case IPMODE_SHARED: 131 | result = connectable.getIPInfo(0); 132 | break; 133 | } 134 | 135 | return result; 136 | }; 137 | 138 | init(); 139 | }; 140 | -------------------------------------------------------------------------------- /js/DHCPClient.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | function requestDHCPInfoCommand(id) 15 | { 16 | var elem = network.getElement(id); 17 | elem.getApp("DHCPClient").requestInfo(); 18 | } 19 | 20 | var DHCPClient = function(ifacepos) 21 | { 22 | var owner = null; 23 | var ifacepos = ifacepos; 24 | var menu = null; 25 | 26 | this.save = function() 27 | { 28 | var result = {}; 29 | result.version = 1; 30 | result.id = this.getId(); 31 | result.ifacepos = ifacepos; 32 | 33 | return result; 34 | }; 35 | 36 | this.load = function(data) 37 | { 38 | }; 39 | 40 | this.getId = function() 41 | { 42 | return "DHCPClient"; 43 | }; 44 | 45 | this.requestInfo = function() 46 | { 47 | var data = {}; 48 | data.type = "request"; 49 | data.description = "DHCP: request"; 50 | var message = new Message( 51 | "tcp", 52 | owner.getConnectable().getIPInfo(ifacepos).getIPv4(), 53 | "255.255.255.255", 54 | owner.getConnectable().getMAC(ifacepos), 55 | "FF:FF:FF:FF:FF:FF", 56 | getDinamycPort(), 57 | 67, 58 | data, 59 | images[IMAGE_ENVELOPEDHCP]); 60 | owner.getConnectable().getTrafficManager().registerApplication(this, message.getOrigPort(), false); 61 | owner.getConnectable().getConnector(ifacepos).send(message); 62 | }; 63 | 64 | this.receiveMessage = function(message) 65 | { 66 | owner.getConnectable().getIPInfo(ifacepos).setIPv4(message.getData().ipv4); 67 | owner.getConnectable().getIPInfo(ifacepos).setDNS1(message.getData().dns1); 68 | owner.getConnectable().getIPInfo(ifacepos).setDNS2(message.getData().dns2); 69 | //owner.getConnectable().getIPInfo(ifacepos).setGateway(message.getData().gateway); 70 | owner.getConnectable().getGatewayManager().addGatewayInfo("0.0.0.0","0.0.0.0",message.getData().gateway); 71 | owner.getConnectable().getIPInfo(ifacepos).setNetmask(message.getData().netmask); 72 | owner.getConnectable().getIPInfo(ifacepos).setStatic(false); 73 | }; 74 | 75 | this.setOwner = function(o) 76 | { 77 | owner = o; 78 | }; 79 | 80 | this.getIfacepos = function() 81 | { 82 | return ifacepos; 83 | }; 84 | 85 | /*this.getAppController = function() 86 | { 87 | var id = network.getPosForElement(owner); 88 | var result = ""; 89 | return result; 90 | };*/ 91 | 92 | this.getMenuEntries = function() 93 | { 94 | var data = []; 95 | data[0] = {}; 96 | data[0].img = 'img/64/envelope-DHCP.png'; 97 | data[0].text = 'Request DHCP info'; 98 | data[0].js = 'requestDHCPInfoCommand('+owner.id+');'; 99 | 100 | return data; 101 | }; 102 | 103 | 104 | this.getAppDescription = function() 105 | { 106 | return ""; 107 | }; 108 | 109 | }; 110 | -------------------------------------------------------------------------------- /js/DHCPServer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | function editDHCPServerInfo(id) 15 | { 16 | createBkDiv(); 17 | createDHCPServerInfoDiv(id); 18 | } 19 | 20 | function createDHCPServerInfoDiv(id) 21 | { 22 | var host = network.getElement(id); 23 | var app = host.getApp("DHCPServer"); 24 | var div = document.createElement("div"); 25 | /*var l = innerWidth / 2 - 200; 26 | var t = innerHeight / 2 - 75; 27 | 28 | div.setAttribute('style', 'position:absolute;top:' + t + 'px;left:' + l + 'px;z-index:110;background-color:white;width:400px;height:150px;border-radius:10px;border:1px solid;padding:10px;text-align:center;'); 29 | div.setAttribute('id', 'divdhcpserverinfo'); 30 | div.innerHTML = app.getAppController(); 31 | div.innerHTML += '

\ 32 | \ 33 | \ 34 |

'; 35 | document.body.appendChild(div);*/ 36 | 37 | var controls = ''; 38 | controls += ''; 39 | 40 | var w = new UIWindow('divdhcpserverinfo', 'DHCP Server', 400, 200, false, 1.0); 41 | w.setContent(app.getAppController()); 42 | w.setControls(controls); 43 | w.render(); 44 | } 45 | 46 | function saveDHCPServerData(id) 47 | { 48 | var elem = network.getElement(id); 49 | var initial = document.getElementById('dhcpinitial').value; 50 | var final = document.getElementById('dhcpend').value; 51 | var gateway = document.getElementById('dhcpgw').value; 52 | var dns1 = document.getElementById('dhcpdns1').value; 53 | var dns2 = document.getElementById('dhcpdns2').value; 54 | elem.getApp("DHCPServer").setData(initial, final, gateway, dns1, dns2); 55 | 56 | removeBodyDiv('divbk'); 57 | uimanager.getWindow("divdhcpserverinfo").dispose(); 58 | } 59 | 60 | function cancelDHCPServerData() 61 | { 62 | removeBodyDiv('divbk'); 63 | uimanager.getWindow("divdhcpserverinfo").dispose(); 64 | } 65 | 66 | var DHCPServer = function(ifacepos) 67 | { 68 | var owner = null; 69 | var ifacepos = ifacepos; 70 | var initial = 100; 71 | var end = 200; 72 | var gateway = null; 73 | var dns1 = null; 74 | var dns2 = null; 75 | var leases = []; 76 | var leasesbymac = []; 77 | 78 | this.save = function() 79 | { 80 | var result = {}; 81 | result.version = 1; 82 | result.id = this.getId(); 83 | result.ifacepos = ifacepos; 84 | result.initial = initial; 85 | result.end = end; 86 | result.gateway = gateway; 87 | result.dns1 = dns1; 88 | result.dns2 = dns2; 89 | 90 | return result; 91 | }; 92 | 93 | this.load = function(data) 94 | { 95 | initial = data.initial; 96 | end = data.end; 97 | gateway = data.gateway; 98 | dns1 = data.dns1; 99 | dns2 = data.dns2; 100 | }; 101 | 102 | this.getId = function() 103 | { 104 | return "DHCPServer"; 105 | }; 106 | 107 | this.setData = function(initial_p, end_p, gateway_p, dns1_p, dns2_p) 108 | { 109 | initial = initial_p; 110 | end = end_p; 111 | gateway = gateway_p; 112 | dns1 = dns1_p; 113 | dns2 = dns2_p; 114 | }; 115 | 116 | function newLease(mac) 117 | { 118 | var result = initial; 119 | var free = false; 120 | while (!free) 121 | { 122 | if (result in leases) 123 | { 124 | result++; 125 | } 126 | else 127 | { 128 | free = true; 129 | } 130 | } 131 | 132 | var ipdata = owner.getConnectable().getIPInfo(ifacepos).getIPv4().split("."); 133 | var ipbase = ipdata[0] + "." + ipdata[1] + "." + ipdata[2] + "."; 134 | var data = {}; 135 | data.mac = mac; 136 | data.ipv4 = ipbase + result 137 | leases[result] = data; 138 | leasesbymac[mac] = data; 139 | return result; 140 | } 141 | 142 | function getExistingLease(mac) 143 | { 144 | var result = null; 145 | if (mac in leasesbymac) 146 | { 147 | result = leases.indexOf(leasesbymac[mac]); 148 | } 149 | 150 | return result; 151 | } 152 | 153 | this.receiveMessage = function(message) 154 | { 155 | if ((message.getData().type === "request") && 156 | (owner.getConnectable().getIPInfo(ifacepos).getIPv4() !== null)) 157 | { 158 | var newip = getExistingLease(message.getOriginMAC()); 159 | if (newip === null) 160 | { 161 | newip = newLease(message.getOriginMAC()); 162 | } 163 | var data = {}; 164 | data.ipv4 = leases[newip].ipv4; 165 | data.dns1 = dns1; 166 | data.dns2 = dns2; 167 | data.gateway = gateway; 168 | data.netmask = owner.getConnectable().getIPInfo(ifacepos).getNetmask(); 169 | data.description = "DHCP: offer"; 170 | var response = new Message( 171 | "tcp", 172 | owner.getConnectable().getIPInfo(ifacepos).getIPv4(), 173 | leases[newip].ipv4, 174 | owner.getConnectable().getMAC(ifacepos), 175 | message.getOriginMAC(), 176 | 67, 177 | message.getOrigPort(), 178 | data, 179 | images[IMAGE_ENVELOPEDHCP] 180 | ); 181 | owner.getConnectable().getConnector(ifacepos).send(response); 182 | } 183 | }; 184 | 185 | /*this.proccessCommand = function(name, args) 186 | { 187 | switch (name) 188 | { 189 | case "setData": 190 | this.setData(args[0], args[1], args[2], args[3], args[4]); 191 | break; 192 | }; 193 | };*/ 194 | 195 | this.setOwner = function(o) 196 | { 197 | owner = o; 198 | }; 199 | 200 | /*this.getCommands = function() 201 | { 202 | var data = []; 203 | 204 | data["setData"] = {}; 205 | data["setData"].name = "setData"; 206 | data["setData"].args = [ 207 | {name: "initial", type: "int"}, 208 | {name: "end", type: "int"}, 209 | {name: "gateway", type: "ip"}, 210 | {name: "dns1", type: "ip"}, 211 | {name: "dns2", type: "ip"} 212 | ]; 213 | 214 | return data; 215 | };*/ 216 | 217 | this.getIfacepos = function() 218 | { 219 | return ifacepos; 220 | }; 221 | 222 | this.getAppController = function() 223 | { 224 | var id = network.getPosForElement(owner); 225 | result = " \ 226 |
\ 227 | \ 228 |
\ 229 | \ 230 |
\ 231 | \ 232 |
\ 233 | \ 234 |
\ 235 | "; 236 | return result; 237 | }; 238 | 239 | this.getMenuEntries = function() 240 | { 241 | var data = []; 242 | 243 | data[0] = {}; 244 | data[0].img = 'img/64/envelope-DHCP.png'; 245 | data[0].text = 'Edit DHCP server info'; 246 | data[0].js = 'editDHCPServerInfo(' + owner.id + ');'; 247 | 248 | return data; 249 | }; 250 | 251 | this.getAppDescription = function() 252 | { 253 | var result = "DNS Server\n"; 254 | result += "Ini: " + initial + "/End: " + end; 255 | result += "/Gateway: " + ((gateway === null)?"- ":gateway); 256 | result += " /DNS 1: " + ((dns1 === null)?"- ":dns1); 257 | result += " /DNS 2: " + ((dns2 === null)?"- ":dns2); 258 | return result; 259 | }; 260 | 261 | }; 262 | -------------------------------------------------------------------------------- /js/DNSClient.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | function createDNSLookup(id) 15 | { 16 | createBkDiv(); 17 | createDNSLookupDiv(id); 18 | } 19 | 20 | function createDNSLookupDiv(id) 21 | { 22 | var host = network.getElement(id); 23 | var app = host.getApp("DNSClient"); 24 | /*var div = document.createElement("div"); 25 | var l = window.innerWidth / 2 - 200; 26 | var t = window.innerHeight / 2 - 75; 27 | 28 | div.setAttribute('style', 'position:absolute;top:' + t + 'px;left:' + l + 'px;z-index:110;background-color:white;width:400px;height:150px;border-radius:10px;border:1px solid;padding:10px;text-align:center;'); 29 | div.setAttribute('id', 'divdnslookup'); 30 | div.innerHTML = app.getAppController();*/ 31 | var controls = '\ 32 | '; 33 | var w = new UIWindow('divdnslookup', 'DNS lookup', 400, 200, false, 1.0); 34 | w.setContent(app.getAppController()); 35 | w.setControls(controls); 36 | w.render(); 37 | } 38 | 39 | function cancelDNSLookup() 40 | { 41 | uimanager.getWindow("divdnslookup").dispose(); 42 | removeBodyDiv('divbk'); 43 | } 44 | 45 | function requestDNSLookup(id) 46 | { 47 | var elem = network.getElement(id); 48 | var domain = document.getElementById("dnsclientdomain").value; 49 | elem.getApp("DNSClient").DNSLookup(domain); 50 | uimanager.getWindow("divdnslookup").dispose(); 51 | removeBodyDiv('divbk'); 52 | } 53 | 54 | var DNSClient = function(ifacepos) 55 | { 56 | var owner = null; 57 | var ifacepos = ifacepos; 58 | var localtable = []; 59 | 60 | this.save = function() 61 | { 62 | var result = {}; 63 | result.version = 1; 64 | result.id = this.getId(); 65 | result.ifacepos = ifacepos; 66 | 67 | return result; 68 | }; 69 | 70 | this.load = function(data) 71 | { 72 | }; 73 | 74 | this.getId = function() 75 | { 76 | return "DNSClient"; 77 | }; 78 | 79 | this.DNSLookup = function(domain) 80 | { 81 | // Tenemos IP? 82 | if (owner.getConnectable().getIPInfo(ifacepos).getIPv4() !== null) 83 | { 84 | //var MAC = owner.getConnectable().getDstMAC(ifacepos, owner.getConnectable().getIPInfo(ifacepos).getDNS1()); 85 | var MAC = owner.getConnectable().getDstMAC(owner.getConnectable().getIPInfo(ifacepos).getDNS1()); 86 | if (MAC !== null) 87 | { 88 | var data = {}; 89 | data.domain = domain; 90 | data.type = "lookup"; 91 | data.description = "Lookup: " + domain; 92 | var message = new Message( 93 | "tcp", 94 | owner.getConnectable().getIPInfo(ifacepos).getIPv4(), 95 | owner.getConnectable().getIPInfo(ifacepos).getDNS1(), 96 | owner.getConnectable().getMAC(ifacepos), 97 | MAC, 98 | getDinamycPort(), 99 | 53, 100 | data, images[IMAGE_ENVELOPEDNS] 101 | ); 102 | owner.getConnectable().getTrafficManager().registerApplication(this, message.getOrigPort(), false); 103 | owner.getConnectable().getConnector(ifacepos).send(message); 104 | } 105 | } 106 | }; 107 | 108 | this.receiveMessage = function(message) 109 | { 110 | if (message.getData().ip !== null) 111 | { 112 | localtable[message.getData().domain] = message.getData().ip; 113 | } 114 | }; 115 | 116 | this.setOwner = function(o) 117 | { 118 | owner = o; 119 | }; 120 | 121 | this.getIfacepos = function() 122 | { 123 | return ifacepos; 124 | }; 125 | 126 | this.getIp = function(domain) 127 | { 128 | var result = null; 129 | 130 | if (domain in localtable) 131 | { 132 | result = localtable[domain]; 133 | } 134 | 135 | return result; 136 | }; 137 | 138 | this.getAppController = function() 139 | { 140 | var id = network.getPosForElement(owner); 141 | var result = "

\ 142 | \ 143 | \ 144 |

"; 145 | return result; 146 | }; 147 | 148 | this.getMenuEntries = function() 149 | { 150 | var data = []; 151 | data[0] = {}; 152 | data[0].img = 'img/64/envelope-DNS.png'; 153 | data[0].text = 'DNS lookup'; 154 | data[0].js = 'createDNSLookup(' + owner.id + ');'; 155 | 156 | return data; 157 | }; 158 | 159 | this.getAppDescription = function() 160 | { 161 | return ""; 162 | }; 163 | 164 | }; 165 | -------------------------------------------------------------------------------- /js/DNSServer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | function setupDNSServerConfig(id) 15 | { 16 | createBkDiv(); 17 | createDNSServerConfigDiv(id); 18 | } 19 | 20 | function createDNSServerConfigDiv(id) 21 | { 22 | var host = network.getElement(id); 23 | var app = host.getApp("DNSServer"); 24 | /*var div = document.createElement("div"); 25 | var l = window.innerWidth / 2 - 200; 26 | var t = window.innerHeight / 2 - 200;*/ 27 | 28 | var headers = [_("Domain"), _("IP")]; 29 | var data = app.getAppControllerData(); 30 | var uidnstable = new UITable(headers, data, 'dnstable'); 31 | 32 | /*div.setAttribute('style', 'position:absolute;top:' + t + 'px;left:' + l + 'px;z-index:110;background-color:white;width:400px;height:400px;border-radius:10px;border:1px solid;padding:10px;text-align:center;'); 33 | div.setAttribute('id', 'divdnsserverconfig'); 34 | div.innerHTML = app.getAppController();*/ 35 | var controls = '\ 36 | '; 37 | var w = new UIWindow('divdnsserverconfig', 'DNS Server', 400, 400, false, 1.0); 38 | w.setContent(app.getAppController()); 39 | w.setControls(controls); 40 | w.render(); 41 | uidnstable.render(); 42 | } 43 | 44 | function saveDNSServerConfig(id, uitableid) 45 | { 46 | var data = uitables[uitableid].getData(); 47 | var host = network.getElement(id); 48 | var app = host.getApp("DNSServer"); 49 | app.resetDNSTable(); 50 | for (var i = 0; i < data.length; i++) 51 | { 52 | app.setEntry(data[i][0], data[i][1]); 53 | } 54 | 55 | var fwderval = document.getElementById('forwarder').value; 56 | app.setForwarder(fwderval); 57 | 58 | uimanager.getWindow("divdnsserverconfig").dispose(); 59 | removeBodyDiv('divbk'); 60 | uitables[uitableid].dispose(); 61 | } 62 | 63 | function cancelDNSServerConfig(uitableid) 64 | { 65 | uimanager.getWindow("divdnsserverconfig").dispose(); 66 | removeBodyDiv('divbk'); 67 | uitables[uitableid].dispose(); 68 | } 69 | 70 | var DNSServer = function(ifacepos) 71 | { 72 | var owner = null; 73 | var ifacepos = ifacepos; 74 | var dnstable = []; 75 | var forwarder = null; 76 | var forwarderQueue = []; 77 | var _self = this; 78 | 79 | this.save = function() 80 | { 81 | var result = {}; 82 | result.version = 1; 83 | result.id = this.getId(); 84 | result.ifacepos = ifacepos; 85 | result.dnstable = []; 86 | result.forwarder = forwarder; 87 | for (var domain in dnstable) 88 | { 89 | var data = {}; 90 | data.domain = domain; 91 | data.ip = dnstable[domain]; 92 | result.dnstable.push(data); 93 | } 94 | 95 | return result; 96 | }; 97 | 98 | this.load = function(data) 99 | { 100 | if (data.forwarder) 101 | { 102 | forwarder = data.forwarder; 103 | } 104 | 105 | for (var i = 0; i < data.dnstable.length; i++) 106 | { 107 | this.setEntry(data.dnstable[i].domain, data.dnstable[i].ip); 108 | } 109 | }; 110 | 111 | this.getId = function() 112 | { 113 | return "DNSServer"; 114 | }; 115 | 116 | this.getPort = function() 117 | { 118 | return port; 119 | }; 120 | 121 | this.resetDNSTable = function() 122 | { 123 | dnstable = []; 124 | }; 125 | 126 | this.setEntry = function(domain, ip) 127 | { 128 | dnstable[domain] = ip; 129 | }; 130 | 131 | this.deleteDNSEntry = function(domain) 132 | { 133 | if (domain in dnstable) 134 | { 135 | delete dnstable[domain]; 136 | } 137 | }; 138 | 139 | function forwardLookup(message) 140 | { 141 | var MAC = owner.getConnectable().getDstMAC(forwarder); 142 | if (MAC !== null) 143 | { 144 | var data = {}; 145 | data.domain = message.getData().domain; 146 | data.type = "lookup_forward"; 147 | data.description = "Lookup Fwd: " + message.getData().domain; 148 | data.originId = message.getId(); 149 | 150 | var response = new Message( 151 | "tcp", 152 | owner.getConnectable().getIPInfo(ifacepos).getIPv4(), 153 | forwarder, 154 | owner.getConnectable().getMAC(ifacepos), 155 | MAC, 156 | getDinamycPort(), 157 | 53, 158 | data, images[IMAGE_ENVELOPEDNS] 159 | ); 160 | 161 | forwarderQueue[response.getId()] = {}; 162 | forwarderQueue[response.getId()].domain = message.getData().domain; 163 | forwarderQueue[response.getId()].ip = message.getOriginIP(); 164 | forwarderQueue[response.getId()].port = message.getOrigPort(); 165 | forwarderQueue[response.getId()].originId = message.getId(); 166 | 167 | owner.getConnectable().getTrafficManager().registerApplication(_self, response.getOrigPort(), false); 168 | owner.getConnectable().getConnector(ifacepos).send(response); 169 | } 170 | } 171 | ; 172 | 173 | function proccessLookup(message) 174 | { 175 | var send = false; 176 | var data = {}; 177 | data.domain = message.getData().domain; 178 | data.type = "response"; 179 | if (data.domain in dnstable) 180 | { 181 | data.ip = dnstable[data.domain]; 182 | data.description = "Response: " + data.ip; 183 | send = true; 184 | } 185 | else 186 | { 187 | if (forwarder !== null) 188 | { 189 | forwardLookup(message); 190 | } 191 | else 192 | { 193 | data.ip = null; 194 | data.description = "Response: not found"; 195 | send = true; 196 | } 197 | } 198 | 199 | if (send) 200 | { 201 | var response = new Message( 202 | "tcp", 203 | owner.getConnectable().getIPInfo(ifacepos).getIPv4(), 204 | message.getOriginIP(), 205 | owner.getConnectable().getMAC(ifacepos), 206 | owner.getConnectable().getDstMAC(message.getOriginIP()), //message.getOriginMAC(), 207 | 53, 208 | message.getOrigPort(), 209 | data, 210 | images[IMAGE_ENVELOPEDNS] 211 | ); 212 | owner.getConnectable().getConnector(ifacepos).send(response); 213 | } 214 | } 215 | 216 | function proccessLookupForward(message) 217 | { 218 | var send = false; 219 | var data = {}; 220 | data.domain = message.getData().domain; 221 | data.type = "response_forward"; 222 | data.originId = message.getId(); 223 | if (data.domain in dnstable) 224 | { 225 | data.ip = dnstable[data.domain]; 226 | data.description = "Response Fwd: " + data.ip; 227 | send = true; 228 | } 229 | else 230 | { 231 | if (forwarder !== null) 232 | { 233 | forwardLookup(message); 234 | } 235 | else 236 | { 237 | data.ip = null; 238 | data.description = "Response Fwd: not found"; 239 | send = true; 240 | } 241 | } 242 | 243 | if (send) 244 | { 245 | var response = new Message( 246 | "tcp", 247 | owner.getConnectable().getIPInfo(ifacepos).getIPv4(), 248 | message.getOriginIP(), 249 | owner.getConnectable().getMAC(ifacepos), 250 | owner.getConnectable().getDstMAC(message.getOriginIP()), //message.getOriginMAC(), 251 | 53, 252 | message.getOrigPort(), 253 | data, 254 | images[IMAGE_ENVELOPEDNS] 255 | ); 256 | owner.getConnectable().getConnector(ifacepos).send(response); 257 | } 258 | } 259 | 260 | function proccessResponseForward(message) 261 | { 262 | if (message.getData().originId in forwarderQueue) 263 | { 264 | var data = {}; 265 | data.domain = message.getData().domain; 266 | data.type = "response_forward"; 267 | data.originId = forwarderQueue[message.getData().originId].originId; 268 | if (data.domain !== null) 269 | { 270 | data.ip = message.getData().ip; 271 | data.description = "Response Fwd: " + data.ip; 272 | } 273 | else 274 | { 275 | data.ip = null; 276 | data.description = "Response Fwd: not found"; 277 | } 278 | var response = new Message( 279 | "tcp", 280 | owner.getConnectable().getIPInfo(ifacepos).getIPv4(), 281 | forwarderQueue[message.getData().originId].ip, 282 | owner.getConnectable().getMAC(ifacepos), 283 | owner.getConnectable().getDstMAC(forwarderQueue[message.getData().originId].ip), //message.getOriginMAC(), 284 | 53, 285 | forwarderQueue[message.getData().originId].port, 286 | data, 287 | images[IMAGE_ENVELOPEDNS] 288 | ); 289 | delete forwarderQueue[message.getData().originId]; 290 | owner.getConnectable().getConnector(ifacepos).send(response); 291 | } 292 | } 293 | 294 | this.receiveMessage = function(message) 295 | { 296 | if ((message.getData().type === "lookup") && (message.getData().domain)) 297 | { 298 | proccessLookup(message); 299 | } 300 | else if ((message.getData().type === "lookup_forward") && (message.getData().domain)) 301 | { 302 | proccessLookupForward(message); 303 | } 304 | else if ((message.getData().type === "response_forward")) 305 | { 306 | proccessResponseForward(message); 307 | } 308 | }; 309 | 310 | this.setOwner = function(o) 311 | { 312 | owner = o; 313 | }; 314 | 315 | this.getIfacepos = function() 316 | { 317 | return ifacepos; 318 | }; 319 | 320 | this.getAppController = function() 321 | { 322 | var id = network.getPosForElement(owner); 323 | result = "
"; 324 | result += "

"; 325 | result += ""; 326 | var fwderval = (forwarder === null) ? "" : forwarder; 327 | result += ""; 328 | result += "

"; 329 | return result; 330 | }; 331 | 332 | this.getMenuEntries = function() 333 | { 334 | var data = []; 335 | data[0] = {}; 336 | data[0].img = 'img/64/envelope-DNS.png'; 337 | data[0].text = 'DNS server config'; 338 | data[0].js = 'setupDNSServerConfig(' + owner.id + ');'; 339 | 340 | return data; 341 | }; 342 | 343 | this.getAppControllerData = function() 344 | { 345 | var result = []; 346 | 347 | for (var domain in dnstable) 348 | { 349 | var data = []; 350 | data.push(domain); 351 | data.push(dnstable[domain]); 352 | result.push(data); 353 | } 354 | 355 | return result; 356 | }; 357 | 358 | this.setForwarder = function(fwder) 359 | { 360 | forwarder = fwder; 361 | }; 362 | 363 | this.getAppDescription = function() 364 | { 365 | return "DNS Server"; 366 | };}; 367 | -------------------------------------------------------------------------------- /js/Drawable.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | var Drawable = function(c_owner) 15 | { 16 | this.id = getNextID(); 17 | var X = 0; 18 | var Y = 0; 19 | var image = null; 20 | var owner = c_owner; 21 | var rect = new UIRectangle(null, null, this, 0, 0, 0, 0, 0, false); 22 | uimanager.addClickable(rect); 23 | var observers = []; 24 | 25 | this.save = function() 26 | { 27 | var result = {}; 28 | result.version = 1; 29 | result.id = this.id; 30 | result.X = X; 31 | result.Y = Y; 32 | 33 | return result; 34 | }; 35 | 36 | this.load = function(data) 37 | { 38 | X = data.X; 39 | Y = data.Y; 40 | this.id = data.id; 41 | notifyObservers(); 42 | }; 43 | 44 | this.setPosition = function(x, y) 45 | { 46 | X = x; 47 | Y = y; 48 | if (image !== null) 49 | { 50 | rect.setCoords(X, Y, image.width, image.height, 0); 51 | } 52 | notifyObservers(); 53 | }; 54 | 55 | this.getX = function() 56 | { 57 | return X; 58 | }; 59 | 60 | this.getY = function() 61 | { 62 | return Y; 63 | }; 64 | 65 | this.getCenterX = function() 66 | { 67 | return X + image.width / 2; 68 | }; 69 | 70 | this.getCenterY = function() 71 | { 72 | return Y + image.height / 2; 73 | }; 74 | 75 | this.setImage = function(img) 76 | { 77 | image = img; 78 | if (image !== null) 79 | { 80 | rect.setCoords(X, Y, image.width, image.height, 0); 81 | } 82 | notifyObservers(); 83 | }; 84 | 85 | function drawInfo(ctx) 86 | { 87 | var pos = 8; 88 | ctx.font = '8pt'; 89 | ctx.fillStyle = "black"; 90 | var parts = owner.getStrInfo().split("\n"); 91 | for (var i = 0; i < parts.length; i++) 92 | { 93 | ctx.fillText(parts[i], 0, image.height + pos); 94 | pos += 8; 95 | } 96 | if (DEBUG) 97 | { 98 | ctx.fillText("X: " + X + " - Y: " + Y, 0, image.height + pos); 99 | } 100 | } 101 | 102 | this.draw = function(ctx) 103 | { 104 | ctx.save(); 105 | ctx.translate(X, Y); 106 | ctx.drawImage(image, 0, 0); 107 | drawInfo(ctx); 108 | ctx.restore(); 109 | }; 110 | 111 | this.getOwner = function() 112 | { 113 | return owner; 114 | }; 115 | 116 | this.getRect = function() 117 | { 118 | var data = {}; 119 | data.x = X; 120 | data.y = Y; 121 | data.width = image.width; 122 | data.height = image.height; 123 | 124 | return data; 125 | }; 126 | 127 | this.addObserver = function(obs) 128 | { 129 | observers.push(obs); 130 | }; 131 | 132 | this.deleteObserver = function(obs) 133 | { 134 | var pos = observers.indexOf(obs); 135 | observers.splice(pos, 1); 136 | }; 137 | 138 | function notifyObservers() 139 | { 140 | if (image !== null) 141 | { 142 | for (var i = 0; i < observers.length; i++) 143 | { 144 | observers[i].drawableChanged(); 145 | } 146 | } 147 | } 148 | 149 | this.dispose = function() 150 | { 151 | uimanager.removeClickable(rect); 152 | }; 153 | }; 154 | -------------------------------------------------------------------------------- /js/GatewayManager.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | function createGatewaysDiv(id) 15 | { 16 | var host = network.getElement(id); 17 | /*var div = document.createElement("div"); 18 | var l = window.innerWidth / 2 - 200; 19 | var t = window.innerHeight / 2 - 200;*/ 20 | 21 | var headers = [_("Network"), _("Mask"), _("Gateway")]; 22 | var data = host.getConnectable().getGatewayManager().getControllerData(); 23 | var uigwtable = new UITable(headers, data, 'gwtable'); 24 | 25 | /*div.setAttribute('style', 'position:absolute;top:' + t + 'px;left:' + l + 'px;z-index:110;background-color:white;width:700px;height:400px;border-radius:10px;border:1px solid;padding:10px;text-align:center;'); 26 | div.setAttribute('id', 'divgwconfig'); 27 | div.innerHTML = host.getConnectable().getGatewayManager().getController();*/ 28 | 29 | var controls = '\ 30 | '; 31 | 32 | var w = new UIWindow('divgwconfig', _('Gateway Configuration'), 700, 400, false, 1.0); 33 | w.setContent(host.getConnectable().getGatewayManager().getController()); 34 | w.setControls(controls); 35 | w.render(); 36 | 37 | uigwtable.render(); 38 | } 39 | 40 | function editGateways(id) 41 | { 42 | createBkDiv(); 43 | createGatewaysDiv(id); 44 | } 45 | 46 | function cancelGWConfig(uitableid) 47 | { 48 | uimanager.getWindow("divgwconfig").dispose(); 49 | removeBodyDiv('divbk'); 50 | uitables[uitableid].dispose(); 51 | } 52 | 53 | function saveGWConfig(id, uitableid) 54 | { 55 | var host = network.getElement(id); 56 | host.getConnectable().getGatewayManager().purgeGatewayInfo(); 57 | var data = uitables[uitableid].getData(); 58 | for (var i = 0; i < data.length; i++) 59 | { 60 | var dst = data[i][0]; 61 | dst = (dst === "") ? "0.0.0.0" : dst; 62 | var mask = data[i][1]; 63 | mask = (mask === "") ? "0.0.0.0" : mask; 64 | var gw = data[i][2]; 65 | host.getConnectable().getGatewayManager().addGatewayInfo(dst, mask, gw); 66 | } 67 | uimanager.getWindow("divgwconfig").dispose(); 68 | removeBodyDiv('divbk'); 69 | uitables[uitableid].dispose(); 70 | } 71 | 72 | 73 | var GatewayManager = function(connectable) 74 | { 75 | var gateways = []; 76 | var _self = this; 77 | var defaultgw = null; 78 | var connectable = connectable; 79 | 80 | function init() 81 | { 82 | _self.addGatewayInfo("0.0.0.0", "0.0.0.0", null); 83 | } 84 | 85 | this.addGatewayInfo = function(dst, mask, gw) 86 | { 87 | if (isValidIPv4(dst) && ((gw === null) || (isValidIPv4(gw)))) 88 | { 89 | var isdefaultgw = (dst === "0.0.0.0"); 90 | var data = {}; 91 | data.dst = dst; 92 | data.gw = gw; 93 | 94 | if (isdefaultgw) 95 | { 96 | data.mask = "0.0.0.0"; 97 | defaultgw = data; 98 | } 99 | else 100 | { 101 | data.mask = mask; 102 | gateways.push(data); 103 | } 104 | } 105 | }; 106 | 107 | this.save = function() 108 | { 109 | var data = {}; 110 | data.defaultgw = defaultgw.gw; 111 | data.gateways = gateways; 112 | 113 | return data; 114 | }; 115 | 116 | this.load = function(data) 117 | { 118 | if (data !== null) 119 | { 120 | this.addGatewayInfo("0.0.0.0", "0.0.0.0", data.defaultgw); 121 | for (var i = 0; i < data.gateways.length; i++) 122 | { 123 | this.addGatewayInfo(data.gateways[i].dst, data.gateways[i].mask ? data.gateways[i].mask : "255.255.255.0", data.gateways[i].gw); 124 | } 125 | } 126 | }; 127 | 128 | this.purgeGatewayInfo = function() 129 | { 130 | gateways = []; 131 | defaultgw.gw = null; 132 | }; 133 | 134 | this.getController = function() 135 | { 136 | var result = "
"; 137 | return result; 138 | }; 139 | 140 | this.getControllerData = function() 141 | { 142 | var result = []; 143 | 144 | var defdata = []; 145 | if (defaultgw.gw !== null) 146 | { 147 | defdata[0] = defaultgw.dst; 148 | defdata[1] = defaultgw.mask; 149 | defdata[2] = defaultgw.gw; 150 | result.push(defdata); 151 | } 152 | 153 | for (var i = 0; i < gateways.length; i++) 154 | { 155 | var data = []; 156 | data[0] = gateways[i].dst; 157 | data[1] = gateways[i].mask; 158 | data[2] = gateways[i].gw; 159 | result.push(data); 160 | } 161 | 162 | return result; 163 | }; 164 | 165 | this.getGatewayForIP = function(ip) 166 | { 167 | var result = null; 168 | if (isValidIPv4(ip)) 169 | { 170 | var ipint = ipStringToInt(ip); 171 | var i = 0; 172 | while ((result === null) && (i < gateways.length)) 173 | { 174 | var dstint = ipStringToInt(gateways[i].dst); 175 | var maskint = ipStringToInt(gateways[i].mask); 176 | var dstnetwork = dstint & maskint; 177 | var ipnetwork = ipint & maskint; 178 | if (dstnetwork === ipnetwork) 179 | { 180 | result = gateways[i].gw; 181 | } 182 | else 183 | { 184 | i++; 185 | } 186 | } 187 | 188 | if (result === null) 189 | { 190 | result = defaultgw.gw; 191 | } 192 | } 193 | 194 | return result; 195 | }; 196 | 197 | this.getGatewayDescription = function() 198 | { 199 | var result = ""; 200 | 201 | if (defaultgw.gw !== null) 202 | { 203 | result += "Dst: " + defaultgw.dst + " / "; 204 | result += "Mask: " + defaultgw.mask + " / "; 205 | result += "GW: " + defaultgw.gw; 206 | result += "\n"; 207 | } 208 | 209 | for (var i = 0; i < gateways.length; i++) 210 | { 211 | result += "Dst: " + gateways[i].dst + " / "; 212 | result += "Mask: " + gateways[i].mask + " / "; 213 | result += "GW: " + gateways[i].gw; 214 | if (i < gateways.length -1) 215 | { 216 | result += "\n"; 217 | } 218 | } 219 | 220 | return result; 221 | }; 222 | 223 | init(); 224 | }; 225 | -------------------------------------------------------------------------------- /js/Globals.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | var MACMODE_SHARED = 0; 15 | var MACMODE_UNIQUE = 1; 16 | 17 | var IPMODE_SHARED = 0; 18 | var IPMODE_UNIQUE = 1; 19 | var IPMODE_NOIP = 2; 20 | 21 | var IMAGE_SWITCH = 0; 22 | var IMAGE_ROUTER = 1; 23 | var IMAGE_COMPUTER = 2; 24 | var IMAGE_SERVERWEB = 3; 25 | var IMAGE_SERVERDNS = 4; 26 | var IMAGE_SERVERDHCP = 5; 27 | var IMAGE_ENVELOPEDHCP = 6; 28 | var IMAGE_ENVELOPEDNS = 7; 29 | var IMAGE_ENVELOPEHTTP = 8; 30 | var IMAGE_ENVELOPEICMP = 9; 31 | 32 | var REFRESH_INTERVAL = 1000/60; 33 | var LINE_SELECT_TOLERANCE = 2; 34 | 35 | var ROUTER_WAN = 0; 36 | var ROUTER_LAN = 1; 37 | 38 | var DEBUG = false; 39 | 40 | var network = null; 41 | var images = null; 42 | var uimanager = null; 43 | 44 | var lastuseddinamycport = 1024; 45 | var lastusedid = 0; 46 | 47 | function getDinamycPort() 48 | { 49 | return ++lastuseddinamycport; 50 | } 51 | 52 | function getNextID() 53 | { 54 | return ++lastusedid; 55 | } 56 | 57 | var NetworkSimulator = { 58 | initialdata: null, 59 | verbose:false 60 | }; 61 | -------------------------------------------------------------------------------- /js/HTTPClient.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | function viewWebBrowser(id) 15 | { 16 | createBkDiv(); 17 | 18 | var host = network.getElement(id); 19 | var app = host.getApp("HTTPClient"); 20 | /*var div = document.createElement("div"); 21 | var l = window.innerWidth / 2 - 200; 22 | var t = window.innerHeight / 2 - 200; 23 | 24 | div.setAttribute('style', 'position:absolute;top:' + t + 'px;left:' + l + 'px;z-index:110;background-color:white;width:400px;height:400px;border-radius:10px;border:1px solid;padding:10px;text-align:center;opacity:0.5;'); 25 | div.setAttribute('id', 'divhttpclient'); 26 | div.innerHTML = app.getAppController();*/ 27 | var controls = ''; 28 | 29 | var w = new UIWindow('divhttpclient','HTTP Client (Browser)',400,400,false,1.0); 30 | w.setContent(app.getAppController()); 31 | w.setControls(controls); 32 | w.render(); 33 | } 34 | 35 | function closeWebBrowser() 36 | { 37 | removeBodyDiv('divbk'); 38 | uimanager.getWindow("divhttpclient").dispose(); 39 | } 40 | 41 | function requestHTTPWebSite(id) 42 | { 43 | var host = network.getElement(id); 44 | var app = host.getApp("HTTPClient"); 45 | var url = document.getElementById("httpclienturl").value; 46 | app.requestHTTPWebSite(url); 47 | } 48 | 49 | var HTTPClient = function(ifacepos) 50 | { 51 | var owner = null; 52 | var ifacepos = ifacepos; 53 | var lastCode = null; 54 | var lastContent = null; 55 | var lastURL = null; 56 | var _self = this; 57 | 58 | this.save = function() 59 | { 60 | var result = {}; 61 | result.version = 1; 62 | result.id = this.getId(); 63 | result.ifacepos = ifacepos; 64 | 65 | return result; 66 | }; 67 | 68 | this.load = function(data) 69 | { 70 | }; 71 | 72 | this.setOwner = function(c_owner) 73 | { 74 | owner = c_owner; 75 | }; 76 | 77 | this.getOwner = function() 78 | { 79 | return owner; 80 | }; 81 | 82 | this.getIfacepos = function() 83 | { 84 | return ifacepos; 85 | }; 86 | 87 | this.getId = function() 88 | { 89 | return "HTTPClient"; 90 | }; 91 | 92 | this.resetHTTPServerInfo = function() 93 | { 94 | domains = []; 95 | }; 96 | 97 | this.getMenuEntries = function() 98 | { 99 | var data = []; 100 | 101 | data[0] = {}; 102 | data[0].img = 'img/64/envelope-HTTP.png'; 103 | data[0].text = 'Web browser (HTTP client)'; 104 | data[0].js = 'viewWebBrowser(' + owner.id + ');'; 105 | 106 | return data; 107 | }; 108 | 109 | this.getBrowserContents = function() 110 | { 111 | var result = ""; 112 | switch (lastCode) 113 | { 114 | case 0: 115 | result = _("Loading..."); 116 | break; 117 | case 404: 118 | result = _("404 - Not found"); 119 | break; 120 | case 200: 121 | result = lastContent; 122 | break; 123 | case 997: 124 | result = _("Malformed URL.\n\nUse only 'domain_or_ip/filename.html'."); 125 | break; 126 | case 998: 127 | result = _("DNS client not present."); 128 | break; 129 | case 999: 130 | result = _("Domain not in local DNS cache. Look up first.\n\nIf you already performed a lookup, the domain does not exist."); 131 | break; 132 | } 133 | 134 | result = result.replace(/\n/g, '
'); 135 | 136 | return result; 137 | }; 138 | 139 | function updateBrowser() 140 | { 141 | var browsercontents = document.getElementById("httpbrowsercontents"); 142 | if (browsercontents !== null) 143 | { 144 | browsercontents.innerHTML = _self.getBrowserContents(); 145 | } 146 | } 147 | 148 | this.getAppController = function() 149 | { 150 | result = "

"; 151 | result += " "; 152 | result += ""; 153 | result += ""; 154 | result += ""; 155 | result += "

"; 156 | result += "
"; 157 | result += this.getBrowserContents(); 158 | result += "
"; 159 | return result; 160 | }; 161 | 162 | function performHTTPRequest(domain, ip, filename) 163 | { 164 | // Tenemos IP? 165 | if (owner.getConnectable().getIPInfo(ifacepos).getIPv4() !== null) 166 | { 167 | lastCode = 0; 168 | updateBrowser(); 169 | var MAC = owner.getConnectable().getDstMAC(ip); 170 | if (MAC !== null) 171 | { 172 | var data = {}; 173 | data.domain = domain; 174 | data.filename = filename; 175 | data.ip = ip; 176 | data.description = "GET: " + filename; 177 | var message = new Message( 178 | "tcp", 179 | owner.getConnectable().getIPInfo(ifacepos).getIPv4(), 180 | ip, 181 | owner.getConnectable().getMAC(ifacepos), 182 | MAC, 183 | getDinamycPort(), 184 | 80, 185 | data, images[IMAGE_ENVELOPEHTTP] 186 | ); 187 | owner.getConnectable().getTrafficManager().registerApplication(_self, message.getOrigPort(), false); 188 | owner.getConnectable().getConnector(ifacepos).send(message); 189 | } 190 | } 191 | } 192 | 193 | this.requestHTTPWebSite = function(url) 194 | { 195 | var url = document.getElementById("httpclienturl").value; 196 | lastURL = url; 197 | var urlparts = url.split("/", 2); 198 | if (urlparts.length === 2) 199 | { 200 | var ip = null; 201 | var domain = urlparts[0]; 202 | if (isValidIPv4(domain)) 203 | { 204 | ip = urlparts[0]; 205 | performHTTPRequest(ip, ip, urlparts[1]); 206 | } 207 | else 208 | { 209 | var dnsclientapp = owner.getApp("DNSClient"); 210 | if (dnsclientapp === null) 211 | { 212 | lastCode = 998; 213 | updateBrowser(); 214 | } 215 | else 216 | { 217 | var ip = dnsclientapp.getIp(domain); 218 | if (ip === null) 219 | { 220 | lastCode = 999; 221 | updateBrowser(); 222 | } 223 | else 224 | { 225 | performHTTPRequest(domain, ip, urlparts[1]); 226 | } 227 | } 228 | } 229 | } 230 | else 231 | { 232 | lastCode = 997; 233 | updateBrowser(); 234 | } 235 | }; 236 | 237 | this.receiveMessage = function(message) 238 | { 239 | lastCode = message.getData().code; 240 | lastContent = message.getData().contents; 241 | updateBrowser(); 242 | }; 243 | 244 | this.getAppDescription = function() 245 | { 246 | return ""; 247 | }; 248 | 249 | }; 250 | -------------------------------------------------------------------------------- /js/HTTPServer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | function editHTTPServerInfo(id) 15 | { 16 | createBkDiv(); 17 | createHTTPServerInfoDiv1(id); 18 | } 19 | 20 | function createHTTPServerInfoDiv1(id) 21 | { 22 | var host = network.getElement(id); 23 | var app = host.getApp("HTTPServer"); 24 | /*var div = document.createElement("div"); 25 | var l = window.innerWidth / 2 - 200; 26 | var t = window.innerHeight / 2 - 200;*/ 27 | 28 | var headers = [_("Domain")]; 29 | var data = app.getAppControllerData1(); 30 | var uihttptable = new UITable(headers, data, 'httptable'); 31 | uihttptable.setSecondary(true, "editDomainHTTPServerInfo"); 32 | uihttptable.setParam("hostid", id); 33 | 34 | /*div.setAttribute('style', 'position:absolute;top:' + t + 'px;left:' + l + 'px;z-index:110;background-color:white;width:400px;height:400px;border-radius:10px;border:1px solid;padding:10px;text-align:center;overflow-y:scroll;'); 35 | div.setAttribute('id', 'divhttpserverinfo');*/ 36 | var controls = '\ 37 | '; 38 | var w = new UIWindow('divhttpserverinfo', 'HTTP Server', 400, 400, false, 1.0); 39 | w.setContent(app.getAppController1()); 40 | w.setControls(controls); 41 | w.render(); 42 | uihttptable.render(); 43 | } 44 | 45 | function createHTTPServerInfoDiv1back(id, uitableid) 46 | { 47 | var host = network.getElement(id); 48 | var app = host.getApp("HTTPServer"); 49 | /*var div = document.createElement("div"); 50 | var l = document.body.clientWidth / 2 - 200; 51 | var t = document.body.clientHeight / 2 - 200;*/ 52 | 53 | var primaryuitableid = uitables[uitableid].getParam("primaryuitableid"); 54 | var headers = [_("Domain")]; 55 | var data = uitables[primaryuitableid].getData(); 56 | var uihttptable = uitables[primaryuitableid]; 57 | 58 | /*div.setAttribute('style', 'position:absolute;top:' + t + 'px;left:' + l + 'px;z-index:110;background-color:white;width:400px;height:400px;border-radius:10px;border:1px solid;padding:10px;text-align:center;overflow-y:scroll;'); 59 | div.setAttribute('id', 'divhttpserverinfo'); 60 | div.innerHTML = app.getAppController1(); 61 | div.innerHTML += '

\ 62 | \ 63 | \ 64 |

';*/ 65 | var controls = '\ 66 | '; 67 | var w = new UIWindow('divhttpserverinfo', 'HTTP Server', 400, 400, false, 1.0); 68 | w.setContent(app.getAppController1()); 69 | w.setControls(controls); 70 | w.render(); 71 | uihttptable.render(); 72 | } 73 | 74 | function createHTTPServerInfoDiv2(id, primaryuitableid, filedata) 75 | { 76 | var host = network.getElement(id); 77 | var app = host.getApp("HTTPServer"); 78 | /*var div = document.createElement("div"); 79 | var l = document.body.clientWidth / 2 - 200; 80 | var t = document.body.clientHeight / 2 - 200;*/ 81 | 82 | var headers = [_("File")]; 83 | var data = filedata; 84 | var uihttpfiletable = new UITable(headers, data, 'httpfiletable'); 85 | uihttpfiletable.setSecondary(true, "editFileHTTPServerInfo"); 86 | uihttpfiletable.setParam("hostid", id); 87 | uihttpfiletable.setParam("primaryuitableid", primaryuitableid); 88 | 89 | /*div.setAttribute('style', 'position:absolute;top:' + t + 'px;left:' + l + 'px;z-index:110;background-color:white;width:400px;height:400px;border-radius:10px;border:1px solid;padding:10px;text-align:center;overflow-y:scroll;'); 90 | div.setAttribute('id', 'divhttpfileserverinfo'); 91 | div.innerHTML = app.getAppController2();*/ 92 | var controls = ''; 93 | var w = new UIWindow('divhttpfileserverinfo', 'HTTP Domain Files', 400, 400, false, 1.0); 94 | w.setContent(app.getAppController2()); 95 | w.setControls(controls); 96 | w.render(); 97 | uihttpfiletable.render(); 98 | } 99 | 100 | function createHTTPServerInfoDiv3(id, secondarytableid, row) 101 | { 102 | var secondarydata = uitables[secondarytableid].getData(); 103 | var contents = secondarydata[row][1]; 104 | var host = network.getElement(id); 105 | var app = host.getApp("HTTPServer"); 106 | /*var div = document.createElement("div"); 107 | var l = document.body.clientWidth / 2 - 200; 108 | var t = document.body.clientHeight / 2 - 75; 109 | 110 | div.setAttribute('style', 'position:absolute;top:' + t + 'px;left:' + l + 'px;z-index:110;background-color:white;width:400px;height:150px;border-radius:10px;border:1px solid;padding:10px;text-align:center;'); 111 | div.setAttribute('id', 'divhttpcontentsserverinfo'); 112 | div.innerHTML = app.getAppController3(contents);*/ 113 | var controls = ''; 114 | var w = new UIWindow('divhttpcontentsserverinfo', 'HTTP Domain File Edition', 400, 200, false, 1.0); 115 | w.setContent(app.getAppController3(contents)); 116 | w.setControls(controls); 117 | w.render(); 118 | } 119 | 120 | function backHTTPServerData3(id, secondarytableid, row) 121 | { 122 | var secondarydata = uitables[secondarytableid].getData(); 123 | var contents = document.getElementById("httpcontents").value; 124 | secondarydata[row][1] = contents; 125 | /*removeBodyDiv('divhttpcontentsserverinfo');*/ 126 | uimanager.getWindow("divhttpcontentsserverinfo").dispose(); 127 | var primaryuitableid = uitables[secondarytableid].getParam("primaryuitableid"); 128 | createHTTPServerInfoDiv2(id, primaryuitableid, secondarydata); 129 | } 130 | 131 | function editFileHTTPServerInfo(secondarytableid, row) 132 | { 133 | var id = uitables[secondarytableid].getParam("hostid"); 134 | var secondarydata = uitables[secondarytableid].getData(); 135 | if (secondarydata[row].length == 1) 136 | { 137 | secondarydata[row][1] = ""; 138 | } 139 | //removeBodyDiv('divhttpfileserverinfo'); 140 | uimanager.getWindow("divhttpfileserverinfo").dispose(); 141 | createHTTPServerInfoDiv3(id, secondarytableid, row); 142 | } 143 | 144 | function editDomainHTTPServerInfo(primaryuitableid, row) 145 | { 146 | var id = uitables[primaryuitableid].getParam("hostid"); 147 | var primarydata = uitables[primaryuitableid].getData(); 148 | if (primarydata[row].length == 1) 149 | { 150 | primarydata[row][1] = []; 151 | } 152 | var filedata = primarydata[row][1]; 153 | //removeBodyDiv('divhttpserverinfo'); 154 | uimanager.getWindow("divhttpserverinfo").dispose(); 155 | createHTTPServerInfoDiv2(id, primaryuitableid, filedata); 156 | } 157 | 158 | function backHTTPServerData2(id, uitableid) 159 | { 160 | //removeBodyDiv('divhttpfileserverinfo'); 161 | uimanager.getWindow("divhttpfileserverinfo").dispose(); 162 | createHTTPServerInfoDiv1back(id, uitableid); 163 | } 164 | 165 | function saveHTTPServerData1(id, uitableid) 166 | { 167 | var data = uitables[uitableid].getData(); 168 | var host = network.getElement(id); 169 | var app = host.getApp("HTTPServer"); 170 | app.resetHTTPServerInfo(); 171 | for (var i = 0; i < data.length; i++) 172 | { 173 | var domain = data[i][0]; 174 | app.addDomain(domain); 175 | if (data[i].length > 1) 176 | { 177 | for (var j = 0; j < data[i][1].length; j++) 178 | { 179 | var filename = data[i][1][j][0]; 180 | if (data[i][1][j].length === 1) 181 | { 182 | data[i][1][j][1] = ""; 183 | } 184 | var contents = data[i][1][j][1]; 185 | app.setFileContents(domain, filename, contents); 186 | } 187 | } 188 | } 189 | 190 | //removeBodyDiv('divhttpserverinfo'); 191 | uimanager.getWindow("divhttpserverinfo").dispose(); 192 | removeBodyDiv('divbk'); 193 | uitables[uitableid].dispose(); 194 | } 195 | 196 | function cancelHTTPServerData1(uitableid) 197 | { 198 | //removeBodyDiv('divhttpserverinfo'); 199 | uimanager.getWindow("divhttpserverinfo").dispose(); 200 | removeBodyDiv('divbk'); 201 | uitables[uitableid].dispose(); 202 | } 203 | 204 | /* 205 | - Domains 206 | - Files 207 | */ 208 | var HTTPServer = function(ifacepos) 209 | { 210 | var owner = null; 211 | var ifacepos = ifacepos; 212 | var domains = []; 213 | 214 | this.save = function() 215 | { 216 | var result = {}; 217 | result.version = 1; 218 | result.id = this.getId(); 219 | result.ifacepos = ifacepos; 220 | 221 | result.domains = []; 222 | for (domain in domains) 223 | { 224 | var domaindata = {}; 225 | domaindata.domain = domain; 226 | domaindata.files = []; 227 | for (filename in domains[domain]) 228 | { 229 | var filedata = {}; 230 | filedata.filename = filename; 231 | filedata.contents = domains[domain][filename]; 232 | domaindata.files.push(filedata); 233 | } 234 | result.domains.push(domaindata); 235 | } 236 | 237 | return result; 238 | }; 239 | 240 | this.load = function(data) 241 | { 242 | for (var i = 0; i < data.domains.length; i++) 243 | { 244 | var domain = data.domains[i].domain; 245 | this.addDomain(domain); 246 | for (var j = 0; j < data.domains[i].files.length; j++) 247 | { 248 | var filename = data.domains[i].files[j].filename; 249 | var contents = data.domains[i].files[j].contents; 250 | this.setFileContents(domain, filename, contents); 251 | } 252 | } 253 | }; 254 | 255 | this.setOwner = function(c_owner) 256 | { 257 | owner = c_owner; 258 | }; 259 | 260 | this.getOwner = function() 261 | { 262 | return owner; 263 | }; 264 | 265 | this.getIfacepos = function() 266 | { 267 | return ifacepos; 268 | }; 269 | 270 | this.getId = function() 271 | { 272 | return "HTTPServer"; 273 | }; 274 | 275 | this.addDomain = function(domain) 276 | { 277 | if (!(domain in domains)) 278 | { 279 | domains[domain] = []; 280 | } 281 | } 282 | 283 | this.deleteDomain = function(domain) 284 | { 285 | if (domain in domains) 286 | { 287 | delete domains[domain]; 288 | } 289 | } 290 | 291 | this.setFileContents = function(domain, filename, contents) 292 | { 293 | if (domain in domains) 294 | { 295 | domains[domain][filename] = contents; 296 | } 297 | }; 298 | 299 | this.deleteFile = function(domain, filename) 300 | { 301 | if (domain in domains) 302 | { 303 | if (file in domains[domain]) 304 | { 305 | delete domains[domain][filename]; 306 | } 307 | } 308 | }; 309 | 310 | this.resetHTTPServerInfo = function() 311 | { 312 | domains = []; 313 | }; 314 | 315 | this.getMenuEntries = function() 316 | { 317 | var data = []; 318 | 319 | data[0] = {}; 320 | data[0].img = 'img/64/envelope-HTTP.png'; 321 | data[0].text = 'Edit HTTP server info'; 322 | data[0].js = 'editHTTPServerInfo(' + owner.id + ');'; 323 | 324 | return data; 325 | }; 326 | 327 | this.getAppController1 = function() 328 | { 329 | result = "
"; 330 | return result; 331 | }; 332 | 333 | this.getAppController2 = function() 334 | { 335 | result = "
"; 336 | return result; 337 | }; 338 | 339 | this.getAppController3 = function(contents) 340 | { 341 | result = ""; 344 | return result; 345 | }; 346 | 347 | this.getAppControllerData1 = function() 348 | { 349 | var result = []; 350 | 351 | for (var domain in domains) 352 | { 353 | var data = []; 354 | data.push(domain); 355 | var files = []; 356 | for (var filename in domains[domain]) 357 | { 358 | var fileinfo = []; 359 | fileinfo[0] = filename; 360 | fileinfo[1] = domains[domain][filename]; 361 | files.push(fileinfo); 362 | } 363 | data.push(files); 364 | result.push(data); 365 | } 366 | 367 | return result; 368 | }; 369 | 370 | this.receiveMessage = function(message) 371 | { 372 | var data = message.getData(); 373 | var domain = data.domain; 374 | var filename = data.filename; 375 | var ip = data.ip; 376 | var code = null; 377 | var contents = null; 378 | 379 | if (domain in domains) 380 | { 381 | if (filename in domains[domain]) 382 | { 383 | code = 200; 384 | contents = domains[domain][filename]; 385 | } 386 | else 387 | { 388 | code = 404; 389 | contents = ""; 390 | } 391 | } 392 | else 393 | { 394 | if (isValidIPv4(domain)) 395 | { 396 | // Default: 1st domain 397 | var domainKeys = Object.keys(domains); 398 | if ((domainKeys.length > 0) && (filename in domains[domainKeys[0]])) 399 | { 400 | code = 200; 401 | contents = domains[domainKeys[0]][filename]; 402 | } 403 | else 404 | { 405 | code = 404; 406 | contents = ""; 407 | } 408 | } 409 | else 410 | { 411 | code = 404; 412 | contents = ""; 413 | } 414 | } 415 | var responsedata = {}; 416 | responsedata.code = code; 417 | responsedata.contents = contents; 418 | responsedata.description = code + "-"+filename; 419 | var response = new Message( 420 | "tcp", 421 | owner.getConnectable().getIPInfo(ifacepos).getIPv4(), 422 | message.getOriginIP(), 423 | owner.getConnectable().getMAC(ifacepos), 424 | owner.getConnectable().getDstMAC(message.getOriginIP()), //message.getOriginMAC(), 425 | 80, 426 | message.getOrigPort(), 427 | responsedata, 428 | images[IMAGE_ENVELOPEHTTP] 429 | ); 430 | owner.getConnectable().getConnector(ifacepos).send(response); 431 | }; 432 | 433 | this.getAppDescription = function() 434 | { 435 | return "HTTP Server"; 436 | }; 437 | }; 438 | -------------------------------------------------------------------------------- /js/Host.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | function editNameGroup(id) 15 | { 16 | createBkDiv(); 17 | createNameGroupDiv(id); 18 | } 19 | 20 | function createNameGroupDiv(id) 21 | { 22 | var host = network.getElement(id); 23 | /*var div = document.createElement("div"); 24 | var l = window.innerWidth / 2 - 200; 25 | var t = window.innerHeight / 2 - 200; 26 | 27 | div.setAttribute('style', 'position:absolute;top:' + t + 'px;left:' + l + 'px;z-index:110;background-color:white;width:700px;height:400px;border-radius:10px;border:1px solid;padding:10px;text-align:center;'); 28 | div.setAttribute('id', 'divnamegroup');*/ 29 | var innerHTML = '

'; 30 | innerHTML += ''; 31 | innerHTML += '
'; 32 | innerHTML += ''; 33 | innerHTML += ''; 34 | innerHTML += '

'; 35 | var controls = '

\ 36 | \ 37 | \ 38 |

'; 39 | /*div.innerHTML = innerHTML; 40 | document.body.appendChild(div);*/ 41 | var w = new UIWindow('divnamegroup', _('Edit name / group'), 400, 150, false, 1.0); 42 | w.setContent(innerHTML); 43 | w.setControls(controls); 44 | w.render(); 45 | } 46 | 47 | function cancelNameGroup() 48 | { 49 | uimanager.getWindow("divnamegroup").dispose(); 50 | removeBodyDiv('divbk'); 51 | } 52 | 53 | function saveNameGroup(id) 54 | { 55 | var host = network.getElement(id); 56 | var name = document.getElementById("nametxt").value; 57 | var group = document.getElementById("grouptxt").value; 58 | group = (group === "")?null:group; 59 | host.setName(name); 60 | host.setGroup(group); 61 | uimanager.getWindow("divnamegroup").dispose(); 62 | removeBodyDiv('divbk'); 63 | } 64 | 65 | function networkDiagnostics(id) 66 | { 67 | createBkDiv(); 68 | createDiagnosticsDiv(id); 69 | } 70 | 71 | function createDiagnosticsDiv(id) 72 | { 73 | var host = network.getElement(id); 74 | var div = document.createElement("div"); 75 | /*var l = window.innerWidth / 2 - 200; 76 | var t = window.innerHeight / 2 - 200; 77 | 78 | div.setAttribute('style', 'position:absolute;top:' + t + 'px;left:' + l + 'px;z-index:110;background-color:white;width:700px;height:400px;border-radius:10px;border:1px solid;padding:10px;text-align:center;opacity:0.5;'); 79 | div.setAttribute('id', 'divdiagnostics');*/ 80 | var innerHTML = '

'; 81 | innerHTML += ''; 87 | innerHTML += ''; 88 | innerHTML += '

'; 89 | innerHTML += '

'; 90 | innerHTML += ''; 91 | innerHTML += ''; 92 | innerHTML += '

'; 93 | innerHTML += '
'; 94 | innerHTML += host.getConnectable().getTrafficManager().getDiagnosticsInfo(); 95 | innerHTML += '
'; 96 | var controls = '

'; 97 | /*div.innerHTML = innerHTML; 98 | document.body.appendChild(div);*/ 99 | var window = new UIWindow('divdiagnostics','Network diagnostics',400,400,false,1.0); 100 | window.setContent(innerHTML); 101 | window.setControls(controls); 102 | window.render(); 103 | } 104 | 105 | function diagnosticsPing(id) 106 | { 107 | var host = network.getElement(id); 108 | var dst = document.getElementById("diagnosticstxt").value; 109 | var ifacepos = document.getElementById("ifacepos").value; 110 | host.getConnectable().getTrafficManager().ping(dst, ifacepos); 111 | } 112 | 113 | function diagnosticsTraceroute(id) 114 | { 115 | var host = network.getElement(id); 116 | var dst = document.getElementById("diagnosticstxt").value; 117 | var ifacepos = document.getElementById("ifacepos").value; 118 | host.getConnectable().getTrafficManager().traceroute(dst, ifacepos); 119 | } 120 | 121 | function cancelDiagnostics() 122 | { 123 | removeBodyDiv('divbk'); 124 | uimanager.getWindow("divdiagnostics").dispose(); 125 | } 126 | 127 | function editNATTable(id) 128 | { 129 | createBkDiv(); 130 | createNATDiv(id); 131 | } 132 | 133 | function createNATDiv(id) 134 | { 135 | var host = network.getElement(id); 136 | var div = document.createElement("div"); 137 | /*var l = window.innerWidth / 2 - 350; 138 | var t = window.innerHeight / 2 - 200;*/ 139 | 140 | var headers = [_("Input interface"),_("WAN Port"),_("LAN Port"),_("IP")]; 141 | var data = host.getConnectable().getTrafficManager().getNATData(); 142 | var uinattable = new UITable(headers,data,'nattable'); 143 | 144 | /*div.setAttribute('style', 'position:absolute;top:' + t + 'px;left:' + l + 'px;z-index:110;background-color:white;width:700px;height:400px;border-radius:10px;border:1px solid;padding:10px;text-align:center;'); 145 | div.setAttribute('id', 'divnatconfig');*/ 146 | var innerHTML = ""; 147 | if (host.getType() === "router") 148 | { 149 | var chktxt = (host.getConnectable().getPerformNAT()?"checked='checked'":""); 150 | innerHTML += "

"; 151 | innerHTML += ""; 152 | innerHTML += ""; 153 | innerHTML += "

"; 154 | } 155 | innerHTML += '
'; 156 | var controls = '

\ 157 | \ 158 | \ 159 |

'; 160 | /*div.innerHTML = innerHTML; 161 | document.body.appendChild(div);*/ 162 | var w = new UIWindow('divnatconfig', 'Edit NAT', 700, 400, false, 1.0); 163 | w.setContent(innerHTML); 164 | w.setControls(controls); 165 | w.render(); 166 | uinattable.render(); 167 | } 168 | 169 | function cancelNATConfig(uitableid) 170 | { 171 | uimanager.getWindow("divnatconfig").dispose(); 172 | removeBodyDiv('divbk'); 173 | uitables[uitableid].dispose(); 174 | } 175 | 176 | function saveNATConfig(id, uitableid) 177 | { 178 | var host = network.getElement(id); 179 | host.getConnectable().getTrafficManager().removeFixedNATData(); 180 | var data = uitables[uitableid].getData(); 181 | for (var i = 0; i < data.length; i++) 182 | { 183 | host.getConnectable().getTrafficManager().addNATEntry(data[i][2],data[i][1],data[i][3],data[i][0],true); 184 | } 185 | var performNAT = document.getElementById("performNAT"); 186 | if (performNAT !== null) 187 | { 188 | host.getConnectable().setPerformNAT(performNAT.checked); 189 | }; 190 | uimanager.getWindow("divnatconfig").dispose(); 191 | removeBodyDiv('divbk'); 192 | uitables[uitableid].dispose(); 193 | } 194 | 195 | function editIpInfo(id, pos) 196 | { 197 | createBkDiv(); 198 | createIpDiv(id, pos); 199 | } 200 | 201 | function createIpDiv(id, pos) 202 | { 203 | var host = network.getElement(id); 204 | var connectable = host.getConnectable(); 205 | var ipinfo = connectable.getIPInfo(pos); 206 | var div = document.createElement("div"); 207 | var l = window.innerWidth / 2 - 200; 208 | var t = window.innerHeight / 2 - 75; 209 | 210 | var ip = ipinfo.getIPv4() !== null?ipinfo.getIPv4():""; 211 | var nm = ipinfo.getNetmask() !== null?ipinfo.getNetmask():"255.255.255.0"; 212 | var dns1 = ipinfo.getDNS1() !== null?ipinfo.getDNS1():""; 213 | var dns2 = ipinfo.getDNS2() !== null?ipinfo.getDNS2():""; 214 | 215 | div.setAttribute('style', 'position:absolute;top:' + t + 'px;left:' + l + 'px;z-index:110;background-color:white;width:400px;height:150px;border-radius:10px;border:1px solid;padding:10px;text-align:center;'); 216 | div.setAttribute('id', 'divipinfo'); 217 | var innerHTML = ''; 218 | innerHTML += '
'; 219 | innerHTML += ''; 220 | innerHTML += '
'; 221 | innerHTML += ''; 222 | innerHTML += '
'; 223 | innerHTML += ''; 224 | innerHTML += '
'; 225 | var controls = '

\ 226 | \ 227 | \ 228 |

'; 229 | //document.body.appendChild(div); 230 | var w = new UIWindow('divipinfo', 'Edit IP Info', 400, 150, false, 1.0); 231 | w.setContent(innerHTML); 232 | w.setControls(controls); 233 | w.render(); 234 | } 235 | 236 | function saveIpInfo(id, pos) 237 | { 238 | var host = network.getElement(id); 239 | 240 | var ipv4 = document.getElementById("ip").value; 241 | var netmask = document.getElementById("nm").value; 242 | var dns1 = document.getElementById("dns1").value; 243 | var dns2 = document.getElementById("dns2").value; 244 | 245 | ipv4 = ipv4 === ""?null:ipv4; 246 | netmask = netmask === ""?null:netmask; 247 | dns1 = dns1 === ""?null:dns1; 248 | dns2 = dns2 === ""?null:dns2; 249 | 250 | host.getConnectable().getIPInfo(pos).setIPv4(ipv4); 251 | host.getConnectable().getIPInfo(pos).setNetmask(netmask); 252 | host.getConnectable().getIPInfo(pos).setDNS1(dns1); 253 | host.getConnectable().getIPInfo(pos).setDNS2(dns2); 254 | host.getConnectable().getIPInfo(pos).setStatic(true); 255 | 256 | uimanager.getWindow("divipinfo").dispose(); 257 | removeBodyDiv('divbk'); 258 | } 259 | 260 | function cancelIpInfo() 261 | { 262 | uimanager.getWindow("divipinfo").dispose(); 263 | removeBodyDiv('divbk'); 264 | } 265 | 266 | var Host = function(type, ports) 267 | { 268 | this.id = getNextID(); 269 | var type = type; 270 | var connectable = null; 271 | var drawable = null; 272 | var _self = this; 273 | var ports = ports; 274 | var menu = null; 275 | var name = type + " " + this.id; 276 | var group = null; 277 | 278 | var apps = []; 279 | 280 | this.save = function() 281 | { 282 | var result = {}; 283 | result.version = 1; 284 | result.id = this.id; 285 | result.type = type; 286 | result.drawable = drawable.save(); 287 | result.connectable = connectable.save(); 288 | result.ports = ports; 289 | result.apps = []; 290 | result.name = name; 291 | result.group = group; 292 | 293 | for (var id in apps) 294 | { 295 | var data = {}; 296 | data.app = apps[id].app.save(); 297 | data.port = apps[id].port; 298 | data.fixed = apps[id].fixed; 299 | data.type = id; 300 | data.ifacepos = apps[id].app.getIfacepos(); 301 | result.apps.push(data); 302 | } 303 | 304 | return result; 305 | }; 306 | 307 | this.load = function(data) 308 | { 309 | this.id = data.id; 310 | type = data.type; 311 | drawable.load(data.drawable); 312 | switch (type) 313 | { 314 | case "computer": 315 | drawable.setImage(network.getImages()[IMAGE_COMPUTER]); 316 | break; 317 | case "dhcpserver": 318 | drawable.setImage(network.getImages()[IMAGE_SERVERDHCP]); 319 | break; 320 | case "dnsserver": 321 | drawable.setImage(network.getImages()[IMAGE_SERVERDNS]); 322 | break; 323 | case "httpserver": 324 | drawable.setImage(network.getImages()[IMAGE_SERVERWEB]); 325 | break; 326 | case "router": 327 | drawable.setImage(network.getImages()[IMAGE_ROUTER]); 328 | break; 329 | case "switch": 330 | drawable.setImage(network.getImages()[IMAGE_SWITCH]); 331 | break; 332 | } 333 | connectable.load(data.connectable); 334 | if (data.apps) 335 | { 336 | for (var i = 0; i < data.apps.length; i++) 337 | { 338 | var app = eval('new ' + data.apps[i].type + '(' + data.apps[i].ifacepos + ')'); 339 | app.load(data.apps[i].app); 340 | this.addApp(app, data.apps[i].port, data.apps[i].fixed); 341 | } 342 | } 343 | 344 | if (data.name) 345 | { 346 | this.setName(data.name); 347 | } 348 | if (data.group) 349 | { 350 | group = data.group; 351 | } 352 | 353 | redoMenu(); 354 | }; 355 | 356 | function init() 357 | { 358 | switch (type) 359 | { 360 | case "router": 361 | connectable = new Connectable(_self, MACMODE_UNIQUE, IPMODE_UNIQUE, true, true); 362 | break; 363 | case "switch": 364 | connectable = new Connectable(_self, MACMODE_SHARED, IPMODE_NOIP, false, false); 365 | break; 366 | default: 367 | connectable = new Connectable(_self, MACMODE_UNIQUE, IPMODE_UNIQUE, true, false); 368 | break; 369 | } 370 | for (var i = 0; i < ports; i++) 371 | { 372 | var connector = new Connector(connectable); 373 | } 374 | drawable = new Drawable(_self); 375 | drawable.addObserver(_self); 376 | menu = new UIMenu(name, 0, 0, false); 377 | addStaticMenu(); 378 | uimanager.addMenu(menu); 379 | } 380 | 381 | this.setName = function(n) 382 | { 383 | name = n; 384 | redoMenu(); 385 | }; 386 | 387 | this.setGroup = function(g) 388 | { 389 | group = g; 390 | }; 391 | 392 | this.getName = function() 393 | { 394 | return name; 395 | }; 396 | 397 | this.getGroup = function() 398 | { 399 | return group; 400 | }; 401 | 402 | this.getConnectorDesc = function(i) 403 | { 404 | var result = _("Interface ") + i; 405 | if (type === "router") 406 | { 407 | result = (i === ROUTER_WAN) ? "WAN" : "LAN"; 408 | } 409 | 410 | return result; 411 | } 412 | 413 | function addStaticMenu() 414 | { 415 | menu.addEntry("img/64/delete.png", "Delete element", "deleteSelected();"); 416 | menu.addEntry("img/64/edit.png", "Edit Name / Group", "editNameGroup(" + _self.id + ");"); 417 | menu.addEntry("img/64/link.png", "Create Link", "createLinkAction();"); 418 | if (connectable.getIpMode() !== IPMODE_NOIP) 419 | { 420 | menu.addEntry("img/64/inspect.png", "Network diagnostics", "networkDiagnostics(" + _self.id + ");"); 421 | menu.addEntry("img/64/edit.png", "Edit Gateways", "editGateways(" + _self.id + ");"); 422 | } 423 | 424 | if (connectable.getIpMode() === IPMODE_UNIQUE) 425 | { 426 | for (var i = 0; i < connectable.getConnectorNumber(); i++) 427 | { 428 | menu.addEntry("img/64/edit.png", "Edit IP Info - " + _self.getConnectorDesc(i), "editIpInfo(" + _self.id + "," + i + ");"); 429 | } 430 | } 431 | 432 | if (type === "router") 433 | { 434 | menu.addEntry("img/64/edit.png", "Edit NAT table", "editNATTable(" + _self.id + ");"); 435 | } 436 | } 437 | 438 | this.drawableChanged = function() 439 | { 440 | var rect = drawable.getRect(); 441 | 442 | menu.setPos(rect.x + rect.width, rect.y); 443 | }; 444 | 445 | function redoMenu() 446 | { 447 | menu.purge(); 448 | menu.setDescription(name); 449 | 450 | addStaticMenu(); 451 | 452 | for (var id in apps) 453 | { 454 | var app = apps[id]; 455 | var entries = app.app.getMenuEntries(); 456 | for (var i = 0; i < entries.length; i++) 457 | { 458 | menu.addEntry(entries[i].img, entries[i].text, entries[i].js); 459 | } 460 | } 461 | } 462 | 463 | this.addApp = function(app, port, fixed) 464 | { 465 | apps[app.getId()] = {}; 466 | apps[app.getId()].app = app; 467 | apps[app.getId()].port = port; 468 | apps[app.getId()].fixed = fixed; 469 | app.setOwner(_self); 470 | if (fixed) 471 | { 472 | connectable.getTrafficManager().registerApplication(app, port, true); 473 | } 474 | 475 | redoMenu(); 476 | }; 477 | 478 | this.getAppNames = function(id) 479 | { 480 | return Object.keys(apps); 481 | }; 482 | 483 | this.getApp = function(id) 484 | { 485 | var result = null; 486 | 487 | if (id in apps) 488 | { 489 | result = apps[id].app; 490 | } 491 | 492 | return result; 493 | }; 494 | 495 | this.getConnectable = function() 496 | { 497 | return connectable; 498 | } 499 | 500 | this.getDrawable = function() 501 | { 502 | return drawable; 503 | }; 504 | 505 | this.getType = function() 506 | { 507 | return type; 508 | }; 509 | 510 | this.getVerboseStr = function(connectable,i) 511 | { 512 | result = ""; 513 | 514 | result += "Network Mask: " + ((connectable.getIPInfo(i).getNetmask() === null)?"-":connectable.getIPInfo(i).getNetmask()); 515 | result += "\n"; 516 | result += "DNS 1: " + ((connectable.getIPInfo(i).getDNS1() === null)?"-":connectable.getIPInfo(i).getDNS1()); 517 | result += "\n"; 518 | result += "DNS 2: " + ((connectable.getIPInfo(i).getDNS2() === null)?"-":connectable.getIPInfo(i).getDNS2()); 519 | if (connectable.getGatewayManager() !== null) 520 | { 521 | result += "\n"; 522 | result += connectable.getGatewayManager().getGatewayDescription(); 523 | } 524 | if (apps !== null) 525 | { 526 | var names = this.getAppNames(); 527 | for (var i=0;i= 0) && (part1 <= 255) && 28 | (part2 !== NaN) && (part2 >= 0) && (part2 <= 255) && 29 | (part3 !== NaN) && (part3 >= 0) && (part3 <= 255) && 30 | (part4 !== NaN) && (part4 >= 0) && (part4 <= 255); 31 | } 32 | } 33 | else 34 | { 35 | result = true; 36 | } 37 | 38 | return result; 39 | } 40 | ; 41 | 42 | function ipStringToInt(ip) 43 | { 44 | var result = null; 45 | if (ip !== null) 46 | { 47 | var parts = ip.split("."); 48 | 49 | result = (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | (parts[3]); 50 | } 51 | 52 | return result; 53 | } 54 | 55 | function ipIntToString(ip) 56 | { 57 | result = null; 58 | 59 | if (ip !== null) 60 | { 61 | var byte1 = ip & 0XFF; 62 | var byte2 = ip >> 8 & 0xFF; 63 | var byte3 = ip >> 16 & 0xFF; 64 | var byte4 = ip >> 24 & 0xFF; 65 | 66 | result = byte4 + "." + byte3 + "." + byte2 + "." + byte1; 67 | } 68 | 69 | return result; 70 | } 71 | 72 | var IPInfo = function() 73 | { 74 | var IPv4 = null; 75 | var DNS1 = null; 76 | var DNS2 = null; 77 | var netmask = null; 78 | var static = false; 79 | 80 | this.save = function() 81 | { 82 | var result = {}; 83 | result.IPv4 = static ? IPv4 : null; 84 | result.DNS1 = static ? DNS1 : null; 85 | result.DNS2 = static ? DNS2 : null; 86 | result.netmask = static ? netmask : null; 87 | result.static = static; 88 | 89 | return result; 90 | }; 91 | 92 | this.load = function(data) 93 | { 94 | if (data != null) 95 | { 96 | IPv4 = data.IPv4; 97 | DNS1 = data.DNS1; 98 | DNS2 = data.DNS2; 99 | netmask = data.netmask; 100 | static = data.static; 101 | } 102 | }; 103 | 104 | this.sameNetwork = function(ip) 105 | { 106 | var result = false; 107 | if ((IPv4 !== null) && (netmask !== null) && isValidIPv4(ip)) 108 | { 109 | //console.log("Is "+ip+" in my network "+ipIntToString(IPv4)+"?"); 110 | var intip = ipStringToInt(ip); 111 | var testnetwork = intip & netmask; 112 | var thisnetwork = IPv4 & netmask; 113 | result = testnetwork === thisnetwork; 114 | } 115 | return result; 116 | }; 117 | 118 | this.setIPv4 = function(ipv4) 119 | { 120 | if (isValidIPv4(ipv4)) 121 | { 122 | IPv4 = ipStringToInt(ipv4); 123 | } 124 | }; 125 | 126 | this.setNetmask = function(mask) 127 | { 128 | if (isValidIPv4(mask)) 129 | { 130 | netmask = ipStringToInt(mask); 131 | } 132 | }; 133 | 134 | this.setDNS1 = function(dns) 135 | { 136 | if (isValidIPv4(dns)) 137 | { 138 | DNS1 = ipStringToInt(dns); 139 | } 140 | }; 141 | 142 | this.setDNS2 = function(dns) 143 | { 144 | if (isValidIPv4(dns)) 145 | { 146 | DNS2 = ipStringToInt(dns); 147 | } 148 | }; 149 | 150 | this.setStatic = function(s) 151 | { 152 | static = s; 153 | }; 154 | 155 | this.getIPv4 = function() 156 | { 157 | return ipIntToString(IPv4); 158 | }; 159 | 160 | this.getDNS1 = function() 161 | { 162 | return ipIntToString(DNS1); 163 | }; 164 | 165 | this.getDNS2 = function() 166 | { 167 | return ipIntToString(DNS2); 168 | }; 169 | 170 | this.getNetmask = function() 171 | { 172 | return ipIntToString(netmask); 173 | }; 174 | 175 | this.getStatic = function() 176 | { 177 | return static; 178 | }; 179 | }; 180 | -------------------------------------------------------------------------------- /js/ImageLoader.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | var ImageLoader = function(filearray, callback) 15 | { 16 | var filearray = filearray; 17 | var loadedImages = []; 18 | var next = 0; 19 | var callback = callback; 20 | 21 | function internalLoad() 22 | { 23 | if (next < filearray.length) 24 | { 25 | var pos = next; 26 | next++; 27 | var img = new Image(); 28 | loadedImages.push(img); 29 | img.onload = function() 30 | { 31 | internalLoad(); 32 | }; 33 | img.src = filearray[pos]; 34 | } 35 | else 36 | { 37 | callback(loadedImages); 38 | } 39 | } 40 | 41 | this.getLoadedImages = function () 42 | { 43 | return this.loadedImages; 44 | }; 45 | 46 | this.load = function() 47 | { 48 | internalLoad(); 49 | }; 50 | }; 51 | -------------------------------------------------------------------------------- /js/Link.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | function selectLinkConnectors(id1, id2) 15 | { 16 | createBkDiv(); 17 | createLinkConnectorsDiv(id1, id2); 18 | } 19 | 20 | function getElementConnectorsSelectables(host) 21 | { 22 | var result = ""; 23 | for (var i = 0; i < host.getConnectable().getConnectorNumber(); i++) 24 | { 25 | var connector = host.getConnectable().getConnector(i); 26 | var disabledTxt = connector.isConnected() ? " disabled='disabled' " : ""; 27 | result += ""; 28 | result += host.getConnectorDesc(i); 29 | result += "
"; 30 | } 31 | return result; 32 | } 33 | 34 | function createLinkConnectorsDiv(id1, id2) 35 | { 36 | var host1 = network.getElement(id1); 37 | var host2 = network.getElement(id2); 38 | /*var div = document.createElement("div"); 39 | var l = window.innerWidth / 2 - 200; 40 | var t = window.innerHeight / 2 - 200; 41 | 42 | div.setAttribute('style', 'position:absolute;top:' + t + 'px;left:' + l + 'px;z-index:110;background-color:white;width:400px;height:400px;border-radius:10px;border:1px solid;padding:10px;text-align:center;'); 43 | div.setAttribute('id', 'divlinkconnectors');*/ 44 | var html = ''; 45 | html += ''; 46 | html += ''; 47 | html += ''; 50 | html += ''; 53 | html += ''; 54 | html += '
'+host1.getName()+''+host2.getName()+'
'; 48 | html += getElementConnectorsSelectables(host1); 49 | html += ''; 51 | html += getElementConnectorsSelectables(host2); 52 | html += '
'; 55 | var controls = '

\ 56 | \ 57 | \ 58 |

'; 59 | /*div.innerHTML = html; 60 | document.body.appendChild(div);*/ 61 | var w = new UIWindow('divlinkconnectors', 'Create Link', 400, 400, false, 1.0); 62 | w.setContent(html); 63 | w.setControls(controls); 64 | w.render(); 65 | } 66 | 67 | function saveLinkConnectors(id1, id2) 68 | { 69 | var selected1 = document.querySelector('input[name="link_host_' + id1 + '"]:checked'); 70 | var selected2 = document.querySelector('input[name="link_host_' + id2 + '"]:checked'); 71 | if ((selected1 !== null) && (selected2 !== null)) 72 | { 73 | var c1 = selected1.value; 74 | var c2 = selected2.value; 75 | if ((c1 !== null) && (c2 !== null)) 76 | { 77 | network.createLink(id1, c1, id2, c2); 78 | uimanager.getWindow("divlinkconnectors").dispose(); 79 | removeBodyDiv('divbk'); 80 | } 81 | } 82 | } 83 | 84 | function cancelLinkConnectors() 85 | { 86 | uimanager.getWindow("divlinkconnectors").dispose(); 87 | removeBodyDiv('divbk'); 88 | } 89 | 90 | /* 91 | - El link tiene un UILine asociado 92 | - Cada vez que se mueve uno de los drawables se actualiza el UILine 93 | - Dispose: borra el UILine 94 | */ 95 | 96 | var Link = function(c1, c2) 97 | { 98 | this.id = getNextID(); 99 | var connector1 = c1; 100 | var connector2 = c2; 101 | var messages = []; 102 | var _self = this; 103 | var uiline = null; 104 | var menu = null; 105 | 106 | this.save = function() 107 | { 108 | var result = {}; 109 | result.version = 1; 110 | result.id = this.id; 111 | result.connector1 = connector1.id; 112 | result.connector2 = connector2.id; 113 | 114 | return result; 115 | }; 116 | 117 | this.load = function(data) 118 | { 119 | this.id = data.id; 120 | }; 121 | 122 | function init() 123 | { 124 | connector1.setLink(_self); 125 | connector2.setLink(_self); 126 | var vertices = getVertices(); 127 | uiline = new UILine(null, null, _self, vertices.x1, vertices.y1, vertices.x2, vertices.y2, 0); 128 | uimanager.addClickable(uiline); 129 | connector1.getConnectable().getOwner().getDrawable().addObserver(_self); 130 | connector2.getConnectable().getOwner().getDrawable().addObserver(_self); 131 | menu = new UIMenu("Link", 0, 0, false); 132 | addStaticMenu(); 133 | uimanager.addMenu(menu); 134 | } 135 | 136 | function addStaticMenu() 137 | { 138 | menu.addEntry("img/64/delete.png", "Delete element", "deleteSelected();"); 139 | } 140 | 141 | this.drawableChanged = function() 142 | { 143 | var vertices = getVertices(); 144 | uiline.setCoords(vertices.x1, vertices.y1, vertices.x2, vertices.y2, 0); 145 | } 146 | 147 | this.dispose = function() 148 | { 149 | uimanager.removeClickable(uiline); 150 | connector1.getConnectable().getOwner().getDrawable().deleteObserver(_self); 151 | connector2.getConnectable().getOwner().getDrawable().deleteObserver(_self); 152 | if (menu.getVisible()) 153 | { 154 | menu.hide(); 155 | } 156 | uimanager.deleteMenu(menu); 157 | }; 158 | 159 | this.getConnector1 = function() 160 | { 161 | return connector1; 162 | }; 163 | 164 | this.getConnector2 = function() 165 | { 166 | return connector2; 167 | }; 168 | 169 | this.delete = function() 170 | { 171 | connector1.setLink(null); 172 | connector2.setLink(null); 173 | }; 174 | 175 | this.addMessage = function(orig, message) { 176 | var data = {}; 177 | data.pos = 0; 178 | data.message = message; 179 | data.orig = orig; 180 | data.dst = (orig === connector1) ? connector2 : connector1; 181 | messages.push(data); 182 | }; 183 | 184 | function getMessageCoords(pos) 185 | { 186 | var origX = messages[pos].orig.getConnectable().getOwner().getDrawable().getCenterX(); 187 | var origY = messages[pos].orig.getConnectable().getOwner().getDrawable().getCenterY(); 188 | var dstX = messages[pos].dst.getConnectable().getOwner().getDrawable().getCenterX(); 189 | var dstY = messages[pos].dst.getConnectable().getOwner().getDrawable().getCenterY(); 190 | var X = origX + (dstX - origX) * messages[pos].pos / 100; 191 | var Y = origY + (dstY - origY) * messages[pos].pos / 100; 192 | 193 | return {x: X,y: Y}; 194 | } 195 | 196 | function drawMessageInfo(ctx, message) 197 | { 198 | var pos = 8; 199 | ctx.font = '8pt'; 200 | ctx.fillStyle = "black"; 201 | var parts = message.getStrInfo().split("\n"); 202 | for (var i = 0; i < parts.length; i++) 203 | { 204 | ctx.fillText(parts[i], 0, message.getImage().height + pos); 205 | pos += 8; 206 | } 207 | } 208 | 209 | function drawMessages(ctx) 210 | { 211 | for (var i = 0; i < messages.length; i++) 212 | { 213 | var coords = getMessageCoords(i); 214 | ctx.save(); 215 | ctx.translate(coords.x, coords.y); 216 | ctx.drawImage(messages[i].message.getImage(), 0, 0); 217 | drawMessageInfo(ctx,messages[i].message); 218 | ctx.restore(); 219 | } 220 | } 221 | 222 | function getVertices() 223 | { 224 | return { 225 | x1: connector1.getConnectable().getOwner().getDrawable().getCenterX(), 226 | y1: connector1.getConnectable().getOwner().getDrawable().getCenterY(), 227 | x2: connector2.getConnectable().getOwner().getDrawable().getCenterX(), 228 | y2: connector2.getConnectable().getOwner().getDrawable().getCenterY() 229 | }; 230 | } 231 | 232 | /*function drawConnectorDescription(ctx, connector, x1, y1, x2, y2) 233 | { 234 | var mod = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); 235 | var X = x1 + (x2 - x1) * 32 / mod; 236 | var Y = y1 + (y2 - y1) * 32 / mod; 237 | ctx.font = '8pt'; 238 | ctx.fillStyle = "black"; 239 | ctx.fillText(connector.getDescription(), X, Y); 240 | }*/ 241 | 242 | this.draw = function(ctx, selected) 243 | { 244 | var vertices = getVertices(); 245 | ctx.lineWidth = 2; 246 | ctx.strokeStyle = selected ? "blue" : "red"; 247 | ctx.beginPath(); 248 | ctx.moveTo(vertices.x1, vertices.y1); 249 | ctx.lineTo(vertices.x2, vertices.y2); 250 | ctx.stroke(); 251 | 252 | //drawConnectorDescription(ctx, connector1, vertices.x1, vertices.y1, vertices.x2, vertices.y2); 253 | //drawConnectorDescription(ctx, connector2, vertices.x2, vertices.y2, vertices.x1, vertices.y1); 254 | 255 | drawMessages(ctx); 256 | }; 257 | 258 | this.update = function() 259 | { 260 | var newmessages = []; 261 | for (var i = 0; i < messages.length; i++) 262 | { 263 | messages[i].pos += AnimationControls.MSG_ADVANCE; 264 | if (messages[i].pos < 100) 265 | { 266 | newmessages.push(messages[i]); 267 | } 268 | else 269 | { 270 | messages[i].dst.receive(messages[i].message); 271 | } 272 | } 273 | 274 | messages = newmessages; 275 | } 276 | 277 | this.messageHasCoords = function(pos, x, y) 278 | { 279 | var coords = getMessageCoords(pos); 280 | 281 | return (coords.x <= x) && (x <= coords.x + messages[pos].message.getImage().width) && 282 | (coords.y <= y) && (y <= coords.y + messages[pos].message.getImage().height); 283 | }; 284 | 285 | this.getMessage = function(pos) 286 | { 287 | return messages[pos].message; 288 | }; 289 | 290 | this.getMessageCount = function() 291 | { 292 | return messages.length; 293 | }; 294 | 295 | this.hasCoords = function(x, y) 296 | { 297 | var vertices = getVertices(); 298 | 299 | return distToSegment({x: x,y: y}, {x: vertices.x1,y: vertices.y1}, {x: vertices.x2,y: vertices.y2}) < LINE_SELECT_TOLERANCE; 300 | }; 301 | 302 | this.getCenter = function() 303 | { 304 | var result = {}; 305 | var vertices = getVertices(); 306 | 307 | result.x = (vertices.x1 + vertices.x2) / 2.0; 308 | result.y = (vertices.y1 + vertices.y2) / 2.0; 309 | 310 | return result; 311 | }; 312 | 313 | this.getMenu = function() 314 | { 315 | return menu; 316 | }; 317 | 318 | init(); 319 | }; 320 | -------------------------------------------------------------------------------- /js/Message.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | var lastMessageId = 0; 15 | 16 | function getNextMessageId() 17 | { 18 | return ++lastMessageId; 19 | } 20 | 21 | var Message = function(type, origIP, dstIP, origMAC, dstMAC, origPort, dstPort, dat, img) 22 | { 23 | var originIP = origIP; 24 | var destinationIP = dstIP; 25 | var originMAC = origMAC; 26 | var destinationMAC = dstMAC; 27 | var origPort = origPort; 28 | var dstPort = dstPort; 29 | var data = dat; 30 | var image = img; 31 | var id = getNextMessageId(); 32 | var type = type; 33 | var TTL = 32; 34 | 35 | this.decreaseTTL = function() 36 | { 37 | TTL--; 38 | }; 39 | 40 | this.canSend = function() 41 | { 42 | return TTL !== 0; 43 | }; 44 | 45 | this.getId = function() { 46 | return id; 47 | }; 48 | 49 | this.getImage = function() { 50 | return image; 51 | }; 52 | 53 | this.getOriginIP = function() { 54 | return originIP; 55 | }; 56 | 57 | this.setOriginIP = function(ip) { 58 | originIP = ip; 59 | }; 60 | 61 | this.getOriginMAC = function() { 62 | return originMAC; 63 | }; 64 | 65 | this.setOriginMAC = function(mac) { 66 | originMAC = mac; 67 | }; 68 | 69 | this.getDestinationIP = function() { 70 | return destinationIP; 71 | }; 72 | 73 | this.setDestinationIP = function(ip) { 74 | destinationIP = ip; 75 | }; 76 | 77 | this.getDestinationMAC = function() { 78 | return destinationMAC; 79 | }; 80 | 81 | this.setDestinationMAC = function(mac) { 82 | destinationMAC = mac; 83 | }; 84 | 85 | this.getOrigPort = function() { 86 | return origPort; 87 | }; 88 | 89 | this.setOrigPort = function(port) { 90 | origPort = port; 91 | }; 92 | 93 | this.getDstPort = function() { 94 | return dstPort; 95 | }; 96 | 97 | this.setDstPort = function(port) { 98 | dstPort = port; 99 | }; 100 | 101 | this.getData = function() { 102 | return data; 103 | }; 104 | 105 | this.getType = function() 106 | { 107 | return type; 108 | }; 109 | 110 | this.getStrInfo = function() 111 | { 112 | var result = "Src: " + ((this.getOriginIP() === null)?"-":this.getOriginIP()) + "\n"; 113 | result += "Dst: " + ((this.getDestinationIP() === null)?"-":this.getDestinationIP()); 114 | if (data.description) 115 | { 116 | result += "\n"; 117 | result += data.description; 118 | } 119 | 120 | return result; 121 | }; 122 | }; 123 | -------------------------------------------------------------------------------- /js/Network.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | function deleteSelected() 15 | { 16 | if ((network.getSelected() !== null) && (network.getSelected() instanceof Host)) 17 | { 18 | if (confirm("Do you really want to delete the selected element?")) 19 | { 20 | network.deleteSelectedElement(); 21 | uimanager.selectedElementDeleted(); 22 | } 23 | } 24 | else if ((network.getSelected() !== null) && (network.getSelected() instanceof Link)) 25 | { 26 | if (confirm("Do you really want to delete the selected link?")) 27 | { 28 | network.deleteSelectedLink(); 29 | uimanager.selectedLineDeleted(); 30 | } 31 | } 32 | } 33 | 34 | var Network = function(imgs, context, w, h) 35 | { 36 | var elements = []; 37 | var links = []; 38 | var images = imgs; 39 | var ctx = context; 40 | var _self = this; 41 | var W = w; 42 | var H = h; 43 | var selected = null; 44 | 45 | this.init = function() 46 | { 47 | setInterval(render, REFRESH_INTERVAL); 48 | }; 49 | 50 | this.getImages = function() 51 | { 52 | return images; 53 | }; 54 | 55 | this.createComputer = function(x, y) 56 | { 57 | c = new Host("computer", 1); 58 | c.getDrawable().setPosition(x, y); 59 | c.getDrawable().setImage(images[IMAGE_COMPUTER]); 60 | 61 | var dhcpClient = new DHCPClient(0); 62 | c.addApp(dhcpClient, -1, false); 63 | 64 | var dnsClient = new DNSClient(0); 65 | c.addApp(dnsClient, -1, false); 66 | 67 | var httpClient = new HTTPClient(0); 68 | c.addApp(httpClient, -1, false); 69 | 70 | elements[c.id] = c; 71 | 72 | return c.id; 73 | }; 74 | 75 | this.createDHCPServer = function(x, y) 76 | { 77 | c = new Host("dhcpserver", 1); 78 | c.getDrawable().setPosition(x, y); 79 | c.getDrawable().setImage(images[IMAGE_SERVERDHCP]); 80 | var dhcpServer = new DHCPServer(0); 81 | c.addApp(dhcpServer, 67, true); 82 | elements[c.id] = c; 83 | 84 | return c.id; 85 | }; 86 | 87 | this.createDNSServer = function(x, y) 88 | { 89 | c = new Host("dnsserver", 1); 90 | c.getDrawable().setPosition(x, y); 91 | c.getDrawable().setImage(images[IMAGE_SERVERDNS]); 92 | var dnsServer = new DNSServer(0); 93 | c.addApp(dnsServer, 53, true); 94 | elements[c.id] = c; 95 | 96 | return c.id; 97 | }; 98 | 99 | this.createHTTPServer = function(x, y) 100 | { 101 | c = new Host("httpserver", 1); 102 | c.getDrawable().setPosition(x, y); 103 | c.getDrawable().setImage(images[IMAGE_SERVERWEB]); 104 | var httpServer = new HTTPServer(0); 105 | c.addApp(httpServer, 80, true); 106 | elements[c.id] = c; 107 | 108 | return c.id; 109 | }; 110 | 111 | this.createSwitch = function(x, y, ports) 112 | { 113 | s = new Host("switch", ports); 114 | s.getDrawable().setPosition(x, y); 115 | s.getDrawable().setImage(images[IMAGE_SWITCH]); 116 | elements[s.id] = s; 117 | 118 | return s.id; 119 | }; 120 | 121 | this.createRouter = function(x, y) 122 | { 123 | r = new Host("router", 2); 124 | r.getDrawable().setPosition(x, y); 125 | r.getDrawable().setImage(images[IMAGE_ROUTER]); 126 | elements[r.id] = r; 127 | 128 | return r.id; 129 | }; 130 | 131 | this.createLink = function(e1, c1, e2, c2) 132 | { 133 | var element1 = elements[e1]; 134 | var element2 = elements[e2]; 135 | 136 | var connector1 = element1.getConnectable().getConnector(c1); 137 | var connector2 = element2.getConnectable().getConnector(c2); 138 | var success = false; 139 | 140 | if ((connector1 !== null) && (connector2 !== null)) 141 | { 142 | var link = new Link(connector1, connector2); 143 | links.push(link); 144 | success = links.length; 145 | } 146 | 147 | return success; 148 | }; 149 | 150 | this.getElement = function(id) 151 | { 152 | var result = null; 153 | 154 | result = elements[id]; 155 | 156 | return result; 157 | }; 158 | 159 | this.getLink = function(pos) 160 | { 161 | var result = null; 162 | 163 | if (pos < links.length) 164 | { 165 | result = links[pos]; 166 | } 167 | 168 | return result; 169 | }; 170 | 171 | function countUntilDestination(connector, dstIP, dstMAC, visited) 172 | { 173 | var result = -1; 174 | // Si el conector no tiene link, devolvemos -1 175 | if (connector.isConnected()) 176 | { 177 | // Si el conector tiene link, cogemos el conectable del otro extremo 178 | var c = connector.getConnectedConnector().getConnectable(); 179 | // Si no lo hemos visitado 180 | if (visited.indexOf(c) === -1) 181 | { 182 | // Si tiene la dirección, devolvemos 0 183 | if (c.compatibleIP(dstIP, false) || c.compatibleMAC(dstMAC, false)) 184 | { 185 | result = 0; 186 | } 187 | else 188 | { 189 | // Si no, contamos hasta el destino en cada uno de sus conectores 190 | var min = 100000; 191 | for (var i = 0; i < c.getConnectorNumber(); i++) 192 | { 193 | visited.push(c); 194 | var num = countUntilDestination(c.getConnector(i), dstIP, dstMAC, visited); 195 | num = (num === -1) ? -1 : num + 1; 196 | if ((num !== -1) && (num < min)) 197 | { 198 | result = c.getConnector(i); 199 | min = num; 200 | } 201 | } 202 | 203 | if (min !== 100000) 204 | { 205 | result = min; 206 | } 207 | } 208 | } 209 | } 210 | 211 | return result; 212 | } 213 | 214 | this.findNextConnectorInPath = function(currentConnectable, dstIP, dstMAC) 215 | { 216 | // Por cada uno de los conectores del conectable, contamos cuántos pasos hay desde cada uno 217 | var result = null; 218 | var min = 100000; 219 | for (var i = 0; i < currentConnectable.getConnectorNumber(); i++) 220 | { 221 | var visited = []; 222 | visited.push(currentConnectable); 223 | var num = countUntilDestination(currentConnectable.getConnector(i), dstIP, dstMAC, visited); 224 | num = (num === -1) ? -1 : num + 1; 225 | if ((num !== -1) && (num < min)) 226 | { 227 | result = currentConnectable.getConnector(i); 228 | min = num; 229 | } 230 | } 231 | 232 | return result; 233 | }; 234 | 235 | this.getElementInCoords = function(x, y) 236 | { 237 | var result = null; 238 | var i = 0; 239 | var keys = Object.keys(elements); 240 | while ((result === null) && (i < keys.length)) 241 | { 242 | if (elements[keys[i]].getDrawable().hasCoords(x, y)) 243 | { 244 | result = elements[keys[i]]; 245 | } 246 | else 247 | { 248 | i++; 249 | } 250 | } 251 | 252 | return result; 253 | }; 254 | 255 | this.getMessageInCoords = function(x, y) 256 | { 257 | var result = null; 258 | var i = 0; 259 | 260 | while ((result === null) && (i < links.length)) 261 | { 262 | var messagecount = links[i].getMessageCount(); 263 | var j = 0; 264 | while ((result === null) && (j < messagecount)) 265 | { 266 | if (links[i].messageHasCoords(j, x, y)) 267 | { 268 | result = links[i].getMessage(j); 269 | } 270 | else 271 | { 272 | j++; 273 | } 274 | } 275 | if (result === null) 276 | { 277 | i++; 278 | } 279 | } 280 | 281 | return result; 282 | }; 283 | 284 | this.getPosForElement = function(elem) 285 | { 286 | return elements.indexOf(elem); 287 | }; 288 | 289 | this.getLinkInCoords = function(x, y) 290 | { 291 | var result = null; 292 | var i = 0; 293 | 294 | while ((result === null) && (i < links.length)) 295 | { 296 | if (links[i].hasCoords(x, y)) 297 | { 298 | result = links[i]; 299 | } 300 | else 301 | { 302 | i++; 303 | } 304 | } 305 | 306 | return result; 307 | }; 308 | 309 | this.setSelected = function(s) 310 | { 311 | selected = s; 312 | }; 313 | 314 | this.getSelected = function() 315 | { 316 | return selected; 317 | }; 318 | 319 | function deleteLink(link) 320 | { 321 | link.getConnector1().setLink(null); 322 | link.getConnector2().setLink(null); 323 | var pos = links.indexOf(link); 324 | links.splice(pos, 1); 325 | link.dispose(); 326 | } 327 | 328 | function deleteElement(element) 329 | { 330 | var num = selected.getConnectable().getConnectorNumber(); 331 | for (var i = 0; i < num; i++) 332 | { 333 | var connector = selected.getConnectable().getConnector(i); 334 | if (connector.getLink() !== null) 335 | { 336 | deleteLink(connector.getLink()); 337 | } 338 | } 339 | var pos = elements.indexOf(element); 340 | //elements.splice(pos, 1); 341 | delete elements[pos]; 342 | } 343 | 344 | this.deleteSelectedLink = function() 345 | { 346 | deleteLink(selected); 347 | selected = null; 348 | }; 349 | 350 | this.deleteSelectedElement = function() 351 | { 352 | deleteElement(selected); 353 | selected.dispose(); 354 | selected = null; 355 | }; 356 | 357 | function renderGroups(ctx) 358 | { 359 | var groups = []; 360 | var keys = Object.keys(elements); 361 | for (var i = 0; i < keys.length; i++) 362 | { 363 | var host = elements[keys[i]]; 364 | if (host.getGroup() !== null) 365 | { 366 | if (!(host.getGroup() in groups)) 367 | { 368 | var data = {}; 369 | data.minx = 1000000; 370 | data.miny = 1000000; 371 | data.maxx = 0; 372 | data.maxy = 0; 373 | 374 | groups[host.getGroup()] = data; 375 | } 376 | var data = groups[host.getGroup()]; 377 | var rect = host.getDrawable().getRect(); 378 | if (data.minx > rect.x) 379 | { 380 | data.minx = rect.x; 381 | } 382 | if (data.miny > rect.y) 383 | { 384 | data.miny = rect.y; 385 | } 386 | if (data.maxx < rect.x + rect.width) 387 | { 388 | data.maxx = rect.x + rect.width; 389 | } 390 | if (data.maxy < rect.y + rect.height) 391 | { 392 | data.maxy = rect.y + rect.height; 393 | } 394 | } 395 | } 396 | 397 | keys = Object.keys(groups); 398 | for (var i = 0; i < keys.length; i++) 399 | { 400 | var data = groups[keys[i]]; 401 | ctx.strokeStyle = "rgba(255,255,255,0.5)"; 402 | ctx.lineWidth = 4; 403 | ctx.strokeRect(data.minx - 10, data.miny - 10, data.maxx - data.minx + 20, data.maxy - data.miny + 20); 404 | ctx.font = '16pt'; 405 | ctx.fillStyle = "rgba(255,255,255,1.0)"; 406 | ctx.fillText(keys[i], data.minx, data.maxy + 20); 407 | } 408 | } 409 | 410 | function render() 411 | { 412 | ctx.fillStyle = "#DDDDDD"; 413 | ctx.fillRect(0, 0, W, H); 414 | 415 | for (var i = 0; i < links.length; i++) 416 | { 417 | links[i].update(); 418 | links[i].draw(ctx, selected === links[i]); 419 | } 420 | 421 | var keys = Object.keys(elements); 422 | for (var i = 0; i < keys.length; i++) 423 | { 424 | elements[keys[i]].getDrawable().draw(ctx); 425 | } 426 | 427 | renderGroups(ctx); 428 | 429 | uimanager.render(ctx); 430 | 431 | if (DEBUG) 432 | { 433 | ctx.fillStyle = "#000000"; 434 | var coords = uimanager.getMousePos(); 435 | ctx.fillText("Mouse coords - X: " + coords.X + " - Y: " + coords.Y, 10, 100); 436 | } 437 | } 438 | 439 | this.save = function() 440 | { 441 | var result = {}; 442 | result.version = 1; 443 | result.lastusedid = lastusedid; 444 | result.elements = []; 445 | result.links = []; 446 | 447 | var keys = Object.keys(elements); 448 | for (var i = 0; i < keys.length; i++) 449 | { 450 | result.elements.push(elements[keys[i]].save()); 451 | } 452 | 453 | for (var i = 0; i < links.length; i++) 454 | { 455 | result.links.push(links[i].save()); 456 | } 457 | 458 | return JSON.stringify(result); 459 | }; 460 | 461 | this.load = function(data) 462 | { 463 | uimanager.reset(); 464 | switch (data.version) 465 | { 466 | case 1: 467 | loadv1(data); 468 | break; 469 | } 470 | ; 471 | }; 472 | 473 | function loadv1(data) 474 | { 475 | links = []; 476 | elements = []; 477 | 478 | for (var i = 0; i < data.elements.length; i++) 479 | { 480 | var element = null; 481 | var ports = 1; 482 | if (data.elements[i].ports) 483 | { 484 | ports = data.elements[i].ports; 485 | } 486 | else if (data.elements[i].type === "router") 487 | { 488 | ports = 2; 489 | } 490 | element = new Host(data.elements[i].type, ports); 491 | element.load(data.elements[i]); 492 | elements[element.id] = element; 493 | } 494 | 495 | for (var i = 0; i < data.links.length; i++) 496 | { 497 | var c1 = _self.findConnector(data.links[i].connector1); 498 | var c2 = _self.findConnector(data.links[i].connector2); 499 | var link = new Link(c1, c2); 500 | link.load(data.links[i]); 501 | links.push(link); 502 | } 503 | 504 | lastusedid = data.lastusedid; 505 | } 506 | 507 | this.findConnector = function(id) 508 | { 509 | var keys = Object.keys(elements); 510 | var result = null; 511 | var i = 0; 512 | while ((result === null) && (i < keys.length)) 513 | { 514 | result = elements[keys[i]].getConnectable().findConnector(id); 515 | i++; 516 | } 517 | 518 | return result; 519 | }; 520 | }; 521 | -------------------------------------------------------------------------------- /js/UIClickable.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | function UIClickable(callback, params, object) 15 | { 16 | var callback = callback; 17 | var params = params; 18 | var object = object; 19 | 20 | this.isInCoords = function(X, Y, Z) 21 | { 22 | alert("This function needs to be redefined - isInCoords"); 23 | }; 24 | 25 | this.performAction = function() 26 | { 27 | if (callback !== null) 28 | { 29 | callback(params); 30 | } 31 | }; 32 | 33 | this.getObject = function() 34 | { 35 | return object; 36 | }; 37 | }; 38 | -------------------------------------------------------------------------------- /js/UILine.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | // THANK_YOU: http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment 15 | function sqr(x) { return x * x } 16 | function dist2(v, w) { return sqr(v.x - w.x) + sqr(v.y - w.y) } 17 | function distToSegmentSquared(p, v, w) { 18 | var l2 = dist2(v, w); 19 | if (l2 == 0) return dist2(p, v); 20 | var t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2; 21 | if (t < 0) return dist2(p, v); 22 | if (t > 1) return dist2(p, w); 23 | return dist2(p, { x: v.x + t * (w.x - v.x), 24 | y: v.y + t * (w.y - v.y) }); 25 | } 26 | function distToSegment(p, v, w) { return Math.sqrt(distToSegmentSquared(p, v, w)); } 27 | 28 | UILine.prototype = new UIClickable(); 29 | UILine.prototype.constructor = UILine; 30 | function UILine(callback, params, object, X1, Y1, X2, Y2, Z) 31 | { 32 | UIClickable.call(this,callback,params, object); 33 | this.X1 = X1; 34 | this.Y1 = Y1; 35 | this.X2 = X2; 36 | this.Y2 = Y2; 37 | this.Z = Z; 38 | 39 | this.setCoords = function(cX1, cY1, cX2, cY2, Z) 40 | { 41 | this.X1 = cX1; 42 | this.Y1 = cY1; 43 | this.X2 = cX2; 44 | this.Y2 = cY2; 45 | this.Z = Z; 46 | }; 47 | 48 | this.isInCoords = function(cX,cY) 49 | { 50 | return distToSegment({x: cX,y: cY}, {x: this.X1,y: this.Y1}, {x: this.X2,y: this.Y2}) < LINE_SELECT_TOLERANCE; 51 | }; 52 | }; 53 | -------------------------------------------------------------------------------- /js/UIMenu.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | var UIMenu = function(description, X,Y, fixed) 15 | { 16 | var X = X; 17 | var Y = Y; 18 | var entries = []; 19 | var id = "uimenu_" + getNextID(); 20 | var description = description; 21 | var visible = false; 22 | var fixed = fixed; 23 | var _self = this; 24 | 25 | function init() 26 | { 27 | uitranslation.addObserver(_self); 28 | } 29 | 30 | this.dispose = function() 31 | { 32 | uitranslation.deleteObserver(this); 33 | }; 34 | 35 | this.localeChanged = function() 36 | { 37 | /*for (var i = 0; i < entries.length; i++) 38 | { 39 | var span = document.getElementById(entries[i].id); 40 | span.innerHTML = _(entries[i].text); 41 | }*/ 42 | }; 43 | 44 | this.getId = function() 45 | { 46 | return id; 47 | }; 48 | 49 | this.getVisible = function() 50 | { 51 | return visible; 52 | }; 53 | 54 | this.addEntry = function(img, text, js) 55 | { 56 | var data = {}; 57 | data.id = "entry_" + getNextID(); 58 | data.img = img; 59 | data.text = text; 60 | data.js = js; 61 | entries.push(data); 62 | }; 63 | 64 | this.setPos = function(cX, cY) 65 | { 66 | X = cX; 67 | Y = cY; 68 | } 69 | 70 | this.setDescription = function(desc) 71 | { 72 | description = desc; 73 | }; 74 | 75 | this.purge = function() 76 | { 77 | entries = []; 78 | } 79 | 80 | this.show = function() 81 | { 82 | var div = document.createElement("div"); 83 | div.setAttribute("id",id); 84 | div.setAttribute("style","width:200px;background-color:#EEEEEE;border:3px solid white;position:"+ (fixed?"fixed":"absolute") +";top:"+Y+"px;left:"+X+"px;font-size:0.8em;padding:0px 10px 0px;"); 85 | 86 | var innerHtml = "" + _(description) + "
"; 87 | 88 | for (var i = 0; i < entries.length; i++) 89 | { 90 | innerHtml += ""; 91 | innerHtml += ""; 92 | innerHtml += "" + _(entries[i].text) + "
"; 93 | if (i !== entries.length - 1) 94 | { 95 | innerHtml += "
" 96 | } 97 | } 98 | 99 | div.innerHTML = innerHtml; 100 | 101 | document.body.appendChild(div); 102 | visible = true; 103 | }; 104 | 105 | this.hide = function() 106 | { 107 | var div = document.getElementById(id); 108 | document.body.removeChild(div); 109 | visible = false; 110 | }; 111 | 112 | init(); 113 | }; -------------------------------------------------------------------------------- /js/UIRectangle.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | UIRectangle.prototype = new UIClickable(); 15 | UIRectangle.prototype.constructor = UIRectangle; 16 | function UIRectangle(callback, params, object, X, Y, W, H, Z, fixed) 17 | { 18 | UIClickable.call(this,callback,params,object); 19 | this.X = X; 20 | this.Y = Y; 21 | this.W = W; 22 | this.H = H; 23 | this.Z = Z; 24 | var fixed = fixed; 25 | 26 | this.setCoords = function(cX,cY,cW,cH,cZ) 27 | { 28 | this.X = cX; 29 | this.Y = cY; 30 | this.W = cW; 31 | this.H = cH; 32 | this.Z = cZ; 33 | }; 34 | 35 | //UIRectangle.prototype.isInCoords = function(cX,cY) 36 | this.isInCoords = function(cX,cY) 37 | { 38 | if (fixed) 39 | { 40 | cX -= document.body.scrollLeft; 41 | cY -= document.body.scrollTop; 42 | } 43 | return (this.X <= cX) && (cX <= (this.X + this.W)) && (this.Y < cY) && (cY < (this.Y + this.H)); 44 | }; 45 | 46 | }; 47 | 48 | -------------------------------------------------------------------------------- /js/UITable.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | var lasttableid = 0; 15 | var uitables = []; 16 | 17 | function getNextTableID() 18 | { 19 | return ++lasttableid; 20 | } 21 | 22 | function deleteUITableRow(id,row) 23 | { 24 | uitables[id].deleteRow(row); 25 | } 26 | 27 | function addUITableRow(id) 28 | { 29 | uitables[id].addRow(); 30 | } 31 | 32 | var UITable = function(headers, data, tableid) 33 | { 34 | var headers = headers; 35 | var data = data; 36 | var tableid = tableid; 37 | var id = "uitable_" + getNextTableID(); 38 | var editsecondary = false; 39 | var editsecondaryfunc = null; 40 | var params = []; 41 | uitables[id] = this; 42 | 43 | this.getId = function() 44 | { 45 | return id; 46 | }; 47 | 48 | this.setParam = function(id, value) 49 | { 50 | params[id] = value; 51 | }; 52 | 53 | this.getParam = function(id) 54 | { 55 | var result = null; 56 | if (id in params) 57 | { 58 | result = params[id]; 59 | } 60 | return result; 61 | }; 62 | 63 | this.setSecondary = function(editsecondary_p, editsecondaryfunc_p) 64 | { 65 | editsecondary = editsecondary_p; 66 | editsecondaryfunc = editsecondaryfunc_p; 67 | }; 68 | 69 | this.render = function() 70 | { 71 | var result = ''; 72 | result += ''; 73 | for (var i = 0; i < headers.length; i++) 74 | { 75 | result += '' + headers[i] + ''; 76 | } 77 | result += ''+_("Controls")+'' 78 | result += ''; 79 | 80 | for (var i = 0; i < data.length; i++) 81 | { 82 | result += ''; 83 | for (var j = 0; j < headers.length; j++) 84 | { 85 | var inputid = tableid + "_" + i + "_" + j; 86 | result += ''; 87 | result += ''; 88 | result += ''; 89 | } 90 | result += ''; 91 | result += ''+_('; 92 | if (editsecondary) 93 | { 94 | result += ''+_('; 95 | } 96 | result += ''; 97 | result += ''; 98 | } 99 | result += ''; 100 | for (var j = 0; j < headers.length; j++) 101 | { 102 | var inputid = tableid + "_new_" + j; 103 | result += ''; 104 | result += ''; 105 | result += ''; 106 | } 107 | result += ''+_('; 108 | result += ''; 109 | 110 | document.getElementById(tableid).innerHTML = result; 111 | }; 112 | 113 | this.deleteRow = function(row) 114 | { 115 | data.splice(row,1); 116 | this.render(); 117 | }; 118 | 119 | this.dispose = function() 120 | { 121 | delete uitables[id]; 122 | }; 123 | 124 | this.getData = function() 125 | { 126 | return data; 127 | }; 128 | 129 | this.addRow = function() 130 | { 131 | var row = []; 132 | 133 | for (var j = 0; j < headers.length; j++) 134 | { 135 | var inputid = tableid + "_new_" + j; 136 | var value = document.getElementById(inputid).value; 137 | row.push(value); 138 | } 139 | 140 | data.push(row); 141 | this.render(); 142 | }; 143 | }; 144 | -------------------------------------------------------------------------------- /js/UITranslation.js: -------------------------------------------------------------------------------- 1 | function createLocaleDiv() 2 | { 3 | createBkDiv(); 4 | 5 | var w = new UIWindow("localediv", "Select language", 300, 150, false, 1.0); 6 | var content = uitranslation.getControls() 7 | var controls = ''; 8 | controls += ''; 9 | w.setContent(content); 10 | w.setControls(controls); 11 | w.render(); 12 | } 13 | 14 | function localeSelected() 15 | { 16 | var locale = document.getElementById("localeselector").value; 17 | uitranslation.selectLocale(locale); 18 | removeBodyDiv('divbk'); 19 | uimanager.getWindow("localediv").dispose(); 20 | } 21 | 22 | function localeCancelled() 23 | { 24 | removeBodyDiv('divbk'); 25 | uimanager.getWindow("localediv").dispose(); 26 | } 27 | 28 | function _(text) 29 | { 30 | return uitranslation._(text); 31 | } 32 | 33 | var UITranslation = function() { 34 | var current = "en_GB"; 35 | var locales = []; 36 | var observers = []; 37 | 38 | this.registerLocale = function(locale) 39 | { 40 | locales[locale.locale] = locale; 41 | }; 42 | 43 | this.getLocales = function() 44 | { 45 | return Object.keys(locales); 46 | }; 47 | 48 | this.addObserver = function(observer) 49 | { 50 | observers.push(observer); 51 | }; 52 | 53 | this.removeObserver = function(observer) 54 | { 55 | var pos = observers.indexOf(observer); 56 | if (pos >= 0) 57 | { 58 | observers.splice(pos, 1); 59 | } 60 | }; 61 | 62 | this.selectLocale = function(locale) 63 | { 64 | current = locale; 65 | notifyObservers(); 66 | }; 67 | 68 | function notifyObservers() 69 | { 70 | for (var i = 0; i < observers.length; i++) 71 | { 72 | observers[i].localeChanged(); 73 | } 74 | } 75 | 76 | this._ = function(text) 77 | { 78 | var result = text; 79 | if ((current in locales) && (text in locales[current])) 80 | { 81 | result = locales[current][text]; 82 | } 83 | 84 | return result; 85 | }; 86 | 87 | this.getControls = function() 88 | { 89 | var result = ''; 97 | 98 | return result; 99 | }; 100 | }; 101 | 102 | var uitranslation = new UITranslation(); 103 | -------------------------------------------------------------------------------- /js/UIWindow.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | var UIWindow = function(windowid, title, w, h, scrollable, opacity) 15 | { 16 | var STATE_MOUSE_DOWN = 0; 17 | var STATE_MOUSE_UP = 1; 18 | var state = STATE_MOUSE_UP; 19 | 20 | var ACTION_MOUSE_DOWN = 0; 21 | var ACTION_MOUSE_UP = 1; 22 | var ACTION_MOUSE_MOVE = 2; 23 | 24 | var title = title; 25 | var w = w; 26 | var h = h; 27 | var x = window.innerWidth / 2 - w / 2; 28 | var y = window.innerHeight / 2 - h / 2; 29 | var opacity = opacity; 30 | var scrollable = scrollable; 31 | var windowid = windowid; 32 | var contentid = contentid + "_contents"; 33 | var controlsid = controlsid + "_controls"; 34 | var outerdiv = null; 35 | var titlediv = null; 36 | var contentDiv = null; 37 | var controlsDiv = null; 38 | 39 | var click_offset_x = 0; 40 | var click_offset_y = 0; 41 | var move_X = 0; 42 | var move_Y = 0; 43 | 44 | var _self = this; 45 | 46 | function windowMouseDownEvent(e) 47 | { 48 | var bbox = titlediv.getBoundingClientRect(); 49 | var evt_x = e.clientX; 50 | var evt_y = e.clientY; 51 | 52 | if ((bbox.left <= evt_x) && (evt_x <= (bbox.left + bbox.width)) 53 | && (bbox.top <= evt_y) && (evt_y <= (bbox.top + bbox.height))) 54 | { 55 | dispatchEvent(evt_x, evt_y, ACTION_MOUSE_DOWN); 56 | } 57 | } 58 | 59 | function windowMouseUpEvent(e) 60 | { 61 | dispatchEvent(-1, -1, ACTION_MOUSE_UP); 62 | } 63 | 64 | function windowMouseMoveEvent(e) 65 | { 66 | var evt_x = e.clientX; 67 | var evt_y = e.clientY; 68 | 69 | dispatchEvent(evt_x, evt_y, ACTION_MOUSE_MOVE); 70 | } 71 | 72 | function dispatchEvent(evt_x, evt_y, action) 73 | { 74 | switch (state) 75 | { 76 | case STATE_MOUSE_DOWN: 77 | switch (action) 78 | { 79 | case ACTION_MOUSE_UP: 80 | state = STATE_MOUSE_UP; 81 | break; 82 | case ACTION_MOUSE_MOVE: 83 | x = evt_x - click_offset_x + scrollX; 84 | y = evt_y - click_offset_y + scrollY; 85 | outerdiv.setAttribute('style', getOuterStyle()); 86 | break; 87 | } 88 | break; 89 | case STATE_MOUSE_UP: 90 | switch (action) 91 | { 92 | case ACTION_MOUSE_DOWN: 93 | var bbox = titlediv.getBoundingClientRect(); 94 | click_offset_x = evt_x - bbox.left; 95 | click_offset_y = evt_y - bbox.top; 96 | state = STATE_MOUSE_DOWN; 97 | break; 98 | } 99 | break; 100 | } 101 | } 102 | 103 | function getOuterStyle() 104 | { 105 | return 'position:absolute;top:' + y + 'px;left:' + x + 'px;z-index:110;background-color:white;width:' + w + 'px;height:' + h + 'px;border-radius:10px;border:1px solid;padding:10px;text-align:center;opacity:' + opacity + ';'; 106 | } 107 | 108 | function init() 109 | { 110 | outerdiv = document.createElement("div"); 111 | outerdiv.setAttribute('id', windowid); 112 | outerdiv.setAttribute('style', getOuterStyle()); 113 | 114 | titlediv = document.createElement("div"); 115 | titlediv.setAttribute('id', windowid + "_title"); 116 | titlediv.setAttribute('style', 'width:100%;height:20px;background-color:blue;color:white;font-weight:bold;-webkit-touch-callout: none;-webkit-user-select: none;-khtml-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;'); 117 | titlediv.innerHTML = _(title); 118 | 119 | contentDiv = document.createElement("div"); 120 | contentDiv.setAttribute('id', contentid); 121 | contentDiv.setAttribute('style', 'width:100%; height:' + h - 80 + 'px;') 122 | 123 | controlsDiv = document.createElement("div"); 124 | controlsDiv.setAttribute('id', controlsid); 125 | controlsDiv.setAttribute('style', 'width:100%; height:40px;') 126 | 127 | //var bkdiv = document.getElementById('divbk'); 128 | window.addEventListener("mousedown", windowMouseDownEvent, true); 129 | window.addEventListener("mouseup", windowMouseUpEvent, true); 130 | window.addEventListener("mousemove", windowMouseMoveEvent, true); 131 | 132 | uimanager.addWindow(_self); 133 | uitranslation.addObserver(_self); 134 | } 135 | 136 | this.render = function() 137 | { 138 | outerdiv.appendChild(titlediv); 139 | outerdiv.appendChild(contentDiv); 140 | outerdiv.appendChild(controlsDiv); 141 | 142 | document.body.appendChild(outerdiv); 143 | }; 144 | 145 | this.setControls = function(controls) 146 | { 147 | controlsDiv.innerHTML = controls; 148 | }; 149 | 150 | this.setContent = function(content) 151 | { 152 | contentDiv.innerHTML = content; 153 | }; 154 | 155 | this.dispose = function() 156 | { 157 | window.removeEventListener("mousedown", windowMouseDownEvent); 158 | window.removeEventListener("mouseup", windowMouseUpEvent); 159 | window.removeEventListener("mousemove", windowMouseMoveEvent); 160 | uimanager.removeWindow(this); 161 | removeBodyDiv(windowid); 162 | uitranslation.removeObserver(this); 163 | }; 164 | 165 | this.getId = function() 166 | { 167 | return windowid; 168 | }; 169 | 170 | this.getPos = function() 171 | { 172 | return {x: x, y: y}; 173 | }; 174 | 175 | this.setPos = function(nx, ny) 176 | { 177 | x = nx; 178 | y = ny; 179 | outerdiv.setAttribute('style', getOuterStyle()); 180 | }; 181 | 182 | this.localeChanged = function() 183 | { 184 | titlediv.innerHTML = _(title); 185 | }; 186 | 187 | init(); 188 | }; 189 | -------------------------------------------------------------------------------- /js/i18n/.directory: -------------------------------------------------------------------------------- 1 | [Dolphin] 2 | HeaderColumnWidths=106,72,95 3 | Timestamp=2018,3,4,16,44,5 4 | Version=4 5 | ViewMode=1 6 | -------------------------------------------------------------------------------- /js/i18n/en_GB.js: -------------------------------------------------------------------------------- 1 | var en_GB ={ 2 | name: "English (GB)", 3 | locale: "en_GB" 4 | 5 | // Default language 6 | }; 7 | 8 | uitranslation.registerLocale(en_GB); -------------------------------------------------------------------------------- /js/i18n/es_ES.js: -------------------------------------------------------------------------------- 1 | var es_ES ={ 2 | name: "Español", 3 | locale: "es_ES", 4 | "Animation Controls": "Controles de Animación", 5 | "Accept": "Aceptar", 6 | "Cancel": "Cancelar", 7 | "Language:": "Idioma:", 8 | "Select language": "Selecciona idioma", 9 | "Upload":"Cargar", 10 | "Save":"Guardar", 11 | "Add Host":"Añadir equipo", 12 | "Add DHCP server":"Añadir servidor DHCP", 13 | "Add DNS server":"Añadir servidor DNS", 14 | "Add web server":"Añadir servidor web", 15 | "Add switch":"Añadir switch", 16 | "Add router":"Añadir router", 17 | "Delete element":"Eliminar", 18 | "Edit Name / Group":"Editar nombre/grupo", 19 | "Create Link":"Crear enlace", 20 | "Network diagnostics":"Diagnósticos de red", 21 | "Edit Gateways":"Editar gateways", 22 | "Edit IP Info - Interface 0":"Editar información IP - Interfaz 0", 23 | "Edit IP Info - WAN":"Editar información IP - WAN", 24 | "Edit IP Info - LAN":"Editar información IP - LAN", 25 | "Edit NAT table":"Editar tabla NAT", 26 | "Main menu":"Menú principal", 27 | "Upload file":"Cargar fichero", 28 | "Request DHCP info":"Solicitar info. DHCP", 29 | "DNS lookup":"Búsqueda DNS", 30 | "Web browser (HTTP client)":"Navegador web (cliente HTTP)", 31 | "Edit name / group":"Editar nombre / grupo", 32 | "Save":"Guardar", 33 | "Exit":"Salir", 34 | "Group:":"Grupo:", 35 | "Name:":"Nombre:", 36 | "Interface ":"Interfaz ", 37 | "Network":"Red", 38 | "Mask":"Máscara", 39 | "Gateway":"Gateway", 40 | "Controls":"Controles", 41 | "Gateway Configuration":"Configuración de gateways", 42 | "IP Address:":"Dirección IP:", 43 | "Network Mask:":"Máscara de red:", 44 | "DNS 1:":"DNS 1:", 45 | "DNS 2:":"DNS 2:", 46 | "Edit IP Info":"Editar Info IP:", 47 | "Domain:":"Dominio:", 48 | "Lookup":"Buscar", 49 | "Domain":"Dominio", 50 | "IP":"IP", 51 | "DNS Server":"Servidor DNS", 52 | "Forwarder:":"Forwarder:", 53 | "DNS server config":"Configurar servidor DNS", 54 | "DHCP Server":"Servidor DHCP", 55 | "Initial:":"Inicial:", 56 | "Final:":"Final:", 57 | "Gateway:":"Gateway:", 58 | "Close":"Cerrar", 59 | "HTTP Client (Browser)":"Cliente HTTP (Navegador)", 60 | "Loading...":"Cargando...", 61 | "404 - Not found":"404 - No encontrado", 62 | "Malformed URL.\n\nUse only 'domain_or_ip/filename.html'.":"URL incorrecta.\n\nUsa sólo 'dominio_o_ip/fichero.html'.", 63 | "DNS client not present.":"Falta cliente DNS.", 64 | "Domain not in local DNS cache. Look up first.\n\nIf you already performed a lookup, the domain does not exist.":"El dominio no está en la caché local. Busca primero.\n\nSi ya has realizado la búsqueda, el dominio no existe..", 65 | "Edit DHCP server info":"Editar información del servidor DHCP", 66 | "HTTP Server":"Servidor HTTP", 67 | "File":"Fichero", 68 | "Back":"Atrás", 69 | "HTTP Domain Files":"Ficheros del Dominio HTTP", 70 | "HTTP Domain File Edition":"Edición de Fichero del Dominio HTTP", 71 | "Input interface":"Interfaz de entrada", 72 | "WAN Port":"Puerto WAN", 73 | "LAN Port":"Puerto LAN", 74 | "IP: ":"IP: ", 75 | "Gateway mode (uses NAT).":"Modo gateway (usa NAT).", 76 | "Edit NAT":"Editar NAT", 77 | "Edit HTTP server info":"Editar información del servidor HTTP", 78 | "Delete":"Eliminar", 79 | "Edit":"Editar", 80 | "Add":"Añadir", 81 | "Sending traceroute to: ":"Enviando traceroute a: ", 82 | "Sending ping to: ":"Enviando ping a: ", 83 | "Ping response recieved from ":"Respuesta a ping recibida de ", 84 | " - Traceroute to ":" - Traceroute a ", 85 | "Network unreachable: ":"Red inaccesible: ", 86 | "Network not configured for interface: ":"Red no configurada para la interfaz: ", 87 | "File name:":"Nombre del fichero:", 88 | "Download":"Descargar", 89 | "Download file":"Descargar fichero" 90 | }; 91 | 92 | uitranslation.registerLocale(es_ES); 93 | -------------------------------------------------------------------------------- /js/i18n/eu_ES.js: -------------------------------------------------------------------------------- 1 | var eu_ES = { 2 | name: "Euskara", 3 | locale: "eu_ES", 4 | "Animation Controls": "Animazio kontrolak", 5 | "Accept": "Onartu", 6 | "Cancel": "Ezeztatu", 7 | "Language:": "Hizkuntza:", 8 | "Select language": "Aukeratu hizkuntza", 9 | "Upload": "Kargatu", 10 | "Save": "Gorde", 11 | "Add Host": "Gehitu ordenagailua", 12 | "Add DHCP server": "Gehitu DHCP zerbitzaria", 13 | "Add DNS server": "Gehitu DNS zerbitzaria", 14 | "Add web server": "Gehitu web zerbitzaria", 15 | "Add switch": "Gehitu switch", 16 | "Add router": "Gehitu router", 17 | "Delete element": "Ezabatu", 18 | "Edit Name / Group": "Izena/taldea editatu", 19 | "Create Link": "Sortu lotura", 20 | "Network diagnostics": "Sare diagnostikoak", 21 | "Edit Gateways": "Gateway-ak editatu", 22 | "Edit IP Info - Interface 0":"IP informazioa editatu - Interfaze 0", 23 | "Edit IP Info - WAN":"IP informazioa editatu - WAN", 24 | "Edit IP Info - LAN":"IP informazioa editatu - LAN", 25 | "Edit NAT table": "NAT taula editatu", 26 | "Main menu":"Menu nagusia", 27 | "Upload file":"Fitxategia kargatu", 28 | "Request DHCP info":"DHCP info eskatu", 29 | "DNS lookup":"DNS bilaketa", 30 | "Web browser (HTTP client)":"Nabigatzaile (HTTP bezeroa)", 31 | "Edit name / group":"Izena / taldea editatu", 32 | "Save":"Gorde", 33 | "Exit":"Irten", 34 | "Group:":"Taldea:", 35 | "Name:":"Izena:", 36 | "Interface ":"Interfaze ", 37 | "Network":"Sarea", 38 | "Mask":"Maskara", 39 | "Gateway":"Gateway", 40 | "Controls":"Kontrolak", 41 | "Gateway Configuration":"Gateway-ak konfiguratu", 42 | "IP Address:":"IP Helbidea:", 43 | "Network Mask:":"Sare-maskara:", 44 | "DNS 1:":"DNS 1:", 45 | "DNS 2:":"DNS 2:", 46 | "Edit IP Info":"IP Info editatu", 47 | "Domain:":"Domeinua:", 48 | "Lookup":"Bilatu", 49 | "Domain":"Domeinua", 50 | "IP":"IP", 51 | "DNS Server":"DNS Zerbitzaria", 52 | "Forwarder:":"Forwarder:", 53 | "DNS server config":"DNS zerbitzaria konfiguratu", 54 | "DHCP Server":"DHCP Zerbitzaria", 55 | "Initial:":"Lehena:", 56 | "Final:":"Azkena:", 57 | "Gateway:":"Gateway:", 58 | "Close":"Itxi", 59 | "HTTP Client (Browser)":"HTTP Bezeroa (Nabigatzailea)", 60 | "Loading...":"Kargatzen...", 61 | "404 - Not found":"404 - Ez da aurkitu", 62 | "Malformed URL.\n\nUse only 'domain_or_ip/filename.html'.":"URL ez da zuzena.\n\nErabili 'domeinu_edo_ip/fitxategia.html' bakarrik.", 63 | "DNS client not present.":"DNS bezeroa ez dago.", 64 | "Domain not in local DNS cache. Look up first.\n\nIf you already performed a lookup, the domain does not exist.":"Domeinua ez dago DNS cachean. Lehenik eta behin, bilatu.\n\nBilaketa jada eginda badago, domeinua ez dago.", 65 | "Edit DHCP server info":"Editatu DHCP zerbitzariaren informazioa", 66 | "HTTP Server":"HTTP Zerbitzaria", 67 | "File":"Fitxategia", 68 | "Back":"Atzera", 69 | "HTTP Domain Files":"HTTP Domeinuaren Fitxategiak", 70 | "HTTP Domain File Edition":"HTTP Domeinuaren Fitxategia Editatu", 71 | "Input interface":"Sarrera Interfazea", 72 | "WAN Port":"WAN Ataka", 73 | "LAN Port":"LAN Ataka", 74 | "IP: ":"IP: ", 75 | "Gateway mode (uses NAT).":"Gateway modua (NAT erabiltzen du).", 76 | "Edit NAT":"NAT editatu", 77 | "Edit HTTP server info":"HTTP zerbitzariaren informazioa editatu", 78 | "Delete":"Ezabatu", 79 | "Edit":"Editatu", 80 | "Add":"Gehitu", 81 | "Sending traceroute to: ":"Traceroute bidaltzen honako helbide honetara: ", 82 | "Sending ping to: ":"Ping bidaltzen honako helbide honetara: ", 83 | "Ping response recieved from ":"Ping erantzuna honako helbide honetatik: ", 84 | " - Traceroute to ":" - Traceroute honako helbide honetara: ", 85 | "Network unreachable: ":"Sarea eskuraezina: ", 86 | "Network not configured for interface: ":"Sarea ez dago konfiguratuta interfaze honetan: ", 87 | "File name:":"Fitxategiaren izena:", 88 | "Download":"Deskargatu", 89 | "Download file":"Deskargatu fitxategia" 90 | }; 91 | 92 | uitranslation.registerLocale(eu_ES); 93 | -------------------------------------------------------------------------------- /js/simulator.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Education Network Simulator project and covered 3 | * by GPLv3 license. See full terms in the LICENSE file at the root folder 4 | * or at http://www.gnu.org/licenses/gpl-3.0.html. 5 | * 6 | * (c) 2015 Jorge García Ochoa de Aspuru 7 | * bardok@gmail.com 8 | * 9 | * Images are copyrighted by their respective authors and have been 10 | * downloaded from http://pixabay.com/ 11 | * 12 | */ 13 | 14 | function newElement(type) 15 | { 16 | switch (type) 17 | { 18 | case "host": 19 | network.createComputer(0, 50); 20 | break; 21 | case "dns": 22 | network.createDNSServer(0, 50); 23 | break; 24 | case "dhcp": 25 | network.createDHCPServer(0, 50); 26 | break; 27 | case "web": 28 | network.createHTTPServer(0, 50); 29 | break; 30 | case "switch": 31 | network.createSwitch(0, 50, 8); 32 | break; 33 | case "router": 34 | network.createRouter(0, 50); 35 | break; 36 | } 37 | } 38 | 39 | function simulator(imgs) 40 | { 41 | images = imgs; 42 | var container = document.getElementById("simcontainer"); 43 | var canvas = document.getElementById("simcanvas"); 44 | 45 | var W = container.offsetWidth * window.devicePixelRatio; 46 | var H = container.offsetHeight * window.devicePixelRatio; 47 | canvas.width = W; 48 | canvas.height = H; 49 | var ctx = canvas.getContext("2d", {antialias: true}); 50 | 51 | uimanager = new UIManager(); 52 | 53 | network = new Network(images, ctx, W, H); 54 | network.init(); 55 | 56 | if (NetworkSimulator.initialdata !== null) 57 | { 58 | network.load(NetworkSimulator.initialdata); 59 | } 60 | 61 | createControlsWindow(); 62 | } 63 | 64 | -------------------------------------------------------------------------------- /materials/ideas/info.txt: -------------------------------------------------------------------------------- 1 | DHCPClient 2 | - requestinfo 3 | - se registra en el TrafficController para recibir un mensaje 4 | - construye el mensaje 5 | - llama a TrafficController.sendmessage() 6 | 7 | - receivemessage 8 | - pone la IPInfo 9 | 10 | DHCPServer 11 | - lista IP inicial y final (sólo último número) 12 | - lista [ipocupada - mac] 13 | 14 | - init 15 | - se registra en el TrafficController para recibir mensajes 16 | 17 | - receivemessage 18 | - construye el mensaje 19 | - llama a TrafficController.sendmessage() 20 | -------------------------------------------------------------------------------- /materials/ideas/rerouting.txt: -------------------------------------------------------------------------------- 1 | NAT 2 | [puerto externo] puerto interno, ip interna, fijo 3 | - recibir: 4 | Si hay entrada para el puerto del mensaje, cambiar la IP de destino por la ip interna y el puerto de destino por el puerto interno y reenviar 5 | Si no es fijo, borrar la entrada 6 | - enviar: 7 | Generar un puerto aleatorio, cambiar el puerto del mensaje por el puerto aleatorio y la ip de origen por la ip del conector y añadir una entrada no fija a la tabla 8 | Reenviar 9 | 10 | tabla ARP 11 | mac 12 | iface 13 | 14 | función getMACforIP del conectable 15 | - preguntar a todos los conectores si tienen link. 16 | - si lo tienen, preguntar al conector del otro lado "whohasIP" 17 | - Si devuelve la mac, guardar en la tabla la entrada 18 | 19 | función whohasIP del conector 20 | - mirar si es mi IP. Si la es, devuelvo mi MAC 21 | - si no, preguntar al conector del otro lado "whohasIP" y devolver 22 | 23 | función getDstMAC 24 | - Si la IP es de la misma red, pedir la MAC de la IP 25 | - Si la IP es de otra red, pedir la MAC del GW 26 | 27 | El routing va siempre por dirección HW 28 | 29 | findNextConnectorInPath(srcConnector, currentConnectable, dstIP, dstMAC) 30 | 31 | - Si la IP de destino no es de la red del srcConnector, le pedimos a srcConnector el GW 32 | por el que hay que enviarlo y cambiamos la IP 33 | 34 | En router, al recibir un mensaje 35 | - Si no es para el router, ni es broadcast, buscamos el GW por el que enviarlo 36 | - Creamos un nuevo puerto vacío en el router como nuevo puerto de origen del mensaje 37 | - En la aplicación NAT añadimos una entrada con el nuevo puerto, y los datos del antiguo y la ip original 38 | - Añadimos una entrada NAT volátil con el nuevo puerto y la app NAT 39 | - Cambiamos la IP de origen por la de la interfaz del GW por la que se envía y el puerto por el nuevo 40 | - Se envía por esa interfaz 41 | - Si es para el router 42 | - se encarga la app del NAT -------------------------------------------------------------------------------- /materials/snapshots/snapshot01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot01.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot02.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot03.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot04.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot05.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot06.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot07.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot08.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot09.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot10.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot11.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot12.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot13.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot14.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot15.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot16.png -------------------------------------------------------------------------------- /materials/snapshots/snapshot17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malkiah/NetworkSimulator/36c4f28b45d37253067a107668db027db772adf2/materials/snapshots/snapshot17.png -------------------------------------------------------------------------------- /notes.txt: -------------------------------------------------------------------------------- 1 | Prepare (Ubuntu): 2 | $ sudo apt-get install npm nodejs-legacy 3 | $ sudo npm install -g grunt 4 | $ sudo npm install -g grunt-cli 5 | 6 | Uglify: 7 | $ grunt 8 | 9 | GIT config: 10 | $ git config --global user.email "...@..." 11 | $ git config --global user.name "... ..." 12 | 13 | GIT use (commit): 14 | $ git add . 15 | $ git commit 16 | $ git push 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SampleGrunt", 3 | "version": "0.1.0", 4 | "author": "Brandon Random", 5 | "private": true, 6 | "devDependencies": { 7 | "grunt": "~0.4.0", 8 | "grunt-contrib-uglify": "~0.7.0" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /simulator.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Simulator 7 | 8 | 31 | 32 | 63 | 64 | 65 |
66 | 67 |
68 | 69 | 70 | -------------------------------------------------------------------------------- /simulator01.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Simulator 6 | 7 | 8 | 28 | 29 | 55 | 56 | 57 |
58 | 59 |
60 | 61 | 62 | -------------------------------------------------------------------------------- /simulatordev.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Simulator 6 | 7 | 12 | 17 | 22 | 27 | 32 | 37 | 42 | 47 | 52 | 57 | 62 | 67 | 72 | 77 | 82 | 87 | 92 | 97 | 101 | 105 | 109 | 113 | 117 | 121 | 125 | 129 | 133 | 136 | 139 | 142 | 148 | 169 | 170 | 196 | 197 | 198 |
199 | 200 |
201 | 202 | 203 | -------------------------------------------------------------------------------- /simulatorteacher.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Simulator 6 | 7 | 27 | 28 | 54 | 55 | 56 |
57 | 58 |
59 | 60 | 61 | --------------------------------------------------------------------------------