OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
esi.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include "net/esi.h"
6 
7 #include "base/parse_object.h"
8 #include "base/util.h"
9 #include "base/string_util.h"
10 #include "base/address.h"
11 
12 using namespace std;
13 
14 static const uint8_t max_esi_bytes[] = {
15  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
16 };
17 
20 
22  memset(data_, 0, kSize);
23 }
24 
26  memcpy(data_, data, kSize);
27 }
28 
30  boost::system::error_code *errorp) {
31  if (str == "zero_esi")
33  if (str == "max_esi")
35 
36  size_t num_colons = count(str.begin(), str.end(), ':');
37  if (num_colons != 1 && num_colons != 9) {
38  if (errorp != NULL)
39  *errorp = make_error_code(boost::system::errc::invalid_argument);
41  }
42 
43  uint8_t data[kSize];
44  memset(data, 0, kSize);
45 
46  // AS based or IP based.
47  if (num_colons == 1) {
48  size_t pos = str.find(':');
49  assert(pos != string::npos);
50  string asn_or_ip(str.substr(0, pos));
51 
52  size_t num_dots = count(asn_or_ip.begin(), asn_or_ip.end(), '.');
53  if (num_dots != 0 && num_dots != 3) {
54  if (errorp != NULL)
55  *errorp = make_error_code(boost::system::errc::invalid_argument);
57  }
58 
59  // AS based.
60  if (num_dots == 0) {
61  uint32_t asn;
62  bool ret = stringToInteger(asn_or_ip, asn);
63  if (!ret) {
64  if (errorp != NULL) {
65  *errorp = make_error_code(boost::system::errc::invalid_argument);
67  }
68  }
69 
70  data[0] = AS_BASED;
71  put_value(&data[1], 4, asn);
72  }
73 
74  // IP based.
75  if (num_dots == 3) {
76  boost::system::error_code ec;
77  Ip4Address addr = Ip4Address::from_string(asn_or_ip, ec);
78  if (ec.value() != 0) {
79  if (errorp != NULL) {
80  *errorp = make_error_code(boost::system::errc::invalid_argument);
82  }
83  }
84 
85  data[0] = IP_BASED;
86  const Ip4Address::bytes_type &bytes = addr.to_bytes();
87  copy(bytes.begin(), bytes.begin() + 4, &data[1]);
88  }
89 
90  // Parse discriminator - common for AS based and IP based.
91  string disc_str(str, pos + 1);
92  uint32_t disc;
93  bool ret = stringToInteger(disc_str, disc);
94  if (!ret) {
95  if (errorp != NULL) {
96  *errorp = make_error_code(boost::system::errc::invalid_argument);
98  }
99  }
100  put_value(&data[5], 4, disc);
101  }
102 
103  // All other formats - raw colon separated bytes.
104  if (num_colons == 9) {
105  char extra;
106  int ret = sscanf(str.c_str(),
107  "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx%c",
108  &data[0], &data[1], &data[2], &data[3], &data[4],
109  &data[5], &data[6], &data[7], &data[8], &data[9], &extra);
110  if (ret != kSize || strchr(str.c_str(), 'x') || strchr(str.c_str(), 'X')) {
111  if (errorp != NULL)
112  *errorp = make_error_code(boost::system::errc::invalid_argument);
114  }
115  }
116 
117  return EthernetSegmentId(data);
118 }
119 
121  if (CompareTo(kZeroEsi) == 0)
122  return "zero_esi";
123  if (CompareTo(kMaxEsi) == 0)
124  return "max_esi";
125 
126  switch (Type()) {
127  case AS_BASED: {
128  uint32_t asn = get_value(data_ + 1, 4);
129  uint32_t value = get_value(data_ + 5, 4);
130  return integerToString(asn) + ":" + integerToString(value);
131  break;
132  }
133  case IP_BASED: {
134  Ip4Address addr(get_value(data_ + 1, 4));
135  uint32_t value = get_value(data_ + 5, 4);
136  return addr.to_string() + ":" + integerToString(value);
137  break;
138  }
139  case MAC_BASED:
140  case STP_BASED:
141  case LACP_BASED:
142  case CONFIGURED:
143  default: {
144  char temp[64];
145  snprintf(temp, sizeof(temp),
146  "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
147  data_[0], data_[1], data_[2], data_[3], data_[4],
148  data_[5], data_[6], data_[7], data_[8], data_[9]);
149  return temp;
150  }
151  }
152 
153  return "bad_esi";
154 }
155 
157  return memcmp(data_, rhs.data_, kSize);
158 }
EthernetSegmentId()
Definition: esi.cc:21
bool stringToInteger(const std::string &str, NumberType &num)
Definition: string_util.h:71
static uint64_t get_value(const uint8_t *data, int size)
Definition: parse_object.h:39
static EthernetSegmentId FromString(const std::string &str, boost::system::error_code *errorp=NULL)
Definition: esi.cc:29
static const uint8_t max_esi_bytes[]
Definition: esi.cc:14
static const std::string integerToString(const NumberType &num)
Definition: string_util.h:19
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
static const EthernetSegmentId kZeroEsi
Definition: esi.h:16
std::string ToString() const
Definition: esi.cc:120
int CompareTo(const EthernetSegmentId &rhs) const
Definition: esi.cc:156
static int CompareTo(const AuthenticationKey &lhs, const AuthenticationKey &rhs)
Definition: bgp_config.cc:31
static const EthernetSegmentId kMaxEsi
Definition: esi.h:17
uint8_t data_[kSize]
Definition: esi.h:63
static void put_value(uint8_t *data, int size, uint64_t value)
Definition: parse_object.h:55