gnet.cpp

Go to the documentation of this file.
00001 // gnet.cpp -- Version 0.3
00002 
00003 #include <string.h>
00004 #include <unistd.h>      //close...etc
00005 #include "gmain.h"
00006 
00007 #ifdef gDOS_SPEC
00008 #include <winsock2.h>
00009 #else
00010 #include <sys/socket.h>  //socket... (sys/types.h)
00011 #include <netdb.h>       //gethostbyname...etc
00012 #include <arpa/inet.h>   //inet_addr...
00013 #endif //gDOS_SPEC (~)
00014 
00015 #include <errno.h>
00016 
00017 #include "gnet.h"
00018 
00019 // Static members
00020 int gSocket::sockCount=0;
00021 
00022 ////////////////////////////////////////////////////////////
00023 gIpAddr::gIpAddr (char* ipStr)
00024     : b1( 0 ),
00025       b2( 0 ),
00026       b3( 0 ),
00027       b4( 0 )
00028 {
00029  if ( ipStr!=nil ) SetAddrFromStr( ipStr );
00030 }
00031 
00032 gIpAddr::gIpAddr (t_uint8 c1, t_uint8 c2, t_uint8 c3, t_uint8 c4)
00033     : b1( c1 ),
00034       b2( c2 ),
00035       b3( c3 ),
00036       b4( c4 )
00037 {
00038 }
00039 
00040 gIpAddr::~gIpAddr ()
00041 {
00042 }
00043 
00044 bool gIpAddr::IsOk ()
00045 {
00046  return (b1 | b2 | b3 | b4)!=0;
00047 }
00048 
00049 t_uchar* gIpAddr::String ()
00050 {
00051  gString sTemp( 30, ' ' );
00052  addrStr = sTemp;
00053  sprintf( addrStr.Str(), "%u.%u.%u.%u", b1, b2, b3, b4 );
00054  return (t_uchar*)addrStr.Str();
00055 }
00056 
00057 t_uchar* gIpAddr::ToString (t_uchar* uBuf)
00058 {
00059  t_uchar* uStr = String();
00060  if ( uBuf==nil ) return uStr;
00061  strcpy( (char*)uBuf, (char*)uStr );
00062  return uBuf;
00063 }
00064 
00065 void gIpAddr::Reset ()
00066 {
00067  gControl::Reset();
00068  b1 = b2 = b3 = b4 = 0;
00069 }
00070 
00071 void gIpAddr::SetAddr (t_gIpAddr nboAddr)
00072 {
00073  b4 = nboAddr & 0xFF;
00074  nboAddr >>= 8;
00075  b3 = nboAddr & 0xFF;
00076  nboAddr >>= 8;
00077  b2 = nboAddr & 0xFF;
00078  nboAddr >>= 8;
00079  b1 = nboAddr & 0xFF;
00080  nboAddr >>= 8;
00081  ASSERTION(nboAddr==0,"nboAddr>32bit?");
00082 }
00083 
00084 
00085 bool gIpAddr::SetAddrFromStr (char* str)
00086 {
00087  int a1=-1, a2=-1, a3=-1, a4=-1;
00088  ASSERTION(str!=nil,"str!=nil");
00089  Reset();
00090  lastOpError = sscanf(str,"%d.%d.%d.%d",&a1,&a2,&a3,&a4);
00091  lastOpError = -1*(lastOpError!=4);
00092  if ( lastOpError!=0 ) return false;
00093  lastOpError = a1<0 || a1>255;
00094  lastOpError += a2<0 || a2>255;
00095  lastOpError += a3<0 || a3>255;
00096  lastOpError += a4<0 || a4>255;
00097  lastOpError = -lastOpError;
00098  if ( lastOpError!=0 ) return false;
00099  b1 = (t_uint8)a1;
00100  b2 = (t_uint8)a2;
00101  b3 = (t_uint8)a3;
00102  b4 = (t_uint8)a4;
00103  return true;
00104 }
00105 
00106 t_gIpAddr gIpAddr::GetNetworkAddress ()
00107 {
00108  unsigned long nBO = thisGetIP( b1, b2, b3, b4 );
00109  return (t_gIpAddr)nBO;
00110 }
00111 
00112 int gIpAddr::GetHostByName (char* hostname)
00113 {
00114  struct hostent* hp=nil;
00115  ASSERTION(hostname!=nil,"hostname!=nil");
00116  Reset();
00117 #ifdef gSUPPRESS_INET
00118  ASSERTION_FALSE("gSUPPRESS_INET: gethostbyname");
00119 #else
00120  hp = gethostbyname( hostname );
00121 #endif
00122  lastOpError = hp==nil;
00123  if ( lastOpError!=0 ) {
00124      SetError( errno );
00125      return -1;
00126  }
00127  char** hAddr;
00128  hAddr = &hp->h_addr;
00129  thisSetIPfromHostEnt( hAddr, hp->h_length );
00130  return 0;
00131 }
00132 
00133 int gIpAddr::GetHostByAddr (gString& sRes)
00134 {
00135  gList lRes;
00136  return thisGetHostByAddr( (char*)String(), sRes, lRes );
00137 }
00138 
00139 gIpAddr& gIpAddr::operator= (gIpAddr& copy)
00140 {
00141  b1 = copy.b1;
00142  b2 = copy.b2;
00143  b3 = copy.b3;
00144  b4 = copy.b4;
00145  return *this;
00146 }
00147 
00148 void gIpAddr::Show (bool doShowAll)
00149 {
00150  printf("%s%s",String(),doShowAll?"\n":"\0");
00151 }
00152 
00153 unsigned long gIpAddr::thisGetIP (t_uint8 a1, t_uint8 a2, t_uint8 a3, t_uint8 a4)
00154 {
00155  unsigned long result;
00156  result = a1;
00157  result <<= 8;
00158  result += a2;
00159  result <<= 8;
00160  result += a3;
00161  result <<= 8;
00162  result += a4;
00163  return result;
00164 }
00165 
00166 unsigned long gIpAddr::thisGetHostByteOrder (t_gIpAddr netByteOrder)
00167 {
00168 #ifdef gSUPPRESS_INET
00169  ASSERTION_FALSE("gSUPPRESS_INET: ntohl");
00170  return 0UL;
00171 #else
00172  unsigned long result = ntohl( (unsigned long)netByteOrder );
00173  return result;
00174 #endif
00175 }
00176 
00177 int gIpAddr::thisSetIPfromHostByteOrder (in_addr_t hostByteOrder)
00178 {
00179 #ifdef gSUPPRESS_INET
00180  ASSERTION_FALSE("gSUPPRESS_INET: htonl");
00181 #else
00182  unsigned long nBO = htonl( hostByteOrder );
00183  // nBO is the network-byte-order
00184  SetAddr( (t_gIpAddr)nBO );
00185 #endif
00186  return 0;
00187 }
00188 
00189 int gIpAddr::thisSetIPfromHostEnt (char* h_addr, int h_length)
00190 {
00191  struct sockaddr_in hostAddressData;
00192 
00193  ASSERTION(h_addr!=nil,"h_addr!=nil");
00194  memset( (char*)&hostAddressData, 0, sizeof(hostAddressData) );
00195  memcpy( &hostAddressData.sin_addr, h_addr, h_length );
00196  // Acc. netinet/in.h;
00197  // typedef uint32_t in_addr_t;
00198  // struct in_addr {
00199  //     in_addr_t s_addr;
00200  // };
00201  in_addr_t hostByteOrder = hostAddressData.sin_addr.s_addr;
00202  return thisSetIPfromHostByteOrder( hostByteOrder );
00203 }
00204 
00205 int gIpAddr::thisGetHostByAddr (char* ipStr, gString& sRes, gList& lRes)
00206 {
00207  struct hostent* hp=nil;
00208  char* inAddrTmp;
00209  char* str;
00210  char** pStr;
00211  struct in_addr hardInAddr;
00212 
00213  ASSERTION(ipStr!=nil,"ipStr!=nil");
00214  memset( &hardInAddr, 0x0, sizeof(hardInAddr) );
00215  inAddrTmp = (char*)&hardInAddr;
00216 
00217 #ifdef gSUPPRESS_INET
00218  ASSERTION_FALSE("gSUPPRESS_INET: inet_addr");
00219 #else
00220  hardInAddr.s_addr = inet_addr( ipStr );
00221  if ( hardInAddr.s_addr==INADDR_NONE ) {
00222      return SetError( 2 );
00223  }
00224  hp = gethostbyaddr( inAddrTmp, sizeof(hardInAddr), AF_INET );
00225  if ( hp==nil ) {
00226      return SetError( -1 );
00227  }
00228  sRes.Set( (char*)hp->h_name );
00229  // Aliases for host
00230  pStr = hp->h_aliases;
00231  while ( (str = *pStr)!=nil ) {
00232      pStr++;
00233      lRes.Add( str );
00234  }
00235 #endif //gSUPPRESS_INET (~)
00236  return 0;
00237 }
00238 ////////////////////////////////////////////////////////////
00239 gIpV4Mask::gIpV4Mask (t_uint32 aMask)
00240     :  nBitsCIDR( 0 ), mask( aMask )
00241 {
00242  thisSetNBitsFromMask( aMask );
00243 }
00244 
00245 gIpV4Mask::gIpV4Mask (t_uint8 bitsCIDR)
00246     : nBitsCIDR( bitsCIDR ),
00247       mask( 0xFFFFFFFF )
00248 {
00249  SetBitsCIDR( bitsCIDR );
00250 }
00251 
00252 gIpV4Mask::gIpV4Mask (gIpV4Mask::eClass addrClass)
00253     : mask( 0 )
00254 {
00255  switch ( addrClass ) {
00256  case e_ClassA:
00257      SetBitsCIDR( 8 );
00258      break;
00259  case e_ClassB:
00260      SetBitsCIDR( 16 );
00261      break;
00262  case e_ClassC:
00263      SetBitsCIDR( 24 );
00264      break;
00265  default:
00266      ASSERTION_FALSE("gIpV4Mask(addrClass)");
00267      break;
00268  }
00269 }
00270 
00271 gIpV4Mask::~gIpV4Mask ()
00272 {
00273 }
00274 
00275 void gIpV4Mask::SetBitsCIDR (t_uint8 bitsCIDR)
00276 {
00277  ASSERTION(bitsCIDR<=32,"bitsCIDR<=32");
00278  nBitsCIDR = bitsCIDR;
00279  mask = 0xFFFFFFFF;
00280  if ( bitsCIDR<32 ) {
00281      mask >>= bitsCIDR;
00282      mask ^= 0xFFFFFFFF;
00283  }
00284 }
00285 
00286 int gIpV4Mask::thisSetNBitsFromMask (t_uint32 aMask)
00287 {
00288  t_uint16 shiftCount( 0 ), maxCount( 0 );
00289  t_uint32 uMask( aMask );
00290 
00291  nBitsCIDR = 0;
00292  mask = 0xFFFFFFFF;
00293  for ( ; shiftCount<32 && (uMask & 1)==0; shiftCount++) {
00294      uMask >>= 1;
00295  }
00296 
00297  if ( shiftCount>=32 ) return 1;
00298 
00299  for (maxCount=shiftCount; maxCount<32; maxCount++) {
00300      //printf("DBG: 0x%08lX, shiftCount=%u\n",(unsigned long)uMask,maxCount);
00301      if ( (uMask & 1)==0 ) return 2;  // Invalid mask!
00302      uMask >>= 1;
00303  }
00304 
00305  nBitsCIDR = 32-(t_uint8)shiftCount;
00306  mask = aMask;
00307 
00308  return 0;
00309 }
00310 ////////////////////////////////////////////////////////////
00311 gHostAddr::gHostAddr (char* hostStr)
00312     : destHostStr( hostStr )
00313 {
00314  GetHostByName( hostStr );
00315 }
00316 
00317 gHostAddr::gHostAddr (t_uint8 c1, t_uint8 c2, t_uint8 c3, t_uint8 c4)
00318     : gIpAddr( c1, c2, c3, c4 )
00319 {
00320 }
00321 
00322 gHostAddr::gHostAddr (gIpAddr& ipAddr)
00323     : gIpAddr( ipAddr.GetB1(), ipAddr.GetB2(), ipAddr.GetB3(), ipAddr.GetB4() )
00324 {
00325 }
00326 
00327 gHostAddr::~gHostAddr ()
00328 {
00329 }
00330 
00331 bool gHostAddr::IsOk ()
00332 {
00333  return gIpAddr::IsOk();
00334 }
00335 
00336 t_uchar* gHostAddr::String ()
00337 {
00338  if ( gIpAddr::IsOk() ) return gIpAddr::String();
00339  return (t_uchar*)destHostStr.Str();
00340 }
00341 
00342 bool gHostAddr::SetHostName (char* hostStr)
00343 {
00344  destHostStr.SetEmpty();
00345  if ( hostStr==nil || hostStr[0]==0 ) return false;
00346  destHostStr.Set( hostStr );
00347  return true;
00348 }
00349 
00350 void gHostAddr::Show (bool doShowAll)
00351 {
00352  if ( doShowAll==false ) {
00353      gIpAddr::Show( false );
00354  }
00355  printf("%s:%s\n",destHostStr.Str(),String());
00356 }
00357 ////////////////////////////////////////////////////////////
00358 gSocket::gSocket (int socketHandle, eSocketKind socketKind)
00359     : gInt( socketHandle ),
00360       sockKind( socketKind ),
00361       hostConnected( nil )
00362 {
00363  bool isFirst = sockCount==0;
00364 
00365  if ( isFirst ) {
00366      gStorageControl::Self().RegisterService( "socket", STG_SVC_KND_SOCK, STG_SVC_IDX_SOCK );
00367      gStorageControl::Self().ServiceAlloc( "socket" );
00368  }
00369 
00370  sockCount++;
00371 }
00372 
00373 gSocket::~gSocket ()
00374 {
00375  delete hostConnected;
00376  hostConnected = nil;
00377 }
00378 
00379 bool gSocket::IsOk ()
00380 {
00381  return IsOpened() && IsConnected();
00382 }
00383 
00384 bool gSocket::IsOpened ()
00385 {
00386  return c>0;
00387 }
00388 
00389 int gSocket::Handle ()
00390 {
00391  ASSERTION(IsOpened(),"IsOpened()");
00392  return c;
00393 }
00394 
00395 bool gSocket::IsConnected ()
00396 {
00397  return hostConnected!=nil;
00398 }
00399 
00400 bool gSocket::Open (t_uchar* uName)
00401 {
00402  char sBuf[50];
00403 
00404  if ( uName==nil ) {
00405      // 'Invent' one string
00406      sprintf(sBuf,"%s#%d",sockKind==e_TCP?"TCP":"UDP",sockCount);
00407  }
00408  else {
00409      // The code below induces problems
00410      //strncpy( sBuf, (char*)uName, 49 );
00411      //uName[49] = 0;
00412      // (not used due to bug of glibc)
00413      ASSERTION(strlen((char*)uName)+1<50,"Node-name too long");
00414      strcpy( sBuf, (char*)uName );
00415  }
00416 
00417 #ifdef DEBUG
00418  {
00419      sServiceRegister* pSvc = gStorageControl::Self().GetServicePtr("socket");
00420      printf("DBG: [%s|%s] index=%d, used=%d\n",
00421             uName, "<>",
00422             pSvc->data->pNodes[0].index,
00423             pSvc->data->pNodes[0].used);
00424  }
00425 #endif //DEBUG
00426 
00427 #ifdef gSUPPRESS_INET
00428  c = -1;
00429  ASSERTION_FALSE("gSUPPRESS_INET: socket");
00430 #else
00431  c = socket( AF_INET, SOCK_STREAM, 0 );
00432 #endif
00433  if ( c<0 ) return false;
00434 
00435  sServiceNode aNode;
00436  aNode.used = (short)sockKind;
00437  aNode.handle = c;
00438  strcpy( aNode.shortName, sBuf );
00439  aNode.pStorage = this;
00440  gStorageControl::Self().ServiceAdd( "socket", aNode );
00441 
00442  return true;
00443 }
00444 
00445 bool gSocket::Close ()
00446 {
00447  if ( c<=0 ) return false;
00448  close( c );
00449  c = -1;
00450  return gStorageControl::Self().ServiceDelete( "socket", this );
00451 }
00452 
00453 bool gSocket::SetConnection (gIpAddr& ipAddr)
00454 {
00455  // Set connection twice? Return false
00456  if ( IsOk() ) return false;
00457  hostConnected = new gHostAddr( ipAddr );
00458  ASSERTION(hostConnected!=nil,"hostConnected!=nil");
00459  return hostConnected->IsOk();
00460 }
00461 
00462 bool gSocket::SetConnection (gHostAddr& hostAddr)
00463 {
00464  bool isOk;
00465  gIpAddr ipAddr( hostAddr.GetB1(), hostAddr.GetB2(), hostAddr.GetB3(), hostAddr.GetB4() );
00466  isOk = SetConnection( ipAddr );
00467  if ( isOk==false ) return false;
00468  return hostConnected->SetHostName( hostAddr.GetHostName() );
00469 }
00470 ////////////////////////////////////////////////////////////
00471 gNetConnect::gNetConnect ()
00472 {
00473 }
00474 
00475 gNetConnect::~gNetConnect ()
00476 {
00477 }
00478 
00479 bool gNetConnect::Read (t_uchar& c)
00480 {
00481  static t_uchar uChr;
00482  ssize_t nOctetsRead;
00483  // In DOS, 'recv' is used often
00484 #ifdef gDOS_SPEC
00485  static char cChr;
00486  nOctetsRead = recv( Handle(), &cChr, 1, 0 );
00487  uChr = (t_uchar)cChr;
00488 #else
00489  nOctetsRead = read( Handle(), &uChr, 1 );
00490 #endif //gDOS_SPEC (~)
00491  if ( nOctetsRead==1 ) {
00492      c = uChr;
00493      lastOpError = 0;
00494      return true;
00495  }
00496  SetError( errno );
00497  return false;
00498 }
00499 
00500 bool gNetConnect::Read (t_uchar* uBuf, unsigned nBytes)
00501 {
00502  ssize_t nOctetsRead;
00503  lastOpError = 0;
00504  if ( nBytes==0 ) return true;
00505  // Always initialize memory
00506  memset( uBuf, 0x0, (size_t)nBytes );
00507  // Read from socket
00508 #ifdef gDOS_SPEC
00509  nOctetsRead = recv( Handle(), (char*)uBuf, (size_t)nBytes, 0 );
00510 #else
00511  nOctetsRead = read( Handle(), uBuf, (size_t)nBytes );
00512  DBGPRINT("DBG: read(%d)=%u\n",(unsigned)nBytes,(int)nOctetsRead);
00513 #endif //gDOS_SPEC (~)
00514  if ( nOctetsRead==(ssize_t)nBytes ) return true;
00515  SetError( errno );
00516  return false;
00517 }
00518 
00519 bool gNetConnect::ReadLine (gString& s)
00520 {
00521  static t_uchar uChr;
00522 
00523  s.SetEmpty();
00524  for ( ; Read( uChr )==true; ) {
00525      if ( uChr=='\r' ) continue;
00526      if ( uChr=='\n' ) return true;
00527      s.Add( uChr );
00528  }
00529  return false;
00530 }
00531 
00532 int gNetConnect::Write (char* s)
00533 {
00534  return Write( s, strlen(s) );
00535 }
00536 
00537 int gNetConnect::Write (gString& s)
00538 {
00539  return Write( s.Str(), s.Length() );
00540 }
00541 
00542 int gNetConnect::Write (char* s, unsigned nOctets)
00543 {
00544  ssize_t nOctetsWritten, nOctetsToWrite = (ssize_t)nOctets;;
00545  ASSERTION(s!=nil,"s!=nil");
00546  if ( nOctets==0 ) return 0;
00547  // In DOS, 'send' is used often
00548 #ifdef gDOS_SPEC
00549  nOctetsWritten = send( Handle(), s, nOctets, 0 );
00550 #else
00551  nOctetsWritten = write( Handle(), s, nOctets );
00552 #endif //gDOS_SPEC (~)
00553  if ( nOctetsWritten==nOctetsToWrite ) {
00554      return lastOpError = 0;
00555  }
00556  return SetError( errno );
00557 }
00558 ////////////////////////////////////////////////////////////
00559 gTcpConnect::gTcpConnect (char* destHostname, t_gPort cPort, bool doConnect)
00560     : destAddr( destHostname ),
00561       destPort( cPort ),
00562       socket( 0, gSocket::e_TCP )
00563 {
00564  SetError( destAddr.lastOpError );
00565  if ( lastOpError==0 && doConnect==true ) Connect();
00566 }
00567 
00568 gTcpConnect::gTcpConnect (t_uint8 c1, t_uint8 c2, t_uint8 c3, t_uint8 c4, t_gPort cPort, bool doConnect)
00569     : destAddr( c1, c2, c3, c4 ),
00570       destPort( cPort ),
00571       socket( 0, gSocket::e_TCP )
00572 {
00573  lastOpError = destAddr.IsOk();
00574  if ( lastOpError==0 && doConnect==true ) Connect();
00575 }
00576 
00577 gTcpConnect::~gTcpConnect ()
00578 {
00579  socket.Close();
00580 }
00581 
00582 bool gTcpConnect::IsOk ()
00583 {
00584  return socket.IsOpened();
00585 }
00586 
00587 int gTcpConnect::Handle ()
00588 {
00589  int fd;
00590  // CHECK: assert: socket must be opened&valid
00591  fd = socket.Handle();
00592  ASSERTION(IsOk(),"gTcpConnect::Handle (1)");
00593  ASSERTION(fd>=0,"gTcpConnect::Handle (2)");
00594  return fd;
00595 }
00596 
00597 t_uchar* gTcpConnect::String ()
00598 {
00599  return destAddr.String();
00600 }
00601 
00602 t_uchar* gTcpConnect::ToString (t_uchar* uBuf)
00603 {
00604  t_uchar* uStr = String();
00605  if ( uBuf==nil ) return uStr;
00606  strcpy( (char*)uBuf, (char*)uStr );
00607  return uBuf;
00608 }
00609 
00610 bool gTcpConnect::Connect ()
00611 {
00612  bool isOk;
00613  int error;
00614  isOk = socket.IsOpened()==false;
00615  if ( isOk==false ) {
00616      SetError( -1 );
00617      return false;
00618  }
00619  isOk = socket.Open( String() );
00620  if ( isOk==false ) return false;
00621  error = thisConnect( socket );
00622  isOk = error==0;
00623  return isOk;
00624 }
00625 
00626 bool gTcpConnect::Close ()
00627 {
00628  return socket.Close();
00629 }
00630 
00631 void gTcpConnect::Show (bool doShowAll)
00632 {
00633  printf("IP:%s%s\n",
00634         String(),
00635         doShowAll ?
00636         (socket.IsOpened() ? "[opened]" : "[closed]")
00637         :
00638         "\0");
00639 }
00640 
00641 int gTcpConnect::thisConnect (gSocket& aSocket)
00642 {
00643  int socketId = aSocket.Handle();
00644  struct sockaddr_in toHostAddressData;
00645  int sizeofAddrData = sizeof(toHostAddressData);
00646 
00647 #ifdef gSUPPRESS_INET
00648  lastOpError = -1;
00649  ASSERTION_FALSE("gSUPPRESS_INET: connect");
00650 #else
00651  memset( (char*)&toHostAddressData, 0, sizeofAddrData );
00652  toHostAddressData.sin_family = AF_INET;
00653  toHostAddressData.sin_addr.s_addr = destAddr.GetHostAddress();
00654  toHostAddressData.sin_port = htons( destPort );
00655 
00656  lastOpError = connect( socketId, (struct sockaddr*)&toHostAddressData, sizeofAddrData )!=0;
00657 #endif //gSUPPRESS_INET (~)
00658  if ( lastOpError!=0 ) return SetError( errno );
00659 
00660  // Inform the socket to whom the connection was established
00661  aSocket.SetConnection( destAddr );
00662 
00663  return 0;
00664 }
00665 ////////////////////////////////////////////////////////////
00666 

Generated on Sat Aug 18 02:40:57 2007 for xpfweb_v2x lib by  doxygen 1.4.2