~ubuntu-branches/ubuntu/jaunty/xorp/jaunty

« back to all changes in this revision

Viewing changes to bgp/aspath.cc

  • Committer: Bazaar Package Importer
  • Author(s): Jose Calhariz, Javier Fernandez-Sanguino, Jose Calhariz
  • Date: 2008-01-23 01:24:37 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080123012437-7l2u9r0k8e7op8st
Tags: 1.5~cvs.20080128-1
[ Javier Fernandez-Sanguino ]
* Update to latest CVS contents
* Modify debian/rules to prevent autobuilders from building 
  the binary-independent components: (Closes: #441121)
  - Create a new Build-Depends-Indep with all the TeX
  components used to build documentation
  - Since autobuilders call build, which in turns calls build-indep, hack
    the debian rules file so that the documentation is only built if ps2pdf,
    dvips and pslatex are available. 
* Modify the init.d script:
  - restart action: Do not attempt to stop xorp if not running
  - stop function: fix errors in the script
  - add a try-restart action
  - restructure the init.d script, move the restart code to a function
  - review the use of echo calls and exit values
* Use, as examples, the new boot files at rtrmgr/config/

[ Jose Calhariz ]
* Add depends on ncurses-dev, I don't know why xorp use tigetstr
  function from curses.  This way the depends field change less between
  build environments.
* Removed pushd and popd commands from Makefile and replaced with cd
  commands, was a bashism and FTBFS (closes: #453637)
* debian/control converted to utf-8 (closes: #454026) (closes: #453485)
* init.d/xorp now returns 0 if disabled.
* Added Vcs-Browser and Vcs-Svn fields pointing to the repository of the
  package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
2
2
 
3
 
// Copyright (c) 2001-2007 International Computer Science Institute
 
3
// Copyright (c) 2001-2008 International Computer Science Institute
4
4
//
5
5
// Permission is hereby granted, free of charge, to any person obtaining a
6
6
// copy of this software and associated documentation files (the "Software")
12
12
// notice is a summary of the XORP LICENSE file; the license in that file is
13
13
// legally binding.
14
14
 
15
 
#ident "$XORP: xorp/bgp/aspath.cc,v 1.40 2007/04/05 02:02:48 zec Exp $"
 
15
#ident "$XORP: xorp/bgp/aspath.cc,v 1.42 2008/01/04 03:15:17 pavlin Exp $"
16
16
 
17
 
// #define DEBUG_LOGGING
18
 
// #define DEBUG_PRINT_FUNCTION_NAME
 
17
//#define DEBUG_LOGGING
 
18
//#define DEBUG_PRINT_FUNCTION_NAME
19
19
 
20
20
#include "bgp_module.h"
21
21
 
42
42
 
43
43
extern void dump_bytes(const uint8_t *d, uint8_t l);
44
44
 
45
 
/* *************** AsSegment ********************** */
 
45
/* *************** ASSegment ********************** */
46
46
 
47
47
/**
48
48
 * Convert the external representation into the internal one. 
49
49
 * _type is d[0], _entries is d[1], entries follow.
50
50
 */
51
51
void
52
 
AsSegment::decode(const uint8_t *d) throw(CorruptMessage)
 
52
ASSegment::decode(const uint8_t *d) throw(CorruptMessage)
53
53
{
54
54
    size_t n = d[1];
55
55
    clear();
76
76
 * Convert from internal to external representation.
77
77
 */
78
78
const uint8_t *
79
 
AsSegment::encode(size_t &len, uint8_t *data) const
 
79
ASSegment::encode(size_t &len, uint8_t *data) const
80
80
{
81
81
    debug_msg("AsSegment encode\n");
82
82
    XLOG_ASSERT(_aslist.size() <= 255);
102
102
}
103
103
 
104
104
const AsNum&
105
 
AsSegment::first_asnum() const
 
105
ASSegment::first_asnum() const
106
106
{
107
107
    if (_type == AS_SET || _type == AS_CONFED_SET) {
108
108
        // This shouldn't be possible.  The spec doesn't explicitly
118
118
}
119
119
 
120
120
/**
121
 
 * prints AsSegments as 
 
121
 * prints ASSegments as 
122
122
 *
123
123
 *  AS_SEQUENCE:         [comma-separated-asn-list]  
124
124
 *  AS_SET:              {comma-separated-asn-list}
126
126
 *  AS_CONFED_SET:       <comma-separated-asn-list> 
127
127
 */
128
128
string
129
 
AsSegment::str() const
 
129
ASSegment::str() const
130
130
{
131
131
    string s;
132
132
    string sep; 
174
174
}
175
175
 
176
176
/**
177
 
 * prints AsSegments as 
 
177
 * prints ASSegments as 
178
178
 *
179
179
 *  AS_SEQUENCE:         comma-separated-asn-list
180
180
 *  AS_SET:              {comma-separated-asn-list}
182
182
 *  AS_CONFED_SET:       <comma-separated-asn-list> 
183
183
 */
184
184
string
185
 
AsSegment::short_str() const
 
185
ASSegment::short_str() const
186
186
{
187
187
    string s;
188
188
    string sep; 
234
234
 * compares internal representations for equality.
235
235
 */
236
236
bool
237
 
AsSegment::operator==(const AsSegment& him) const
 
237
ASSegment::operator==(const ASSegment& him) const
238
238
{
239
239
    return (_aslist == him._aslist);
240
240
}
243
243
 * Compares internal representations for <.
244
244
 */
245
245
bool
246
 
AsSegment::operator<(const AsSegment& him) const
 
246
ASSegment::operator<(const ASSegment& him) const
247
247
{
248
248
    int mysize = _aslist.size();
249
249
    int hissize = him._aslist.size();
257
257
// XXX isn't this the same format as on the wire ???
258
258
 
259
259
size_t
260
 
AsSegment::encode_for_mib(uint8_t* buf, size_t buf_size) const
 
260
ASSegment::encode_for_mib(uint8_t* buf, size_t buf_size) const
261
261
{
262
262
    //See RFC 1657, Page 15 for the encoding
263
263
    XLOG_ASSERT(buf_size >= (2 + _aslist.size() * 2));
272
272
}
273
273
 
274
274
bool
275
 
AsSegment::two_byte_compatible() const
 
275
ASSegment::two_byte_compatible() const
276
276
{
277
277
    const_iterator i;
278
278
    for (i = _aslist.begin(); i != _aslist.end(); i++) {
282
282
    return true;
283
283
}
284
284
 
285
 
/* *************** As4Segment ***************** */
 
285
/* *************** AS4Segment ***************** */
286
286
 
287
287
 
288
288
/**
292
292
 * _type is d[0], _entries is d[1], entries follow.
293
293
 */
294
294
void
295
 
As4Segment::decode(const uint8_t *d) throw(CorruptMessage)
 
295
AS4Segment::decode(const uint8_t *d) throw(CorruptMessage)
296
296
{
297
297
    size_t n = d[1];
298
298
    clear();
326
326
 * Convert from internal to external AS4_PATH representation.
327
327
 */
328
328
const uint8_t *
329
 
As4Segment::encode(size_t &len, uint8_t *data) const
 
329
AS4Segment::encode(size_t &len, uint8_t *data) const
330
330
{
331
 
    debug_msg("AsSegment encode\n");
 
331
    debug_msg("AS4Segment encode\n");
332
332
    XLOG_ASSERT(_aslist.size() <= 255);
333
333
 
334
334
    size_t i = wire_size();
353
353
}
354
354
 
355
355
 
356
 
/* *************** AsPath *********************** */
 
356
/* *************** ASPath *********************** */
357
357
 
358
358
/**
359
 
 * AsPath constructor by parsing strings.  Input strings 
 
359
 * ASPath constructor by parsing strings.  Input strings 
360
360
 * should have the form 
361
361
 * 
362
362
 *         "segment, segment, segment, ... ,segment"  
371
371
 *  blank spaces " " can appear at any point in the string. 
372
372
 */
373
373
 
374
 
AsPath::AsPath(const char *as_path) throw(InvalidString)
 
374
ASPath::ASPath(const char *as_path) throw(InvalidString)
375
375
{
376
 
    debug_msg("AsPath(%s) constructor called\n", as_path);
 
376
    debug_msg("ASPath(%s) constructor called\n", as_path);
377
377
    _num_segments = 0;
378
378
    _path_len = 0;
379
379
 
385
385
        path = path.substr(0, pos) + path.substr(pos + 1);
386
386
    }
387
387
 
388
 
    AsSegment seg;
 
388
    ASSegment seg;
389
389
    for (size_t i = 0; i < path.length(); i++) {
390
390
        char c = path[i];
391
391
 
396
396
            if (seg.type() == AS_NONE)  // possibly start new segment
397
397
                seg.set_type(AS_SEQUENCE);
398
398
 
399
 
            while (i < path.length() && xorp_isdigit(path[i]))
 
399
            while (i < path.length() && (xorp_isdigit(path[i]) || path[i]=='.')) {
400
400
                i++;
 
401
            }
401
402
        
402
 
            uint16_t num = atoi(path.substr(start, i).c_str());
 
403
            string asnum = path.substr(start, i-start);
403
404
            i--; // back to last valid character
404
 
            debug_msg("asnum = %d\n", num);
405
 
            seg.add_as(AsNum(num));
 
405
            debug_msg("asnum = %s\n", asnum.c_str());
 
406
            seg.add_as(AsNum(asnum));
406
407
        } else if (c == '[') {
407
408
            if (seg.type() == AS_SEQUENCE) {
408
409
                // push previous thing and start a new one
490
491
        add_segment(seg);
491
492
    else if (seg.type() == AS_SET)
492
493
        xorp_throw(InvalidString,
493
 
                       c_format("Unterminated AsSet: %s", path.c_str()));
494
 
    debug_msg("end of AsPath()\n");
 
494
                       c_format("Unterminated ASSet: %s", path.c_str()));
 
495
    debug_msg("end of ASPath()\n");
495
496
}
496
497
 
497
498
/**
498
 
 * populate an AsPath from the received data representation
 
499
 * populate an ASPath from the received data representation
499
500
 */
500
501
void
501
 
AsPath::decode(const uint8_t *d, size_t l) throw(CorruptMessage)
 
502
ASPath::decode(const uint8_t *d, size_t l) throw(CorruptMessage)
502
503
{
503
504
    _num_segments = 0;
504
505
    _path_len = 0;
510
511
                                XORP_UINT_CAST(len), XORP_UINT_CAST(l)),
511
512
                       UPDATEMSGERR, MALASPATH);
512
513
 
513
 
        AsSegment s(d);
 
514
        ASSegment s(d);
514
515
        add_segment(s);
515
516
        d += len;
516
517
        l -= len;
518
519
}
519
520
 
520
521
/**
521
 
 * construct a new aggregate AsPath from two AsPaths
 
522
 * construct a new aggregate ASPath from two ASPaths
522
523
 */
523
 
AsPath::AsPath(const AsPath &asp1, const AsPath &asp2)
 
524
ASPath::ASPath(const ASPath &asp1, const ASPath &asp2)
524
525
{
525
526
    _num_segments = 0;
526
527
    _path_len = 0;
544
545
                break;
545
546
 
546
547
        if (matchelem) {
547
 
            AsSegment newseg(asp1.segment(curseg).type());
 
548
            ASSegment newseg(asp1.segment(curseg).type());
548
549
            for (size_t elem = 0; elem < matchelem; elem++)
549
550
                newseg.add_as(asp1.segment(curseg).as_num(elem));
550
551
            this->add_segment(newseg);
558
559
    }
559
560
 
560
561
    if (!fullmatch) {
561
 
        AsSegment new_asset(AS_SET);
 
562
        ASSegment new_asset(AS_SET);
562
563
        size_t startelem = matchelem;
563
564
        for (size_t curseg1 = curseg; curseg1 < asp1.num_segments();
564
565
             curseg1++) {
586
587
}
587
588
 
588
589
void
589
 
AsPath::add_segment(const AsSegment& s)
 
590
ASPath::add_segment(const ASSegment& s)
590
591
{
591
592
    debug_msg("Adding As Segment\n");
592
593
    _segments.push_back(s);
599
600
}
600
601
 
601
602
void
602
 
AsPath::prepend_segment(const AsSegment& s)
 
603
ASPath::prepend_segment(const ASSegment& s)
603
604
{
604
605
    debug_msg("Prepending As Segment\n");
605
606
    _segments.push_front(s);
612
613
}
613
614
 
614
615
string
615
 
AsPath::str() const
 
616
ASPath::str() const
616
617
{
617
 
    string s = "AsPath:";
 
618
    string s = "ASPath:";
618
619
    const_iterator iter = _segments.begin();
619
620
    while(iter != _segments.end()) {
620
621
        s.append(" ");
625
626
}
626
627
 
627
628
string
628
 
AsPath::short_str() const
 
629
ASPath::short_str() const
629
630
{
630
631
    string s;
631
632
    const_iterator iter = _segments.begin();
639
640
}
640
641
 
641
642
size_t
642
 
AsPath::wire_size() const
 
643
ASPath::wire_size() const
643
644
{
644
645
    size_t l = 0;
645
646
    const_iterator iter = _segments.begin();
650
651
}
651
652
 
652
653
const uint8_t *
653
 
AsPath::encode(size_t &len, uint8_t *buf) const
 
654
ASPath::encode(size_t &len, uint8_t *buf) const
654
655
{
655
656
    XLOG_ASSERT(_num_segments == _segments.size());     // XXX expensive
656
657
    const_iterator i;
673
674
}
674
675
 
675
676
void
676
 
AsPath::prepend_as(const AsNum &asn)
 
677
ASPath::prepend_as(const AsNum &asn)
677
678
{
678
679
    if (_segments.empty() || _segments.front().type() == AS_SET) {
679
 
        AsSegment seg = AsSegment(AS_SEQUENCE);
 
680
        ASSegment seg = ASSegment(AS_SEQUENCE);
680
681
 
681
682
        seg.add_as(asn);
682
683
        _segments.push_front(seg);
689
690
}
690
691
 
691
692
void
692
 
AsPath::prepend_confed_as(const AsNum &asn)
 
693
ASPath::prepend_confed_as(const AsNum &asn)
693
694
{
694
695
    if (_segments.empty() || _segments.front().type() == AS_SET 
695
696
        || _segments.front().type() == AS_SEQUENCE) {
696
 
        AsSegment seg = AsSegment(AS_CONFED_SEQUENCE);
 
697
        ASSegment seg = ASSegment(AS_CONFED_SEQUENCE);
697
698
 
698
699
        seg.add_as(asn);
699
700
        _segments.push_front(seg);
706
707
}
707
708
 
708
709
void
709
 
AsPath::remove_confed_segments()
 
710
ASPath::remove_confed_segments()
710
711
{
711
712
        debug_msg("Deleting all CONFED Segments\n");
712
713
        const_iterator iter = _segments.begin();
725
726
}
726
727
 
727
728
bool
728
 
AsPath::contains_confed_segments() const
 
729
ASPath::contains_confed_segments() const
729
730
{
730
731
    for (const_iterator i = _segments.begin(); i != _segments.end(); i++) {
731
732
        ASPathSegType type = (*i).type();
736
737
    return false;
737
738
}
738
739
 
 
740
ASPath&
 
741
ASPath::operator=(const ASPath& him)
 
742
{
 
743
    // clear out my list
 
744
    while (!_segments.empty()) {
 
745
        _segments.pop_front();
 
746
    }
 
747
 
 
748
    // copy in from his
 
749
    const_iterator i;
 
750
    for (i = him._segments.begin() ;i != him._segments.end(); i++) {
 
751
        _segments.push_back(*i);
 
752
    }
 
753
    return *this;
 
754
}
 
755
 
739
756
bool
740
 
AsPath::operator==(const AsPath& him) const
 
757
ASPath::operator==(const ASPath& him) const
741
758
{
742
759
    if (_num_segments != him._num_segments) 
743
760
        return false;
750
767
}
751
768
 
752
769
bool
753
 
AsPath::operator<(const AsPath& him) const
 
770
ASPath::operator<(const ASPath& him) const
754
771
{
755
772
    if (_num_segments < him._num_segments)
756
773
        return true;
768
785
}
769
786
 
770
787
void
771
 
AsPath::encode_for_mib(vector<uint8_t>& encode_buf) const
 
788
ASPath::encode_for_mib(vector<uint8_t>& encode_buf) const
772
789
{
773
790
    //See RFC 1657, Page 15 for the encoding.
774
791
    size_t buf_size = wire_size();
793
810
}
794
811
 
795
812
bool
796
 
AsPath::two_byte_compatible() const
 
813
ASPath::two_byte_compatible() const
797
814
{
798
815
    const_iterator i = _segments.begin();
799
816
    for(i = _segments.begin(); i != _segments.end(); i++) {
803
820
    return true;
804
821
}
805
822
 
 
823
void 
 
824
ASPath::merge_as4_path(AS4Path& as4_path)
 
825
{
 
826
    as4_path.cross_validate(*this);
 
827
    (*this) = as4_path;
 
828
}
806
829
 
807
 
As4Path::As4Path(const uint8_t* d, size_t len, const AsPath& as_path)
 
830
#if 0
 
831
AS4Path::AS4Path(const uint8_t* d, size_t len, const ASPath& as_path)
808
832
     throw(CorruptMessage)
809
833
{
810
834
    decode(d, len);
811
835
    cross_validate(as_path);
812
836
}
 
837
#endif
 
838
 
 
839
 
 
840
AS4Path::AS4Path(const uint8_t* d, size_t len)
 
841
     throw(CorruptMessage)
 
842
{
 
843
    decode(d, len);
 
844
}
813
845
 
814
846
/**
815
 
 * populate a AsPath from the received data representation from a
 
847
 * populate a ASPath from the received data representation from a
816
848
 * AS4_PATH attribute.
817
849
 */
818
850
void
819
 
As4Path::decode(const uint8_t *d, size_t l) throw(CorruptMessage)
 
851
AS4Path::decode(const uint8_t *d, size_t l) throw(CorruptMessage)
820
852
{
821
853
    _num_segments = 0;
822
854
    _path_len = 0;
824
856
        size_t len = 2 + d[1]*4;        // XXX length in bytes for 32bit AS's
825
857
        XLOG_ASSERT(len <= l);
826
858
 
827
 
        As4Segment s(d);
 
859
        AS4Segment s(d);
828
860
        add_segment(s);
829
861
        d += len;
830
862
        l -= len;
837
869
 * is missing 
838
870
 */
839
871
 
840
 
void As4Path::cross_validate(const AsPath& as_path)
 
872
void AS4Path::cross_validate(const ASPath& as_path)
841
873
{
 
874
    debug_msg("cross validate\n%s\n%s\n", str().c_str(), as_path.str().c_str());
 
875
              
842
876
    if (as_path.path_length() < path_length() ) {
 
877
        debug_msg("as_path.path_length() < path_length()\n");
843
878
        // This is illegal.  The spec says to ignore the AS4_PATH
844
879
        // attribute and use the data from the AS_PATH attribute throw
845
880
        // away the data we had.
847
882
            _segments.pop_front();
848
883
        }
849
884
        // copy in from the AS_PATH version 
850
 
        for (uint32_t i = 0; i < as_path.path_length(); i++) {
 
885
        for (uint32_t i = 0; i < as_path.num_segments(); i++) {
 
886
            debug_msg("adding %u %s\n", i, as_path.segment(i).str().c_str()); 
851
887
            add_segment(as_path.segment(i));
852
888
        }
853
889
        return;
867
903
        // The AS_PATH has at least as many segments as the
868
904
        // AS4_PATH find where they differ, and copy across.
869
905
        for (uint32_t i = 1; i <= num_segments(); i++) {
870
 
            const AsSegment *old_seg;
871
 
            AsSegment *new_seg;
 
906
            const ASSegment *old_seg;
 
907
            ASSegment *new_seg;
872
908
            old_seg = &(as_path.segment(as_path.num_segments() - i));
873
 
            new_seg = const_cast<AsSegment*>(&(segment(num_segments() - i)));
 
909
            new_seg = const_cast<ASSegment*>(&(segment(num_segments() - i)));
 
910
            printf("old seg: %s\n", old_seg->str().c_str());
 
911
            printf("new seg: %s\n", new_seg->str().c_str());
874
912
            if (old_seg->path_length() == new_seg->path_length()) 
875
913
                continue;
876
914
            if (old_seg->path_length() < new_seg->path_length()) {
877
915
                // ooops - WTF happened here
 
916
                debug_msg("do patchup\n");
878
917
                do_patchup(as_path);
879
918
            }
880
919
            if (old_seg->path_length() > new_seg->path_length()) {
881
920
                // found a segment that needs data copying over
 
921
                debug_msg("pad segment\n");
 
922
                printf("new_seg type: %u\n", new_seg->type());
882
923
                pad_segment(*old_seg, *new_seg);
883
924
            }
884
925
        }
885
 
        
 
926
 
 
927
        debug_msg("after patching: \n");
 
928
        debug_msg("old as_path (len %u): %s\n", (uint32_t)as_path.path_length(), as_path.str().c_str());
 
929
        debug_msg("new as_path (len %u): %s\n", (uint32_t)path_length(), str().c_str());
886
930
        if (as_path.path_length() == path_length()) {
887
931
            return;
888
932
        }
899
943
    }
900
944
}
901
945
 
902
 
void As4Path::pad_segment(const AsSegment& old_seg, AsSegment& new_seg) 
 
946
void AS4Path::pad_segment(const ASSegment& old_seg, ASSegment& new_seg) 
903
947
{
 
948
    debug_msg("pad: new type: %u\n", new_seg.type());
904
949
    if (new_seg.type() == AS_SET) {
 
950
        debug_msg("new == AS_SET\n");
905
951
        // find everything in the old seg that's not in the new seg,
906
952
        // and add it.
907
953
        for (int i = old_seg.as_size()-1; i >= 0; i--) {
920
966
    }
921
967
 
922
968
    if (old_seg.type() == AS_SET) {
 
969
        debug_msg("old == AS_SET\n");
923
970
        // The old segment was an AS_SET, but the new isn't.  Looks
924
971
        // like some old BGP speaker did some form of aggregation.
925
972
        // Convert the new one to an AS_SET too.
928
975
        return;
929
976
    }
930
977
 
 
978
    debug_msg("both are sequences\n");
931
979
    // They're both AS_SEQUENCES, so we need to preserve sequence.
932
980
    // First validate that new_seg is a sub-sequence of old_seg
933
981
    for (uint32_t i = 1; i <= new_seg.as_size(); i++) {
934
982
        const AsNum *old_asn = &(old_seg.as_num(old_seg.as_size()-i));
935
983
        const AsNum *new_asn = &(new_seg.as_num(new_seg.as_size()-i));
936
 
        if (*old_asn != *new_asn) {
 
984
        debug_msg("old_asn: %s, new_asn: %s\n", old_asn->str().c_str(), new_asn->str().c_str());
 
985
        // do a compare on the 16-bit compat versions of the numbers
 
986
        if (old_asn->as() != new_asn->as()) {
 
987
            debug_msg("Mismatch\n");
937
988
            // We've got a mismatch - make it into an AS_SET.  This is
938
989
            // a pretty arbitrary decision, but this shouldn't happen
939
990
            // in reality.  At least it should be safe.
946
997
    // now we can simply copy across the missing AS numbers
947
998
    for (int i = old_seg.as_size() - new_seg.as_size() - 1; i >= 0; i--) {
948
999
        new_seg.prepend_as(old_seg.as_num(i));
 
1000
        _path_len++;
949
1001
    }
950
1002
    return;
951
1003
}
952
1004
 
953
 
void As4Path::do_patchup(const AsPath& as_path)
 
1005
void AS4Path::do_patchup(const ASPath& as_path)
954
1006
{
955
1007
    // we get here when the cross validation fails, and we need to do
956
1008
    // something that isn't actually illegal.
960
1012
    // previously in the AS4_PATH.  This at least should prevent
961
1013
    // loops forming, but it's really ugly.
962
1014
 
963
 
    AsSegment new_set(AS_SET);
 
1015
    ASSegment new_set(AS_SET);
964
1016
    for (uint32_t i = 0; i < as_path.path_length(); i++) {
965
 
        const AsSegment *s = &(as_path.segment(i));
 
1017
        const ASSegment *s = &(as_path.segment(i));
966
1018
        for (uint32_t j = 0; j < s->path_length(); j++) {
967
1019
            const AsNum *asn = &(s->as_num(j));
968
1020
            if (asn->as() == AsNum::AS_TRAN)
996
1048
}
997
1049
 
998
1050
const uint8_t *
999
 
As4Path::encode(size_t &len, uint8_t *buf) const
 
1051
AS4Path::encode(size_t &len, uint8_t *buf) const
1000
1052
{
 
1053
    debug_msg("AS4Path::encode\n");
1001
1054
    XLOG_ASSERT(_num_segments == _segments.size());     // XXX expensive
1002
1055
    const_iterator i;
1003
1056
    size_t pos, l = wire_size();
1011
1064
 
1012
1065
    // encode into the buffer
1013
1066
    for (pos = 0, i = _segments.begin(); i != _segments.end(); ++i) {
1014
 
        const As4Segment *new_seg = (const As4Segment*)(&(*i));
 
1067
        const AS4Segment *new_seg = (const AS4Segment*)(&(*i));
1015
1068
        l = new_seg->wire_size();
1016
1069
        new_seg->encode(l, buf + pos);
1017
1070
        pos += l;
1021
1074
 
1022
1075
 
1023
1076
size_t
1024
 
As4Path::wire_size() const
 
1077
AS4Path::wire_size() const
1025
1078
{
1026
1079
    size_t l = 0;
1027
1080
    const_iterator i;
1028
1081
 
1029
1082
    for (i = _segments.begin(); i != _segments.end(); ++i) {
1030
 
        const As4Segment *new_seg = (const As4Segment*)(&(*i));
 
1083
        const AS4Segment *new_seg = (const AS4Segment*)(&(*i));
1031
1084
        l += new_seg->wire_size();
1032
1085
    }
1033
1086
    return l;