/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Yokogawa Electric Corporation,
* YDC Corporation, IPA (Information-technology Promotion Agency, Japan).
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms, with
* or without modification, are permitted provided that the following
* conditions and disclaimer are agreed and accepted by the user:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the names of the copyrighters, the name of the project which
* is related to this software (hereinafter referred to as "project") nor
* the names of the contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. No merchantable use may be permitted without prior written
* notification to the copyrighters. However, using this software for the
* purpose of testing or evaluating any products including merchantable
* products may be permitted without any notification to the copyrighters.
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHTERS, THE PROJECT AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING
* BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHTERS, THE PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT,STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $TAHI: v6eval/lib/Cm/CmSocket.h,v 1.26 2003/10/23 04:37:30 akisada Exp $
*/
#ifndef _Cm_CmSocket_h_
#define _Cm_CmSocket_h_ 1
/* Interface Definition */
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "CmTypes.h"
#if !defined(__KAME__)
struct in6_addr {
union {
uint8_t u6_addr8[16];
} u6_addr; /* 128 bit IP6 address */
};
struct sockaddr_in6 {
u_char sin6_len; /* length of this struct(sa_family_t)*/
u_char sin6_family; /* AF_INET6 (sa_family_t) */
uint16_t sin6_port; /* Transport layer port # (in_port_t)*/
uint32_t sin6_flowinfo; /* IP6 flow information */
struct in6_addr sin6_addr; /* IP6 address */
uint32_t sin6_scope_id; /* intface scope id */
};
#define s6_addr u6_addr.u6_addr8
#define getipnodebyname(a,b,c,d)0
#endif
#ifndef IN6_IS_ADDR_LINKLOCAL
#define IN6_IS_ADDR_LINKLOCAL(a)\
(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
#endif
#ifndef IN6_ARE_ADDR_EQUAL
#define IN6_ARE_ADDR_EQUAL(a, b)\
(memcmp((a), (b), sizeof(struct in6_addr)) == 0)
#endif
/* Macro to set link local index to the IPv6 address. For KAME IPv6
stack. */
#ifdef __KAME__
#define IN6_LINKLOCAL_IFINDEX(a) ((a).s6_addr[2] << 8 | (a).s6_addr[3])
#define SET_IN6_LINKLOCAL_IFINDEX(a, i) \
do { \
(a).s6_addr[2] = ((i) >> 8) & 0xff; \
(a).s6_addr[3] = (i) & 0xff; \
} while (0)
#else
#define IN6_LINKLOCAL_IFINDEX(a)0
#define SET_IN6_LINKLOCAL_IFINDEX(a, i)
#endif /* KAME */
#if !defined(AF_INET6)
#define AF_INET6 28 /* IPv6 */
inline const char* inet_ntop(int, const void* , char* , size_t) {return 0;}
#endif
typedef struct sockaddr sock;
typedef struct sockaddr_in inSock;
typedef struct sockaddr_un unSock;
typedef struct sockaddr_in6 in6Sock;
struct CmSockAddr {
private:
uint16_t alloc_;
uint16_t length_;
sock* addr_;
public:
CmSockAddr(int l,const sock* s=0);
virtual ~CmSockAddr();
//----------------------------------------------------------------------
// SOCKADDR AREA MANUPULATION
public:
int length() const;
sock* sockAddr() const;
static int initSocket(sock*,size_t,int);
CmSockAddr* socketArea(int l,const sock* s=0);
protected:
inSock* inetAddr() const;
in6Sock* inet6Addr() const;
unSock* unixAddr() const;
//----------------------------------------------------------------------
// ATTRIBUTE MANUPULATION
public:
u_short family() const;
u_short service() const;
const in_addr address() const;
protected:
bool family(u_short);
bool service(u_short);
bool address(const in_addr& anAddr);
int alloc() const;
//----------------------------------------------------------------------
// FOR DICITIONARY SERVICES
public:
uint32_t hash() const;
bool isEqual(const CmSockAddr* o) const;
int compare(const CmSockAddr* o) const;
virtual void print() const;
};
inline int CmSockAddr::alloc() const {return alloc_;}
inline int CmSockAddr::length() const {return length_;}
inline sock* CmSockAddr::sockAddr() const {return addr_;}
struct SocketSet;
//======================================================================
struct CmSocket:public CmSockAddr {
private:
int fileDesc_;
int syserrno_;
static SocketSet* bindedSockets_;
//----------------------------------------------------------------------
// Construction/Destruction
// Instance is created by InetSocket/UnixSocket static functions.
// InetSocket/UnixSocket provide general peterns of socket creation.
//----------------------------------------------------------------------
public:
CmSocket(int l,const sock* s=0,int fd=-1);
virtual ~CmSocket();
//----------------------------------------------------------------------
// General usage of functions.
// 1. Stream Listen
// 1) Create Instance with service,serivce and/or host,pathname.
// 2) listen() it.
// 3) if selected, then accept() to create same class of instance.
// 4) send/receive with created object.
// 2. Stream Connection
// the connection side can be managed either from or to side.
// 1) Create Instance with service,serivce and/or host,pathname,
// which you want to connect to.
// 2) connect() it.
// 3) send/receive.
// ...
// 1) Create Instance with service,serivce and/or host,pathname,
// which you want to connect from.
// 2) connect(to) it.
// 3) send/receive.
// 3. Datagram send
// 1) Create Instance.
// 2) socket() it.
// 3) Create Instance of sendto.
// 4) send.
// 4. Datagram receive
// 1) Create Instance to receive.
// 2) bind() it.
// 3) Create Instance of from.
// 4) receive.
//----------------------------------------------------------------------
// BASIC OPERATION
public:
int listen(int aBacklog=5);
CmSocket* accept();
virtual int connect(CmSockAddr* to=0);
int bind(bool reuse=true);
virtual int socket()=0;
virtual CmSocket* close();
virtual int receive(STR buf,int len)=0;
virtual int send(CSTR buf,int len)=0;
virtual int sendAll(CSTR buf,int len);
virtual int recvAll(STR buf,int len);
//----------------------------------------------------------------------
// portability to datagram socket
virtual int recvfrom(STR,int,CmSockAddr*);
virtual int sendto(CSTR,int,CmSockAddr*);
//----------------------------------------------------------------------
// OPTIONAL OPERATIONS
public:
CmSockAddr* getsockname();
CmSockAddr* getpeername();
bool nonBlocking(int =1);
bool setReuseAddrOpt(bool=true);
bool setReusePortOpt(bool=true);
bool setDebugOpt(bool=true);
int socketType(int aType,int aProtocol=0);
//----------------------------------------------------------------------
// broadcast return broadcast sockaddr_in for ifreq.
// broadcasts return all broadcasts sockaddr_in for system.
public:
inSock* broadcast(struct ifreq* p);
int broadcasts(inSock* *b);
//----------------------------------------------------------------------
// ATTRIBUTE MANUPULATION
public:
inline int fileDesc() const;
inline int syserrno() const;
virtual bool retryError() const;
public:
virtual void printPeers() const;
//----------------------------------------------------------------------
// PRIVATE MEMBER: You do not need to look below.
protected:
inline int myFD() const;
CmSocket* fileDesc(int aFD);
virtual int sysError(CSTR aFunc);
virtual CmSocket* create(int,const sock*,int=-1)=0;
virtual CmSocket* accept(int,const sock*,int=-1);
static SocketSet* bindedSockets();
void clearBind();
static void clearBinds();
};
inline int CmSocket::fileDesc() const {return fileDesc_;}
inline int CmSocket::syserrno() const {return syserrno_;}
inline int CmSocket::myFD() const {return fileDesc();}
inline CmSocket* CmSocket::fileDesc(int aFD) {fileDesc_=aFD; return this;}
//======================================================================
// Stream Specific Functions
struct CmStream:public CmSocket {
private:
CmSockAddr* self_;
CmSockAddr* peer_;
public:
CmStream(int l,const sock* s=0,int fd=-1);
CmStream(const inSock&,int fd=-1);
CmStream(const in6Sock&,int fd=-1);
CmSockAddr* self() const;
CmSockAddr* peer() const;
virtual int socket();
virtual CmSocket* create(int,const sock*,int=-1);
virtual CmSocket* accept(int,const sock*,int=-1);
virtual int connect(CmSockAddr* to=0);
virtual int receive(STR buf,int len);
virtual int send(CSTR buf,int len);
virtual int sendAll(CSTR buf,int len);
virtual int recvAll(STR buf,int len);
virtual void print() const;
virtual void printPeers() const;
private:
void self(CmSockAddr*);
void peer(CmSockAddr*);
};
inline CmSockAddr* CmStream::self() const {return self_;}
inline CmSockAddr* CmStream::peer() const {return peer_;}
inline void CmStream::self(CmSockAddr* s) {self_=s;}
inline void CmStream::peer(CmSockAddr* s) {peer_=s;}
//======================================================================
// Datagram Specific Functions
// Datagram Socket can be used with connect and send/receive,
// and can be specified the receiver when sending or can be given
// the sender when receiving.
struct CmDgram:public CmSocket {
CmDgram(int l,const sock* s=0,int fd=-1);
CmDgram(const inSock&,int fd=-1);
CmDgram(const in6Sock&,int fd=-1);
virtual int socket();
virtual CmSocket* create(int,const sock*,int=-1);
virtual int receive(STR,int);
virtual int recvfrom(STR,int,CmSockAddr*);
virtual int send(CSTR,int);
virtual int sendto(CSTR,int,CmSockAddr*);
virtual int sendfrom(CSTR,int,CmSocket*);
virtual void print() const;
};
//======================================================================
// Raw Specific Functions
struct CmRaw:public CmDgram {
CmRaw(int l,const sock* s=0,int fd=-1);
virtual int socket();
virtual CmSocket* create(int,const sock*,int=-1);
virtual void print() const;
};
//======================================================================
// for Unix Domain Socket
// It can be stream/datagram and any address or pathname.
struct UnixSocket {
static CmSocket* stream();
static CmSocket* stream(CSTR aName);
static CmDgram* datagram();
static CmDgram* datagram(CSTR aName);
static int initSocket(unSock& un);
static int service(unSock& un,CSTR serv);
};
//======================================================================
// for Inet Domain Socket
// It can be stream/datagram and any address or service
// with/without hostname/ipaddress.
struct InetSocket {
static int getService(CSTR serv);
//----------------------------------------------------------------------
// defaultService is used for debugging.
// The priority of port number as follow.
// debug environment->defined on system->default value
static int defaultService(CSTR serv,CSTR debug,int def);
static int initSocket(inSock& in);
static int initSocket(in6Sock& in);
static int service(inSock& in,int serv);
static int service(in6Sock& in,int serv);
static int serviceAddress(inSock& in,int serv,const in_addr& anAddr);
static int serviceAddress(in6Sock& in,int serv,const in6_addr& anAddr);
static inSock* serviceHost4(int serv,CSTR aHost,int&);
static in6Sock* serviceHost6(int serv,CSTR aHost,int&);
static sock* serviceHost(int serv,CSTR aHost,int&);
static CSTR myHostname();
static const in_addr myIpAddress();
//----------------------------------------------------------------------
static CmSocket* stream();
static CmSocket* stream6();
static CmDgram* datagram();
static CmDgram* datagram6();
static CmSocket* stream(int serv);
static CmSocket* stream6(int serv);
static CmDgram* datagram(int serv);
static CmDgram* datagram6(int serv);
static CmSocket* stream(CSTR s);
static CmSocket* stream6(CSTR s);
static CmDgram* datagram(CSTR s);
static CmDgram* datagram6(CSTR s);
static CmSocket* stream(int serv,const in_addr& anAddr);
static CmDgram* datagram(int serv,const in_addr& anAddr);
static CmSocket* stream(int serv,const in6_addr& anAddr);
static CmDgram* datagram(int serv,const in6_addr& anAddr);
static CmSocket* stream(CSTR s,const in_addr& anAddr);
static CmDgram* datagram(CSTR s,const in_addr& anAddr);
static CmSocket* stream(CSTR s,const in6_addr& anAddr);
static CmDgram* datagram(CSTR s,const in6_addr& anAddr);
static CmSocket* stream(int serv,CSTR aHost);
static CmDgram* datagram(int serv,CSTR aHost);
static CmSocket* stream(CSTR s,CSTR aHost);
static CmDgram* datagram(CSTR s,CSTR aHost);
};
//----------------------------------------------------------------------
inline CmSocket* InetSocket::stream(CSTR s) {
return stream(getService(s));}
inline CmSocket* InetSocket::stream6(CSTR s) {
return stream(getService(s));}
inline CmDgram* InetSocket::datagram(CSTR s) {
return datagram(getService(s));}
inline CmDgram* InetSocket::datagram6(CSTR s) {
return datagram(getService(s));}
//----------------------------------------------------------------------
inline CmSocket* InetSocket::stream(CSTR s,CSTR aHost) {
return stream(getService(s),aHost);}
inline CmDgram* InetSocket::datagram(CSTR s,CSTR aHost) {
return datagram(getService(s),aHost);}
//----------------------------------------------------------------------
inline CmSocket* InetSocket::stream(CSTR s,const in_addr& anAddr) {
return stream(getService(s),anAddr);}
inline CmSocket* InetSocket::stream(CSTR s,const in6_addr& anAddr) {
return stream(getService(s),anAddr);}
inline CmDgram* InetSocket::datagram(CSTR s,const in_addr& anAddr) {
return datagram(getService(s),anAddr);}
inline CmDgram* InetSocket::datagram(CSTR s,const in6_addr& anAddr) {
return datagram(getService(s),anAddr);}
//----------------------------------------------------------------------
inline bool operator==(const in_addr& a,const in_addr& b) {
return a.s_addr==b.s_addr;}
#include "CmCltn.h"
interfaceCmSet(SocketSet,CmSocket);
#ifndef DBGFLAGS
// avoid warning of compilation
// gcc version 3.3.1 [FreeBSD]
// warning: array subscript has type `char'
#define DBGFLAGS(c) (dbgFlags[(int)(c)])
#endif // DBGFLAGS
#endif
syntax highlighted by Code2HTML, v. 0.9.1