WvStreams
wvipaliaser.cc
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>
10
11
12WvIPAliaser::AliasList WvIPAliaser::all_aliases;
13
14
15
17
18
19
20WvIPAliaser::Alias::Alias(const WvIPAddr &_ip) : ip(_ip)
21{
22 WvIPAddr noip;
23 WvIPNet nonet(noip, noip);
24 link_count = 0;
25
26 for (index = 0; index < 256; index++)
27 {
28 WvInterface i(WvString("lo:wv%s", index));
29
30 if (!i.isup() || i.ipaddr() == nonet) // not in use yet!
31 {
32 i.setipaddr(ip);
33 i.up(true);
34 if (WvIPAddr(i.ipaddr()) != ip)
35 {
36 // no permission, most likely.
37 index = -1;
38 i.up(false);
39 }
40 return;
41 }
42
43 if (i.isup() && WvIPNet(i.ipaddr(),32) == ip)
44 {
45 // a bit weird... this alias already has the right address.
46 // Keep it.
47 return;
48 }
49 }
50
51 // got through all possible names without a free one? Weird!
52 index = -1;
53}
54
55
56WvIPAliaser::Alias::~Alias()
57{
58 if (index >= 0)
59 {
60 WvInterface i(WvString("lo:wv%s", index));
61 // i.setipaddr(WvIPAddr()); // not necessary in recent kernels
62 i.up(false);
63 }
64}
65
66
67
69
70
71
72WvIPAliaser::WvIPAliaser() : interfaces()
73{
74 // nothing to do
75}
76
77
78WvIPAliaser::~WvIPAliaser()
79{
80 // clear the alias list
81 start_edit();
82 done_edit();
83}
84
85
87{
88 AliasList::Iter i(aliases);
89
90 #ifndef NDEBUG
91 AliasList::Iter i_all(all_aliases);
92 #endif
93
94 interfaces.update();
95
96 for (i.rewind(); i.next(); )
97 {
98 assert(i_all.find(i.ptr()));
99
100 // the global alias entry goes down by one
101 i().link_count--;
102 }
103
104 // empty out the local list
105 aliases.zap();
106}
107
108
109WvIPAliaser::Alias *WvIPAliaser::ipsearch(WvIPAliaser::AliasList &l,
110 const WvIPAddr &ip)
111{
112 AliasList::Iter i(l);
113
114 for (i.rewind(); i.next(); )
115 {
116 if (i->ip == WvIPAddr(ip))
117 return i.ptr();
118 }
119
120 return NULL;
121}
122
123
124bool WvIPAliaser::add(const WvIPAddr &ip)
125{
126 Alias *a;
127
128 if (WvIPAddr(ip) == WvIPAddr() || ipsearch(aliases, ip))
129 return false; // already done.
130
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;
137
138 a = ipsearch(all_aliases, ip);
139 if (a)
140 {
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;
146 }
147 else
148 {
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;
156 }
157}
158
159
160bool WvIPAliaser::done_edit()
161{
162 bool any_change=false;
163 AliasList::Iter i(all_aliases);
164
165 i.rewind(); i.next();
166 while (i.cur())
167 {
168 Alias &a = *i;
169 if (!a.link_count) {
170 i.unlink();
171 any_change = true;
172 } else
173 i.next();
174 }
175
176 return any_change;
177}
178
179
180void WvIPAliaser::dump()
181{
182 {
183 WvLog log("local aliases");
184 AliasList::Iter i(aliases);
185 for (i.rewind(); i.next(); )
186 {
187 Alias &a = *i;
188 log("#%s = lo:wv%s: %s (%s links)\n",
189 a.index, a.index, a.ip, a.link_count);
190 }
191 log(".\n");
192 }
193
194 {
195 WvLog log("global aliases");
196 AliasList::Iter i(all_aliases);
197 for (i.rewind(); i.next(); )
198 {
199 Alias &a = *i;
200 log("#%s = lo:wv%s: %s (%s links)\n",
201 a.index, a.index, a.ip, a.link_count);
202 }
203 log(".\n.\n");
204 }
205}
An IP address is made up of a "dotted quad" – four decimal numbers in the form www....
Definition wvaddr.h:250
void start_edit()
you must call start_edit() once, then add() any number of times, then done_edit() once,...
An IP network comprises two WvIPAddr structures: an address and a netmask.
Definition wvaddr.h:313
A WvInterface manages a particular network interface.
Definition wvinterface.h:25
A WvLog stream accepts log messages from applications and forwards them to all registered WvLogRcv's.
Definition wvlog.h:57
WvString is an implementation of a simple and efficient printable-string class.
Definition wvstring.h:330