1 var readline = require('readline');
2 var net = require('net');
8 var asPaths = new Array();
9 var readyToSend = false;
17 var cState = "starting";
26 if(typeof process.argv[2] == "undefined") {
30 if(typeof process.argv[3] == "undefined") {
35 console.log("Usage: "+process.argv[1]+" MyAS MyIP");
43 // ----------- startup
45 myAS = process.argv[2];
46 myIP = process.argv[3];
51 createAsPathArray(1048576);
56 // ----------- startup
69 function updatePrompt() {
70 currentPrompt = "("+myAS+"/"+myIP+") "+cState+":"+nCons+"/"+nSent+" ("+currentIPa+"."+currentIPb+"."+currentIPc+") > ";
74 currentPrompt = "("+myAS+"/"+myIP+") starting... > ";
76 rl = readline.createInterface({
78 output: process.stdout
81 rl.on('line', function (cmd) {
108 rl.setPrompt(currentPrompt);
115 function doPrompt() {
117 rl.setPrompt(currentPrompt);
121 function printCLIUsage() {
123 console.log("\th[elp],? - this help menu");
124 console.log("\tu - start sending route updates to connected peers");
125 console.log("\tp - pause sending route updates to connected peers");
126 console.log("\ts - status");
127 console.log("\tq[uit],exit,end - Quit");
128 console.log("Prompt layout");
129 console.log("\t(AS/IP) state:connections/updates sent");
146 //------------- network
148 function startUpdates() {
152 function serverconnection(c) {
156 c.on("end", function() {
157 //console.log("Server disconnected");
165 c.on("data", function(buffer) {
166 parseBuffer(buffer, c);
169 cState = "connected";
173 //c.write("hello\r\n");
177 function startServer() {
178 server = net.createServer(serverconnection);
180 server.listen(10179, function() {
181 //console.log("LOG: Server bound");
187 //------------- network
198 // -------------- BGP
200 function getNextIP() {
202 //var currentIPa = 1;
203 //var currentIPb = 0;
204 //var currentIPc = 0;
207 if(currentIPc > 254) {
210 if(currentIPb == 168 && currentIPa == 192) currentIPb++;
211 if(currentIPb > 254) {
214 // dont publish bogons or 127
215 if(currentIPa == 10) currentIPa++;
216 if(currentIPa == 127) currentIPa++;
217 if(currentIPa == 128) currentIPa++;
222 //console.log("created "+a+"."+b+"."+c+" from "+i);
223 return currentIPa+"."+currentIPb+"."+currentIPc;
227 function getASPath() {
231 function constructUpdateMessage(n_up, myas, myip) {
234 var aspath = getASPath();
236 // first the header components
239 // next the length component
242 // next the n unfeasible
245 // next, path attr length
249 // now we begin the path attrs
250 // first origin - simple
253 // next as path - hard, flag + type + len + aspath segment
256 // as path segment size = 1 (type), + 1 (len) + as's*2
257 var aspathlen = ((aspath.length+1)*2)+1+1;
258 aspathn += aspathlen;
260 // now next hop attrs = flag (1) + type (1) + len (1) + octets (4);
264 // now nlri = prefix len (1) + prefix fixed in our case (3)
270 //console.log("size: " + bsize + ", an: " + aspathn + " al:" + aspathlen);
271 var buf = new Buffer(bsize);
274 // now lets create the buffer
275 buf.fill(0xff, bp, bp+16);
277 buf.writeUInt16BE(bsize, bp);
279 buf.writeUInt8(2, bp);
281 buf.writeUInt16BE(0, bp);
283 buf.writeUInt16BE(aspathn, bp);
288 buf.writeUInt8(0x40, bp);
290 buf.writeUInt8(1, bp);
292 buf.writeUInt8(1, bp);
294 buf.writeUInt8(0, bp);
298 buf.writeUInt8(0x40, bp);
300 buf.writeUInt8(2, bp);
302 buf.writeUInt8(aspathlen, bp);
304 buf.writeUInt8(2, bp);
306 buf.writeUInt8(aspath.length+1, bp);
308 //console.log("writing in my aspath: "+myas);
309 buf.writeUInt16BE(myas, bp);
311 aspath.forEach(function (ed) {
312 //console.log("writing in aspath: "+ed);
313 buf.writeUInt16BE(ed, bp);
318 buf.writeUInt8(0x40, bp);
320 buf.writeUInt8(3, bp);
322 buf.writeUInt8(4, bp);
324 myip.split(".").forEach(function (ed) {
325 //console.log("writing in next hop info: " + ed);
326 buf.writeUInt8(parseInt(ed), bp);
331 for(var nn=0; nn < n_up; nn++) {
332 buf.writeUInt8(24, bp);
334 var ip = getNextIP();
335 ip.split(".").forEach(function(ed){
336 //console.log("Writing in nlri: "+ed);
337 buf.writeUInt8(parseInt(ed), bp);
342 console.log("buf is:");
344 console.log(buf.length);
349 function createAsPathArray(size) {
350 for(var i=0; i<size; i++) {
351 asPaths[i] = createaspath(i);
356 function createaspath(i) {
359 var ret = new Array();
361 for(var t=0; t<n; t++) {
363 as = 1024 + (i%30000);
369 function parseBuffer(b, c) {
370 var len = b.readUInt16BE(16);
371 var type = b.readUInt8(18);
373 //console.log("got input: " + len + ", type: " + type);
376 var vers = b.readUInt8(19);
377 var as = b.readUInt16BE(20);
378 var ht = b.readUInt16BE(22);
379 var ot1 = b.readUInt8(24);
380 var ot2 = b.readUInt8(25);
381 var ot3 = b.readUInt8(26);
382 var ot4 = b.readUInt8(27);
383 var opl = b.readUInt8(28);
384 console.log("got open type, vers: "+vers+", as: " + as);
385 console.log("ht: " + ht + ", id: "+ot1+"."+ot2+"."+ot3+"."+ot4+", opl: "+opl);
388 console.log("sending our open type");
389 var out = new Buffer(29);
392 out.fill(0xff, 0, 16);
393 out.writeUInt16BE(29, 16);
394 out.writeUInt8(1, 18);
395 out.writeUInt8(4, 19);
396 out.writeUInt16BE(myas, 20);
397 out.writeUInt16BE(90, 22);
398 out.writeUInt8(10, 24);
399 out.writeUInt8(99, 25);
400 out.writeUInt8(99, 26);
401 out.writeUInt8(1,27);
402 out.writeUInt8(0,28);
405 } else if(type == 4) {
406 console.log("writing keepalive - exact as sent");
409 //if(updateSent ==0) beginUpdateSend(c);
410 } else if(type == 2) {
411 console.log("got update...");
412 if(updateSent ==0) beginUpdateSend(c);
414 console.log("sending end...");