00001 #ifndef PLATFORM_APERIOS
00002 #include "netstream.h"
00003 #include <iostream>
00004 #include <sstream>
00005
00006 using namespace std;
00007
00008 const IPaddr IPaddr::ANY(INADDR_ANY);
00009 const IPaddr IPaddr::BROADCAST(INADDR_BROADCAST);
00010
00011 const unsigned int IPaddr::maxHostNameLen = 256;
00012
00013 IPaddr::IPaddr() : server(), ipname(), ipport(0) { Init(); }
00014
00015 IPaddr::IPaddr(const ipnum_t& num) : server(), ipname(), ipport(0) { Init(); set_num(num); }
00016
00017 IPaddr::IPaddr(const ipname_t& name) : server(), ipname(), ipport(0) { Init(); set_name(name); }
00018
00019 IPaddr::IPaddr(const ipnum_t& num, const ipport_t& port) : server(), ipname(), ipport(0) { Init(); set_addr(num,port); }
00020
00021 IPaddr::IPaddr(const ipname_t& name, const ipport_t& port) : server(), ipname(), ipport(0) { Init(); set_addr(name,port); }
00022
00023 bool IPaddr::set_num(const ipnum_t& num) {
00024 if(get_num()!=num) {
00025 Init();
00026 server.sin_family = AF_INET;
00027 server.sin_addr.s_addr = htonl(num);
00028 server.sin_port = htons(ipport);
00029 struct in_addr a;
00030 a.s_addr = server.sin_addr.s_addr;
00031 char addrname[maxHostNameLen];
00032 inet_ntop(AF_INET,&a,addrname,maxHostNameLen);
00033 ipname=addrname;
00034 }
00035 return true;
00036 }
00037
00038 bool IPaddr::set_name(const ipname_t& name) {
00039 Init();
00040 if(name.find(":")!=ipname_t::npos) {
00041 size_t pos = name.find(":");
00042 int p;
00043 if(!(stringstream(name.substr(pos+1)) >> p) || p<0 || p>=(1<<16)) {
00044 cerr << "Bad port number " << name.substr(pos+1) << endl;
00045 return false;
00046 }
00047 set_port(p);
00048 return set_name(name.substr(0,pos));
00049 }
00050 if(!isalpha(name[0])) {
00051
00052 struct in_addr a;
00053 if(inet_pton(AF_INET,name.c_str(),&a)<=0) {
00054 cerr << "IPaddr error: inet_pton failed: " << name << endl;
00055 server.sin_addr.s_addr = INADDR_NONE;
00056 return false;
00057 }
00058 return set_num(ntohl(a.s_addr));
00059 } else {
00060 Init();
00061 struct hostent * data = gethostbyname(name.c_str());
00062 if(data == NULL) {
00063 cerr << "IPaddr error: gethostbyname failed: " << name << endl;
00064 server.sin_addr.s_addr = INADDR_NONE;
00065 return false;
00066 }
00067 ipname=name;
00068
00069 memcpy((char *) &server.sin_addr, data->h_addr_list[0], data->h_length);
00070 server.sin_family = data->h_addrtype;
00071 server.sin_port = htons(ipport);
00072 }
00073 return true;
00074 }
00075
00076 IPaddr::ipname_t IPaddr::get_display_num() const {
00077 struct in_addr a;
00078 a.s_addr = server.sin_addr.s_addr;
00079 char addrname[maxHostNameLen];
00080 inet_ntop(AF_INET,&a,addrname,maxHostNameLen);
00081 return addrname;
00082 }
00083
00084 IPaddr::ipname_t IPaddr::get_rname() const {
00085 struct in_addr a;
00086 a.s_addr = server.sin_addr.s_addr;
00087 struct hostent * data = gethostbyaddr((char*)&a,sizeof(a),AF_INET);
00088 if(data==NULL) {
00089 cerr << "IPaddr error: gethostbyaddr failed: " << ipname << endl;
00090 return "";
00091 }
00092 return data->h_name;
00093 }
00094
00095 void IPaddr::Init() {
00096 ipname="";
00097 memset((char *) &server, 0, sizeof(server));
00098 server.sin_addr.s_addr = INADDR_NONE;
00099 }
00100
00101 bool netstream_server::serve(const IPaddr& addr, bool useDatagram) {
00102 if(opsock>=0)
00103 close();
00104 tgtAddress=addr;
00105 datagram=useDatagram;
00106
00107
00108 opsock = ::socket(AF_INET, datagram ? (int)SOCK_DGRAM : (int)SOCK_STREAM, 0);
00109 if(opsock < 0) {
00110 perror("netstream socket");
00111
00112 opsock=-1;
00113 return false;
00114 }
00115 int on=1;
00116 if ( ::setsockopt ( opsock, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 ) {
00117 perror("netstream SO_REUSEADDR setsockopt");
00118 }
00119 #ifdef __APPLE__
00120 if ( ::setsockopt ( opsock, SOL_SOCKET, SO_NOSIGPIPE, ( const char* ) &on, sizeof ( on ) ) == -1 ) {
00121 perror("netstream SO_NOSIGPIPE setsockopt");
00122 }
00123 #endif
00124 if(datagram) {
00125 if ( ::setsockopt ( opsock, SOL_SOCKET, SO_BROADCAST, ( const char* ) &on, sizeof ( on ) ) == -1 ) {
00126 perror("netstream SO_BROADCAST setsockopt");
00127 }
00128 }
00129
00130 sockaddr_in server = addr.get_addr();
00131
00132
00133 if(::bind(opsock, (const sockaddr *) &server, sizeof(server)) != 0) {
00134
00135 close();
00136 return false;
00137 }
00138
00139
00140 if(::listen(opsock, 0) != 0) {
00141 perror("netstream listen");
00142 close();
00143 return false;
00144 }
00145
00146 return true;
00147 }
00148
00149
00150 #endif