1 //===========================================================================
2 //  $Name: arts++-1-1-a13 $
3 //  $Id: ArtsBgp4AsPathSegment.cc,v 1.2 2004/04/21 23:51:31 kkeys Exp $
4 //===========================================================================
5 //  Copyright Notice
6 //
7 //  By accessing this software, arts++, you are duly informed
8 //  of and agree to be bound by the conditions described below in this
9 //  notice:
10 //
11 //  This software product, arts++, is developed by Daniel W. McRobb, and
12 //  copyrighted(C) 1998 by the University of California, San Diego
13 //  (UCSD), with all rights reserved.  UCSD administers the CAIDA grant,
14 //  NCR-9711092, under which part of this code was developed.
15 //
16 //  There is no charge for arts++ software.  You can redistribute it
17 //  and/or modify it under the terms of the GNU Lesser General Public
18 //  License, Version 2.1, February 1999, which is incorporated by
19 //  reference herein.
20 //
21 //  arts++ is distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS, OF
22 //  MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE or that the use
23 //  of it will not infringe on any third party's intellectual
24 //  property rights.
25 //
26 //  You should have received a copy of the GNU Lesser General Public
27 //  License along with arts++.  Copies can also be obtained from:
28 //
29 //    http://www.gnu.org/copyleft/lesser.html
30 //
31 //  or by writing to:
32 //
33 //  Free Software Foundation, Inc.
34 //  59 Temple Place, Suite 330
35 //  Boston, MA 02111-1307
36 //  USA
37 //
38 //  Or contact:
39 //
40 //    info@caida.org
41 //===========================================================================
42 
43 extern "C" {
44 #include "artslocal.h"
45 }
46 
47 #include <string>
48 
49 #if defined(HAVE_SSTREAM)
50   #include <sstream>
51 #elif defined(HAVE_STRSTREAM)
52   #include <strstream>
53 #else
54   #include <strstream.h>
55 #endif
56 #include <algorithm>
57 
58 #include "ArtsPrimitive.hh"
59 #include "ArtsBgp4AsPathSegment.hh"
60 
61 using namespace std;
62 
63 static const std::string rcsid = "@(#) $Name: arts++-1-1-a13 $ $Id: ArtsBgp4AsPathSegment.cc,v 1.2 2004/04/21 23:51:31 kkeys Exp $";
64 
65 //----------------------------------------------------------------------------
66 //              ArtsBgp4AsPathSegment::ArtsBgp4AsPathSegment()
67 //............................................................................
68 //
69 //----------------------------------------------------------------------------
ArtsBgp4AsPathSegment()70 ArtsBgp4AsPathSegment::ArtsBgp4AsPathSegment()
71 {
72   this->_type = 0;
73 
74   #ifndef NDEBUG
75     ++_numObjects;
76   #endif
77 }
78 
79 //----------------------------------------------------------------------------
80 // ArtsBgp4AsPathSegment::
81 // ArtsBgp4AsPathSegment(const ArtsBgp4AsPathSegment & asPathSegment)
82 //............................................................................
83 //
84 //----------------------------------------------------------------------------
85 ArtsBgp4AsPathSegment::
ArtsBgp4AsPathSegment(const ArtsBgp4AsPathSegment & asPathSegment)86 ArtsBgp4AsPathSegment(const ArtsBgp4AsPathSegment & asPathSegment)
87 {
88   this->_type = asPathSegment.Type();
89   this->_AS = asPathSegment.AS();
90 }
91 
92 //----------------------------------------------------------------------------
93 //             ArtsBgp4AsPathSegment::~ArtsBgp4AsPathSegment()
94 //............................................................................
95 //
96 //----------------------------------------------------------------------------
~ArtsBgp4AsPathSegment()97 ArtsBgp4AsPathSegment::~ArtsBgp4AsPathSegment()
98 {
99   #ifndef NDEBUG
100     if (_numObjects > 0)
101       --_numObjects;
102   #endif
103 
104   if (! (*this)._AS.empty())
105     (*this)._AS.erase((*this)._AS.begin(),(*this)._AS.end());
106 }
107 
108 //-------------------------------------------------------------------------
109 //               uint8_t ArtsBgp4AsPathSegment::Type() const
110 //.........................................................................
111 //
112 //-------------------------------------------------------------------------
Type() const113 uint8_t ArtsBgp4AsPathSegment::Type() const
114 {
115   return(this->_type);
116 }
117 
118 //-------------------------------------------------------------------------
119 //            uint8_t ArtsBgp4AsPathSegment::Type(uint8_t type)
120 //.........................................................................
121 //
122 //-------------------------------------------------------------------------
Type(uint8_t type)123 uint8_t ArtsBgp4AsPathSegment::Type(uint8_t type)
124 {
125   this->_type = type;
126   return(this->_type);
127 }
128 
129 //-------------------------------------------------------------------------
130 //            vector<uint16_t> & ArtsBgp4AsPathSegment::AS() const
131 //.........................................................................
132 //
133 //-------------------------------------------------------------------------
AS() const134 vector<uint16_t> & ArtsBgp4AsPathSegment::AS() const
135 {
136   return(this->_AS);
137 }
138 
139 //----------------------------------------------------------------------------
140 // istream & ArtsBgp4AsPathSegment::read(istream & is, uint8_t version)
141 //............................................................................
142 //
143 //----------------------------------------------------------------------------
read(istream & is,uint8_t version)144 istream & ArtsBgp4AsPathSegment::read(istream & is, uint8_t version)
145 {
146   uint8_t   numAses;
147   uint16_t  as;
148 
149   is.read((char*)&this->_type,sizeof(this->_type));
150   is.read((char*)&numAses,sizeof(numAses));
151   if (numAses > 0) {
152     this->_AS.reserve(numAses);
153     for (int asNum = 0; asNum < numAses; asNum++) {
154       g_ArtsLibInternal_Primitive.ReadUint16(is,as,sizeof(as));
155       this->_AS.push_back(as);
156     }
157   }
158 
159   return(is);
160 }
161 
162 //----------------------------------------------------------------------------
163 //        int ArtsBgp4AsPathSegment::read(int fd, uint8_t version)
164 //............................................................................
165 //
166 //----------------------------------------------------------------------------
read(int fd,uint8_t version)167 int ArtsBgp4AsPathSegment::read(int fd, uint8_t version)
168 {
169   int       rc;
170   uint8_t   numAses;
171   uint16_t  as;
172   int       bytesRead = 0;
173 
174   rc = g_ArtsLibInternal_Primitive.FdRead(fd,&this->_type,sizeof(this->_type));
175   if (rc < sizeof(this->_type))
176     return(-1);
177   bytesRead += rc;
178   rc = g_ArtsLibInternal_Primitive.FdRead(fd,&numAses,sizeof(numAses));
179   if (rc < sizeof(numAses))
180     return(-1);
181   bytesRead += rc;
182   if (numAses > 0) {
183     this->_AS.reserve(numAses);
184     for (int asNum = 0; asNum < numAses; asNum++) {
185       rc = g_ArtsLibInternal_Primitive.ReadUint16(fd,as,sizeof(as));
186       if (rc < sizeof(as))
187         return(-1);
188       bytesRead += rc;
189       this->_AS.push_back(as);
190     }
191   }
192 
193   return(bytesRead);
194 }
195 
196 //----------------------------------------------------------------------------
197 //     ostream & ArtsBgp4AsPathSegment::write(ostream & os,
198 //                                             uint8_t version) const
199 //............................................................................
200 //
201 //----------------------------------------------------------------------------
write(ostream & os,uint8_t version) const202 ostream & ArtsBgp4AsPathSegment::write(ostream & os,
203                                        uint8_t version) const
204 {
205   os.write((char*)&this->_type,sizeof(this->_type));
206 
207   uint8_t   numAses = this->_AS.size();
208   os.write((char*)&numAses,sizeof(numAses));
209 
210   for (int asNum = 0; asNum < numAses; asNum++) {
211     g_ArtsLibInternal_Primitive.WriteUint16(os,this->_AS[asNum],
212                                             sizeof(uint16_t));
213   }
214   return(os);
215 }
216 
217 //----------------------------------------------------------------------------
218 //   int ArtsBgp4AsPathSegment::write(int fd, uint8_t version) const
219 //............................................................................
220 //
221 //----------------------------------------------------------------------------
write(int fd,uint8_t version) const222 int ArtsBgp4AsPathSegment::write(int fd, uint8_t version) const
223 {
224   int       rc;
225   uint8_t   numAses;
226   int       bytesWritten = 0;
227 
228   rc = g_ArtsLibInternal_Primitive.FdWrite(fd,&this->_type,
229                                            sizeof(this->_type));
230   if (rc < sizeof(this->_type))
231     return(-1);
232   bytesWritten += rc;
233   numAses = this->_AS.size();
234   rc = g_ArtsLibInternal_Primitive.FdWrite(fd,&numAses,sizeof(numAses));
235   if (rc < sizeof(numAses))
236     return(-1);
237   bytesWritten += rc;
238   for (int asNum = 0; asNum < numAses; asNum++) {
239     rc = g_ArtsLibInternal_Primitive.WriteUint16(fd,this->_AS[asNum],
240                                                  sizeof(uint16_t));
241     if (rc < sizeof(uint16_t))
242       return(-1);
243     bytesWritten += rc;
244   }
245   return(rc);
246 }
247 
248 //----------------------------------------------------------------------------
249 //    uint32_t ArtsBgp4AsPathSegment::Length(uint8_t version) const
250 //............................................................................
251 //
252 //----------------------------------------------------------------------------
Length(uint8_t version) const253 uint32_t ArtsBgp4AsPathSegment::Length(uint8_t version) const
254 {
255   return(sizeof(this->_type) + sizeof(uint8_t) +
256          (sizeof(uint16_t) * this->_AS.size()));
257 }
258 
259 //----------------------------------------------------------------------------
260 //              void ArtsBgp4AsPathSegment::AddAs(uint16_t as)
261 //............................................................................
262 //
263 //----------------------------------------------------------------------------
AddAs(uint16_t as)264 void ArtsBgp4AsPathSegment::AddAs(uint16_t as)
265 {
266   this->_AS.push_back(as);
267   return;
268 }
269 
270 //----------------------------------------------------------------------------
271 //                   void ArtsBgp4AsPathSegment::Unique()
272 //............................................................................
273 //
274 //----------------------------------------------------------------------------
Unique()275 void ArtsBgp4AsPathSegment::Unique()
276 {
277   // don't muck with AS_SET segments
278   if (this->_type == k_segmentTypeSet)
279     return;
280 
281   // remove adjacent duplicate AS numbers in AS path segment
282   vector<uint16_t>::iterator  newSegmentEnd;
283   newSegmentEnd = unique(this->_AS.begin(),this->_AS.end());
284   this->_AS.erase(newSegmentEnd,this->_AS.end());
285 
286   return;
287 }
288 
289 //----------------------------------------------------------------------------
290 //         ostream &
291 //         operator << (ostream & os,
292 //                      const ArtsBgp4AsPathSegment & bgp4AsPathSegment)
293 //............................................................................
294 //
295 //----------------------------------------------------------------------------
296 ostream &
operator <<(ostream & os,const ArtsBgp4AsPathSegment & bgp4AsPathSegment)297 operator << (ostream & os,
298              const ArtsBgp4AsPathSegment & bgp4AsPathSegment)
299 {
300   if (bgp4AsPathSegment.AS().size() < 1)
301     return(os);
302 
303   vector<uint16_t>::iterator  asIter;
304 
305   asIter = bgp4AsPathSegment.AS().begin();
306 
307   if (bgp4AsPathSegment.Type() == ArtsBgp4AsPathSegment::k_segmentTypeSet) {
308     os << "[" << (*asIter);
309   }
310   else {
311     os << (*asIter);
312   }
313 
314   for (asIter++; asIter != bgp4AsPathSegment.AS().end(); asIter++) {
315     os << " " << (*asIter);
316   }
317   if (bgp4AsPathSegment.Type() == ArtsBgp4AsPathSegment::k_segmentTypeSet) {
318     os << "]";
319   }
320   return(os);
321 }
322 
323 //----------------------------------------------------------------------------
324 //               ArtsBgp4AsPathSegment &
325 //               ArtsBgp4AsPathSegment::operator =
326 //                 (const ArtsBgp4AsPathSegment & asPathSegment)
327 //............................................................................
328 //
329 //----------------------------------------------------------------------------
330 ArtsBgp4AsPathSegment &
operator =(const ArtsBgp4AsPathSegment & asPathSegment)331 ArtsBgp4AsPathSegment::operator = (const ArtsBgp4AsPathSegment & asPathSegment)
332 {
333   this->_type = asPathSegment.Type();
334   this->_AS.reserve(asPathSegment.AS().size());
335   this->_AS = asPathSegment.AS();
336   return(*this);
337 }
338 
339 uint32_t  ArtsBgp4AsPathSegment::_numObjects = 0;
340