LCOV - code coverage report
Current view: top level - bfd - bfd_control_packet.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 107 112 95.5 %
Date: 2026-06-04 02:06:09 Functions: 19 19 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2014 CodiLime, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "bfd/bfd_control_packet.h"
       6             : 
       7             : #include <string>
       8             : #include <list>
       9             : #include <boost/mpl/list.hpp>
      10             : 
      11             : #include "base/proto.h"
      12             : 
      13             : namespace BFD {
      14             : 
      15             : class VersionAndDiagnostic: public ProtoElement<VersionAndDiagnostic> {
      16             :  public:
      17             :     static const int kSize = 1;
      18             : 
      19             :     static const int kVersionBitmask = 0xE0;
      20             :     static const int kVersionOffset = 5;
      21             :     static const int kDiagnosticBitmask = 0x1F;
      22             :     static const int kSupportedVersion = 1;
      23             : 
      24         121 :     static bool Verifier(const ControlPacket *obj, const uint8_t *data,
      25             :                          size_t size, ParseContext *context) {
      26         121 :         uint8_t value = get_value(data, 1);
      27         121 :         return ((value & kVersionBitmask) >>
      28             :                     kVersionOffset == kSupportedVersion)
      29         121 :                 && ((value & kDiagnosticBitmask) < kDiagnosticFirstInvalid);
      30             :     }
      31             : 
      32             :     typedef struct {
      33         121 :         static void set(ControlPacket *obj, uint8_t value) {
      34         121 :             obj->diagnostic = (Diagnostic) (value & kDiagnosticBitmask);
      35         121 :         }
      36             : 
      37         121 :         static uint8_t get(const ControlPacket *obj) {
      38         121 :             return obj->diagnostic | (kSupportedVersion << kVersionOffset);
      39             :         }
      40             :     } Setter;
      41             : };
      42             : 
      43             : class Flags: public ProtoElement<Flags> {
      44             :  public:
      45             :     static const int kSize = 1;
      46             : 
      47             :     static const int kStateBitmask = 0xC0;
      48             :     static const int kStateOffset = 6;
      49             :     static const int kPollOffset = 5;
      50             :     static const int kFinallOffset = 4;
      51             :     static const int kControlPlaneIndependentOffset = 3;
      52             :     static const int kAuthenticationPresentOffset = 2;
      53             :     static const int kDemandOffset = 1;
      54             :     static const int kMultipointOffset = 0;
      55             : 
      56             :     typedef struct {
      57         121 :         static void set(ControlPacket *obj, uint8_t value) {
      58         121 :             obj->state = (BFDState) ((value & kStateBitmask)
      59         121 :                                      >> kStateOffset);
      60         121 :             obj->poll = value & (1 << kPollOffset);
      61         121 :             obj->final = value & (1 << kFinallOffset);
      62         121 :             obj->control_plane_independent = value &
      63             :                                        (1 << kControlPlaneIndependentOffset);
      64         121 :             obj->authentication_present = value &
      65             :                                       (1 << kAuthenticationPresentOffset);
      66         121 :             obj->demand = value & (1 << kDemandOffset);
      67         121 :             obj->multipoint = value & (1 << kMultipointOffset);
      68         121 :         }
      69             : 
      70         121 :         static uint8_t get(const ControlPacket *obj) {
      71         121 :             return (obj->state << kStateOffset) | (obj->poll << kPollOffset)
      72         121 :                     | (obj->final << kFinallOffset)
      73         121 :                     | (obj->control_plane_independent
      74         121 :                        << kControlPlaneIndependentOffset)
      75         121 :                     | (obj->authentication_present
      76         121 :                        << kAuthenticationPresentOffset)
      77         121 :                     | (obj->demand << kDemandOffset)
      78         121 :                     | (obj->multipoint << kMultipointOffset);
      79             :         }
      80             :     } Setter;
      81             : };
      82             : 
      83             : class DetectionTimeMultiplier: public ProtoElement<DetectionTimeMultiplier> {
      84             :  public:
      85             :     typedef Accessor<ControlPacket, int,
      86             :                      &ControlPacket::detection_time_multiplier> Setter;
      87             : 
      88             :     static const int kSize = 1;
      89             : 
      90         121 :     static bool Verifier(const ControlPacket *obj, const uint8_t *data,
      91             :                          size_t size, ParseContext *context) {
      92         121 :         uint8_t value = get_value(data, 1);
      93         121 :         return value > 0;
      94             :     }
      95             : };
      96             : 
      97             : class Length: public ProtoElement<Length> {
      98             :  public:
      99             :     typedef Accessor<ControlPacket, int, &ControlPacket::length> Setter;
     100             : 
     101             :     static const int kSize = 1;
     102             : 
     103         121 :     static bool Verifier(const void *obj, const uint8_t *data, size_t size,
     104             :                          ParseContext *context) {
     105         121 :         uint8_t value = get_value(data, 1);
     106         121 :         return value == kMinimalPacketLength;
     107             :     }
     108             : };
     109             : 
     110             : class SenderDiscriminator: public ProtoElement<SenderDiscriminator> {
     111             :  public:
     112             :     typedef Accessor<ControlPacket, uint32_t,
     113             :                      &ControlPacket::sender_discriminator> Setter;
     114             : 
     115             :     static const int kSize = 4;
     116             : 
     117         121 :     static bool Verifier(const ControlPacket *obj, const uint8_t *data,
     118             :                          size_t size, ParseContext *context) {
     119         121 :         uint32_t value = get_value(data, 4);
     120         121 :         return value > 0;
     121             :     }
     122             : };
     123             : 
     124             : class ReceiverDiscriminator: public ProtoElement<ReceiverDiscriminator> {
     125             :  public:
     126             :     typedef Accessor<ControlPacket, uint32_t,
     127             :                      &ControlPacket::receiver_discriminator> Setter;
     128             : 
     129             :     static const int kSize = 4;
     130             : };
     131             : 
     132             : class DesiredMinTxInterval: public ProtoElement<DesiredMinTxInterval> {
     133             :  public:
     134             :     typedef struct {
     135         121 :         static void set(ControlPacket *obj, uint32_t value) {
     136         121 :             obj->desired_min_tx_interval =
     137         121 :                 boost::posix_time::microseconds(value);
     138         121 :         }
     139             : 
     140         121 :         static uint32_t get(const ControlPacket *obj) {
     141         121 :             return obj->desired_min_tx_interval.total_microseconds();
     142             :         }
     143             :     } Setter;
     144             : 
     145             :     static const int kSize = 4;
     146             : };
     147             : 
     148             : class RequiredMinRxInterval: public ProtoElement<RequiredMinRxInterval> {
     149             :  public:
     150             :     typedef struct {
     151         121 :         static void set(ControlPacket *obj, uint32_t value) {
     152         121 :             obj->required_min_rx_interval =
     153         121 :                 boost::posix_time::microseconds(value);
     154         121 :         }
     155             : 
     156         121 :         static uint32_t get(const ControlPacket *obj) {
     157         121 :             return obj->required_min_rx_interval.total_microseconds();
     158             :         }
     159             :     } Setter;
     160             : 
     161             :     static const int kSize = 4;
     162             : };
     163             : 
     164             : class RequiredMinEchoRXInterval :
     165             :             public ProtoElement<RequiredMinEchoRXInterval> {
     166             :  public:
     167             :     typedef struct {
     168         121 :         static void set(ControlPacket *obj, uint32_t value) {
     169         121 :             obj->required_min_echo_rx_interval =
     170         121 :                 boost::posix_time::microseconds(value);
     171         121 :         }
     172             : 
     173         121 :         static uint32_t get(const ControlPacket *obj) {
     174         121 :             return obj->required_min_echo_rx_interval.total_microseconds();
     175             :         }
     176             :     } Setter;
     177             : 
     178             :     static const int kSize = 4;
     179             : };
     180             : 
     181             : class ControlPacketMessage: public ProtoSequence<ControlPacketMessage> {
     182             :  public:
     183             :     typedef mpl::list<VersionAndDiagnostic, Flags, DetectionTimeMultiplier,
     184             :                       Length, SenderDiscriminator, ReceiverDiscriminator,
     185             :                       DesiredMinTxInterval, RequiredMinRxInterval,
     186             :                       RequiredMinEchoRXInterval> Sequence;
     187             : };
     188             : 
     189           2 : std::string ControlPacket::toString() const {
     190           2 :     std::ostringstream out;
     191           2 :     out << "Length: " << length << "\n";
     192           2 :     out << "Diagnostic: " << diagnostic << "\n";
     193           2 :     out << "State: " << state << "\n";
     194           2 :     out << "Poll: " << poll << "\n";
     195           2 :     out << "Final: " << final << "\n";
     196           2 :     out << "ControlPlaneIndependent: " << control_plane_independent << "\n";
     197           2 :     out << "AuthenticationPresent: " << authentication_present << "\n";
     198           2 :     out << "Demand: " << demand << "\n";
     199           2 :     out << "Multipoint: " << multipoint << "\n";
     200           2 :     out << "DetectionTimeMultiplier: " << detection_time_multiplier << "\n";
     201           2 :     out << "SenderDiscriminator: 0x"
     202           2 :         << std::hex << sender_discriminator << "\n";
     203           2 :     out << "ReceiverDiscriminator: 0x" << std::hex << receiver_discriminator
     204           2 :         << "\n";
     205           2 :     out << "DesiredMinTxInterval: " << desired_min_tx_interval << "\n";
     206           2 :     out << "RequiredMinRxInterval: " << required_min_rx_interval << "\n";
     207             :     out << "RequiredMinEchoRXInterval: "
     208           2 :         << required_min_echo_rx_interval << "\n";
     209           4 :     return out.str();
     210           2 : }
     211             : 
     212         115 : ResultCode ControlPacket::Verify() const {
     213         115 :     if (multipoint)
     214           0 :         return kResultCode_InvalidPacket;
     215             : 
     216         115 :     if (authentication_present)
     217           0 :         return kResultCode_NotImplemented;
     218             : 
     219         115 :     if (receiver_discriminator == 0 && state == kUp)
     220           0 :         return kResultCode_InvalidPacket;
     221             : 
     222         115 :     if (poll && final)
     223           0 :         return kResultCode_InvalidPacket;
     224             : 
     225         115 :     return kResultCode_Ok;
     226             : }
     227             : 
     228         121 : ControlPacket* ParseControlPacket(const uint8_t *data, size_t size) {
     229         121 :     ParseContext context;
     230         121 :     int result = ControlPacketMessage::Parse(data, size, &context,
     231         121 :                                              new ControlPacket());
     232         121 :     if (result < 0 || (size_t)result != size) {
     233           0 :         return NULL;
     234             :     }
     235         121 :     return static_cast<ControlPacket *>(context.release());
     236         121 : }
     237             : 
     238         121 : int EncodeControlPacket(const ControlPacket *msg, uint8_t *data, size_t size) {
     239         121 :     EncodeContext context;
     240         242 :     return ControlPacketMessage::Encode(&context, msg, data, size);
     241         121 : }
     242             : 
     243           1 : bool operator==(const ControlPacket &p1, const ControlPacket &p2) {
     244           1 :     return p1.poll == p2.poll && p1.final == p2.final
     245           1 :             && p1.control_plane_independent == p2.control_plane_independent
     246           1 :             && p1.authentication_present == p2.authentication_present
     247           1 :             && p1.demand == p2.demand && p1.multipoint == p2.multipoint
     248           1 :             && p1.detection_time_multiplier == p2.detection_time_multiplier
     249           1 :             && p1.length == p2.length
     250           1 :             && p1.sender_discriminator == p2.sender_discriminator
     251           1 :             && p1.receiver_discriminator == p2.receiver_discriminator
     252           1 :             && p1.diagnostic == p2.diagnostic && p1.state == p2.state
     253           1 :             && p1.desired_min_tx_interval == p2.desired_min_tx_interval
     254           1 :             && p1.required_min_rx_interval == p2.required_min_rx_interval
     255           2 :             && p1.required_min_echo_rx_interval ==
     256           1 :                 p2.required_min_echo_rx_interval;
     257             : }
     258             : }  // namespace BFD

Generated by: LCOV version 1.14