Make WvStreams compile with gcc 4.4.
[wvstreams.git] / linuxstreams / wvipaliaser.cc
blobc524fe76215257f9c31124cccc71c46e2dc5936e
1 /*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4 *
5 * WvIPAliaser handles IP aliasing in the Linux kernel. See wvipaliaser.h.
6 */
7 #include "wvipaliaser.h"
8 #include "wvinterface.h"
9 #include <assert.h>
12 WvIPAliaser::AliasList WvIPAliaser::all_aliases;
16 ///////////////////////////////////// WvIPAliaser::Alias
20 WvIPAliaser::Alias::Alias(const WvIPAddr &_ip) : ip(_ip)
22 WvIPAddr noip;
23 WvIPNet nonet(noip, noip);
24 link_count = 0;
26 for (index = 0; index < 256; index++)
28 WvInterface i(WvString("lo:wv%s", index));
30 if (!i.isup() || i.ipaddr() == nonet) // not in use yet!
32 i.setipaddr(ip);
33 i.up(true);
34 if (WvIPAddr(i.ipaddr()) != ip)
36 // no permission, most likely.
37 index = -1;
38 i.up(false);
40 return;
43 if (i.isup() && WvIPNet(i.ipaddr(),32) == ip)
45 // a bit weird... this alias already has the right address.
46 // Keep it.
47 return;
51 // got through all possible names without a free one? Weird!
52 index = -1;
56 WvIPAliaser::Alias::~Alias()
58 if (index >= 0)
60 WvInterface i(WvString("lo:wv%s", index));
61 // i.setipaddr(WvIPAddr()); // not necessary in recent kernels
62 i.up(false);
68 //////////////////////////////////// WvIPAliaser
72 WvIPAliaser::WvIPAliaser() : interfaces()
74 // nothing to do
78 WvIPAliaser::~WvIPAliaser()
80 // clear the alias list
81 start_edit();
82 done_edit();
86 void WvIPAliaser::start_edit()
88 AliasList::Iter i(aliases);
90 #ifndef NDEBUG
91 AliasList::Iter i_all(all_aliases);
92 #endif
94 interfaces.update();
96 for (i.rewind(); i.next(); )
98 assert(i_all.find(i.ptr()));
100 // the global alias entry goes down by one
101 i().link_count--;
104 // empty out the local list
105 aliases.zap();
109 WvIPAliaser::Alias *WvIPAliaser::ipsearch(WvIPAliaser::AliasList &l,
110 const WvIPAddr &ip)
112 AliasList::Iter i(l);
114 for (i.rewind(); i.next(); )
116 if (i->ip == WvIPAddr(ip))
117 return i.ptr();
120 return NULL;
124 bool WvIPAliaser::add(const WvIPAddr &ip)
126 Alias *a;
128 if (WvIPAddr(ip) == WvIPAddr() || ipsearch(aliases, ip))
129 return false; // already done.
131 // If the alias is already a local address, there is no need for an alias.
132 // We have to be careful that we don't find an existing alias as the
133 // local interface. Otherwise, we'll toggle that alias on and off.
134 WvString ifc(interfaces.islocal(WvIPAddr(ip)));
135 if (!!ifc && !strchr(ifc, ':')) // Make sure it is a real interface
136 return false;
138 a = ipsearch(all_aliases, ip);
139 if (a)
141 // It's already in the global list, so we add its entry to
142 // our list and increase the link count.
143 aliases.append(a, false);
144 a->link_count++;
145 return false;
147 else
149 // It's not there, so we add a new alias to the global list and
150 // our local list.
151 a = new Alias(ip);
152 aliases.append(a, false);
153 all_aliases.append(a, true);
154 a->link_count++;
155 return true;
160 bool WvIPAliaser::done_edit()
162 bool any_change=false;
163 AliasList::Iter i(all_aliases);
165 i.rewind(); i.next();
166 while (i.cur())
168 Alias &a = *i;
169 if (!a.link_count) {
170 i.unlink();
171 any_change = true;
172 } else
173 i.next();
176 return any_change;
180 void WvIPAliaser::dump()
183 WvLog log("local aliases");
184 AliasList::Iter i(aliases);
185 for (i.rewind(); i.next(); )
187 Alias &a = *i;
188 log("#%s = lo:wv%s: %s (%s links)\n",
189 a.index, a.index, a.ip, a.link_count);
191 log(".\n");
195 WvLog log("global aliases");
196 AliasList::Iter i(all_aliases);
197 for (i.rewind(); i.next(); )
199 Alias &a = *i;
200 log("#%s = lo:wv%s: %s (%s links)\n",
201 a.index, a.index, a.ip, a.link_count);
203 log(".\n.\n");