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-11-09 02:10:49 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             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #include "bgp/rtarget/rtarget_address.h"
       7             : 
       8             : #include <algorithm>
       9             : 
      10             : #include "base/parse_object.h"
      11             : #include "bgp/bgp_common.h"
      12             : 
      13             : using std::copy;
      14             : using std::string;
      15             : 
      16             : RouteTarget RouteTarget::null_rtarget;
      17             : 
      18     1157690 : RouteTarget::RouteTarget() {
      19     1157690 :     data_.fill(0);
      20     1157455 : }
      21             : 
      22     8147022 : RouteTarget::RouteTarget(const bytes_type &data) {
      23     8147022 :     copy(data.begin(), data.end(), data_.begin());
      24     8146530 : }
      25             : 
      26       27376 : RouteTarget::RouteTarget(const Ip4Address &address, uint16_t num) {
      27       27376 :     data_[0] = 0x1;
      28       27376 :     data_[1] = 0x2;
      29       27376 :     put_value(&data_[2], 4, address.to_ulong());
      30       27376 :     put_value(&data_[6], 2, num);
      31       27376 : }
      32             : 
      33       62855 : const uint64_t RouteTarget::GetExtCommunityValue() const {
      34       62855 :     return get_value(data_.begin(), 8);
      35             : }
      36             : 
      37     1151599 : RouteTarget RouteTarget::FromString(const string &str,
      38             :                                     boost::system::error_code *errorp) {
      39     1151599 :     RouteTarget rt;
      40             :     uint8_t data[RouteTarget::kSize];
      41             : 
      42             :     // target:1:2 OR target:1.2.3.4:3
      43     1151343 :     size_t pos = str.find(':');
      44     1151411 :     if (pos == string::npos) {
      45           1 :         if (errorp != NULL) {
      46           1 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
      47             :         }
      48           1 :         return RouteTarget::null_rtarget;
      49             :     }
      50             : 
      51     1151410 :     string first(str.substr(0, pos));
      52     1151452 :     if (first != "target") {
      53           5 :         if (errorp != NULL) {
      54           5 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
      55             :         }
      56           5 :         return RouteTarget::null_rtarget;
      57             :     }
      58             : 
      59     1152960 :     string rest(str.substr(pos+1));
      60             : 
      61     1152396 :     pos = rest.find(':');
      62     1153413 :     if (pos == string::npos) {
      63           3 :         if (errorp != NULL) {
      64           3 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
      65             :         }
      66           3 :         return RouteTarget::null_rtarget;
      67             :     }
      68             : 
      69     1153410 :     boost::system::error_code ec;
      70     1153410 :     string second(rest.substr(0, pos));
      71     1152775 :     Ip4Address addr = Ip4Address::from_string(second, ec);
      72     1152715 :     int offset = 6;
      73             :     char *endptr;
      74     1152715 :     if (ec.failed()) {
      75      999288 :         bool is_as4 = false;
      76             :         // Not an IP address, try ASN.
      77      999288 :         if (second.c_str()[pos - 1] == 'L') {
      78           0 :             is_as4 = true;
      79           0 :             second = second.substr(0, pos - 1);
      80             :         }
      81             : 
      82      999289 :         int64_t asn = strtol(second.c_str(), &endptr, 10);
      83      999285 :         if (asn == 0 || asn > 0xFFFFFFFF || *endptr != '\0') {
      84           0 :             if (errorp != NULL) {
      85             :                 *errorp =
      86           2 :                     make_error_code(boost::system::errc::invalid_argument);
      87             :             }
      88           2 :             return RouteTarget::null_rtarget;
      89             :         }
      90             : 
      91      999289 :         if (asn > AS2_MAX || is_as4) {
      92         189 :             data[0] = 0x2;
      93         189 :             put_value(&data[2], 4, asn);
      94             :         } else {
      95      999100 :             data[0] = 0x0;
      96      999100 :             put_value(&data[2], 2, asn);
      97      999075 :             offset = 4;
      98             :         }
      99      999226 :         data[1] = 0x2;
     100             :     } else {
     101      153483 :         data[0] = 0x1;
     102      153483 :         data[1] = 0x2;
     103      153483 :         uint32_t l_addr = addr.to_ulong();
     104      153409 :         put_value(&data[2], 4, l_addr);
     105             :     }
     106             : 
     107     1152585 :     string third(rest.substr(pos+1));
     108     1151905 :     uint64_t value = strtol(third.c_str(), &endptr, 10);
     109     1152089 :     if (*endptr != '\0') {
     110         102 :         if (errorp != NULL) {
     111         102 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     112             :         }
     113         102 :         return RouteTarget::null_rtarget;
     114             :     }
     115             : 
     116             :     // Check assigned number for type 0.
     117     1151987 :     if (offset == 4 && value > 0xFFFFFFFF) {
     118           3 :         if (errorp != NULL) {
     119           3 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     120             :         }
     121           3 :         return RouteTarget::null_rtarget;
     122             :     }
     123             : 
     124             :     // Check assigned number for type 1 and 2
     125     1151984 :     if (offset == 6 && value > 0xFFFF) {
     126           6 :         if (errorp != NULL) {
     127           6 :             *errorp = make_error_code(boost::system::errc::invalid_argument);
     128             :         }
     129           6 :         return RouteTarget::null_rtarget;
     130             :     }
     131             : 
     132     1151978 :     put_value(&data[offset], RouteTarget::kSize - offset, value);
     133     1151887 :     copy(&data[0], &data[RouteTarget::kSize], rt.data_.begin());
     134     1151366 :     return rt;
     135     1151487 : }
     136             : 
     137     4318116 : string RouteTarget::ToString() const {
     138             :     uint8_t data[RouteTarget::kSize];
     139     4318116 :     copy(data_.begin(), data_.end(), &data[0]);
     140     4318095 :     if (data[0] == 0) {
     141     1207068 :         uint16_t asn = get_value(data + 2, 2);
     142     1207064 :         uint32_t num = get_value(data + 4, 4);
     143             :         char temp[50];
     144     1207061 :         snprintf(temp, sizeof(temp), "target:%u:%u", asn, num);
     145     1207061 :         return string(temp);
     146     3111027 :     } else if (data[0] == 2) {
     147        6249 :         uint32_t asn = get_value(data + 2, 4);
     148        6249 :         uint16_t num = get_value(data + 6, 2);
     149             :         char temp[50];
     150        6249 :         if (asn > AS2_MAX)
     151        6245 :             snprintf(temp, sizeof(temp), "target:%u:%u", asn, num);
     152             :         else
     153           4 :             snprintf(temp, sizeof(temp), "target:%uL:%u", asn, num);
     154        6249 :         return string(temp);
     155             :     } else {
     156     3104778 :         Ip4Address addr(get_value(data + 2, 4));
     157     3104774 :         uint16_t num = get_value(data + 6, 2);
     158             :         char temp[50];
     159     3104742 :         snprintf(temp, sizeof(temp), "target:%s:%u",
     160     6209508 :                  addr.to_string().c_str(), num);
     161     3104831 :         return string(temp);
     162             :     }
     163             : }

Generated by: LCOV version 1.14