Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

wvaddr.h

Go to the documentation of this file.
00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * Device-independent and device-specific hardware/protocol address classes
00006  * that can store themselves efficiently as well as create a printable string
00007  * version of themselves.
00008  */
00009 #ifndef __WVADDR_H
00010 #define __WVADDR_H
00011 
00012 #include "wvstring.h"
00013 
00014 // FIXME: this is not needed on platforms other than Linux
00015 #ifdef __linux
00016 #include <linux/if_ether.h>
00017 #endif
00018 
00019 #if 0
00020 // FIXME: this is needed on BSD and Darwin
00021 #include <sys/param.h>
00022 #include <sys/socket.h>
00023 #include <net/if_arp.h>
00024 #include <netinet/in_systm.h>
00025 #include <net/ethernet.h>
00026 #define ETH_ALEN ETHER_ADDR_LEN
00027 #endif
00028 
00029 #if defined(ISBSD) || defined(ISDARWIN)
00030 #include <arpa/inet.h>
00031 #include "if_arp.h"
00032 #endif
00033 
00034 #ifndef _WIN32
00035 #include <netinet/in.h>
00036 #else
00037 
00038 #include <winsock2.h>
00039 #define ETH_ALEN                6
00040 #define IP_ALEN                 4
00041 #endif
00042 
00043 #ifndef __u32
00044 typedef unsigned int __u32;
00045 #endif
00046 #ifndef __u16
00047 typedef short unsigned int __u16;
00048 #endif
00049 
00050 
00051 static const char * type_wvaddr = "WvAddr";
00052 static const char * type_wvipaddr = "WvIPAddr";
00053 static const char * type_wvipnet = "WvIPNet";
00054 static const char * type_wvipportaddr = "WvIPPortAddr";
00055 
00056 #define WVADDR type_wvaddr
00057 #define WVIPADDR type_wvipaddr
00058 #define WVIPNET type_wvipnet
00059 #define WVIPPORTADDR type_wvipportaddr
00060 
00061 
00062 /**
00063  * Common packet encapsulation types, with the ability to convert a Linux
00064  * ARPHRD_* value or (struct sockaddr) sa_family value.  (Those two use the
00065  * same set of values.)
00066  */
00067 class WvEncap
00068 {
00069     static char strings[][20];         // printable-string names per type
00070     static int extypes[];              // external types (ARPHRD_*, etc)
00071 public:
00072     // NOTE:  if you change enum CapType, don't forget to change extypes[]
00073     //   and strings[] in wvaddr.cc!
00074     enum CapType {
00075         // hardware encapsulation
00076         Unknown = 0,
00077         Loopback,
00078         Ethertap,
00079         Ethernet,
00080         ARCnet,
00081         SLIP,
00082         CSLIP,
00083         PPP,
00084         
00085         // protocol encapsulation
00086         IPv4,
00087         Unix,
00088         
00089         // END
00090         NUM_ENCAP_TYPES
00091     };
00092     CapType cap;
00093     
00094     WvEncap(CapType _cap = Unknown)
00095         { cap = _cap; }
00096     
00097     WvEncap(int extype);
00098     
00099     operator CapType () const
00100         { return cap; }
00101     
00102     operator WvString () const
00103         { return strings[cap]; }
00104 };
00105 
00106 
00107 /**
00108  * Base class for different address types, each of which will have
00109  * the ability to convert itself to/from a printable string, as well
00110  * as other type-specific abilities.
00111  */
00112 class WvAddr
00113 {
00114 protected:
00115     virtual WvString printable() const = 0;
00116 
00117 public:
00118     WvAddr() {};
00119     virtual ~WvAddr() {};
00120     static WvAddr *gen(struct sockaddr *addr);
00121     
00122     virtual WvEncap encap() const = 0;
00123     operator WvString() const
00124         { return printable(); }
00125 
00126     virtual bool comparator(const WvAddr *a2, bool first_pass = true) const;
00127     // Poor man's rtti
00128     virtual const char *type() const
00129         { return WVADDR; };
00130     
00131     virtual bool isbroadcast() const;
00132 
00133     virtual struct sockaddr *sockaddr() const = 0;
00134     virtual size_t sockaddr_len() const = 0;
00135     virtual const unsigned char *rawdata() const;
00136     virtual size_t rawdata_len() const;
00137     
00138     virtual unsigned WvHash() const;
00139     
00140     bool operator== (const WvAddr &a2) const
00141         { return comparator(&a2); }
00142     bool operator!= (const WvAddr &a2) const
00143         { return ! (*this == a2); }
00144 };
00145 
00146 
00147 // useful for hash tables (see wvhashtable.h)
00148 unsigned WvHash(const WvAddr &addr);
00149 
00150 
00151 /**
00152  * A WvAddr that simply contains a printable string with a user-defined
00153  * encapsulation type.
00154  */
00155 class WvStringAddr : public WvAddr
00156 {
00157     WvString addr;
00158     WvEncap cap;
00159 
00160 protected:
00161     virtual WvString printable() const;
00162 
00163 public:
00164     WvStringAddr(WvStringParm s, const WvEncap &_cap);
00165     WvStringAddr(const struct sockaddr *_addr);
00166     virtual ~WvStringAddr();
00167     virtual WvEncap encap() const;
00168     virtual struct sockaddr *sockaddr() const;
00169     virtual size_t sockaddr_len() const;
00170     virtual const unsigned char *rawdata() const;
00171     virtual size_t rawdata_len() const;
00172 };
00173 
00174 
00175 #ifndef _WIN32
00176 /**
00177  * An ethernet address is made up of a string of hex numbers, in the form
00178  *     AA:BB:CC:DD:EE:FF
00179  */
00180 class WvEtherAddr : public WvAddr
00181 {
00182     unsigned char binaddr[ETH_ALEN];
00183 
00184 protected:
00185     virtual WvString printable() const;
00186 
00187 public:
00188     WvEtherAddr(const unsigned char _binaddr[ETH_ALEN] = NULL)
00189         { if (_binaddr) memcpy(binaddr, _binaddr, ETH_ALEN); }
00190     WvEtherAddr(const char string[])
00191         { string_init(string); }
00192     WvEtherAddr(WvStringParm string)
00193         { string_init(string); }
00194     void string_init(const char string[]);
00195     WvEtherAddr(const struct sockaddr *addr)
00196         { memcpy(binaddr, (void *)addr->sa_data, ETH_ALEN); }
00197     virtual ~WvEtherAddr();
00198     
00199     virtual WvEncap encap() const;
00200     virtual bool isbroadcast() const;
00201     virtual struct sockaddr *sockaddr() const;
00202     virtual size_t sockaddr_len() const;
00203     virtual const unsigned char *rawdata() const;
00204     virtual size_t rawdata_len() const;
00205 };
00206 
00207 
00208 /** An ARCnet address is made up of a single hex number.  */
00209 class WvARCnetAddr : public WvAddr
00210 {
00211     unsigned char binaddr;
00212 
00213 protected:
00214     virtual WvString printable() const;
00215 
00216 public:
00217     WvARCnetAddr(const unsigned char _binaddr[1] = NULL)
00218         { if (_binaddr) binaddr = _binaddr[0]; }
00219     WvARCnetAddr(const char string[])
00220         { binaddr = strtoul(string, NULL, 16); }
00221     WvARCnetAddr(WvStringParm string)
00222         { binaddr = strtoul(string, NULL, 16); }
00223     WvARCnetAddr(const struct sockaddr *addr)
00224         { binaddr = ((unsigned char *)addr->sa_data)[0]; }
00225     virtual ~WvARCnetAddr();
00226     
00227     virtual WvEncap encap() const;
00228     virtual struct sockaddr *sockaddr() const;
00229     virtual size_t sockaddr_len() const;
00230     virtual const unsigned char *rawdata() const;
00231     virtual size_t rawdata_len() const;
00232 };
00233 #endif // !_WIN32
00234 
00235 /**
00236  * An IP address is made up of a "dotted quad" -- four decimal numbers in
00237  * the form
00238  *     www.xxx.yyy.zzz
00239  * 
00240  * We don't support automatic name lookups yet, but this will be the place
00241  * to do it when support is added.
00242  */
00243 class WvIPAddr : public WvAddr
00244 {
00245 protected:
00246     virtual WvString printable() const;
00247 public:
00248     unsigned char binaddr[4];
00249 
00250     WvIPAddr(const unsigned char _binaddr[4])
00251         { if (_binaddr) memcpy(binaddr, _binaddr, 4); }
00252     WvIPAddr(const __u32 _binaddr = 0)
00253         { memcpy(binaddr, &_binaddr, 4); }
00254     WvIPAddr(const char string[])
00255         { string_init(string); }
00256     WvIPAddr(WvStringParm string)
00257         { string_init(string); }
00258     void string_init(const char string[]);
00259     WvIPAddr(const struct sockaddr *addr)
00260         { memcpy(binaddr,
00261                  (void *)&((struct sockaddr_in *)addr)->sin_addr.s_addr, 4); }
00262     WvIPAddr(const WvIPAddr &_addr)
00263         { memcpy(binaddr, _addr.binaddr, 4); }
00264     virtual ~WvIPAddr();
00265 
00266     virtual bool comparator(const WvAddr *a2, bool first_pass = true) const;
00267     virtual const char *type() const
00268         { return WVIPADDR; };
00269     
00270     WvIPAddr operator& (const WvIPAddr &a2) const;
00271     WvIPAddr operator| (const WvIPAddr &a2) const;
00272     WvIPAddr operator^ (const WvIPAddr &a2) const;
00273     WvIPAddr operator~ () const;
00274     WvIPAddr operator+ (int n) const;
00275     WvIPAddr operator- (int n) const;
00276 
00277     __u32 addr() const
00278         { return *(__u32 *)binaddr; }
00279 
00280     bool is_zero() const
00281         { return addr() == 0; }
00282 
00283     virtual WvEncap encap() const;
00284 
00285     virtual struct sockaddr *sockaddr() const;
00286     virtual size_t sockaddr_len() const;
00287     virtual const unsigned char *rawdata() const;
00288     virtual size_t rawdata_len() const;
00289 };
00290 
00291 
00292 /**
00293  * An IP network comprises two WvIPAddr structures: an address and a
00294  * netmask. The two ANDed together comprise the "network address",
00295  * which, if it is correct, can be ORed with any IP address on the
00296  * network without changing the address.  Together, a network address
00297  * and netmask provide a good description of the IP addresses
00298  * available on a network.
00299  * 
00300  * WvIPNet internally stores a base IP address (the inherited WvIPAddr)
00301  * and the netmask (a member variable).
00302  * 
00303  * Note that the rawdata() function is inherited from WvIPAddr, so it does
00304  * not include the netmask in the raw data.
00305  */
00306 class WvIPNet : public WvIPAddr
00307 {
00308 protected:
00309     WvIPAddr mask;
00310     virtual WvString printable() const;
00311     
00312 public:
00313     WvIPNet(const WvIPNet &_net);
00314     WvIPNet(const char string[]) : WvIPAddr(string)
00315         { string_init(string); }
00316     WvIPNet(WvStringParm string) : WvIPAddr(string)
00317         { string_init(string); }
00318     void string_init(const char string[]);
00319     WvIPNet(const WvIPAddr &base, const WvIPAddr &_mask);
00320 
00321     virtual bool comparator(const WvAddr *a2, bool first_pass = true) const;
00322     virtual const char *type() const
00323         { return WVIPNET; };
00324     
00325     /**
00326      * construct an IPNet from a base address and a number of bits in
00327      * the netmask.  The default of 32 gives a one-host network,
00328      * (netmask 255.255.255.255).
00329      */
00330     WvIPNet(const WvIPAddr &base, int bits = 32);
00331     
00332     /** construct an empty IPNet for later copying (probably by operator=) */
00333     WvIPNet();
00334     
00335     virtual ~WvIPNet();
00336     
00337     /** Override the hash and comparison functions */
00338     virtual unsigned WvHash() const;
00339     
00340     /** Get the 'base IP address' component, netmask, network, and broadcast */
00341     WvIPAddr base() const
00342         { return *this; }
00343     WvIPAddr netmask() const
00344         { return mask; }
00345     WvIPAddr network() const
00346         { return *this & mask; }
00347     WvIPAddr broadcast() const
00348         { return *this | ~mask; }
00349     
00350     /** adjust the netmask so that 'addr' would be included in this network */
00351     void include(const WvIPNet &addr);
00352     
00353     /** determine whether the given address is already included in this net */
00354     bool includes(const WvIPNet &addr) const;
00355     
00356     /**
00357      * weird netmasks such as 255.0.255.0 (easy example) are almost never
00358      * used -- they have '0' bits in the middle.  However, using the
00359      * include() function will result in odd netmasks like this, since
00360      * it will not eliminate a '1' bit unless absolutely necessary.
00361      * normalize() would convert the above netmask into 255.0.0.0, which
00362      * is probably the netmask _really_ in use.  bits() calculates
00363      * the number of leading '1' bits in the normalized netmask, without
00364      * actually doing the normalization.
00365      */
00366     int bits() const;
00367     void normalize();
00368     
00369     /** is this net the default gateway? (0.0.0.0/0) */
00370     bool is_default() const
00371         { return mask.binaddr[0] == 0; }
00372     
00373     /** is it a plain host? (x.x.x.x/32) */
00374     bool is_host() const
00375         { return mask.binaddr[3] == 255; }
00376 };
00377 
00378 
00379 
00380 /**
00381  * An IP+Port address also includes a port number, with the resulting form
00382  *     www.xxx.yyy.zzz:pppp
00383  * 
00384  * Note that the rawdata() function is inherited from WvIPAddr, so it does
00385  * not include the port number in the raw data.
00386  */
00387 class WvIPPortAddr : public WvIPAddr
00388 {
00389 protected:
00390     virtual WvString printable() const;
00391 
00392 public:
00393     __u16 port;
00394     
00395     WvIPPortAddr();
00396     WvIPPortAddr(const unsigned char _ipaddr[4], __u16 _port = 0) 
00397           : WvIPAddr(_ipaddr), port(_port) { };
00398     WvIPPortAddr(const WvIPAddr &_ipaddr, __u16 _port = 0);
00399     WvIPPortAddr(const char string[]) : WvIPAddr(string)
00400         { string_init(string); }
00401     WvIPPortAddr(WvStringParm string) : WvIPAddr(string)
00402         { string_init(string); }
00403     void string_init(const char string[]);
00404     WvIPPortAddr(__u16 _port);          // assumes address 0.0.0.0, (ie local)
00405     WvIPPortAddr(const char string[], __u16 _port);
00406     
00407     WvIPPortAddr(struct sockaddr_in *sin) : WvIPAddr(sin->sin_addr.s_addr)
00408         { port = ntohs(sin->sin_port); }
00409     virtual ~WvIPPortAddr();
00410 
00411     virtual bool comparator(const WvAddr *a2, bool first_pass = true) const;
00412     virtual const char *type() const
00413         { return WVIPPORTADDR; };
00414 
00415     virtual struct sockaddr *sockaddr() const;
00416 
00417     // Override the hash and comparison functions
00418     virtual unsigned WvHash() const;
00419 };
00420 
00421 #ifndef _WIN32
00422 /** A Unix domain socket address is really just a filename.  */
00423 class WvUnixAddr : public WvAddr
00424 {
00425 protected:
00426     WvString sockname;
00427     virtual WvString printable() const;
00428     
00429 public:
00430     WvUnixAddr(const char *_sockname);
00431     WvUnixAddr(WvStringParm _sockname);
00432     WvUnixAddr(const WvUnixAddr &_addr);
00433     virtual ~WvUnixAddr();
00434     
00435     virtual WvEncap encap() const;
00436 
00437     virtual struct sockaddr *sockaddr() const;
00438     virtual size_t sockaddr_len() const;
00439     virtual const unsigned char *rawdata() const;
00440     virtual size_t rawdata_len() const;
00441 };
00442 
00443 #endif //windows
00444 #endif // __WVADDR_H

Generated on Sat Feb 21 21:05:23 2004 for WvStreams by doxygen 1.3.5