1 //===========================================================================
2 //  $Name: arts++-1-1-a13 $
3 //  $Id: ArtsPortChoice.cc,v 1.2 2004/04/21 23:51:33 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 <assert.h>
45 }
46 
47 #include <string>
48 
49 #include "ArtsPrimitive.hh"
50 #include "ArtsPortChoice.hh"
51 
52 using namespace std;
53 
54 static const std::string rcsid = "@(#) $Name: arts++-1-1-a13 $ $Id: ArtsPortChoice.cc,v 1.2 2004/04/21 23:51:33 kkeys Exp $";
55 
56 //-------------------------------------------------------------------------
57 //                     ArtsPortChoice::ArtsPortChoice()
58 //.........................................................................
59 //
60 //-------------------------------------------------------------------------
ArtsPortChoice()61 ArtsPortChoice::ArtsPortChoice()
62 {
63   this->_flags = 0x00;
64   this->_value.first = 0;
65   this->_value.second = 0;
66 
67   #ifndef NDEBUG
68     ++ArtsPortChoice::_numObjects;
69   #endif
70 }
71 
72 //----------------------------------------------------------------------------
73 //    ArtsPortChoice::ArtsPortChoice(const ArtsPortChoice & portChoice)
74 //............................................................................
75 //
76 //----------------------------------------------------------------------------
ArtsPortChoice(const ArtsPortChoice & portChoice)77 ArtsPortChoice::ArtsPortChoice(const ArtsPortChoice & portChoice)
78 {
79   this->_flags = portChoice.Flags();
80   this->_value.first = portChoice.Value().first;
81   this->_value.second = portChoice.Value().second;
82 
83   #ifndef NDEBUG
84     ++ArtsPortChoice::_numObjects;
85   #endif
86 }
87 
88 //-------------------------------------------------------------------------
89 //              ArtsPortChoice::ArtsPortChoice(uint16_t port)
90 //.........................................................................
91 //
92 //-------------------------------------------------------------------------
ArtsPortChoice(uint16_t port)93 ArtsPortChoice::ArtsPortChoice(uint16_t port)
94 {
95   this->Value(port);
96 
97   #ifndef NDEBUG
98     ++ArtsPortChoice::_numObjects;
99   #endif
100 }
101 
102 //-------------------------------------------------------------------------
103 //  ArtsPortChoice::ArtsPortChoice(uint16_t firstPort, uint16_t lastPort)
104 //.........................................................................
105 //
106 //-------------------------------------------------------------------------
ArtsPortChoice(uint16_t firstPort,uint16_t lastPort)107 ArtsPortChoice::ArtsPortChoice(uint16_t firstPort, uint16_t lastPort)
108 {
109   this->Value(firstPort,lastPort);
110 
111   #ifndef NDEBUG
112     ++ArtsPortChoice::_numObjects;
113   #endif
114 }
115 
116 //-------------------------------------------------------------------------
117 //                    ArtsPortChoice::~ArtsPortChoice()
118 //.........................................................................
119 //
120 //-------------------------------------------------------------------------
~ArtsPortChoice()121 ArtsPortChoice::~ArtsPortChoice()
122 {
123   #ifndef NDEBUG
124     --ArtsPortChoice::_numObjects;
125   #endif
126 }
127 
128 //----------------------------------------------------------------------------
129 //                  uint8_t ArtsPortChoice::Flags() const
130 //............................................................................
131 //
132 //----------------------------------------------------------------------------
Flags() const133 uint8_t ArtsPortChoice::Flags() const
134 {
135   return(this->_flags);
136 }
137 
138 //-------------------------------------------------------------------------
139 //             const value_type & ArtsPortChoice::Value() const
140 //.........................................................................
141 //
142 //-------------------------------------------------------------------------
Value() const143 const ArtsPortChoice::value_type & ArtsPortChoice::Value() const
144 {
145   return(this->_value);
146 }
147 
148 //-------------------------------------------------------------------------
149 //              uint16_t ArtsPortChoice::Value(uint16_t port)
150 //.........................................................................
151 //
152 //-------------------------------------------------------------------------
Value(uint16_t port)153 uint16_t ArtsPortChoice::Value(uint16_t port)
154 {
155   this->IsRange(false);
156 
157   if (port > 0xff)
158     this->_flags |= this->k_firstPortLengthMask;
159   else
160     this->_flags &= (~ this->k_firstPortLengthMask);
161 
162   this->_value.first = port;
163 
164   return(this->_value.first);
165 }
166 
167 
168 //-------------------------------------------------------------------------
169 //                    const ArtsPortChoice::value_type &
170 //                    ArtsPortChoice::Value(uint16_t firstPort,
171 //                                          uint16_t lastPort)
172 //.........................................................................
173 //
174 //-------------------------------------------------------------------------
175 const ArtsPortChoice::value_type &
Value(uint16_t firstPort,uint16_t lastPort)176 ArtsPortChoice::Value(uint16_t firstPort,
177                       uint16_t lastPort)
178 {
179   assert(lastPort >= firstPort);
180 
181   this->IsRange(true);
182 
183   if (firstPort > 0xff)
184     this->_flags |= this->k_firstPortLengthMask;
185   else
186     this->_flags &= (~ this->k_firstPortLengthMask);
187 
188   this->_value.first = firstPort;
189 
190   if (lastPort > 0xff)
191     this->_flags |= this->k_lastPortLengthMask;
192   else
193     this->_flags &= (~ this->k_lastPortLengthMask);
194 
195   this->_value.second = lastPort;
196 
197   return(this->_value);
198 }
199 
200 
201 //-------------------------------------------------------------------------
202 //            bool ArtsPortChoice::Matches(uint16_t port) const
203 //.........................................................................
204 //
205 //-------------------------------------------------------------------------
Matches(uint16_t port) const206 bool ArtsPortChoice::Matches(uint16_t port) const
207 {
208   bool  rc = false;
209 
210   if (this->IsRange()) {
211     if (port >= this->_value.first && port <= this->_value.second) {
212       rc = true;
213     }
214   }
215   else {
216     if (port == this->_value.first) {
217       rc = true;
218     }
219   }
220   return(rc);
221 }
222 
223 //-------------------------------------------------------------------------
224 //                 uint32_t ArtsPortChoice::Length() const
225 //.........................................................................
226 //
227 //-------------------------------------------------------------------------
Length() const228 uint32_t ArtsPortChoice::Length() const
229 {
230   uint32_t  length = 0;
231 
232   length += sizeof(this->_flags);
233 
234   length += 1;
235   if (this->_flags & this->k_firstPortLengthMask) {
236     length += 1;
237   }
238 
239   if (this->IsRange()) {
240     length += 1;
241     if (this->_flags & this->k_lastPortLengthMask) {
242       length += 1;
243     }
244   }
245   return(length);
246 }
247 
248 //-------------------------------------------------------------------------
249 //                     int ArtsPortChoice::read(int fd)
250 //.........................................................................
251 //
252 //-------------------------------------------------------------------------
read(int fd)253 int ArtsPortChoice::read(int fd)
254 {
255   int       rc;
256   int       bytesRead = 0;
257   uint8_t   portLength;
258 
259   rc = g_ArtsLibInternal_Primitive.FdRead(fd,&this->_flags,
260                                           sizeof(this->_flags));
261   if (rc <= 0)
262     return(rc);
263   bytesRead += rc;
264 
265   portLength = 1;
266   if (this->_flags & this->k_firstPortLengthMask)
267     portLength = 2;
268   rc = g_ArtsLibInternal_Primitive.ReadUint16(fd,this->_value.first,
269                                               portLength);
270   if (rc < portLength) {
271     return(-1);
272   }
273   bytesRead += rc;
274 
275   if (this->IsRange()) {
276     portLength = 1;
277     if (this->_flags & this->k_lastPortLengthMask)
278       portLength = 2;
279     rc = g_ArtsLibInternal_Primitive.ReadUint16(fd,this->_value.second,
280                                                 portLength);
281     if (rc < portLength) {
282       return(-1);
283     }
284     bytesRead += rc;
285   }
286   return(bytesRead);
287 }
288 
289 //-------------------------------------------------------------------------
290 //               istream & ArtsPortChoice::read(istream & is)
291 //.........................................................................
292 //
293 //-------------------------------------------------------------------------
read(istream & is)294 istream & ArtsPortChoice::read(istream & is)
295 {
296   uint8_t   portLength;
297 
298   is.read((char*)&this->_flags,sizeof(this->_flags));
299   if (!is)
300     return(is);
301 
302   portLength = 1;
303   if (this->_flags & this->k_firstPortLengthMask)
304     portLength = 2;
305   g_ArtsLibInternal_Primitive.ReadUint16(is,this->_value.first,portLength);
306   if (!is)
307     return(is);
308 
309   if (this->IsRange()) {
310     portLength = 1;
311     if (this->_flags & this->k_lastPortLengthMask)
312       portLength = 2;
313     g_ArtsLibInternal_Primitive.ReadUint16(is,this->_value.second,
314                                            portLength);
315   }
316   return(is);
317 }
318 
319 //-------------------------------------------------------------------------
320 //                 int ArtsPortChoice::write(int fd) const
321 //.........................................................................
322 //
323 //-------------------------------------------------------------------------
write(int fd) const324 int ArtsPortChoice::write(int fd) const
325 {
326   int      rc;
327   int      bytesWritten = 0;
328   uint8_t  portLength;
329 
330   rc = g_ArtsLibInternal_Primitive.FdWrite(fd,&this->_flags,
331                                            sizeof(this->_flags));
332   if (rc < sizeof(this->_flags)) {
333     return(-1);
334   }
335   bytesWritten += rc;
336 
337   portLength = 1;
338   if (this->_flags & this->k_firstPortLengthMask)
339     portLength = 2;
340   rc = g_ArtsLibInternal_Primitive.WriteUint16(fd,this->_value.first,
341                                                portLength);
342   if (rc < portLength)
343     return(-1);
344   bytesWritten += rc;
345 
346   if (this->IsRange()) {
347     portLength = 1;
348     if (this->_flags & this->k_lastPortLengthMask)
349       portLength = 2;
350     rc = g_ArtsLibInternal_Primitive.WriteUint16(fd,this->_value.second,
351                                                  portLength);
352     if (rc < portLength)
353       return(-1);
354     bytesWritten += rc;
355   }
356   return(bytesWritten);
357 }
358 
359 
360 //-------------------------------------------------------------------------
361 //           ostream & ArtsPortChoice::write(ostream & os) const
362 //.........................................................................
363 //
364 //-------------------------------------------------------------------------
write(ostream & os) const365 ostream & ArtsPortChoice::write(ostream & os) const
366 {
367   uint8_t  portLength;
368 
369   os.write((char*)&this->_flags,sizeof(this->_flags));
370 
371   portLength = 1;
372   if (this->_flags & this->k_firstPortLengthMask)
373     portLength = 2;
374   g_ArtsLibInternal_Primitive.WriteUint16(os,this->_value.first,portLength);
375   if (this->IsRange()) {
376     portLength = 1;
377     if (this->_flags & this->k_lastPortLengthMask)
378       portLength = 2;
379     g_ArtsLibInternal_Primitive.WriteUint16(os,this->_value.second,portLength);
380   }
381   return(os);
382 }
383 
384 //-------------------------------------------------------------------------
385 // bool ArtsPortChoice::operator == (const ArtsPortChoice & portChoice) const
386 //.........................................................................
387 //
388 //-------------------------------------------------------------------------
operator ==(const ArtsPortChoice & portChoice) const389 bool ArtsPortChoice::operator == (const ArtsPortChoice & portChoice) const
390 {
391 
392   if (this->IsRange() != portChoice.IsRange()) {
393     return(false);
394   }
395   if (this->Value().first != portChoice.Value().first) {
396     return(false);
397   }
398   if (this->IsRange()) {
399     if (this->Value().second != portChoice.Value().second) {
400       return(false);
401     }
402   }
403   return(true);
404 }
405 
406 //-------------------------------------------------------------------------
407 // bool ArtsPortChoice::operator < (const ArtsPortChoice & portChoice) const
408 //.........................................................................
409 //
410 //-------------------------------------------------------------------------
operator <(const ArtsPortChoice & portChoice) const411 bool ArtsPortChoice::operator < (const ArtsPortChoice & portChoice) const
412 {
413   if (this->Value().first < portChoice.Value().first) {
414     return(true);
415   }
416   if (this->IsRange()) {
417     if (this->Value().second < portChoice.Value().second) {
418       return(true);
419     }
420   }
421 
422   return(false);
423 }
424 
425 
426 //-------------------------------------------------------------------------
427 //         ostream & operator << (ostream& os,
428 //                                const ArtsPortChoice & portChoice)
429 //.........................................................................
430 //
431 //-------------------------------------------------------------------------
operator <<(ostream & os,const ArtsPortChoice & portChoice)432 ostream & operator << (ostream& os,
433                        const ArtsPortChoice & portChoice)
434 {
435   os << portChoice.Value().first;
436   if (portChoice.IsRange())
437     os << "-" << portChoice.Value().second;
438   return(os);
439 }
440 
441 uint32_t ArtsPortChoice::_numObjects = 0;
442