/***************************************
chunk_id chunk_size header-field
0 16 s.ip[15:0]
1 16 s.ip[31:16]
2 16 d.ip[15:0]
3 16 d.ip[31:16]
4 8 proto
5 16 s.port
6 16 d.port
****************************************/
#include "stdinc.h"
#include "rfc.h"
#include "dheap.h"
int phase = 4; // number of pahses
FILE *fpr; // ruleset file
FILE *fpt; // test trace file
int p0_table[7][65536]; //phase 0 chunk tables
int p1_table[4][MAXTABLE]; //phase 1 chunk tables
int p2_table[2][MAXTABLE]; //phase 2 chunk tables
int p3_table[MAXTABLE]; //phase 3 chunk tables
struct eq p0_eq[7][2*MAXRULES]; //phase 0 chunk equivalence class
struct eq p1_eq[4][2*MAXRULES]; //phase 1 chunk equivalence class
struct eq p2_eq[2][2*MAXRULES]; //phase 2 chunk equivalence class
struct eq p3_eq[2*MAXRULES]; //phase 3 chunk equivalence class
int p0_neq[7]; //phase 0 number of chunk equivalence classes
int p1_neq[4]; //phase 1 number of chunk equivalence classes
int p2_neq[2]; //phase 2 number of chunk equivalence classes
int p3_neq; //phase 3 number of chunk equivalence classes
int preprocessing_2chunk(eq *a, int na, eq *b, int nb, eq *x, int *tb){
int i, j, k, r;
int current_num_rules;
int *current_rule_list = NULL;
int current_eq_id;
int match;
current_eq_id = -1;
for(i=0; i<na; i++){
for(j=0; j<nb; j++){
// get the intersection rule set
if(a[i].numrules == 0 || b[j].numrules == 0) {
current_num_rules = 0;
}else{
k=0; r=0;
current_num_rules = 0;
while(k < a[i].numrules && r < b[j].numrules){
if(a[i].rulelist[k] == b[j].rulelist[r]){
current_num_rules ++;
k++; r++;
}else if(a[i].rulelist[k] > b[j].rulelist[r]){
r++;
}else{
k++;
}
}
current_rule_list = (int *)calloc(current_num_rules, sizeof(int));
k=0; r=0;
current_num_rules = 0;
while(k < a[i].numrules && r < b[j].numrules){
if(a[i].rulelist[k] == b[j].rulelist[r]){
current_rule_list[current_num_rules] = a[i].rulelist[k];
current_num_rules ++;
k++; r++;
}else if(a[i].rulelist[k] > b[j].rulelist[r]){
r++;
}else{
k++;
}
}
}
//set the equivalence classes
match = 0;
for(k=0; k<=current_eq_id; k++){
if(current_num_rules == x[k].numrules){
match = 1;
for(r=0; r<current_num_rules; r++){
if(x[k].rulelist[r] != current_rule_list[r]){
match = 0;
break;
}
}
if(match == 1){
tb[i*nb +j] = k;
break;
}
}
}
if(match == 0){
current_eq_id ++;
x[current_eq_id].numrules = current_num_rules;
x[current_eq_id].rulelist = current_rule_list;
tb[i*nb +j] = current_eq_id;
}
}
}
return current_eq_id+1;
}
int preprocessing_3chunk(eq *a, int na, eq *b, int nb, eq *c, int nc, eq *x, int *tb){
int i, j, s, k, r, t;
int current_num_rules;
int *current_rule_list = NULL;
int current_eq_id;
int match;
current_eq_id = -1;
for(i=0; i<na; i++){
for(j=0; j<nb; j++){
for(s=0; s<nc; s++){
//get the intersection list
if(a[i].numrules == 0 || b[j].numrules == 0 || c[s].numrules == 0) {
current_num_rules = 0;
}else{
k=0; r=0; t=0;
current_num_rules = 0;
while(k < a[i].numrules && r < b[j].numrules && t < c[s].numrules){
if(a[i].rulelist[k] == b[j].rulelist[r] && a[i].rulelist[k] == c[s].rulelist[t]){
current_num_rules ++;
k++; r++; t++;
}else if(a[i].rulelist[k] <= b[j].rulelist[r] && a[i].rulelist[k] <= c[s].rulelist[t]){
k++;
}else if(b[j].rulelist[r] <= a[i].rulelist[k] && b[j].rulelist[r] <= c[s].rulelist[t]){
r++;
}else{
t++;
}
}
current_rule_list = (int *)calloc(current_num_rules, sizeof(int));
k=0; r=0; t=0;
current_num_rules = 0;
while(k < a[i].numrules && r < b[j].numrules && t < c[s].numrules){
if(a[i].rulelist[k] == b[j].rulelist[r] && a[i].rulelist[k] == c[s].rulelist[t]){
current_rule_list[current_num_rules] = a[i].rulelist[k];
current_num_rules ++;
k++; r++; t++;
}else if(a[i].rulelist[k] <= b[j].rulelist[r] && a[i].rulelist[k] <= c[s].rulelist[t]){
k++;
}else if(b[j].rulelist[r] <= a[i].rulelist[k] && b[j].rulelist[r] <= c[s].rulelist[t]){
r++;
}else{
t++;
}
}
}
//set the equivalent classes
match = 0;
for(k=0; k<=current_eq_id; k++){
if(current_num_rules == x[k].numrules){
match = 1;
for(r=0; r<current_num_rules; r++){
if(x[k].rulelist[r] != current_rule_list[r]){
match = 0;
break;
}
}
if(match == 1){
tb[i*nb*nc +j*nc +s] = k;
break;
}
}
}
if(match == 0){
current_eq_id ++;
x[current_eq_id].numrules = current_num_rules;
x[current_eq_id].rulelist = current_rule_list;
tb[i*nb*nc +j*nc +s] = current_eq_id;
}
}
}
}
return current_eq_id+1;
}
int loadrule(FILE *fp, pc_rule *rule){
int tmp;
unsigned sip1, sip2, sip3, sip4, siplen;
unsigned dip1, dip2, dip3, dip4, diplen;
unsigned proto, protomask;
int i = 0;
while(1){
if(fscanf(fp,"@%d.%d.%d.%d/%d %d.%d.%d.%d/%d %d : %d %d : %d %x/%x\n",
&sip1, &sip2, &sip3, &sip4, &siplen, &dip1, &dip2, &dip3, &dip4, &diplen,
&rule[i].field[3].low, &rule[i].field[3].high, &rule[i].field[4].low, &rule[i].field[4].high,
&proto, &protomask) != 16) break;
if(siplen == 0){
rule[i].field[0].low = 0;
rule[i].field[0].high = 0xFFFFFFFF;
}else if(siplen > 0 && siplen <= 8){
tmp = sip1<<24;
rule[i].field[0].low = tmp;
rule[i].field[0].high = rule[i].field[0].low + (1<<(32-siplen)) - 1;
}else if(siplen > 8 && siplen <= 16){
tmp = sip1<<24; tmp += sip2<<16;
rule[i].field[0].low = tmp;
rule[i].field[0].high = rule[i].field[0].low + (1<<(32-siplen)) - 1;
}else if(siplen > 16 && siplen <= 24){
tmp = sip1<<24; tmp += sip2<<16; tmp +=sip3<<8;
rule[i].field[0].low = tmp;
rule[i].field[0].high = rule[i].field[0].low + (1<<(32-siplen)) - 1;
}else if(siplen > 24 && siplen <= 32){
tmp = sip1<<24; tmp += sip2<<16; tmp += sip3<<8; tmp += sip4;
rule[i].field[0].low = tmp;
rule[i].field[0].high = rule[i].field[0].low + (1<<(32-siplen)) - 1;
}else{
printf("Src IP length exceeds 32\n");
return 0;
}
if(diplen == 0){
rule[i].field[1].low = 0;
rule[i].field[1].high = 0xFFFFFFFF;
}else if(diplen > 0 && diplen <= 8){
tmp = dip1<<24;
rule[i].field[1].low = tmp;
rule[i].field[1].high = rule[i].field[1].low + (1<<(32-diplen)) - 1;
}else if(diplen > 8 && diplen <= 16){
tmp = dip1<<24; tmp +=dip2<<16;
rule[i].field[1]