-
Notifications
You must be signed in to change notification settings - Fork 390
/
origin_vn.cc
121 lines (100 loc) · 2.99 KB
/
origin_vn.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/
#include "bgp/origin-vn/origin_vn.h"
#include <stdio.h>
#include <algorithm>
using std::copy;
using std::string;
OriginVn OriginVn::null_originvn;
OriginVn::OriginVn() {
data_.fill(0);
}
OriginVn::OriginVn(as_t asn, uint32_t vn_index) {
data_[0] = 0x80;
data_[1] = 0x71;
put_value(&data_[2], 2, asn);
put_value(&data_[4], 4, vn_index);
}
OriginVn::OriginVn(const bytes_type &data) {
copy(data.begin(), data.end(), data_.begin());
}
OriginVn OriginVn::FromString(const string &str,
boost::system::error_code *errorp) {
OriginVn origin_vn;
uint8_t data[OriginVn::kSize];
size_t pos = str.find(':');
if (pos == string::npos) {
if (errorp != NULL) {
*errorp = make_error_code(boost::system::errc::invalid_argument);
}
return OriginVn::null_originvn;
}
string first(str.substr(0, pos));
if (first != "originvn") {
if (errorp != NULL) {
*errorp = make_error_code(boost::system::errc::invalid_argument);
}
return OriginVn::null_originvn;
}
string rest(str.substr(pos+1));
pos = rest.find(':');
if (pos == string::npos) {
if (errorp != NULL) {
*errorp = make_error_code(boost::system::errc::invalid_argument);
}
return OriginVn::null_originvn;
}
string second(rest.substr(0, pos));
char *endptr;
int64_t asn = strtol(second.c_str(), &endptr, 10);
if (asn == 0 || asn >= 65535 || *endptr != '\0') {
if (errorp != NULL) {
*errorp = make_error_code(boost::system::errc::invalid_argument);
}
return OriginVn::null_originvn;
}
string third(rest.substr(pos+1));
uint64_t value = strtol(third.c_str(), &endptr, 10);
if (*endptr != '\0') {
if (errorp != NULL) {
*errorp = make_error_code(boost::system::errc::invalid_argument);
}
return OriginVn::null_originvn;
}
// Check assigned number.
if (value > 0xFFFFFFFF) {
if (errorp != NULL) {
*errorp = make_error_code(boost::system::errc::invalid_argument);
}
return OriginVn::null_originvn;
}
data[0] = 0x80;
data[1] = 0x71;
put_value(&data[2], 2, asn);
put_value(&data[4], 4, value);
copy(&data[0], &data[OriginVn::kSize], origin_vn.data_.begin());
return origin_vn;
}
as_t OriginVn::as_number() const {
if (data_[0] == 0x80 && data_[1] == 0x71) {
as_t as_number = get_value(data_.data() + 2, 2);
return as_number;
}
return 0;
}
int OriginVn::vn_index() const {
if (data_[0] == 0x80 && data_[1] == 0x71) {
int vn_index = get_value(data_.data() + 4, 4);
return vn_index;
}
return 0;
}
bool OriginVn::IsGlobal() const {
return (vn_index() >= kMinGlobalId);
}
string OriginVn::ToString() {
char temp[50];
snprintf(temp, sizeof(temp), "originvn:%u:%u", as_number(), vn_index());
return string(temp);
}