new bgpfake code
[random_node_code.git] / bgpfake / bf2.js
1 var readline = require('readline');
2 var net = require('net');
3
4
5
6 // ---- vars
7
8 var asPaths = new Array();
9 var readyToSend = false;
10 var currentPrompt;
11 var rl;
12 var nCons = 0;
13 var nSent = 0;
14 var myAS;
15 var myIP;
16 var server;
17 var cState = "starting";
18 var currentIPa = 1;
19 var currentIPb = 0;
20 var currentIPc = 0;
21
22
23 // ---- vars
24
25
26 if(typeof process.argv[2] == "undefined") {
27         usage();
28 }
29
30 if(typeof process.argv[3] == "undefined") {
31         usage();
32 }
33
34 function usage() {
35         console.log("Usage: "+process.argv[1]+" MyAS MyIP");
36         process.exit(1);
37 }
38
39
40
41
42
43 // ----------- startup
44
45 myAS = process.argv[2];
46 myIP = process.argv[3];
47
48
49 startCLI();
50 doPrompt();
51 createAsPathArray(1048576);
52 startServer();
53 cState = "idle";
54 doPrompt();
55
56 // ----------- startup
57
58
59
60
61
62
63
64
65
66
67 // --------- CLI
68
69 function updatePrompt() {
70         currentPrompt = "("+myAS+"/"+myIP+") "+cState+":"+nCons+"/"+nSent+" ("+currentIPa+"."+currentIPb+"."+currentIPc+") > ";
71 }
72
73 function startCLI() {
74         currentPrompt = "("+myAS+"/"+myIP+") starting... > ";
75
76         rl = readline.createInterface({
77                   input: process.stdin,
78                   output: process.stdout
79                 });
80         
81         rl.on('line', function (cmd) {
82                 switch(cmd) {
83                 
84                 case "?":
85                 case "help":
86                 case "h":
87                         printCLIUsage();
88                         break;
89                 case "s":
90                         printStatus();
91                         break;
92                 case "u":
93                         startUpdates();
94                         break;
95                 case "p":
96                         stopUpdates();
97                         break;
98                 case "q":
99                 case "quit":
100                 case "end":
101                           rl.close();
102                           process.exit(0);
103                           break;
104                 case "":
105                         break;
106                 }
107                 
108                 rl.setPrompt(currentPrompt);
109                 rl.prompt();
110         });
111 }
112
113
114
115 function doPrompt() {
116         updatePrompt();
117         rl.setPrompt(currentPrompt);
118         rl.prompt();    
119 }
120
121 function printCLIUsage() {
122         console.log("Help");
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");
130 }
131
132 // ------------- CLI
133
134
135
136
137
138
139
140
141
142
143
144
145
146 //------------- network
147
148 function startUpdates() {
149         
150 }
151
152 function serverconnection(c) {
153
154         scon = c;
155
156         c.on("end", function() {
157                 //console.log("Server disconnected");
158                 nCons--;
159                 if(nCons == 0) {
160                         cState = "idle";
161                         doPrompt();
162                 }
163         });
164
165         c.on("data", function(buffer) {
166                 parseBuffer(buffer, c);
167         });
168
169         cState = "connected";
170         nCons++;
171         doPrompt();
172
173         //c.write("hello\r\n");
174 }
175
176
177 function startServer() {
178         server = net.createServer(serverconnection);
179
180         server.listen(10179, function() {
181                 //console.log("LOG: Server bound");
182                 doPrompt();
183         });
184         
185 }
186
187 //------------- network
188
189
190
191
192
193
194
195
196
197
198 // -------------- BGP 
199
200 function getNextIP() {
201         // split into octets
202         //var currentIPa = 1;
203         //var currentIPb = 0;
204         //var currentIPc = 0;
205
206         currentIPc++;
207         if(currentIPc > 254) {
208                 
209                 currentIPb++;
210                 if(currentIPb == 168 && currentIPa == 192) currentIPb++;
211                 if(currentIPb > 254) {
212                         currentIPa++;
213                         
214                         // dont publish bogons or 127
215                         if(currentIPa == 10) currentIPa++;
216                         if(currentIPa == 127) currentIPa++;
217                         if(currentIPa == 128) currentIPa++;                     
218                 }
219         }
220         
221         
222         //console.log("created "+a+"."+b+"."+c+" from "+i);
223         return currentIPa+"."+currentIPb+"."+currentIPc;
224
225 }
226
227 function getASPath() {
228         
229 }
230
231 function constructUpdateMessage(n_up, myas, myip) {
232         var bsize = 0;
233
234         var aspath = getASPath();
235         
236         // first the header components
237         bsize += 16;
238
239         // next the length component
240         bsize += 2;
241
242         // next the n unfeasible
243         bsize += 2;
244
245         // next, path attr length
246         bsize += 2;
247
248
249         // now we begin the path attrs
250         // first origin - simple
251         var aspathn = 4;
252
253         // next as path - hard, flag + type + len + aspath segment
254         aspathn += 3;
255
256         // as path segment size = 1 (type), + 1 (len) + as's*2
257         var aspathlen = ((aspath.length+1)*2)+1+1;
258         aspathn += aspathlen;
259         
260         // now next hop attrs = flag (1) + type (1) + len (1) + octets (4);
261         aspathn += 7;
262         bsize += aspathn;
263
264         // now nlri = prefix len (1) + prefix fixed in our case (3)
265         bsize += 4*n_up;
266
267         // fudge
268         bsize+=1;
269
270         //console.log("size: " + bsize + ", an: " + aspathn + " al:" + aspathlen);
271         var buf = new Buffer(bsize);
272         var bp = 0;
273
274         // now lets create the buffer
275         buf.fill(0xff, bp, bp+16);
276         bp+=16;
277         buf.writeUInt16BE(bsize, bp);
278         bp+=2;
279         buf.writeUInt8(2, bp);
280         bp++;
281         buf.writeUInt16BE(0, bp);
282         bp+=2;
283         buf.writeUInt16BE(aspathn, bp);
284         bp+=2;
285
286         // path attr
287         // origin
288         buf.writeUInt8(0x40, bp);
289         bp++;
290         buf.writeUInt8(1, bp);
291         bp++;
292         buf.writeUInt8(1, bp);
293         bp++;
294         buf.writeUInt8(0, bp);
295         bp++;
296
297         // as path
298         buf.writeUInt8(0x40, bp);
299         bp++;
300         buf.writeUInt8(2, bp);
301         bp++;
302         buf.writeUInt8(aspathlen, bp);
303         bp++;
304         buf.writeUInt8(2, bp);
305         bp++;
306         buf.writeUInt8(aspath.length+1, bp);
307         bp++;
308         //console.log("writing in my aspath: "+myas);
309         buf.writeUInt16BE(myas, bp);
310         bp+=2;
311         aspath.forEach(function (ed) {
312                 //console.log("writing in aspath: "+ed);
313                 buf.writeUInt16BE(ed, bp);
314                 bp+=2;
315         });
316
317         // next hop
318         buf.writeUInt8(0x40, bp);
319         bp++;
320         buf.writeUInt8(3, bp);
321         bp++;
322         buf.writeUInt8(4, bp);
323         bp++;
324         myip.split(".").forEach(function (ed) {
325                 //console.log("writing in next hop info: " + ed);
326                 buf.writeUInt8(parseInt(ed), bp);
327                 bp++;
328         }); 
329
330         // last, nlri
331         for(var nn=0; nn < n_up; nn++) {
332                 buf.writeUInt8(24, bp);
333                 bp++;
334                 var ip = getNextIP();
335                 ip.split(".").forEach(function(ed){
336                         //console.log("Writing in nlri: "+ed);
337                         buf.writeUInt8(parseInt(ed), bp);
338                         bp++;
339                 });
340         }
341
342         console.log("buf is:");
343         console.log(buf);
344         console.log(buf.length);
345
346         return buf;
347 }
348
349 function createAsPathArray(size) {
350         for(var i=0; i<size; i++) {
351                 asPaths[i] = createaspath(i);
352         }
353 }
354
355
356 function createaspath(i) {
357         var n=(i%5)+2;
358         var as = 1024;
359         var ret = new Array();
360
361         for(var t=0; t<n; t++) {
362                 i = i << 1;
363                 as = 1024 + (i%30000);
364                 ret[t] = as;
365         }
366         return ret;
367 }
368
369 function parseBuffer(b, c) {
370         var len = b.readUInt16BE(16);
371         var type = b.readUInt8(18);
372
373         //console.log("got input: " + len + ", type: " + type);
374
375         if(type == 1) {
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);
386
387
388                 console.log("sending our open type");
389                 var out = new Buffer(29);
390
391
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);
403
404                 c.write(out);
405         } else if(type == 4) {
406                 console.log("writing keepalive - exact as sent");
407                 c.write(b);
408                 readyToSend = true;
409                 //if(updateSent ==0) beginUpdateSend(c);
410         } else if(type == 2) {
411                 console.log("got update...");
412                 if(updateSent ==0) beginUpdateSend(c);
413         } else {
414                 console.log("sending end...");
415                 c.end();
416         }
417
418         
419 }
420
421 //-------------- BGP