1 //===========================================================================
2 //  @(#) $Name: arts++-1-1-a13 $
3 //  @(#) $Id: artstos.cc,v 1.3 2008/04/14 21:17:09 rkoga 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 <sys/types.h>
45 #include<stdio.h>
46 #include <stdlib.h>
47 #include <sys/socket.h>
48 #include <netinet/in.h>
49 #include <arpa/inet.h>
50 #include <netdb.h>
51 #include <time.h>
52 #include <errno.h>
53 }
54 
55 #ifdef HAVE_FSTREAM
56 #include <fstream.h>
57 #else
58 #include <fstream>
59 #endif
60 
61 #include <string>
62 #include <cstring> // strdup(), strerror()
63 #include <iterator>
64 
65 #include "ArtsTosTable.hh"
66 #include "ArtsIfIndexSelectionSet.hh"
67 #include "ArtsTimeIntervalSelectionSet.hh"
68 #include "ArtsPackageVersion.hh"
69 
70 #ifndef NDEBUG
71   #include "ArtsDebug.hh"
72 #endif
73 
74 extern char *tzname[2];
75 
76 using namespace std;
77 
78 static const string rcsid = "@(#) $Name: arts++-1-1-a13 $ $Id: artstos.cc,v 1.3 2008/04/14 21:17:09 rkoga Exp $";
79 static const ArtsPackageVersion  k_artsVersion = ArtsPackageVersion(rcsid);
80 static ArtsTimeIntervalSelectionSet  g_timeIntervalSet;
81 
82 //-------------------------------------------------------------------------
83 //           static void ShowTosTable(const Arts & arts)
84 //.........................................................................
85 //
86 //-------------------------------------------------------------------------
ShowTosTable(const Arts & arts,bool sortByPkts,ArtsIfIndexSelectionSet & ifIndexSet)87 static void ShowTosTable(const Arts & arts, bool sortByPkts,
88                           ArtsIfIndexSelectionSet & ifIndexSet)
89 {
90   struct tm       *localTm;
91   time_t           periodTimes[2];
92   struct in_addr   inAddr;
93 
94   vector<ArtsAttribute>::const_iterator  periodAttribute;
95   vector<ArtsAttribute>::const_iterator  hostAttribute;
96   vector<ArtsAttribute>::const_iterator  ifIndexAttribute;
97   vector<ArtsAttribute>::const_iterator  ifDescrAttribute;
98   vector<ArtsAttribute>::const_iterator  ifIpAddrAttribute;
99 
100   hostAttribute = arts.FindHostAttribute();
101   ifIndexAttribute = arts.FindIfIndexAttribute();
102   if (ifIndexSet.size() > 0) {
103     if (ifIndexAttribute != arts.Attributes().end()) {
104       if (! ifIndexSet.Matches(ifIndexAttribute->IfIndex())) {
105         return;
106       }
107     }
108   }
109 
110   periodAttribute = arts.FindPeriodAttribute();
111   if (periodAttribute != arts.Attributes().end()) {
112     if (g_timeIntervalSet.size() > 0) {
113       if ((! g_timeIntervalSet.Matches(periodAttribute->Period()[0])) ||
114           (! g_timeIntervalSet.Matches(periodAttribute->Period()[1]))) {
115         return;
116       }
117     }
118   }
119 
120   if (hostAttribute != arts.Attributes().end()) {
121     inAddr.s_addr = hostAttribute->Host();
122     cout << "router:  " << inet_ntoa(inAddr) << endl;
123   }
124 
125   if (ifIndexAttribute != arts.Attributes().end()) {
126     cout << "ifIndex: " << ifIndexAttribute->IfIndex();
127   }
128   ifDescrAttribute = arts.FindIfDescrAttribute();
129   ifIpAddrAttribute = arts.FindIfIpAddrAttribute();
130   if (ifDescrAttribute != arts.Attributes().end() &&
131       ifIpAddrAttribute != arts.Attributes().end()) {
132     cout << " (" << ifDescrAttribute->IfDescr() << " ";
133     inAddr.s_addr = ifIpAddrAttribute->IfIpAddr();
134     cout << inet_ntoa(inAddr) << ")";
135   }
136   cout << endl;
137 
138   if (periodAttribute != arts.Attributes().end()) {
139     periodTimes[0] = periodAttribute->Period()[0];
140     periodTimes[1] = periodAttribute->Period()[1];
141     localTm = localtime(&(periodTimes[0]));
142     cout << "period:  " << setfill('0')
143          << setw(2) << (int)localTm->tm_mon+1 << "/"
144          << setw(2) << localTm->tm_mday << "/"
145          << setw(4) << localTm->tm_year + 1900 << " "
146          << setw(2) << localTm->tm_hour << ":"
147          << setw(2) << localTm->tm_min << ":"
148          << setw(2) << localTm->tm_sec << " - ";
149     localTm = localtime(&(periodTimes[1]));
150     cout << setw(2) << (int)localTm->tm_mon+1 << "/"
151          << setw(2) << localTm->tm_mday << "/"
152          << setw(4) << localTm->tm_year + 1900 << " "
153          << setw(2) << localTm->tm_hour << ":"
154          << setw(2) << localTm->tm_min << ":"
155          << setw(2) << localTm->tm_sec << " " << tzname[localTm->tm_isdst]
156          << endl;
157   }
158 
159   time_t timeInterval = periodTimes[1] - periodTimes[0];
160 
161   cout << setfill(' ');
162   cout << setw(8)  << "TOS"
163        << setw(15) << "Pkts"
164        << setw(15) << "Pkts/sec"
165        << setw(15) << "Bytes"
166        << setw(15) << "Bits/sec"
167        << endl;
168   cout << setw(8)  << "--------"
169        << setw(15) << "-------------"
170        << setw(15) << "-------------"
171        << setw(15) << "-------------"
172        << setw(15) << "-------------"
173        << endl;
174 
175   if (sortByPkts)
176     arts.TosTableData()->SortEntriesByPkts();
177   else
178     arts.TosTableData()->SortEntriesByBytes();
179 
180   vector<ArtsTosTableEntry>::const_iterator  tosEntry;
181   for (tosEntry = arts.TosTableData()->TosEntries().begin();
182        tosEntry != arts.TosTableData()->TosEntries().end();
183        tosEntry++) {
184     cout << setw(8) << (uint16_t)tosEntry->TosNumber()
185          << setw(15) << tosEntry->Pkts()
186          << setw(15)
187          << (uint64_t)((double)tosEntry->Pkts() / timeInterval)
188          << setw(15) << tosEntry->Bytes()
189          << setw(15)
190          << (uint64_t)(((double)tosEntry->Bytes() * 8.0) / timeInterval)
191          << endl;
192   }
193   cout << endl;
194 
195   return;
196 }
197 
198 //-------------------------------------------------------------------------
199 //                      void Usage(const char *argv0)
200 //.........................................................................
201 //
202 //-------------------------------------------------------------------------
Usage(const char * argv0)203 void Usage(const char *argv0)
204 {
205   cerr << "Usage: " << argv0
206        << " [-v] [-n] [-p] [-i ifIndexList] [-b beginTime]" << endl
207        << "       [-e endTime] file(s)" << endl;
208   return;
209 }
210 
211 //-------------------------------------------------------------------------
212 //                     int main(int argc, char *argv[])
213 //.........................................................................
214 //
215 //-------------------------------------------------------------------------
main(int argc,char * argv[])216 int main(int argc, char *argv[])
217 {
218   ifstream     *artsStream;
219   extern char  *optarg;
220   extern int    optind;
221   int           optChar;
222   bool          sortByPkts = false;
223   ArtsIfIndexSelectionSet   ifIndexSet;
224   char                     *startTimeExpression = (char *)0;
225   char                     *endTimeExpression = (char *)0;
226 
227   if (argc < 2) {
228     Usage(argv[0]);
229     exit(1);
230   }
231 
232   while ((optChar = getopt(argc,argv,"b:e:i:npv")) != EOF) {
233     switch (optChar) {
234       case 'b':
235         startTimeExpression = (char *)strdup(optarg);
236         break;
237       case 'e':
238         endTimeExpression = (char *)strdup(optarg);
239         break;
240       case 'i':
241         ifIndexSet.Load(optarg);
242         break;
243       case 'p':
244         sortByPkts = true;
245         break;
246       case 'v':
247         cerr << k_artsVersion.Name() << "  " << k_artsVersion.Id() << endl;
248         exit(0);
249         break;
250       case '?':
251       default:
252         Usage(argv[0]);
253         exit(1);
254         break;
255     }
256   }
257 
258   if (optind >= argc) {
259     Usage(argv[0]);
260     exit(1);
261   }
262 
263   if (startTimeExpression || endTimeExpression)
264         g_timeIntervalSet.Load(startTimeExpression,endTimeExpression);
265 
266   for (int fileNum = optind; fileNum < argc; fileNum++) {
267     artsStream = new ifstream(argv[fileNum]);
268     if (!artsStream || !(*artsStream)) {
269       cerr << "[E] unable to open input file '" << argv[fileNum] << "': "
270            << strerror(errno) << endl;
271       continue;
272     }
273 
274     istream_iterator<ArtsTosTable>  inStreamIter(*artsStream);
275     istream_iterator<ArtsTosTable>  inStreamEnd;
276 
277     for (; inStreamIter != inStreamEnd; inStreamIter++) {
278       ShowTosTable(*inStreamIter,sortByPkts,ifIndexSet);
279     }
280     delete(artsStream);
281   }
282 
283   #ifndef NDEBUG
284     atexit(ShowArtsObjectsNotFreed);
285   #endif
286 
287   exit(0);
288 }
289