Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


a571c623f8f8c99e0b494541ef6e6c0ab04cd64e
[palacios.git] / misc / network_servers / vtl / vtl_model.cc
1 #include "vtl_model.h"
2 #include <assert.h>
3
4
5 /* VTL Models */
6
7
8
9
10
11 vtl_model_t * new_vtl_model(model_type_t type) {
12   vtl_model_t * model = (vtl_model_t *)malloc(sizeof(vtl_model_t));
13
14   model->type = type;
15
16   return model;
17 }
18
19
20 int initialize_ethernet_model(ethernet_model_t * model, RawEthernetPacket * pkt, int dir = OUTBOUND_PKT) {
21   ASSERT((model != NULL) && (pkt != NULL));
22
23   printf("initializing ethernet model\n");
24   if (dir == OUTBOUND_PKT) {
25     GET_ETH_DST(pkt->data, model->dst.addr);
26     GET_ETH_SRC(pkt->data, model->src.addr);
27   } else if (dir == INBOUND_PKT) {
28     GET_ETH_DST(pkt->data, model->src.addr);
29     GET_ETH_SRC(pkt->data, model->dst.addr);
30   } else {
31     return -1;
32   }
33
34   model->type = GET_ETH_TYPE(pkt->data);
35
36   return 0;
37 }
38
39 int initialize_ip_model(ip_model_t * model, RawEthernetPacket * pkt, int dir) {
40   ASSERT((model != NULL) && (pkt != NULL));
41
42   if (!is_ip_pkt(pkt)) {
43     return -1;
44   }
45
46   if (dir == OUTBOUND_PKT) {
47     model->src.addr = GET_IP_SRC(pkt->data);
48     model->dst.addr = GET_IP_DST(pkt->data);
49     model->dst.ip_id = 1;
50     model->src.ip_id = GET_IP_ID(pkt->data);
51     model->src.ttl = GET_IP_TTL(pkt->data);
52     model->dst.ttl = 1;
53   } else if (dir == INBOUND_PKT) {
54     model->src.addr = GET_IP_DST(pkt->data);
55     model->dst.addr = GET_IP_SRC(pkt->data);
56     model->src.ip_id = 1;
57     model->dst.ip_id = GET_IP_ID(pkt->data);
58     model->src.ttl = 1;
59     model->dst.ttl = GET_IP_TTL(pkt->data);
60   } else {
61     return -1;
62   }
63
64   model->version = GET_IP_VERSION(pkt->data);
65   model->proto = GET_IP_PROTO(pkt->data);
66
67   if (initialize_ethernet_model(&(model->ethernet), pkt, dir) == -1) {
68     return -1;
69   }
70     
71   return 0;
72 }
73
74 int initialize_tcp_model(tcp_model_t * model, RawEthernetPacket * pkt, int dir) {
75   ASSERT((model != NULL) && (pkt != NULL));
76
77   tcp_opts_t options;
78
79   if (!is_tcp_pkt(pkt)) {
80     return -1;
81   }
82
83   parse_tcp_options(&options, pkt);
84
85   if (dir == OUTBOUND_PKT) {
86     model->src.port = GET_TCP_SRC_PORT(pkt->data);
87     model->dst.port = GET_TCP_DST_PORT(pkt->data);
88     model->src.seq_num = compute_next_tcp_seq_num(pkt);
89     model->src.last_ack = GET_TCP_ACK_NUM(pkt->data);
90     model->src.win = GET_TCP_WIN(pkt->data);
91     model->src.mss = options.mss;
92     model->src.ts = options.local_ts;
93     model->dst.mss = 0;
94     model->dst.ts = 0;
95   } else if (dir == INBOUND_PKT) {
96     model->src.port = GET_TCP_DST_PORT(pkt->data);
97     model->dst.port = GET_TCP_SRC_PORT(pkt->data);
98     model->dst.last_ack = GET_TCP_ACK_NUM(pkt->data);
99     model->src.seq_num = 1;
100     model->dst.seq_num = compute_next_tcp_seq_num(pkt);
101     model->dst.win = GET_TCP_WIN(pkt->data);
102     model->dst.mss = options.mss;
103     model->dst.ts = options.local_ts;
104     model->src.mss = 0;
105     model->src.ts = 0;
106   } else {
107     return -1;
108   }
109
110   if (initialize_ip_model(&(model->ip), pkt, dir) == -1) {
111     return -1;
112   }
113   
114   return 0;
115 }
116
117 int initialize_udp_model(udp_model_t * model, RawEthernetPacket * pkt, int dir) {
118   ASSERT((model != NULL) && (pkt != NULL));
119   
120   if (!is_udp_pkt(pkt)) {
121     return -1;
122   }
123
124   if (dir == OUTBOUND_PKT) {
125     model->src.port = GET_UDP_SRC_PORT(pkt->data);
126     model->dst.port = GET_UDP_DST_PORT(pkt->data);
127   } else if (dir == INBOUND_PKT) {
128     model->src.port = GET_UDP_DST_PORT(pkt->data);
129     model->dst.port = GET_UDP_SRC_PORT(pkt->data);
130   } else {
131     return -1;
132   }
133
134   if (initialize_ip_model(&(model->ip), pkt, dir) == -1) {
135     return -1;
136   }
137
138   return 0;
139 }
140
141
142
143 int initialize_model(vtl_model_t * model, RawEthernetPacket * pkt, int dir) {
144   ASSERT((model != NULL) && (pkt != NULL));
145
146   if (model->type == TCP_MODEL) {
147     return initialize_tcp_model(&(model->model.tcp_model), pkt, dir);
148   } else if (model->type == UDP_MODEL) {
149     return initialize_udp_model(&(model->model.udp_model), pkt, dir);
150   } else if (model->type == IP_MODEL) {
151   } else if (model->type == ETHERNET_MODEL) {
152   }
153
154   return -1;
155 }
156
157
158
159 int is_ethernet_model_pkt(ethernet_model_t * model, RawEthernetPacket * pkt) {
160   ASSERT((model != NULL) && (pkt != NULL));
161
162   if ((memcmp(model->src.addr, ETH_SRC(pkt->data), 6) == 0) &&
163       (memcmp(model->dst.addr, ETH_DST(pkt->data), 6) == 0)) {
164     return OUTBOUND_PKT;
165   } else if ((memcmp(model->src.addr, ETH_DST(pkt->data), 6) == 0) &&
166              (memcmp(model->dst.addr, ETH_SRC(pkt->data), 6) == 0)) {
167     return INBOUND_PKT;
168   }
169
170   return INVALID_PKT;
171 }
172
173 int is_ip_model_pkt(ip_model_t * model, RawEthernetPacket * pkt) {
174   ASSERT((model != NULL) && (pkt != NULL));
175
176   if (!is_ip_pkt(pkt)) {
177     return INVALID_PKT;
178   }
179   
180   if ((model->src.addr == GET_IP_SRC(pkt->data)) &&
181       (model->dst.addr == GET_IP_DST(pkt->data))) {
182     return OUTBOUND_PKT;
183   } else if ((model->src.addr == GET_IP_DST(pkt->data)) &&
184              (model->dst.addr == GET_IP_SRC(pkt->data))) {
185     return INBOUND_PKT;
186   }
187
188   return INVALID_PKT;
189 }
190
191
192 int is_tcp_model_pkt(tcp_model_t * model, RawEthernetPacket * pkt) {
193   ASSERT((model != NULL) && (pkt != NULL));
194   int ip_ret;
195
196   if (!is_tcp_pkt(pkt)) {
197     return INVALID_PKT;
198   }
199
200   if ((ip_ret = is_ip_model_pkt(&(model->ip), pkt)) == INVALID_PKT) {
201     return INVALID_PKT;
202   }
203
204
205   if (ip_ret == OUTBOUND_PKT) {
206     if ((model->src.port == GET_TCP_SRC_PORT(pkt->data)) && 
207         (model->dst.port == GET_TCP_DST_PORT(pkt->data))) {
208       return OUTBOUND_PKT;
209     } 
210   } else if (ip_ret == INBOUND_PKT) {
211     if ((model->src.port == GET_TCP_DST_PORT(pkt->data)) && 
212         (model->dst.port == GET_TCP_SRC_PORT(pkt->data))) {
213       return INBOUND_PKT;
214     }
215   }
216   return INVALID_PKT;
217 }
218
219 int is_udp_model_pkt(udp_model_t * model, RawEthernetPacket * pkt) {
220   ASSERT((model != NULL) && (pkt != NULL));
221   int ip_ret;
222
223   if (!is_udp_pkt(pkt)) {
224     return INVALID_PKT;
225   }
226
227   if ((ip_ret = is_ip_model_pkt(&(model->ip), pkt)) == INVALID_PKT) {
228     return INVALID_PKT;
229   }
230
231   if (ip_ret == OUTBOUND_PKT) {
232     if ((model->src.port == GET_UDP_SRC_PORT(pkt->data)) &&
233         (model->dst.port == GET_UDP_DST_PORT(pkt->data))) {
234       return OUTBOUND_PKT;
235     }
236   } else if (ip_ret == INBOUND_PKT) {
237     if ((model->src.port == GET_UDP_DST_PORT(pkt->data)) &&
238         (model->dst.port == GET_UDP_SRC_PORT(pkt->data))) {
239       return INBOUND_PKT;
240     }
241   }
242
243   return INBOUND_PKT;
244 }
245
246 int is_model_pkt(vtl_model_t * model, RawEthernetPacket * pkt) {
247   ASSERT((model != NULL) && (pkt != NULL));
248   
249   if (model->type == TCP_MODEL) {
250     return is_tcp_model_pkt(&(model->model.tcp_model), pkt);
251   }
252
253   return INVALID_PKT;
254 }
255
256
257 int sync_ip_model(ip_model_t * model, RawEthernetPacket * pkt) {
258   ASSERT((model != NULL) && (pkt != NULL));
259
260   int ip_ret; 
261   
262   ip_ret = is_ip_model_pkt(model, pkt);
263
264   if (ip_ret == OUTBOUND_PKT) {
265     model->src.ip_id = GET_IP_ID(pkt->data);
266     model->src.ttl = GET_IP_TTL(pkt->data);
267   } else if (ip_ret == INBOUND_PKT) {
268     model->dst.ip_id = GET_IP_ID(pkt->data);
269     model->dst.ttl = GET_IP_TTL(pkt->data);
270   } else { 
271     return -1;
272   }
273
274   return 0;
275 }
276
277
278 int sync_tcp_model(tcp_model_t * model, RawEthernetPacket * pkt) {
279   ASSERT((model != NULL) && (pkt != NULL));
280   int tcp_ret;
281   tcp_opts_t options;
282   int has_opts = 0;
283
284   tcp_ret = is_tcp_model_pkt(model, pkt);
285
286   has_opts = parse_tcp_options(&options, pkt);
287
288   if (tcp_ret == OUTBOUND_PKT) {
289     model->src.seq_num = compute_next_tcp_seq_num(pkt);
290     model->src.last_ack = GET_TCP_ACK_NUM(pkt->data);
291     model->src.win = GET_TCP_WIN(pkt->data);
292     if (has_opts == 0) {
293       model->src.mss = options.mss;
294       model->src.ts = options.local_ts;
295     }
296   } else if (tcp_ret == INBOUND_PKT) {
297     model->dst.last_ack = GET_TCP_ACK_NUM(pkt->data);
298     model->dst.seq_num = compute_next_tcp_seq_num(pkt);
299     model->dst.win = GET_TCP_WIN(pkt->data);
300     if (has_opts == 0) {
301       model->dst.mss = options.mss;
302       model->dst.ts = options.local_ts;
303     }
304   } else { 
305     return -1;
306   }
307
308   if (sync_ip_model(&(model->ip), pkt) == -1) {
309     return -1;
310   }
311
312   return 0;
313 }
314
315
316 int sync_udp_model(udp_model_t * model, RawEthernetPacket * pkt) {
317   ASSERT((model != NULL) && (pkt != NULL));
318   int udp_ret;
319   
320   udp_ret = is_udp_model_pkt(model, pkt);
321
322   if (udp_ret == INVALID_PKT) {
323     return -1;
324   }
325
326   if (sync_ip_model(&(model->ip), pkt) == -1) {
327     return -1;
328   }
329   
330   return 0;
331 }
332   
333 int sync_model(vtl_model_t * model, RawEthernetPacket * pkt) {
334
335   if (model->type == TCP_MODEL) {
336     return sync_tcp_model(&(model->model.tcp_model), pkt);
337   } else if (model->type == IP_MODEL) {
338     return sync_ip_model(&(model->model.ip_model), pkt);
339   }
340   return -1;
341 }
342
343 int create_empty_ethernet_pkt(ethernet_model_t * model, RawEthernetPacket * pkt, int dir) {
344   if (dir == OUTBOUND_PKT) {
345     SET_ETH_SRC(pkt->data, model->src.addr);
346     SET_ETH_DST(pkt->data, model->dst.addr);
347   } else if (dir == INBOUND_PKT) {    
348     SET_ETH_SRC(pkt->data, model->dst.addr);
349     SET_ETH_DST(pkt->data, model->src.addr);
350   }
351   SET_ETH_TYPE(pkt->data, model->type);
352   pkt->set_size(ETH_HDR_LEN);
353
354   return 0;
355 }
356
357
358 int create_empty_ip_pkt(ip_model_t * model, RawEthernetPacket * pkt, int dir) {
359   create_empty_ethernet_pkt(&(model->ethernet), pkt, dir);
360
361   SET_IP_VERSION(pkt->data, model->version);
362   SET_IP_HDR_LEN(pkt->data, 20);
363   SET_IP_SVC_TYPE(pkt->data, 0);
364   SET_IP_TOTAL_LEN(pkt->data, 20); // WE ARE JUST AN EMPTY PACKET HERE
365   SET_IP_FLAGS(pkt->data, 0);
366   SET_IP_FRAG(pkt->data, 0);
367   SET_IP_PROTO(pkt->data, model->proto);
368
369
370   if (dir == OUTBOUND_PKT) {
371     SET_IP_ID(pkt->data, model->src.ip_id + 1);
372     SET_IP_TTL(pkt->data, model->src.ttl);    
373     SET_IP_SRC(pkt->data, model->src.addr);
374     SET_IP_DST(pkt->data, model->dst.addr);
375   } else if (dir == INBOUND_PKT) {
376     SET_IP_ID(pkt->data, model->dst.ip_id + 1);
377     SET_IP_TTL(pkt->data, model->dst.ttl);
378     //    SET_IP_TTL(pkt->data, 5);
379     SET_IP_SRC(pkt->data, model->dst.addr);
380     SET_IP_DST(pkt->data, model->src.addr);
381   } 
382
383   compute_ip_checksum(pkt);
384   pkt->set_size(compute_pkt_size(pkt));
385
386   return 0;
387 }
388
389 int create_empty_tcp_pkt(tcp_model_t * model, RawEthernetPacket * pkt, int dir) {
390   create_empty_ip_pkt(&(model->ip), pkt, dir);
391
392   SET_TCP_HDR_LEN(pkt->data, 20);
393   SET_TCP_RSVD(pkt->data, 0);
394   SET_TCP_FLAGS(pkt->data, 0);
395   SET_TCP_URG_PTR(pkt->data, 0);
396
397   if (dir == OUTBOUND_PKT) {
398     SET_TCP_SRC_PORT(pkt->data, model->src.port);
399     SET_TCP_DST_PORT(pkt->data, model->dst.port);
400     SET_TCP_SEQ_NUM(pkt->data, model->src.seq_num);
401     
402     // This is kind of weird
403     // We set the ack number to last ack that was sent on the actual channel
404     // We want to insert packets into the connection without messing things up
405     // So we don't want to ack data that hasn't necessarily been received
406     // Since we're blowing away the seq_num sequence anyway, this might not matter
407     //    SET_TCP_ACK_NUM(pkt->data, model->src.last_ack); 
408     SET_TCP_ACK_NUM(pkt->data, model->dst.seq_num); 
409     SET_TCP_ACK_FLAG(pkt->data);
410
411     SET_TCP_WIN(pkt->data, model->src.win);
412
413   } else if (dir == INBOUND_PKT) {
414     SET_TCP_SRC_PORT(pkt->data, model->dst.port);
415     SET_TCP_DST_PORT(pkt->data, model->src.port);    
416
417     SET_TCP_SEQ_NUM(pkt->data, model->dst.seq_num);
418     
419     // This is kind of weird
420     // We set the ack number to last ack that was sent on the actual channel
421     // We want to insert packets into the connection without messing things up
422     // So we don't want to ack data that hasn't necessarily been received
423     // Since we're blowing away the seq_num sequence anyway, this might not matter
424     //SET_TCP_ACK_NUM(pkt->data, model->dst.last_ack); 
425     SET_TCP_ACK_NUM(pkt->data, model->src.seq_num); 
426
427     SET_TCP_ACK_FLAG(pkt->data);
428
429     SET_TCP_WIN(pkt->data, model->dst.win);
430   }
431
432
433   SET_IP_TOTAL_LEN(pkt->data, GET_IP_HDR_LEN(pkt->data) + GET_TCP_HDR_LEN(pkt->data));
434   pkt->set_size(compute_pkt_size(pkt));
435
436   compute_ip_checksum(pkt);
437
438   compute_tcp_checksum(pkt);
439
440   JRLDBG("tcp_len = %d\n", GET_TCP_HDR_LEN(pkt->data));
441
442
443   // Set the ip hdr len
444
445   return 0;
446 }
447
448
449 int create_empty_udp_pkt(udp_model_t * model, RawEthernetPacket * pkt, int dir) {
450   create_empty_ip_pkt(&(model->ip), pkt, dir);
451
452   if (dir == OUTBOUND_PKT) {
453     SET_UDP_SRC_PORT(pkt->data, model->src.port);
454     SET_UDP_DST_PORT(pkt->data, model->dst.port);
455   } else if (dir == INBOUND_PKT) {
456     SET_UDP_SRC_PORT(pkt->data, model->dst.port);
457     SET_UDP_DST_PORT(pkt->data, model->src.port);
458   }
459   SET_UDP_LEN(pkt->data, 8);
460   SET_IP_TOTAL_LEN(pkt->data, GET_IP_HDR_LEN(pkt->data) + GET_UDP_LEN(pkt->data));
461
462   compute_ip_checksum(pkt);
463   compute_udp_checksum(pkt);
464
465   return 0;
466 }
467
468 int create_empty_pkt(vtl_model_t * model, RawEthernetPacket * pkt, int dir) {
469   if (model->type == TCP_MODEL) {
470     return create_empty_tcp_pkt(&(model->model.tcp_model), pkt, dir);
471   } else if (model->type == UDP_MODEL) {
472     return create_empty_udp_pkt(&(model->model.udp_model), pkt, dir);
473   } else if (model->type == IP_MODEL) {
474     return create_empty_ip_pkt(&(model->model.ip_model), pkt, dir);
475   }
476   return -1;
477 }
478
479
480
481
482 void dbg_dump_eth_model(ethernet_model_t * model) {
483   char src_mac[6];
484   char dst_mac[6];
485
486   printf("ETHERNET MODEL {\n");
487
488   printf("\tType: %s\n", get_eth_protocol(model->type));
489
490   mac_to_string(model->src.addr, src_mac);
491   printf("\tSrc Host {\n");
492   printf("\t\taddr: %s\n", src_mac);
493   printf("\t}\n");
494
495   mac_to_string(model->dst.addr, dst_mac);
496   printf("\tDST Host {\n");
497   printf("\t\taddr: %s\n", dst_mac);
498   printf("\t}\n");
499   printf("}\n");
500 }
501
502
503
504 void dbg_dump_ip_model(ip_model_t * model) {
505   dbg_dump_eth_model(&(model->ethernet));
506
507   printf("IP MODEL {\n");
508   printf("\tVersion: %d\n", model->version);
509   printf("\tProtocol: %s\n", get_ip_protocol(model->proto));
510
511   printf("\tSrc Host {\n");
512   printf("\t\taddr: %s\n", ip_to_string(model->src.addr));
513   printf("\t\tIP ID: %d\n", model->src.ip_id);
514   printf("\t\tttl: %d\n", model->src.ttl);
515   printf("\t}\n");
516
517   printf("\tDst Host {\n");
518   printf("\t\taddr: %s\n", ip_to_string(model->dst.addr));
519   printf("\t\tIP ID: %d\n", model->dst.ip_id);
520   printf("\t\tttl: %d\n", model->dst.ttl);
521   printf("\t}\n");
522
523   printf("}\n");
524 }
525
526 void dbg_dump_tcp_model(tcp_model_t * model) {
527   dbg_dump_ip_model(&(model->ip));
528
529   printf("TCP MODEL {\n");
530   printf("\tSrc Host {\n");
531   printf("\t\tport: %hu\n", model->src.port);
532   printf("\t\tseq: %lu\n", (unsigned long)(model->src.seq_num));
533   printf("\t\tlast ack: %lu\n", (unsigned long)(model->src.last_ack));
534   printf("\t\tWin Size: %hu\n", model->src.win);
535   printf("\t\tTimestamp: %lu\n", (unsigned long)(model->src.ts));
536   printf("\t\tMSS: %hu\n", model->src.mss);
537   
538   printf("\t}\n");
539
540   printf("\tDst Host {\n");
541   printf("\t\tport: %hu\n", model->dst.port);
542   printf("\t\tseq: %lu\n", (unsigned long)(model->dst.seq_num));
543   printf("\t\tlast ack: %lu\n", (unsigned long)(model->dst.last_ack));
544   printf("\t\tWin Size: %hu\n", model->dst.win);
545   printf("\t\tTimestamp: %lu\n", (unsigned long)(model->dst.ts));
546   printf("\t\tMSS: %hu\n", model->dst.mss);
547   printf("\t}\n");
548
549
550   printf("}\n");
551
552 }
553
554
555
556 void dbg_dump_model(vtl_model_t * model) {
557   if (model->type == TCP_MODEL) {
558     dbg_dump_tcp_model(&(model->model.tcp_model));
559   } else if (model->type == IP_MODEL) {
560     dbg_dump_ip_model(&(model->model.ip_model));
561   }  
562 }