00001
00002
00003 #include <string.h>
00004 #include <unistd.h>
00005 #include "gmain.h"
00006
00007 #ifdef gDOS_SPEC
00008 #include <winsock2.h>
00009 #else
00010 #include <sys/socket.h>
00011 #include <netdb.h>
00012 #include <arpa/inet.h>
00013 #endif //gDOS_SPEC (~)
00014
00015 #include <errno.h>
00016
00017 #include "gnet.h"
00018
00019
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
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
00197
00198
00199
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
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
00301 if ( (uMask & 1)==0 ) return 2;
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
00406 sprintf(sBuf,"%s#%d",sockKind==e_TCP?"TCP":"UDP",sockCount);
00407 }
00408 else {
00409
00410
00411
00412
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
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
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
00506 memset( uBuf, 0x0, (size_t)nBytes );
00507
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
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
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
00661 aSocket.SetConnection( destAddr );
00662
00663 return 0;
00664 }
00665
00666