common.cpp

00001 #include "common.h"
00002 #include <stdio.h>
00003 #include <iostream>
00004 #include <string.h>
00005 using namespace std;
00006 
00007 //================================================================
00008 // Packet Header class
00009 //
00010 PacketHdr::PacketHdr()
00011 { 
00012   length_ = 0;  
00013   info_ = new  unsigned char[MAX_HEADER_SIZE] ;
00014 }
00015 
00016 int PacketHdr::getIntegerInfo(int position)
00017 {
00018   int val;
00019   unsigned char *p = info_ +position;
00020   val = *(p++);
00021   val = val << 8 | *(p++);
00022   val = val << 8 | *(p++);
00023   val = val << 8 | *(p++);
00024 
00025   return val;
00026 }
00027 
00028 short PacketHdr::getShortIntegerInfo(int position)
00029 {
00030   short val;
00031   unsigned char *p = info_ + position;
00032   val = *(p++);
00033   val = val << 8 | *(p++);
00034 
00035   return val;
00036 }
00037 
00038 void PacketHdr::setIntegerInfo(int a, int position)
00039 {
00040   unsigned char *p = info_ + position;
00041   *(p++) =  a >> 24;
00042   *(p++) = (a >> 16) & 0xFF;
00043   *(p++) = (a >> 8) & 0xFF;
00044   *(p++) =  a & 0xFF;
00045   length_ +=4;
00046 }
00047 
00048 void PacketHdr::setShortIntegerInfo(short b, int position)
00049 {
00050   unsigned char *p = info_ + position;
00051   *(p++) =  b >> 8;
00052   *(p++) =  b & 0xFF;
00053   length_+=2;
00054 }
00055 
00056 
00057 //=================================================================
00058 //  Packet Class
00059 
00060 Packet::Packet()
00061 {
00062   size_ = 0;
00063   length_ = DEFAULT_PAYLOAD_SIZE;
00064   payload_ = new char[DEFAULT_PAYLOAD_SIZE];
00065   header_ = new PacketHdr();
00066 }
00067 
00073 Packet::Packet(int buffer_length)
00074 {
00075   size_ = 0;
00076   length_ = buffer_length;
00077   payload_ = new char[buffer_length];
00078   header_ = new PacketHdr();
00079 }
00080 
00091 void Packet::setPayloadSize(int size)
00092 {
00093   size_ =  size;
00094   if (size > length_) {
00095     if (payload_ != NULL) delete [] payload_;
00096     length_ = (int)(1.5 * size);
00097     payload_ =  new char[length_];
00098   }
00099 }
00100 
00105 int Packet::fillPayload(int size, char *inputstream)
00106 {
00107   setPayloadSize(size);
00108   if (memcpy((char *)payload_, (char *)inputstream,  size) == NULL) {
00109     throw "Fill payload Failed";
00110   }
00111   return 0;
00112 }
00113 
00118 int Packet::makePacket( char *streambuf )
00119 {
00120   streambuf[0]= ( header_->getSize() ) & 0xff;
00121   streambuf[1]=  0x00;
00122   memcpy(streambuf+1, header_->accessInfo(), header_->getSize());
00123   memcpy(streambuf+1+header_->getSize(), payload_, size_);
00124   
00125   return 1+size_+ header_->getSize();
00126 }
00127 
00131 void Packet::extractHeader( char *streambuf )
00132 {
00133   char* p= streambuf; 
00134   int a  = *(p++);
00135   header_->setHeaderSize(a);
00136   memcpy( header_->accessInfo(), p ,a);   
00137 }
00138 
00139 
00140 // =========================================================================
00141 // Address Class
00142 
00143 Address::Address():port_(-1)
00144 {   
00145   hostname_[0] = '\0';  
00146   macaddr_[0] = '\0';
00147 }
00148 
00149 Address::Address(const char* hostname, short port)
00150 { 
00151    setPort(port); 
00152    setHostname(hostname);
00153 }
00154 
00161 void Address::setHWAddrFromColonFormat(const char* colonmac)
00162 {  
00163   char HexChar;
00164   //First verify the address
00165   int Count  = 0;
00166   int num_mac_char = 0;
00167   /* Two ASCII characters per byte of binary data */
00168   bool error_end = false;
00169   while (!error_end)
00170     { /* Scan string for first non-hex character.  Also stop scanning at end
00171          of string (HexChar == 0), or when out of six binary storage space */
00172       HexChar = (char)colonmac[Count++];
00173       if (HexChar == ':') continue;     
00174       if (HexChar > 0x39) HexChar = HexChar | 0x20;  /* Convert upper case to lower */
00175       if ( (HexChar == 0x00) || num_mac_char  >= (MAC_ADDR_LENGTH * 2) ||
00176            (!(((HexChar >= 0x30) && (HexChar <= 0x39))||  /* 0 - 9 */
00177              ((HexChar >= 0x61) && (HexChar <= 0x66))) ) ) /* a - f */ 
00178         {
00179           error_end = true;
00180         } else 
00181             num_mac_char++;
00182     }
00183   if (num_mac_char != MAC_ADDR_LENGTH * 2 )
00184     throw "Given Wrong MAC address Format.";
00185 
00186   // Conversion
00187   unsigned char HexValue = 0x00;
00188   Count = 0;
00189   num_mac_char = 0;
00190   int mac_byte_num = 0;
00191   while (mac_byte_num < MAC_ADDR_LENGTH )
00192     {
00193       HexChar = (char)colonmac[Count++];
00194       if (HexChar == ':') continue;
00195       num_mac_char++;  // locate a HEX character
00196       if (HexChar > 0x39)
00197         HexChar = HexChar | 0x20;  /* Convert upper case to lower */
00198       HexChar -= 0x30;
00199       if (HexChar > 0x09)  /* HexChar is "a" - "f" */
00200         HexChar -= 0x27;
00201       HexValue = (HexValue << 4) | HexChar;
00202       if (num_mac_char % 2  == 0 ) /* If we've converted two ASCII chars... */
00203         {
00204           macaddr_[mac_byte_num] = HexValue;
00205           HexValue = 0x0;
00206           mac_byte_num++;
00207         }
00208     }  
00209   return;   
00210 }
00211 
00212 
00216 char *Address::convertHWAddrToColonFormat()
00217 {
00218   char *colonformat =  new char[17];
00219   //printf("HW Address: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",u[0], u[1], u[2], u[3], u[4], u[5]);
00220   sprintf(colonformat,"%02X:%02X:%02X:%02X:%02X:%02X",
00221           macaddr_[0],macaddr_[1],macaddr_[2],macaddr_[3],macaddr_[4],macaddr_[5]);
00222   // cout << colonformat << endl;
00223   return colonformat;
00224 
00225 }
00226 
00230 void Address::setHWAddr(unsigned char* hwaddr)
00231 {
00232   memcpy(macaddr_, hwaddr , MAC_ADDR_LENGTH*sizeof(unsigned char));
00233 }
00234 
00239 bool Address::isSameMACAddr( Address *addr)
00240 {
00241   if ( memcmp(macaddr_, addr->getHWAddr(), MAC_ADDR_LENGTH*sizeof(unsigned char))  == 0 )
00242            return true;
00243   return false;
00244 
00245 }
00246 
00247 Address* Address::clone()
00248 {
00249   Address * ad =  new Address(hostname_, port_);
00250   ad->setHWAddr(macaddr_);
00251   return ad;
00252 }
00253 
00254 //===============================================================
00255 // Port Class
00256 
00261 Port::Port():sockfd_(0)
00262 {
00263 }
00264 
00265 void Port::setAddress(Address* addr)
00266 {
00267   setHostname(addr->getHostname());
00268   setPort(addr->getPort());
00269 }
00270 
00271 void Port::setRemoteAddress(Address* daddr)
00272 {
00273   setRemoteHostname(daddr->getHostname());
00274   setRemotePort(daddr->getPort());
00275 }
00276 
00285 struct sockaddr * Port::setSockAddress(Address *addr, struct sockaddr_in *address)
00286 {
00287   char *hostname;
00288   int port;
00289   unsigned int tmp;
00290   struct hostent *hp;
00291 
00292   hostname = addr->getHostname();
00293   port = addr->getPort();
00294 
00295   address->sin_family = AF_INET;
00296   address->sin_port   = htons((short)port);
00297       
00298   if (strcmp(hostname, "") == 0) {
00299     address->sin_addr.s_addr = htonl(INADDR_ANY);  
00300   } 
00301   else {
00302     //tmp = inet_addr(hostname);  // If an IP address is given
00303     tmp = inet_aton(hostname, &(address->sin_addr));
00304     //if(tmp != (unsigned long) INADDR_NONE){    
00305     //  address->sin_addr.s_addr = tmp;  
00306     //}
00307     if (tmp == 0) 
00308     {  // if a hostname is passed, call DNS
00309       if ((hp = gethostbyname(hostname)) == NULL) {
00310         herror("gethostbyname");
00311         throw "Error in Resolving hostname!" ;                           
00312       }
00313       memcpy((char *)&address->sin_addr, (char *)hp->h_addr, hp->h_length);
00314     }
00315   }
00316   return (sockaddr*)address;
00317 }
00318 
00323 void Port::decodeSockAddress(Address *addr, struct sockaddr_in *address)
00324 {
00325   addr->setHostname(inet_ntoa(address->sin_addr));
00326   addr->setPort(ntohs(address->sin_port));  
00327 }
00328 
00329 
00330 
00331 //==========================================================
00332 // Sending Port Class
00333 
00334 
00335 SendingPort::SendingPort(): Port(),bcastflag_(0)
00336 {
00337   setHostname("localhost"); 
00338   setPort(DEFAULT_SEND_PORT);  
00339   // setRemoteHostname("internal2");  
00340 }
00341 
00342 
00343 SendingPort::SendingPort(char *hostname, short port):Port(),bcastflag_(0)
00344 {
00345   setHostname(hostname);
00346   setPort(port);
00347   //setRemotePort(DEFAULT_RECV_PORT); 
00348 }
00349 
00363 void SendingPort::init()
00364 {
00365   //"0" shows the sockfd is uninitialized, -1 means error
00366   if (sockfd_ != 0) {
00367     cout << "socket has not been properly initialized!" << endl;
00368     return;
00369   }
00370   if ( myaddr_.isSet() == false) {
00371     setHostname("localhost");
00372     setPort(DEFAULT_SEND_PORT);
00373   }
00374   //check if itsaddr_ is set
00375   if ( itsaddr_.isSet() == false)
00376     throw "Destination address of a sending port is not set!";
00377 
00378   if ((sockfd_ = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00379     perror("socket");
00380     throw "Error while opening a UDP socket";
00381   }
00382   Address *emptyAddr = new Address("", myaddr_.getPort());
00383   struct sockaddr* addr = setSockAddress(emptyAddr, &mySockAddress_);
00384   if (  bind(sockfd_, addr, sizeof(struct sockaddr_in))  < 0 ){
00385     perror("bind");
00386     throw "Scoket Bind Error";
00387   }
00388    
00389   if (bcastflag_ == 1) 
00390     if (setsockopt(sockfd_,SOL_SOCKET,SO_BROADCAST,&bcastflag_,sizeof(bcastflag_)) == -1   )
00391          {
00392            perror("setsockopt");
00393            throw "Set broadcast option failed.";
00394          }; 
00395 
00396   //create sending buffer
00397   sendingbuf_ = new char[MTU_SIZE+1];
00398   return; 
00399 
00400 }
00401 
00407 void SendingPort::sendPacket(Packet* pkt)
00408 {  
00409    int pktlen = pkt->makePacket(sendingbuf_); 
00410    Address *dst = getRemoteAddr();
00411    int  length = sizeof(struct sockaddr_in); 
00412    struct sockaddr *dest = setSockAddress(dst, &dstSockAddress_);
00413    int len = sendto(sockfd_, sendingbuf_, pktlen, 0, dest, length); 
00414    if (len == -1) 
00415    { 
00416          perror("send");
00417          throw "Sending Error.";
00418    }
00419 }
00420 
00421 
00422 //====================================================================
00423 // Functions of ReceivingPort class
00428 ReceivingPort::ReceivingPort(): Port()
00429 {
00430   pkt_= new Packet(MAXBUFLENGTH);
00431 }
00432 
00447 void ReceivingPort::init()
00448 { 
00449   if (sockfd_ != 0) {
00450     return;
00451   }
00452   if ( myaddr_.isSet() == false) {
00453     setHostname("localhost");
00454     setPort(DEFAULT_RECV_PORT);
00455   }
00456   
00457   if ((sockfd_ = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00458     throw "Error while opening UDP socket of a receiver";
00459   }
00460   Address *emptyAddr = new Address("", myaddr_.getPort());
00461   struct sockaddr* addr = setSockAddress(emptyAddr, &mySockAddress_);
00462   if (  bind(sockfd_, addr, sizeof(struct sockaddr_in))  < 0 ){
00463     throw "Scoket Bind Error occured in an UDP receiver";
00464   }
00465   //cout << "binding to port: " << myaddr_.getPort() << "......" << endl;
00466   // needs a dummy buffer for storing packets
00467   tmpBuffer_ =  new char[MAXBUFLENGTH];
00468 }
00469 
00483 Packet* ReceivingPort::receivePacket()
00484 {
00485   struct sockaddr_in tmpSockAddr;
00486   int length = sizeof(struct sockaddr);
00487   int len = (int)recvfrom(sockfd_, tmpBuffer_, MAXBUFLENGTH, 0, (struct sockaddr*)&tmpSockAddr,(socklen_t *)&length); 
00488   if (len == -1) 
00489   {
00490            perror("recvfrom");
00491            return false;
00492   }         
00493   decodeSockAddress( &itsaddr_, &tmpSockAddr);
00494   pkt_->extractHeader(tmpBuffer_);
00495   //tmpBuffer_ point shall not be moved,it will reused by the receiving port.
00496   pkt_->fillPayload(len-1-pkt_->getHeaderSize(), tmpBuffer_+pkt_->getHeaderSize()+1 );
00497   return pkt_;
00498 }
00499  
00500 //===================================================================
00501 //    LossyReceivingPort class
00505 LossyReceivingPort::LossyReceivingPort(float lossyratio): ReceivingPort(), loss_ratio_(lossyratio)
00506 {
00507 }
00508 
00512 Packet* LossyReceivingPort::receivePacket()
00513 {   
00514   Packet *p = ReceivingPort::receivePacket();
00515   float  x;
00516   // Set evil seed (initial seed)
00517   srand( (unsigned)time( NULL ) );
00518   x = (double) rand()/RAND_MAX;
00519   if ( x <= loss_ratio_) 
00520     return NULL;
00521   else
00522     return p;
00523 }

Generated on Fri Feb 9 12:49:37 2007 for Common_Classes_Projects_ECE544 by  doxygen 1.4.6