OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
rtarget_address.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
6 
7 #include <algorithm>
8 
9 #include "base/parse_object.h"
10 #include "bgp/bgp_common.h"
11 
12 using std::copy;
13 using std::string;
14 
16 
18  data_.fill(0);
19 }
20 
22  copy(data.begin(), data.end(), data_.begin());
23 }
24 
25 RouteTarget::RouteTarget(const Ip4Address &address, uint16_t num) {
26  data_[0] = 0x1;
27  data_[1] = 0x2;
28  put_value(&data_[2], 4, address.to_ulong());
29  put_value(&data_[6], 2, num);
30 }
31 
32 const uint64_t RouteTarget::GetExtCommunityValue() const {
33  return get_value(data_.begin(), 8);
34 }
35 
37  boost::system::error_code *errorp) {
38  RouteTarget rt;
39  uint8_t data[RouteTarget::kSize];
40 
41  // target:1:2 OR target:1.2.3.4:3
42  size_t pos = str.find(':');
43  if (pos == string::npos) {
44  if (errorp != NULL) {
45  *errorp = make_error_code(boost::system::errc::invalid_argument);
46  }
48  }
49 
50  string first(str.substr(0, pos));
51  if (first != "target") {
52  if (errorp != NULL) {
53  *errorp = make_error_code(boost::system::errc::invalid_argument);
54  }
56  }
57 
58  string rest(str.substr(pos+1));
59 
60  pos = rest.find(':');
61  if (pos == string::npos) {
62  if (errorp != NULL) {
63  *errorp = make_error_code(boost::system::errc::invalid_argument);
64  }
66  }
67 
68  boost::system::error_code ec;
69  string second(rest.substr(0, pos));
70  Ip4Address addr = Ip4Address::from_string(second, ec);
71  int offset = 6;
72  char *endptr;
73  if (ec.failed()) {
74  bool is_as4 = false;
75  // Not an IP address, try ASN.
76  if (second.c_str()[pos - 1] == 'L') {
77  is_as4 = true;
78  second = second.substr(0, pos - 1);
79  }
80 
81  int64_t asn = strtol(second.c_str(), &endptr, 10);
82  if (asn == 0 || asn > 0xFFFFFFFF || *endptr != '\0') {
83  if (errorp != NULL) {
84  *errorp =
85  make_error_code(boost::system::errc::invalid_argument);
86  }
88  }
89 
90  if (asn > AS2_MAX || is_as4) {
91  data[0] = 0x2;
92  put_value(&data[2], 4, asn);
93  } else {
94  data[0] = 0x0;
95  put_value(&data[2], 2, asn);
96  offset = 4;
97  }
98  data[1] = 0x2;
99  } else {
100  data[0] = 0x1;
101  data[1] = 0x2;
102  uint32_t l_addr = addr.to_ulong();
103  put_value(&data[2], 4, l_addr);
104  }
105 
106  string third(rest.substr(pos+1));
107  uint64_t value = strtol(third.c_str(), &endptr, 10);
108  if (*endptr != '\0') {
109  if (errorp != NULL) {
110  *errorp = make_error_code(boost::system::errc::invalid_argument);
111  }
113  }
114 
115  // Check assigned number for type 0.
116  if (offset == 4 && value > 0xFFFFFFFF) {
117  if (errorp != NULL) {
118  *errorp = make_error_code(boost::system::errc::invalid_argument);
119  }
121  }
122 
123  // Check assigned number for type 1 and 2
124  if (offset == 6 && value > 0xFFFF) {
125  if (errorp != NULL) {
126  *errorp = make_error_code(boost::system::errc::invalid_argument);
127  }
129  }
130 
131  put_value(&data[offset], RouteTarget::kSize - offset, value);
132  copy(&data[0], &data[RouteTarget::kSize], rt.data_.begin());
133  return rt;
134 }
135 
136 string RouteTarget::ToString() const {
137  uint8_t data[RouteTarget::kSize];
138  copy(data_.begin(), data_.end(), &data[0]);
139  if (data[0] == 0) {
140  uint16_t asn = get_value(data + 2, 2);
141  uint32_t num = get_value(data + 4, 4);
142  char temp[50];
143  snprintf(temp, sizeof(temp), "target:%u:%u", asn, num);
144  return string(temp);
145  } else if (data[0] == 2) {
146  uint32_t asn = get_value(data + 2, 4);
147  uint16_t num = get_value(data + 6, 2);
148  char temp[50];
149  if (asn > AS2_MAX)
150  snprintf(temp, sizeof(temp), "target:%u:%u", asn, num);
151  else
152  snprintf(temp, sizeof(temp), "target:%uL:%u", asn, num);
153  return string(temp);
154  } else {
155  Ip4Address addr(get_value(data + 2, 4));
156  uint16_t num = get_value(data + 6, 2);
157  char temp[50];
158  snprintf(temp, sizeof(temp), "target:%s:%u",
159  addr.to_string().c_str(), num);
160  return string(temp);
161  }
162 }
boost::array< uint8_t, kSize > bytes_type
static const int kSize
static uint64_t get_value(const uint8_t *data, int size)
Definition: parse_object.h:39
static RouteTarget null_rtarget
static RouteTarget FromString(const std::string &str, boost::system::error_code *error=NULL)
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
const uint64_t GetExtCommunityValue() const
std::string ToString() const
bytes_type data_
#define AS2_MAX
Definition: bgp_common.h:24
static void put_value(uint8_t *data, int size, uint64_t value)
Definition: parse_object.h:55