16 #include <arpa/inet.h> 41 setError(E_OPEN, E_UNSPEC_OPEN, NULL, 0);
42 logger->
log(ERROR,
"BgpCapability::parseHeader: unexpected end of capability.\n");
46 code = getValue<uint8_t>(&from);
47 length = getValue<uint8_t>(&from);
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");
70 written +=
_print(indent, to, buf_sz,
"FourOctetAsnCapability {\n");
72 written +=
_print(indent, to, buf_sz,
"Code { %d }\n", code);
73 written +=
_print(indent, to, buf_sz,
"MyAsn { %d }\n",
my_asn);
75 written +=
_print(indent, to, buf_sz,
"}\n");
84 logger->
log(FATAL,
"BgpCapability4BytesAsn::parse: typecode mismatch with object type.\n");
88 if (hdr_len < 0)
return hdr_len;
90 setError(E_OPEN, E_UNSPEC_OPEN, NULL, 0);
91 logger->
log(ERROR,
"BgpCapability4BytesAsn::parse: bad length field (saw %d, want 4).\n",
length);
95 const uint8_t *buffer = from + hdr_len;
96 my_asn = ntohl(getValue<uint32_t>(&buffer));
103 logger->
log(ERROR,
"BgpCapability4BytesAsn::write: dest buffer too small.\n");
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));
121 written +=
_print(indent, to, buf_sz,
"MpBgpCapability {\n");
123 written +=
_print(indent, to, buf_sz,
"Code { %d }\n", code);
124 const char* afi_name = NULL;
125 const char* safi_name = NULL;
128 case IPV4: afi_name =
"IPv4";
break;
129 case IPV6: afi_name =
"IPv6";
break;
130 default: afi_name =
"Unknow";
break;
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";
140 written +=
_print(indent, to, buf_sz,
"Afi { %s }\n", afi_name);
141 written +=
_print(indent, to, buf_sz,
"Safi { %s }\n", safi_name);
143 written +=
_print(indent, to, buf_sz,
"}\n");
151 if (code != MP_BGP) {
152 logger->
log(FATAL,
"BgpCapabilityMpBgp::parse: typecode mismatch with object type.\n");
156 if (hdr_len < 0)
return hdr_len;
159 setError(E_OPEN, E_UNSPEC_OPEN, NULL, 0);
160 logger->
log(ERROR,
"BgpCapabilityMpBgp::parse: bad length field, want 4, saw %d.\n",
length);
163 const uint8_t *buffer = from + hdr_len;
164 afi = ntohs(getValue<uint16_t>(&buffer));
166 uint8_t res = getValue<uint8_t>(&buffer);
168 logger->
log(WARN,
"BgpCapabilityMpBgp::parse: reserved bits != 0.\n");
171 safi = getValue<uint8_t>(&buffer);
178 logger->
log(ERROR,
"BgpCapability4BytesAsn::write: dest buffer too small.\n");
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);
206 if (
length > 0 && value != NULL) free(value);
211 written +=
_print(indent, to, buf_sz,
"UnknowCapability {\n");
213 written +=
_print(indent, to, buf_sz,
"Code { %d }\n", code);
215 written +=
_print(indent, to, buf_sz,
"}\n");
223 if (hdr_len < 0)
return hdr_len;
224 if (
length == 0)
return hdr_len;
226 value = (uint8_t *) malloc(
length);
227 memcpy(value, from + hdr_len,
length);
233 if (buf_sz < (
size_t) (
length + 2)) {
234 logger->
log(ERROR,
"BgpCapabilityUnknow::write: dest buffer too small.\n");
238 uint8_t *buffer = to;
239 putValue<uint8_t>(&buffer, code);
240 putValue<uint8_t>(&buffer,
length);
241 if (
length == 0)
return 2;
243 logger->
log(ERROR,
"BgpCapabilityUnknow: missing value pointer.\n");
246 memcpy(buffer, value,
length);
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.
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...
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.
Buffer operation helpers.
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.
ssize_t parse(const uint8_t *from, size_t msg_sz)
Deserialize a BGP open message capability.