User Manual, Developers Guide and API Documentation

TraceCollector.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2007
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 5, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <IP/trace/TraceCollector.hpp>
00029 
00030 using namespace ip::trace;
00031 
00032 TraceCollector::TraceCollector(std::string _filename):
00033     filename(_filename),
00034     counter(0),
00035     writeHeader(true)
00036 {
00037 }
00038 
00039 void
00040 TraceCollector::addPacketTrace(PacketTrace pt)
00041 {
00042     this->ptc.insert(ptc.end(), pt);
00043     ++counter;
00044     if(counter > 1000)
00045     {
00046         counter = 0;
00047         this->write();
00048     }
00049 }
00050 
00051 void
00052 TraceCollector::write()
00053 {
00054 
00055     std::ofstream theFile;
00056     if (this->writeHeader)
00057     {
00058         theFile.open(this->filename.c_str(), std::ios::out | std::ios::binary);
00059 
00060         this->writeFileHeader(theFile);
00061 
00062     }
00063     else
00064     {
00065         theFile.open(this->filename.c_str(), std::ios::out | std::ios::binary | std::ios::app);
00066     }
00067 
00068     for (PacketTraceContainer::iterator it = ptc.begin();
00069          it != ptc.end();
00070          ++it)
00071     {
00072         this->writePacket(theFile, *it);
00073     }
00074 
00075     theFile.close();
00076     ptc.clear();
00077 }
00078 
00079 void
00080 TraceCollector::writeFileHeader(std::ofstream& theFile)
00081 {
00082     if (this->writeHeader)
00083     {
00084         pcap_hdr_t fileHeader;
00085 
00086         fileHeader.magic_number = 0xA1B2C3D4;
00087         fileHeader.version_major = 2;
00088         fileHeader.version_minor = 4;
00089         fileHeader.thiszone = 0;
00090         fileHeader.sigfigs = 0;
00091         fileHeader.snaplen = 0x0000FFFF;
00092         fileHeader.network = 1;
00093 
00094         theFile.write((char*) &(fileHeader), sizeof(fileHeader));
00095         this->writeHeader = false;
00096     }
00097 }
00098 
00099 bool
00100 TraceCollector::hasSomethingToWrite() const
00101 {
00102     return (!ptc.empty());
00103 }
00104 
00105 void
00106 TraceCollector::writePacket(std::ofstream& theFile, const PacketTrace& pt)
00107 {
00108     mac_hdr_t macHeader;
00109     ip_hdr_t ipHeader;
00110 //  tcp_hdr_t tcpHeader;
00111     packet_hdr_t packetHeader;
00112 
00113     macHeader.destination[5] = pt.destinationMAC.getInteger() & 0xF;
00114     macHeader.destination[4] = (pt.destinationMAC.getInteger() >> 8) & 0xF;
00115     macHeader.destination[3] = (pt.destinationMAC.getInteger() >> 16) & 0xF;
00116     macHeader.destination[2] = (pt.destinationMAC.getInteger() >> 24) & 0xF;
00117     macHeader.destination[1] = 0;
00118     macHeader.destination[0] = 0;
00119     macHeader.source[5] = pt.sourceMAC.getInteger() & 0xF;
00120     macHeader.source[4] = (pt.sourceMAC.getInteger() >> 8) & 0xF;
00121     macHeader.source[3] = (pt.sourceMAC.getInteger() >> 16) & 0xF;
00122     macHeader.source[2] = (pt.sourceMAC.getInteger() >> 24) & 0xF;
00123     macHeader.source[1] = 0;
00124     macHeader.source[0] = 0;
00125     macHeader.type =0x0008; // IP Payload
00126 
00127     ipHeader.versionAndLength = 4 << 4 | 5;
00128     ipHeader.typeOfService = 0;
00129     ipHeader.totalLength = reverse16(sizeof(ipHeader) + pt.payloadSize/8);
00130     ipHeader.identification = 0;
00131     ipHeader.flagsAndOffset = 0;
00132     ipHeader.ttl = pt.TTL;
00133     ipHeader.protocol = pt.protocol;
00134     ipHeader.checksum = 0;
00135     ipHeader.sourceAddress = reverse32(pt.sourceIP.getInteger());
00136     ipHeader.destinationAddress = reverse32(pt.destinationIP.getInteger());
00137 
00138     ipHeader.checksum = reverse16(ipChecksum(ipHeader));
00139 
00140     time_t t;
00141 
00142     time(&t);
00143 
00144     tm* systime = localtime(&t);
00145 
00146     time_t simTimeTmp = static_cast<time_t>(floor(pt.now));
00147     tm* simTime = localtime(&simTimeTmp);
00148 
00149     systime->tm_sec = simTime->tm_sec;
00150     systime->tm_min = simTime->tm_min;
00151     systime->tm_hour = simTime->tm_hour;
00152 
00153     time_t unixtime = mktime(systime);
00154 
00155     packetHeader.timestamp = unixtime;
00156     packetHeader.microseconds = static_cast<unsigned long int>(floor((pt.now - floor(pt.now)) * 1000000));
00157     packetHeader.includedNumOctets = sizeof(macHeader) + sizeof(ipHeader) + pt.payloadSize/8;
00158     packetHeader.origNumOctets = sizeof(macHeader) + sizeof(ipHeader) + pt.payloadSize/8;
00159 
00160     theFile.write((char*) &(packetHeader), sizeof(packetHeader));
00161     theFile.write((char*) &(macHeader), sizeof(macHeader));
00162     theFile.write((char*) &(ipHeader), sizeof(ipHeader));
00163 
00164     char payload = 'W';
00165     for (int i=0; i < pt.payloadSize/8; ++i)
00166     {
00167         theFile.write((char*) &(payload), sizeof(payload));
00168         switch(payload)
00169         {
00170         case 'W':
00171             payload = 'N';
00172             break;
00173         case 'N':
00174             payload = 'S';
00175             break;
00176         case 'S':
00177             payload = 'W';
00178             break;
00179         default:
00180             payload = 'W';
00181         }
00182     }
00183 }
00184 
00185 uint16_t
00186 TraceCollector::reverse16(const uint16_t orig)
00187 {
00188     return (orig & 0x00FF) << 8 | (orig & 0xFF00) >> 8;
00189 }
00190 
00191 unsigned long int
00192 TraceCollector::reverse32(const unsigned long int orig)
00193 {
00194     return ((orig & 0x000000FF) << 24 | (orig & 0x0000FF00) << 8 |
00195             (orig & 0x00FF0000) >> 8  | (orig & 0xFF000000) >> 24);
00196 }
00197 
00198 uint16_t
00199 TraceCollector::ipChecksum(ip_hdr_t ipHeader)
00200 {
00201   unsigned char* buff=(unsigned char*)&ipHeader;
00202   uint16_t len=20;
00203   unsigned long int sum = 0;
00204   for (int i=0;i<len;i=i+2) sum += (unsigned long int)(((buff[i]<<8)&0xFF00) + (buff[i+1]&0xFF));
00205   while (sum>>16) sum = (sum & 0xFFFF) + (sum >> 16);
00206   sum = ~sum;
00207 
00208   return (uint16_t) sum;
00209 }

Generated on Sat May 26 03:32:16 2012 for openWNS by  doxygen 1.5.5