Bgp ser update
a fake serializer for BGP
object bgp_ser_update = {}
<<< member
class `bgp_ser_update`;
>>>
<<< impl
class `bgp_ser_update` : public ivy_binary_ser_128 {
enum bgp_state {bgp_s_wr_len,
bgp_s_wr,
bgp_s_wr_l,
bgp_s_wr_prefix,
bgp_s_path_len,
bgp_s_path_attr,
bgp_s_path_attr_len,
bgp_s_path_attr_origin,
bgp_s_path_attr_as_path,
bgp_s_path_attr_as_path_segment_type,
bgp_s_path_attr_as_path_segment_len,
bgp_s_path_attr_as_path_segment_value,
bgp_s_path_attr_next_hop,
bgp_s_path_attr_multi_exit_disc,
bgp_s_path_attr_local_pref,
bgp_s_path_attr_atomic_aggregate,
bgp_s_path_attr_aggregator,
bgp_s_path_attr_aggregator_ip_addr,
bgp_s_net_info,
bgp_s_net_info_pref} state;
int token_length = 4;
long path_attr_type;
int fence=0;
int current_bgp_size = 0;
int payload_length = 12;
int withdraw_routes_len = 0;
int route_prefix_len = 0;
int total_path_attr_len = 0;
int segment_len = 0;
int route_prefix_len_2 = 0;
int attr_len = 0;
bool optional_bit = false; //first order bit
bool transitive_bit = false; //second order bit
bool partial_bit = false; //third order bit
bool extended_length_bit = false; //fourth order bit
int debug = 0;
int next_state = 0;
public:
bgp_ser_update() : state(bgp_s_wr_len) {
}
virtual void set(int128_t &res) {
switch (state) {
case bgp_s_wr_len:
{
std::cerr << "bgp_s_wr_len 1\n";
setn(res,2);
withdraw_routes_len = res;
std::cerr << "withdraw_routes_len = " << withdraw_routes_len << "\n";
state = bgp_s_wr_l;
}
break;
case bgp_s_wr_l:
{
std::cerr << "bgp_s_wr_l 1\n";
setn(res,1);
route_prefix_len = res;
std::cerr << "route_prefix_len = " << route_prefix_len << "\n";
state = bgp_s_wr_prefix;
}
break;
case bgp_s_wr_prefix:
{
std::cerr << "bgp_s_wr_prefix 1\n";
setn(res,1);
}
break;
case bgp_s_wr:
{
std::cerr << "bgp_s_wr 1\n";
setn(res,1);
std::cerr << "payload_length = " << payload_length << "\n";
//state = bgp_s_path_len;
}
break;
case bgp_s_path_len:
{
std::cerr << "bgp_s_path_len 1\n";
setn(res,2);
total_path_attr_len = res;
state = bgp_s_path_attr;
std::cerr << "total_path_attr_len = " << total_path_attr_len << "\n";
}
break;
case bgp_s_path_attr:
{
std::cerr << "bgp_s_path_attr 1\n";
}
break;
case bgp_s_path_attr_len:
{
int128_t len_res;
std::cerr << "bgp_s_path_attr_len 1\n";
int get = 1;
if(extended_length_bit)
get = 2;
setn(len_res,get); //ivy_binary_deser_128::
attr_len = len_res;
total_path_attr_len -= get;
std::cerr << "attr_len = " << attr_len << "\n";
state = (enum bgp_state) next_state;
std::cerr << "state = " << state << "\n";
std::cerr << "total_path_attr_len = " << total_path_attr_len << "\n";
}
break;
case bgp_s_path_attr_origin:
{
std::cerr << "bgp_s_path_attr_origin 1\n";
setn(res,1);
total_path_attr_len -= 1;
debug = res;
std::cerr << "debug = " << debug << "\n";
std::cerr << "total_path_attr_len = " << total_path_attr_len << "\n";
};
break;
case bgp_s_path_attr_as_path:
{
std::cerr << "bgp_s_path_attr_as_path 1\n";
state = bgp_s_path_attr_as_path_segment_type;
};
break;
case bgp_s_path_attr_as_path_segment_len:
{
std::cerr << "bgp_s_path_attr_as_path_segment_len 1\n";
setn(res,1);
segment_len = res;
total_path_attr_len -= 1;
attr_len -= 1;
state = bgp_s_path_attr_as_path_segment_value;
std::cerr << "total_path_attr_len = " << total_path_attr_len << "\n";
};
break;
case bgp_s_path_attr_as_path_segment_type:
{
std::cerr << "bgp_s_path_attr_as_path_segment_type 1\n";
setn(res,1);
total_path_attr_len -= 1;
attr_len -= 1;
state = bgp_s_path_attr_as_path_segment_len;
std::cerr << "total_path_attr_len = " << total_path_attr_len << "\n";
};
break;
case bgp_s_path_attr_as_path_segment_value:
{
std::cerr << "bgp_s_path_attr_as_path_segment_value 1\n";
setn(res,2);
total_path_attr_len -= 2;
attr_len -= 2;
};
break;
case bgp_s_path_attr_next_hop:
{
std::cerr << "bgp_s_path_attr_next_hop 1\n";
setn(res,4);
total_path_attr_len -= 4;
std::cerr << "total_path_attr_len = " << total_path_attr_len << "\n";
};
break;
case bgp_s_path_attr_multi_exit_disc:
{
std::cerr << "bgp_s_path_attr_multi_exit_disc 1\n";
setn(res,4);
total_path_attr_len -= 4;
std::cerr << "total_path_attr_len = " << total_path_attr_len << "\n";
};
break;
case bgp_s_path_attr_local_pref:
{
std::cerr << "bgp_s_path_attr_local_pref 1\n";
setn(res,4);
total_path_attr_len -= 4;
};
break;
case bgp_s_path_attr_atomic_aggregate:
{
std::cerr << "bgp_s_path_attr_atomic_aggregate 1\n";
};
break;
case bgp_s_path_attr_aggregator:
{
std::cerr << "bgp_s_path_attr_aggregator 1\n";
setn(res,2);
total_path_attr_len -= 2;
state = bgp_s_path_attr_aggregator_ip_addr;
std::cerr << "total_path_attr_len = " << total_path_attr_len << "\n";
};
break;
case bgp_s_path_attr_aggregator_ip_addr:
{
std::cerr << "bgp_s_path_attr_aggregator_ip_addr 1\n";
setn(res,4);
total_path_attr_len -= 4;
};
break;
case bgp_s_net_info:
{
std::cerr << "bgp_s_net_info 1\n";
setn(res,1);
route_prefix_len_2 = res;
state = bgp_s_net_info_pref;
std::cerr << "route_prefix_len_2 = " << route_prefix_len_2 << "\n";
}
break;
case bgp_s_net_info_pref:
{
std::cerr << "bgp_s_net_info_pref 1\n";
if(route_prefix_len_2-1 > 0)
setn(res,1);
route_prefix_len_2 -= 8; //todo prefix is ip prefix, here we only support multiple of 8
}
break;
default:
std::cerr << "bgp_deser_update 3\n";
throw deser_err();
}
}
//Function that return true if the i bit of the byte is 1
bool checkBit(int byte, int i) {
// Shift 1 to the i-th position and perform bitwise AND with the byte
// If the result is non-zero, then the i-th bit is 1, otherwise, it's 0
return (byte & (1 << i)) != 0;
}
//Function that return true if the i bit of the byte is 1
//TODO
bool setBit(int byte, int i) {
// Shift 1 to the i-th position and perform bitwise AND with the byte
// If the result is non-zero, then the i-th bit is 1, otherwise, it's 0
return (byte & (1 << i)) != 0;
}
virtual int open_tag(const std::vector<std::string> &tags) {
if (state == bgp_s_path_attr) {
int128_t ft_flag;
setn(ft_flag,1); // could be bigger
int flag = ft_flag;
std::cerr << "recv flag = " << flag << "\n";
optional_bit = checkBit(flag, 7);
transitive_bit = checkBit(flag, 6);
partial_bit = checkBit(flag, 5);
extended_length_bit = checkBit(flag, 4);
std::cerr << "optional_bit = " << optional_bit << "\n";
std::cerr << "transitive_bit = " << transitive_bit << "\n";
std::cerr << "partial_bit = " << partial_bit << "\n";
std::cerr << "extended_length_bit = " << extended_length_bit << "\n";
total_path_attr_len -= 1;
int128_t ft;
setn(ft,1); // could be bigger
//long long ft;
//ivy_binary_deser::setn(ft,1); // could be bigger
//total_path_attr_len -= 1;
int128_t len_res;
std::cerr << "bgp_s_path_attr_len 1\n";
int get = 1;
if(extended_length_bit)
get = 2;
setn(len_res,get);
attr_len = len_res;
std::cerr << "attr_len = " << attr_len << "\n";
//attr_len = reverse_bytes_int(attr_len);
total_path_attr_len -= 1;
std::cerr << "attr_len = " << attr_len << "\n";
/*
TODO we should get varint and then parse in consequence like in tls_deser_ser
*/
std::cerr << "total_path_attr_len = " << total_path_attr_len << "\n";
path_attr_type = ft;
//state = bgp_s_path_attr_len;
std::cerr << "recv path_attr_type = " << path_attr_type << "\n";
if (path_attr_type == 0) {
//total_path_attr_len -= 1;
state = bgp_s_path_attr_origin;
std::cerr << "state = " << bgp_s_path_attr_origin << "\n";
std::cerr << "state = " << state << "\n";
return 0x01;
}
if (path_attr_type == 1) { //JF
//total_path_attr_len -= 1;
state = bgp_s_path_attr_as_path_segment_type; // bgp_s_path_attr_as_path;
return 0x02;
}
if (path_attr_type == 2) {
//total_path_attr_len -= 1;
state = bgp_s_path_attr_next_hop;
return 0x03;
}
if (path_attr_type == 3) {
//total_path_attr_len -= 1;
state = bgp_s_path_attr_multi_exit_disc;
return 0x04;
}
if (path_attr_type == 4) {
//total_path_attr_len -= 1;
state = bgp_s_path_attr_local_pref; // stream_blocked equivalent to this
return 0x05;
}
if (path_attr_type == 5) {
//total_path_attr_len -= 1;
state = bgp_s_path_attr_atomic_aggregate;
return 0x06;
}
if (path_attr_type == 6) { // new token frame
//total_path_attr_len -= 1;
state = bgp_s_path_attr_aggregator; // new token equivalent to this
return 0x07;
}
//std::cerr << "saw tag " << ft << "\n";
}
std::cerr << "state = " << state << "\n";
std::cerr << "bgp_deser_update 2\n";
throw deser_err();
}
virtual void open_list_elem() {
std::cerr << "open_list_elem tag\n";
if (state == bgp_s_path_attr_as_path_segment_type) {
std::cerr << "bgp_s_path_attr_as_path bgp_deser_update 2\n";
// return attr_len > 0;
}
if (state == bgp_s_wr_l) {
std::cerr << "bgp_s_wr_l bgp_deser_update 2\n";
// return withdraw_routes_len > 0;
}
if (state == bgp_s_wr_prefix) {
std::cerr << "bgp_s_wr_prefix bgp_deser_update 2\n";
route_prefix_len -= 1;
withdraw_routes_len -= 1;
// return route_prefix_len > 0;
}
//// return more(1);
if ( state == bgp_s_path_attr) {
std::cerr << "bgp_s_path_attr bgp_deser_update 2\n";
std::cerr << total_path_attr_len << "\n";
if(total_path_attr_len-1 <= 0) state = bgp_s_net_info;
// return total_path_attr_len-->0;
}
if(state == bgp_s_path_attr_as_path_segment_value){
std::cerr << "bgp_s_path_attr_as_path_segment_value bgp_deser_update 2\n";
total_path_attr_len -= 1;
// return segment_len-->0;
}
if(state == bgp_s_net_info_pref || state == bgp_s_net_info) {
std::cerr << "bgp_s_net_info_pref bgp_deser_update 2\n";
// return route_prefix_len_2 > 0;
}
std::cerr << "bgp_deser_update 1\n";
throw deser_err();
}
void open_list(int len) {
}
void close_list() {
std::cerr << "closing list\n";
if (state == bgp_s_wr_l) {
state = bgp_s_path_len;
}
if (state == bgp_s_wr_prefix) {
if (route_prefix_len == 0) {
if(withdraw_routes_len == 0){
state = bgp_s_path_len;
}
else{
state = bgp_s_wr_l;
}
}
}
if(state == bgp_s_path_attr_as_path_segment_value){
std::cerr << "state == bgp_s_path_attr_as_path_segment_value "<< segment_len << " " << total_path_attr_len <<"\n";
if (segment_len <= 0) {
if(total_path_attr_len == 0){ //TODO
state = bgp_s_net_info;
}
else{
state = bgp_s_path_attr_as_path_segment_value;
}
}
}
}
void close_list_elem() {}
virtual void close_tag() {
std::cerr << "closing tag\n";
if(state == bgp_s_net_info_pref)
state = bgp_s_net_info_pref;
else
state = bgp_s_path_attr;
}
~bgp_ser_update(){}
};
>>>