LCOV - code coverage report
Current view: top level - bgp/extended-community - source_as.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 69 82 84.1 %
Date: 2026-06-08 02:02:55 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2017 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "bgp/extended-community/source_as.h"
       6             : 
       7             : #include <algorithm>
       8             : 
       9             : #include "base/address.h"
      10             : #include "bgp/bgp_common.h"
      11             : 
      12             : using std::copy;
      13             : using std::string;
      14             : 
      15             : SourceAs SourceAs::null_sas;
      16             : 
      17         331 : SourceAs::SourceAs() {
      18         331 :     data_.fill(0);
      19         331 : }
      20             : 
      21         164 : SourceAs::SourceAs(const bytes_type &data) {
      22         164 :     copy(data.begin(), data.end(), data_.begin());
      23         164 : }
      24             : 
      25         156 : uint32_t SourceAs::GetAsn() const {
      26         156 :     if (data_[0] == BgpExtendedCommunityType::TwoOctetAS) {
      27         156 :         return get_value(&data_[2], 2);
      28             :     }
      29             : 
      30           0 :     if (data_[0] == BgpExtendedCommunityType::FourOctetAS) {
      31           0 :         return get_value(&data_[2], 4);
      32             :     }
      33             : 
      34           0 :     return 0;
      35             : }
      36             : 
      37         194 : SourceAs::SourceAs(const uint32_t asn, const uint32_t ri_index) {
      38         194 :     if (asn <= AS2_MAX) {
      39         194 :         data_[0] = BgpExtendedCommunityType::TwoOctetAS;
      40         194 :         put_value(&data_[2], 2, asn);
      41         194 :         put_value(&data_[4], 4, ri_index);
      42             :     } else {
      43           0 :         data_[0] = BgpExtendedCommunityType::FourOctetAS;
      44           0 :         put_value(&data_[2], 4, asn);
      45           0 :         put_value(&data_[6], 2, ri_index);
      46             :     }
      47         194 :     data_[1] = BgpExtendedCommunitySubType::SourceAS;
      48         194 : }
      49             : 
      50          17 : string SourceAs::ToString() const {
      51             :     uint8_t data[SourceAs::kSize];
      52          17 :     copy(data_.begin(), data_.end(), &data[0]);
      53             :     char temp[50];
      54          17 :     if (data[0] == BgpExtendedCommunityType::TwoOctetAS) {
      55           9 :         uint16_t asn = get_value(data + 2, 2);
      56           9 :         uint32_t num = get_value(data + 4, 4);
      57           9 :         snprintf(temp, sizeof(temp), "source-as:%u:%u", asn, num);
      58           9 :         return string(temp);
      59           8 :     } else if (data[0] == BgpExtendedCommunityType::FourOctetAS) {
      60           8 :         uint32_t asn = get_value(data + 2, 4);
      61           8 :         uint16_t num = get_value(data + 6, 2);
      62           8 :         snprintf(temp, sizeof(temp), "source-as:%u:%u", asn, num);
      63           8 :         return string(temp);
      64             :     }
      65           0 :     return "";
      66             : }
      67             : 
      68          15 : SourceAs SourceAs::FromString(const string &str,
      69             :     boost::system::error_code *errorp) {
      70          15 :     SourceAs sas;
      71             :     uint8_t data[SourceAs::kSize];
      72             : 
      73             :     // source-as:1:2
      74          15 :     size_t pos = str.find(':');
      75          15 :     if (pos == string::npos) {
      76           0 :         if (errorp != NULL) {
      77           0 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
      78             :         }
      79           0 :         return SourceAs::null_sas;
      80             :     }
      81             : 
      82          15 :     string first(str.substr(0, pos));
      83          15 :     if (first != "source-as") {
      84           0 :         if (errorp != NULL) {
      85           0 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
      86             :         }
      87           0 :         return SourceAs::null_sas;
      88             :     }
      89             : 
      90          15 :     string rest(str.substr(pos+1));
      91             : 
      92          15 :     pos = rest.find(':');
      93          15 :     if (pos == string::npos) {
      94           1 :         if (errorp != NULL) {
      95           1 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
      96             :         }
      97           1 :         return SourceAs::null_sas;
      98             :     }
      99             : 
     100          14 :     boost::system::error_code ec;
     101          14 :     string second(rest.substr(0, pos));
     102             :     int offset;
     103             :     char *endptr;
     104             :     // Get ASN
     105          14 :     int64_t asn = strtol(second.c_str(), &endptr, 10);
     106          14 :     if (asn == 0 || asn > 0xffffffff || *endptr != '\0') {
     107           2 :         if (errorp != NULL) {
     108           2 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     109             :        }
     110           2 :        return SourceAs::null_sas;
     111             :     }
     112             : 
     113          12 :     string third(rest.substr(pos+1));
     114          12 :     uint64_t value = strtol(third.c_str(), &endptr, 10);
     115          12 :     if (*endptr != '\0') {
     116           2 :         if (errorp != NULL) {
     117           2 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     118             :         }
     119           2 :         return SourceAs::null_sas;
     120             :     }
     121             : 
     122             :     // Check assigned number.
     123          10 :     if ((asn > AS2_MAX && value > 0xFFFF) || value > 0xFFFFFFFF) {
     124           1 :         if (errorp != NULL) {
     125           1 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     126             :         }
     127           1 :         return SourceAs::null_sas;
     128             :     }
     129             : 
     130           9 :     if (asn <= AS2_MAX) {
     131           5 :         data[0] = BgpExtendedCommunityType::TwoOctetAS;
     132           5 :         put_value(&data[2], 2, asn);
     133           5 :         offset = 4;
     134             :     } else {
     135           4 :         data[0] = BgpExtendedCommunityType::FourOctetAS;
     136           4 :         put_value(&data[2], 4, asn);
     137           4 :         offset = 6;
     138             :     }
     139             : 
     140           9 :     data[1] = BgpExtendedCommunitySubType::SourceAS;
     141           9 :     put_value(&data[offset], SourceAs::kSize - offset, value);
     142           9 :     copy(&data[0], &data[SourceAs::kSize], sas.data_.begin());
     143           9 :     return sas;
     144          15 : }

Generated by: LCOV version 1.14