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

wvipaliaser.cc

Go to the documentation of this file.
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  * 
00005  * WvIPAliaser handles IP aliasing in the Linux kernel.  See wvipaliaser.h.
00006  */
00007 #include "wvipaliaser.h"
00008 #include "wvinterface.h"
00009 #include <assert.h>
00010 
00011 
00012 WvIPAliaser::AliasList WvIPAliaser::all_aliases;
00013 
00014 
00015 
00016 ///////////////////////////////////// WvIPAliaser::Alias
00017 
00018 
00019 
00020 WvIPAliaser::Alias::Alias(const WvIPAddr &_ip) : ip(_ip)
00021 {
00022     WvIPAddr noip;
00023     WvIPNet nonet(noip, noip);
00024     link_count = 0;
00025     
00026     for (index = 0; index < 256; index++)
00027     {
00028         WvInterface i(WvString("lo:wv%s", index));
00029         
00030         if (!i.isup() || i.ipaddr() == nonet) // not in use yet!
00031         {
00032             i.setipaddr(ip);
00033             i.up(true);
00034             if (WvIPAddr(i.ipaddr()) != ip)
00035             {
00036                 // no permission, most likely.
00037                 index = -1;
00038                 i.up(false);
00039             }
00040             return;
00041         }
00042         
00043         if (i.isup() && WvIPNet(i.ipaddr(),32) == ip)
00044         {
00045             // a bit weird... this alias already has the right address.
00046             // Keep it.
00047             return; 
00048         }
00049     }
00050     
00051     // got through all possible names without a free one?  Weird!
00052     index = -1;
00053 }
00054 
00055 
00056 WvIPAliaser::Alias::~Alias()
00057 {
00058     if (index >= 0)
00059     {
00060         WvInterface i(WvString("lo:wv%s", index));
00061         // i.setipaddr(WvIPAddr()); // not necessary in recent kernels
00062         i.up(false);
00063     }
00064 }
00065 
00066 
00067 
00068 //////////////////////////////////// WvIPAliaser
00069 
00070 
00071 
00072 WvIPAliaser::WvIPAliaser() : interfaces()
00073 {
00074     // nothing to do
00075 }
00076 
00077 
00078 WvIPAliaser::~WvIPAliaser()
00079 {
00080     // clear the alias list
00081     start_edit();
00082     done_edit();
00083 }
00084 
00085 
00086 void WvIPAliaser::start_edit()
00087 {
00088     AliasList::Iter i(aliases);
00089     
00090     #ifndef NDEBUG
00091     AliasList::Iter i_all(all_aliases);
00092     #endif
00093     
00094     interfaces.update();
00095     
00096     for (i.rewind(); i.next(); )
00097     {
00098         assert(i_all.find(i.ptr()));
00099         
00100         // the global alias entry goes down by one
00101         i().link_count--;
00102     }
00103     
00104     // empty out the local list
00105     aliases.zap();
00106 }
00107 
00108 
00109 WvIPAliaser::Alias *WvIPAliaser::ipsearch(WvIPAliaser::AliasList &l,
00110                                           const WvIPAddr &ip)
00111 {
00112     AliasList::Iter i(l);
00113     
00114     for (i.rewind(); i.next(); )
00115     {
00116         if (i->ip == WvIPAddr(ip))
00117             return i.ptr();
00118     }
00119     
00120     return NULL;
00121 }
00122 
00123 
00124 void WvIPAliaser::add(const WvIPAddr &ip)
00125 {
00126     Alias *a;
00127 
00128     if (WvIPAddr(ip) == WvIPAddr() || ipsearch(aliases, ip))
00129         return;     // already done.
00130     
00131     a = ipsearch(all_aliases, ip);
00132     if (a)                          // already in global list?
00133     {
00134         // add global entry to our list and increase link count
00135         aliases.append(a, false);
00136         a->link_count++;
00137     }
00138     else if (!interfaces.islocal(WvIPAddr(ip)))
00139     {
00140         // if already local, no need for alias
00141         // if non-local, create a new entry and add to both lists
00142         a = new Alias(ip);
00143         aliases.append(a, false);
00144         all_aliases.append(a, true);
00145         a->link_count++;
00146     }
00147 }
00148 
00149 
00150 void WvIPAliaser::done_edit()
00151 {
00152     AliasList::Iter i(all_aliases);
00153     
00154     i.rewind(); i.next();
00155     while (i.cur())
00156     {
00157         Alias &a = *i;
00158         if (!a.link_count)
00159             i.unlink();
00160         else
00161             i.next();
00162     } 
00163 }
00164 
00165 
00166 void WvIPAliaser::dump()
00167 {
00168     {
00169         WvLog log("local aliases");
00170         AliasList::Iter i(aliases);
00171         for (i.rewind(); i.next(); )
00172         {
00173             Alias &a = *i;
00174             log("#%s = lo:wv%s: %s (%s links)\n",
00175                 a.index, a.index, a.ip, a.link_count);
00176         }
00177         log(".\n");
00178     }
00179 
00180     {
00181         WvLog log("global aliases");
00182         AliasList::Iter i(all_aliases);
00183         for (i.rewind(); i.next(); )
00184         {
00185             Alias &a = *i;
00186             log("#%s = lo:wv%s: %s (%s links)\n",
00187                 a.index, a.index, a.ip, a.link_count);
00188         }
00189         log(".\n.\n");
00190     }
00191 }

Generated on Wed Dec 15 15:08:11 2004 for WvStreams by  doxygen 1.3.9.1