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-08-03 02:19:58 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     1157819 : RouteTarget::RouteTarget() {
      18     1157819 :     data_.fill(0);
      19     1157619 : }
      20             : 
      21     8154561 : RouteTarget::RouteTarget(const bytes_type &data) {
      22     8154561 :     copy(data.begin(), data.end(), data_.begin());
      23     8154599 : }
      24             : 
      25       27388 : RouteTarget::RouteTarget(const Ip4Address &address, uint16_t num) {
      26       27388 :     data_[0] = 0x1;
      27       27388 :     data_[1] = 0x2;
      28       27388 :     put_value(&data_[2], 4, address.to_ulong());
      29       27388 :     put_value(&data_[6], 2, num);
      30       27388 : }
      31             : 
      32       63296 : const uint64_t RouteTarget::GetExtCommunityValue() const {
      33       63296 :     return get_value(data_.begin(), 8);
      34             : }
      35             : 
      36     1151700 : RouteTarget RouteTarget::FromString(const string &str,
      37             :                                     boost::system::error_code *errorp) {
      38     1151700 :     RouteTarget rt;
      39             :     uint8_t data[RouteTarget::kSize];
      40             : 
      41             :     // target:1:2 OR target:1.2.3.4:3
      42     1151504 :     size_t pos = str.find(':');
      43     1151539 :     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     1151538 :     string first(str.substr(0, pos));
      51     1151499 :     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     1152626 :     string rest(str.substr(pos+1));
      59             : 
      60     1152190 :     pos = rest.find(':');
      61     1153259 :     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     1153256 :     boost::system::error_code ec;
      69     1153256 :     string second(rest.substr(0, pos));
      70     1152380 :     Ip4Address addr = Ip4Address::from_string(second, ec);
      71     1152356 :     int offset = 6;
      72             :     char *endptr;
      73     1152356 :     if (ec.failed()) {
      74      999073 :         bool is_as4 = false;
      75             :         // Not an IP address, try ASN.
      76      999073 :         if (second.c_str()[pos - 1] == 'L') {
      77           0 :             is_as4 = true;
      78           0 :             second = second.substr(0, pos - 1);
      79             :         }
      80             : 
      81      999075 :         int64_t asn = strtol(second.c_str(), &endptr, 10);
      82      999049 :         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      999054 :         if (asn > AS2_MAX || is_as4) {
      91         174 :             data[0] = 0x2;
      92         174 :             put_value(&data[2], 4, asn);
      93             :         } else {
      94      998880 :             data[0] = 0x0;
      95      998880 :             put_value(&data[2], 2, asn);
      96      998849 :             offset = 4;
      97             :         }
      98      999000 :         data[1] = 0x2;
      99             :     } else {
     100      153449 :         data[0] = 0x1;
     101      153449 :         data[1] = 0x2;
     102      153449 :         uint32_t l_addr = addr.to_ulong();
     103      153372 :         put_value(&data[2], 4, l_addr);
     104             :     }
     105             : 
     106     1152354 :     string third(rest.substr(pos+1));
     107     1151732 :     uint64_t value = strtol(third.c_str(), &endptr, 10);
     108     1151863 :     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     1151761 :     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     1151758 :     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     1151752 :     put_value(&data[offset], RouteTarget::kSize - offset, value);
     132     1151674 :     copy(&data[0], &data[RouteTarget::kSize], rt.data_.begin());
     133     1151262 :     return rt;
     134     1151383 : }
     135             : 
     136     4317650 : string RouteTarget::ToString() const {
     137             :     uint8_t data[RouteTarget::kSize];
     138     4317650 :     copy(data_.begin(), data_.end(), &data[0]);
     139     4317664 :     if (data[0] == 0) {
     140     1206725 :         uint16_t asn = get_value(data + 2, 2);
     141     1206724 :         uint32_t num = get_value(data + 4, 4);
     142             :         char temp[50];
     143     1206724 :         snprintf(temp, sizeof(temp), "target:%u:%u", asn, num);
     144     1206724 :         return string(temp);
     145     3110939 :     } 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     3104690 :         Ip4Address addr(get_value(data + 2, 4));
     156     3104688 :         uint16_t num = get_value(data + 6, 2);
     157             :         char temp[50];
     158     3104599 :         snprintf(temp, sizeof(temp), "target:%s:%u",
     159     6209317 :                  addr.to_string().c_str(), num);
     160     3104770 :         return string(temp);
     161             :     }
     162             : }

Generated by: LCOV version 1.14