Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include "bgp/extended-community/types.h"
6 : #include "bgp/origin-vn/origin_vn.h"
7 :
8 : #include <stdio.h>
9 :
10 : #include <algorithm>
11 :
12 :
13 : using std::copy;
14 : using std::string;
15 :
16 : OriginVn OriginVn::null_originvn;
17 :
18 181 : OriginVn::OriginVn() {
19 181 : data_.fill(0);
20 181 : }
21 :
22 218135 : OriginVn::OriginVn(as_t asn, uint32_t vn_index) {
23 218135 : if (asn <= AS2_MAX) {
24 218133 : data_[0] = BgpExtendedCommunityType::Experimental;
25 218131 : put_value(&data_[2], 2, asn);
26 218130 : put_value(&data_[4], 4, vn_index);
27 : } else {
28 2 : data_[0] = BgpExtendedCommunityType::Experimental4ByteAs;
29 4 : put_value(&data_[2], 4, asn);
30 4 : put_value(&data_[6], 2, vn_index);
31 : }
32 218135 : data_[1] = BgpExtendedCommunityExperimentalSubType::OriginVn;
33 218135 : }
34 :
35 142817 : OriginVn::OriginVn(const bytes_type &data) {
36 142817 : copy(data.begin(), data.end(), data_.begin());
37 142815 : }
38 :
39 21 : OriginVn OriginVn::FromString(const string &str,
40 : boost::system::error_code *errorp) {
41 21 : OriginVn origin_vn;
42 : uint8_t data[OriginVn::kSize];
43 21 : size_t pos = str.find(':');
44 21 : if (pos == string::npos) {
45 1 : if (errorp != NULL) {
46 1 : *errorp = make_error_code(boost::system::errc::invalid_argument);
47 : }
48 1 : return OriginVn::null_originvn;
49 : }
50 :
51 20 : string first(str.substr(0, pos));
52 20 : if (first != "originvn") {
53 3 : if (errorp != NULL) {
54 3 : *errorp = make_error_code(boost::system::errc::invalid_argument);
55 : }
56 3 : return OriginVn::null_originvn;
57 : }
58 :
59 17 : string rest(str.substr(pos+1));
60 :
61 17 : pos = rest.find(':');
62 17 : if (pos == string::npos) {
63 1 : if (errorp != NULL) {
64 1 : *errorp = make_error_code(boost::system::errc::invalid_argument);
65 : }
66 1 : return OriginVn::null_originvn;
67 : }
68 :
69 16 : string second(rest.substr(0, pos));
70 : char *endptr;
71 16 : int64_t asn = strtol(second.c_str(), &endptr, 10);
72 16 : if (asn == 0 || asn > 0xFFFFFFFF || *endptr != '\0') {
73 1 : if (errorp != NULL) {
74 1 : *errorp = make_error_code(boost::system::errc::invalid_argument);
75 : }
76 1 : return OriginVn::null_originvn;
77 : }
78 :
79 15 : string third(rest.substr(pos+1));
80 15 : uint64_t value = strtol(third.c_str(), &endptr, 10);
81 15 : if (*endptr != '\0') {
82 2 : if (errorp != NULL) {
83 2 : *errorp = make_error_code(boost::system::errc::invalid_argument);
84 : }
85 2 : return OriginVn::null_originvn;
86 : }
87 :
88 : // Check assigned number.
89 13 : if ((asn > AS2_MAX && value > 0xFFFF) || value > 0xFFFFFFFF) {
90 1 : if (errorp != NULL) {
91 1 : *errorp = make_error_code(boost::system::errc::invalid_argument);
92 : }
93 1 : return OriginVn::null_originvn;
94 : }
95 :
96 12 : if (asn <= AS2_MAX) {
97 6 : data[0] = BgpExtendedCommunityType::Experimental;
98 6 : put_value(&data[2], 2, asn);
99 6 : put_value(&data[4], 4, value);
100 : } else {
101 6 : data[0] = BgpExtendedCommunityType::Experimental4ByteAs;
102 6 : put_value(&data[2], 4, asn);
103 6 : put_value(&data[6], 2, value);
104 : }
105 12 : data[1] = BgpExtendedCommunityExperimentalSubType::OriginVn;
106 12 : copy(&data[0], &data[OriginVn::kSize], origin_vn.data_.begin());
107 12 : return origin_vn;
108 20 : }
109 :
110 19296 : as_t OriginVn::as_number() const {
111 19296 : if (data_[0] == BgpExtendedCommunityType::Experimental) {
112 19283 : as2_t as_number = get_value(data_.data() + 2, 2);
113 19283 : return as_number;
114 : }
115 13 : if (data_[0] == BgpExtendedCommunityType::Experimental4ByteAs) {
116 13 : as_t as_number = get_value(data_.data() + 2, 4);
117 13 : return as_number;
118 : }
119 0 : return 0;
120 : }
121 :
122 143161 : int OriginVn::vn_index() const {
123 143161 : if (data_[0] == BgpExtendedCommunityType::Experimental) {
124 143141 : int vn_index = get_value(data_.data() + 4, 4);
125 143137 : return vn_index;
126 : }
127 20 : if (data_[0] == BgpExtendedCommunityType::Experimental4ByteAs) {
128 20 : int vn_index = get_value(data_.data() + 6, 2);
129 20 : return vn_index;
130 : }
131 0 : return 0;
132 : }
133 :
134 20530 : bool OriginVn::IsGlobal() const {
135 20530 : return (vn_index() >= kMinGlobalId);
136 : }
137 :
138 499 : string OriginVn::ToString() {
139 : char temp[50];
140 499 : snprintf(temp, sizeof(temp), "originvn:%u:%u", as_number(), vn_index());
141 499 : return string(temp);
142 : }
|