LCOV - code coverage report
Current view: top level - bgp/rtarget - rtarget_address.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 91 94 96.8 %
Date: 2026-06-18 01:51:13 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "bgp/rtarget/rtarget_address.h"
       6             : 
       7             : #include <algorithm>
       8             : 
       9             : #include "base/parse_object.h"
      10             : #include "bgp/bgp_common.h"
      11             : 
      12             : using std::copy;
      13             : using std::string;
      14             : 
      15             : RouteTarget RouteTarget::null_rtarget;
      16             : 
      17     1159497 : RouteTarget::RouteTarget() {
      18     1159497 :     data_.fill(0);
      19     1159368 : }
      20             : 
      21     7951153 : RouteTarget::RouteTarget(const bytes_type &data) {
      22     7951153 :     copy(data.begin(), data.end(), data_.begin());
      23     7950737 : }
      24             : 
      25       27370 : RouteTarget::RouteTarget(const Ip4Address &address, uint16_t num) {
      26       27370 :     data_[0] = 0x1;
      27       27370 :     data_[1] = 0x2;
      28       27370 :     put_value(&data_[2], 4, address.to_ulong());
      29       27370 :     put_value(&data_[6], 2, num);
      30       27370 : }
      31             : 
      32       62774 : const uint64_t RouteTarget::GetExtCommunityValue() const {
      33       62774 :     return get_value(data_.begin(), 8);
      34             : }
      35             : 
      36     1153323 : RouteTarget RouteTarget::FromString(const string &str,
      37             :                                     boost::system::error_code *errorp) {
      38     1153323 :     RouteTarget rt;
      39             :     uint8_t data[RouteTarget::kSize];
      40             : 
      41             :     // target:1:2 OR target:1.2.3.4:3
      42     1153216 :     size_t pos = str.find(':');
      43     1153238 :     if (pos == string::npos) {
      44           1 :         if (errorp != NULL) {
      45           1 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
      46             :         }
      47           1 :         return RouteTarget::null_rtarget;
      48             :     }
      49             : 
      50     1153237 :     string first(str.substr(0, pos));
      51     1153213 :     if (first != "target") {
      52           5 :         if (errorp != NULL) {
      53           5 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
      54             :         }
      55           5 :         return RouteTarget::null_rtarget;
      56             :     }
      57             : 
      58     1154077 :     string rest(str.substr(pos+1));
      59             : 
      60     1153793 :     pos = rest.find(':');
      61     1154259 :     if (pos == string::npos) {
      62           3 :         if (errorp != NULL) {
      63           3 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
      64             :         }
      65           3 :         return RouteTarget::null_rtarget;
      66             :     }
      67             : 
      68     1154256 :     boost::system::error_code ec;
      69     1154256 :     string second(rest.substr(0, pos));
      70     1153943 :     Ip4Address addr = Ip4Address::from_string(second, ec);
      71     1153797 :     int offset = 6;
      72             :     char *endptr;
      73     1153797 :     if (ec.failed()) {
      74     1000187 :         bool is_as4 = false;
      75             :         // Not an IP address, try ASN.
      76     1000187 :         if (second.c_str()[pos - 1] == 'L') {
      77           0 :             is_as4 = true;
      78           0 :             second = second.substr(0, pos - 1);
      79             :         }
      80             : 
      81     1000185 :         int64_t asn = strtol(second.c_str(), &endptr, 10);
      82     1000175 :         if (asn == 0 || asn > 0xFFFFFFFF || *endptr != '\0') {
      83           0 :             if (errorp != NULL) {
      84             :                 *errorp =
      85           2 :                     make_error_code(boost::system::errc::invalid_argument);
      86             :             }
      87           2 :             return RouteTarget::null_rtarget;
      88             :         }
      89             : 
      90     1000175 :         if (asn > AS2_MAX || is_as4) {
      91         158 :             data[0] = 0x2;
      92         158 :             put_value(&data[2], 4, asn);
      93             :         } else {
      94     1000017 :             data[0] = 0x0;
      95     1000017 :             put_value(&data[2], 2, asn);
      96      999997 :             offset = 4;
      97             :         }
      98     1000144 :         data[1] = 0x2;
      99             :     } else {
     100      153810 :         data[0] = 0x1;
     101      153810 :         data[1] = 0x2;
     102      153810 :         uint32_t l_addr = addr.to_ulong();
     103      153773 :         put_value(&data[2], 4, l_addr);
     104             :     }
     105             : 
     106     1153899 :     string third(rest.substr(pos+1));
     107     1153389 :     uint64_t value = strtol(third.c_str(), &endptr, 10);
     108     1153488 :     if (*endptr != '\0') {
     109         102 :         if (errorp != NULL) {
     110         102 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     111             :         }
     112         102 :         return RouteTarget::null_rtarget;
     113             :     }
     114             : 
     115             :     // Check assigned number for type 0.
     116     1153386 :     if (offset == 4 && value > 0xFFFFFFFF) {
     117           3 :         if (errorp != NULL) {
     118           3 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     119             :         }
     120           3 :         return RouteTarget::null_rtarget;
     121             :     }
     122             : 
     123             :     // Check assigned number for type 1 and 2
     124     1153383 :     if (offset == 6 && value > 0xFFFF) {
     125           6 :         if (errorp != NULL) {
     126           6 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     127             :         }
     128           6 :         return RouteTarget::null_rtarget;
     129             :     }
     130             : 
     131     1153377 :     put_value(&data[offset], RouteTarget::kSize - offset, value);
     132     1153311 :     copy(&data[0], &data[RouteTarget::kSize], rt.data_.begin());
     133     1153052 :     return rt;
     134     1153173 : }
     135             : 
     136     4317810 : string RouteTarget::ToString() const {
     137             :     uint8_t data[RouteTarget::kSize];
     138     4317810 :     copy(data_.begin(), data_.end(), &data[0]);
     139     4317834 :     if (data[0] == 0) {
     140     1206928 :         uint16_t asn = get_value(data + 2, 2);
     141     1206943 :         uint32_t num = get_value(data + 4, 4);
     142             :         char temp[50];
     143     1206940 :         snprintf(temp, sizeof(temp), "target:%u:%u", asn, num);
     144     1206940 :         return string(temp);
     145     3110906 :     } else if (data[0] == 2) {
     146        6249 :         uint32_t asn = get_value(data + 2, 4);
     147        6249 :         uint16_t num = get_value(data + 6, 2);
     148             :         char temp[50];
     149        6249 :         if (asn > AS2_MAX)
     150        6245 :             snprintf(temp, sizeof(temp), "target:%u:%u", asn, num);
     151             :         else
     152           4 :             snprintf(temp, sizeof(temp), "target:%uL:%u", asn, num);
     153        6249 :         return string(temp);
     154             :     } else {
     155     3104657 :         Ip4Address addr(get_value(data + 2, 4));
     156     3104650 :         uint16_t num = get_value(data + 6, 2);
     157             :         char temp[50];
     158     3104661 :         snprintf(temp, sizeof(temp), "target:%s:%u",
     159     6209315 :                  addr.to_string().c_str(), num);
     160     3104704 :         return string(temp);
     161             :     }
     162             : }

Generated by: LCOV version 1.14