size_t packet_len;
bfd_packet_t *packet;
+ char const *err = NULL;
*leftover = 0; /* always for UDP */
packet_len = data_size;
- if (data_size < FR_BFD_HEADER_LENGTH) {
- DEBUG2("proto_bfd_udp got 'too short' packet size %zd", data_size);
- fail:
+ if (!fr_bfd_packet_ok(&err, buffer, packet_len)) {
+ DEBUG2("proto_bfd_udp - Received invalid packet on %s - %s", thread->name, err);
thread->stats.total_malformed_requests++;
return 0;
}
packet = (bfd_packet_t *) buffer;
- if (packet->version != 1) {
- DEBUG("BFD packet has wrong version (%d != 1)", packet->version);
- goto fail;
- }
-
- if (packet->length < FR_BFD_HEADER_LENGTH) {
- DEBUG("BFD packet header has wrong length (%d < 24)", packet->length);
- goto fail;
- }
-
- if (packet->length > sizeof(*packet)) {
- DEBUG("BFD packet length is larger than received packet (%d > %zd)", packet->length, sizeof(*packet));
- goto fail;
- }
-
- if (packet->length != packet_len) {
- DEBUG("BFD packet is not the size of the data we read from UDP (%d > %zd)", packet->length, packet_len);
- goto fail;
- }
-
- if (packet->auth_present) {
- if (packet->length < (FR_BFD_HEADER_LENGTH + 2)) { /* auth-type and auth-len */
- DEBUG("BFD packet length is not enough for auth-type and auth-len (%d < 26)",
- packet->length);
- goto fail;
- }
-
- if (packet->length < 24 + packet->auth.basic.auth_len) {
- DEBUG("BFD packet length is not enough for authentication data (%d < %d)",
- packet->length, FR_BFD_HEADER_LENGTH + packet->auth.basic.auth_len);
- goto fail;
-
- }
-
- if (packet->length != FR_BFD_HEADER_LENGTH + packet->auth.basic.auth_len) {
- DEBUG("WARNING: What is the extra data?");
- }
-
- }
-
- if (packet->detect_multi == 0) {
- DEBUG("BFD packet has detect_multi == 0");
- goto fail;
- }
-
- if (packet->multipoint != 0) {
- DEBUG("BFD packet has multi != 0");
- goto fail;
- }
-
- if (packet->my_disc == 0) {
- DEBUG("BFD packet has my_disc == 0");
- goto fail;
- }
-
- if ((packet->your_disc == 0) &&
- !((packet->state == BFD_STATE_DOWN) ||
- (packet->state == BFD_STATE_ADMIN_DOWN))) {
- DEBUG("BFD packet has invalid your-disc / state");
- goto fail;
- }
-
/*
* Print out what we received.
*/
size_t const bfd_auth_type_table_len = NUM_ELEMENTS(bfd_auth_type_table);
+bool fr_bfd_packet_ok(char const **err, uint8_t const *packet, size_t packet_len)
+{
+ bfd_packet_t const *bfd;
+ char const *msg = NULL;
+
+ if (packet_len < FR_BFD_HEADER_LENGTH) {
+ msg = "Packet is too short to be BFD";
+ fail:
+ if (err) *err = msg;
+ return false;
+ }
+
+ bfd = (bfd_packet_t const *) packet;
+
+ if (bfd->version != 1) {
+ msg = "Packet has wrong version - should be 1";
+ goto fail;
+ }
+
+ if (bfd->length < FR_BFD_HEADER_LENGTH) {
+ msg = "Header length is too small";
+ goto fail;
+ }
+
+ if (bfd->length > sizeof(*bfd)) {
+ msg = "Header length is larger than received packet";
+ goto fail;
+ }
+
+ if (bfd->length != packet_len) {
+ msg = "Header length is not the same as the amount of data we read";
+ goto fail;
+ }
+
+ if (bfd->auth_present) {
+ if (bfd->length < (FR_BFD_HEADER_LENGTH + 2)) { /* auth-type and auth-len */
+ msg = "Header length is not enough for auth-type and auth-len";
+ goto fail;
+ }
+
+ if (bfd->length != FR_BFD_HEADER_LENGTH + bfd->auth.basic.auth_len) {
+ msg = "Header length mismatch with auth-len and amount of received data";
+ goto fail;
+
+ }
+ }
+
+ if (bfd->detect_multi == 0) {
+ msg = "Packet has invalid detect-multi == 0";
+ goto fail;
+ }
+
+ if (bfd->multipoint != 0) {
+ msg = "Packet has invalid multipoint != 0";
+ goto fail;
+ }
+
+ if (bfd->my_disc == 0) {
+ msg = "Packet has invalid my-discriminator == 0";
+ goto fail;
+ }
+
+ if ((bfd->your_disc == 0) &&
+ !((bfd->state == BFD_STATE_DOWN) ||
+ (bfd->state == BFD_STATE_ADMIN_DOWN))) {
+ msg = "Packet has your-discrimator==0, but state is not down or admin-down";
+ goto fail;
+ }
+
+ if (err) *err = NULL;
+ return true;
+}
+
+
+
int fr_bfd_init(void)
{
if (instance_count > 0) {