libbgp  0.6
A C++ BGP Library.
bgp-capability.cc
Go to the documentation of this file.
1 
11 #include "bgp-capability.h"
12 #include "bgp-errcode.h"
13 #include "value-op.h"
14 #include <stdlib.h>
15 #include <string.h>
16 #include <arpa/inet.h>
17 
18 namespace libbgp {
19 
26  length = 0;
27 }
28 
39 ssize_t BgpCapability::parseHeader(const uint8_t *from, size_t msg_sz) {
40  if (msg_sz < 2) {
41  setError(E_OPEN, E_UNSPEC_OPEN, NULL, 0);
42  logger->log(ERROR, "BgpCapability::parseHeader: unexpected end of capability.\n");
43  return -1;
44  }
45 
46  code = getValue<uint8_t>(&from);
47  length = getValue<uint8_t>(&from);
48 
49  if ((size_t) (length + 2) > msg_sz) {
50  setError(E_OPEN, E_UNSPEC_OPEN, NULL, 0);
51  logger->log(ERROR, "BgpCapability::parseHeader: capability size exceed capabilities list.\n");
52  return -1;
53  }
54 
55  return 2;
56 }
57 
64  my_asn = 0;
65  code = ASN_4B;
66 }
67 
68 ssize_t BgpCapability4BytesAsn::doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const {
69  ssize_t written = 0;
70  written += _print(indent, to, buf_sz, "FourOctetAsnCapability {\n");
71  indent++; {
72  written += _print(indent, to, buf_sz, "Code { %d }\n", code);
73  written += _print(indent, to, buf_sz, "MyAsn { %d }\n", my_asn);
74  }; indent--;
75  written += _print(indent, to, buf_sz, "}\n");
76 
77  return written;
78 }
79 
80 ssize_t BgpCapability4BytesAsn::parse(const uint8_t *from, size_t msg_sz) {
81  ssize_t hdr_len = parseHeader(from, msg_sz);
82 
83  if (code != ASN_4B) {
84  logger->log(FATAL, "BgpCapability4BytesAsn::parse: typecode mismatch with object type.\n");
85  throw "bad_type";
86  }
87 
88  if (hdr_len < 0) return hdr_len;
89  if (length != 4) {
90  setError(E_OPEN, E_UNSPEC_OPEN, NULL, 0);
91  logger->log(ERROR, "BgpCapability4BytesAsn::parse: bad length field (saw %d, want 4).\n", length);
92  return -1;
93  }
94 
95  const uint8_t *buffer = from + hdr_len;
96  my_asn = ntohl(getValue<uint32_t>(&buffer));
97 
98  return hdr_len + 4;
99 }
100 
101 ssize_t BgpCapability4BytesAsn::write(uint8_t *to, size_t buf_sz) const {
102  if (buf_sz < 6) {
103  logger->log(ERROR, "BgpCapability4BytesAsn::write: dest buffer too small.\n");
104  return -1;
105  }
106 
107  uint8_t *buffer = to;
108  putValue<uint8_t>(&buffer, ASN_4B);
109  putValue<uint8_t>(&buffer, 4);
110  putValue<uint32_t>(&buffer, htonl(my_asn));
111 
112  return 6;
113 }
114 
115 BgpCapabilityMpBgp::BgpCapabilityMpBgp(BgpLogHandler *logger) : BgpCapability(logger) {
116  code = MP_BGP;
117 }
118 
119 ssize_t BgpCapabilityMpBgp::doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const {
120  ssize_t written = 0;
121  written += _print(indent, to, buf_sz, "MpBgpCapability {\n");
122  indent++; {
123  written += _print(indent, to, buf_sz, "Code { %d }\n", code);
124  const char* afi_name = NULL;
125  const char* safi_name = NULL;
126 
127  switch (afi) {
128  case IPV4: afi_name = "IPv4"; break;
129  case IPV6: afi_name = "IPv6"; break;
130  default: afi_name = "Unknow"; break;
131  }
132 
133  switch (safi) {
134  case UNICAST: safi_name = "Unicast"; break;
135  case MULTICAST: safi_name = "Multicast"; break;
136  case UNICAST_AND_MULTICAST: safi_name = "Unicast & Multicast"; break;
137  default: safi_name = "Unknow";
138  }
139 
140  written += _print(indent, to, buf_sz, "Afi { %s }\n", afi_name);
141  written += _print(indent, to, buf_sz, "Safi { %s }\n", safi_name);
142  }; indent--;
143  written += _print(indent, to, buf_sz, "}\n");
144 
145  return written;
146 }
147 
148 ssize_t BgpCapabilityMpBgp::parse(const uint8_t *from, size_t msg_sz) {
149  ssize_t hdr_len = parseHeader(from, msg_sz);
150 
151  if (code != MP_BGP) {
152  logger->log(FATAL, "BgpCapabilityMpBgp::parse: typecode mismatch with object type.\n");
153  throw "bad_type";
154  }
155 
156  if (hdr_len < 0) return hdr_len;
157 
158  if (length != 4) {
159  setError(E_OPEN, E_UNSPEC_OPEN, NULL, 0);
160  logger->log(ERROR, "BgpCapabilityMpBgp::parse: bad length field, want 4, saw %d.\n", length);
161  }
162 
163  const uint8_t *buffer = from + hdr_len;
164  afi = ntohs(getValue<uint16_t>(&buffer));
165 
166  uint8_t res = getValue<uint8_t>(&buffer);
167  if (res != 0) {
168  logger->log(WARN, "BgpCapabilityMpBgp::parse: reserved bits != 0.\n");
169  }
170 
171  safi = getValue<uint8_t>(&buffer);
172 
173  return hdr_len + 4;
174 }
175 
176 ssize_t BgpCapabilityMpBgp::write(uint8_t *to, size_t buf_sz) const {
177  if (buf_sz < 6) {
178  logger->log(ERROR, "BgpCapability4BytesAsn::write: dest buffer too small.\n");
179  return -1;
180  }
181 
182  uint8_t *buffer = to;
183  putValue<uint8_t>(&buffer, MP_BGP);
184  putValue<uint8_t>(&buffer, 4);
185  putValue<uint16_t>(&buffer, htons(afi));
186  putValue<uint8_t>(&buffer, 0);
187  putValue<uint8_t>(&buffer, safi);
188 
189  return 6;
190 }
191 
198  value = NULL;
199 }
200 
206  if (length > 0 && value != NULL) free(value);
207 }
208 
209 ssize_t BgpCapabilityUnknow::doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const {
210  ssize_t written = 0;
211  written += _print(indent, to, buf_sz, "UnknowCapability {\n");
212  indent++; {
213  written += _print(indent, to, buf_sz, "Code { %d }\n", code);
214  }; indent--;
215  written += _print(indent, to, buf_sz, "}\n");
216 
217  return written;
218 }
219 
220 ssize_t BgpCapabilityUnknow::parse(const uint8_t *from, size_t msg_sz) {
221  ssize_t hdr_len = parseHeader(from, msg_sz);
222 
223  if (hdr_len < 0) return hdr_len;
224  if (length == 0) return hdr_len;
225 
226  value = (uint8_t *) malloc(length);
227  memcpy(value, from + hdr_len, length);
228 
229  return hdr_len + length;
230 }
231 
232 ssize_t BgpCapabilityUnknow::write(uint8_t *to, size_t buf_sz) const {
233  if (buf_sz < (size_t) (length + 2)) {
234  logger->log(ERROR, "BgpCapabilityUnknow::write: dest buffer too small.\n");
235  return -1;
236  }
237 
238  uint8_t *buffer = to;
239  putValue<uint8_t>(&buffer, code);
240  putValue<uint8_t>(&buffer, length);
241  if (length == 0) return 2;
242  if (value == NULL) {
243  logger->log(ERROR, "BgpCapabilityUnknow: missing value pointer.\n");
244  return -1;
245  }
246  memcpy(buffer, value, length);
247 
248  return length + 2;
249 }
250 
251 }
ssize_t write(uint8_t *to, size_t buf_sz) const
Serialize a BGP open message capability.
virtual ssize_t length() const
Get size in bytes required to serialize the object.
ssize_t write(uint8_t *to, size_t buf_sz) const
Serialize a BGP open message capability.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
ssize_t parseHeader(const uint8_t *from, size_t msg_sz)
Parse the capability header (code, length).
The BgpCapability base class.
ssize_t parse(const uint8_t *from, size_t msg_sz)
Deserialize a BGP open message capability.
static ssize_t _print(size_t indent, uint8_t **to, size_t *buf_left, const char *format,...)
Print helper.
The serializable base class.
Definition: serializable.h:26
ssize_t parse(const uint8_t *from, size_t msg_sz)
Deserialize a BGP open message capability.
void log(LogLevel level, const char *format_str,...)
Log a message. Consider using LIBBGP_LOG if logging the message needs a lot of computing power...
BGP Capabilities.
BgpCapability(BgpLogHandler *logger)
Construct a new Bgp Capability object.
~BgpCapabilityUnknow()
Destroy the BgpCapabilityUnknow object.
BgpCapability4BytesAsn(BgpLogHandler *logger)
Construct a new BgpCapability4BytesAsn object.
void setError(uint8_t err, uint8_t suberr, const uint8_t *data, size_t data_len)
Set the error information.
Definition: serializable.cc:61
Buffer operation helpers.
Definition: bgp-afi.h:14
The BgpLogHandler class.
BgpCapabilityUnknow(BgpLogHandler *logger)
Construct a new BgpCapabilityUnknow object.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
ssize_t write(uint8_t *to, size_t buf_sz) const
Serialize a BGP open message capability.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
BGP error codes.
ssize_t parse(const uint8_t *from, size_t msg_sz)
Deserialize a BGP open message capability.