00001
00002
00003
00004
00005
00006
00007
00008
#include "wviproute.h"
00009
#include "wvpipe.h"
00010
#include "wvinterface.h"
00011
#include "wvfile.h"
00012
#include "wvstringlist.h"
00013
00014
#include <net/route.h>
00015
#include <ctype.h>
00016
00017 WvIPRoute::WvIPRoute(
WvStringParm _ifc,
const WvIPNet &_net,
00018
const WvIPAddr &_gate,
int _metric,
00019
WvStringParm _table)
00020 : ifc(_ifc), ip(_net), gateway(_gate), table(_table), src()
00021 {
00022
metric = _metric;
00023 }
00024
00025
00026 WvIPRoute::operator WvString()
const
00027
{
00028
WvIPAddr zero;
00029
return WvString(
"%s via %s %s %s metric %s%s",
00030
ip,
ifc,
gateway,
00031 (
src != zero ?
WvString(
"src %s",
src) :
WvString(
"")),
00032
metric,
00033 (
table !=
"default")
00034 ?
WvString(
" (table %s)",
table) :
WvString(
""));
00035 }
00036
00037
00038 bool WvIPRoute::operator== (
const WvIPRoute &r2)
const
00039
{
00040
return (
ip.
network() == r2.
ip.
network() &&
ip.
netmask() == r2.
ip.
netmask()
00041 &&
gateway == r2.
gateway
00042 &&
ifc == r2.
ifc &&
metric == r2.
metric
00043 &&
table == r2.
table);
00044 }
00045
00046
00047
00048
00049
00050
00051 WvIPRouteList::WvIPRouteList() :
log("Route Table",
WvLog::Debug)
00052 {
00053
00054 }
00055
00056
00057
00058
00059
00060 void WvIPRouteList::get_kernel()
00061 {
00062
char *line;
00063
WvString ifc, table, gate, addr, mask, src;
00064
int metric, flags;
00065
bool invalid;
00066
WvIPRoute *r;
00067
WvStringList words;
00068 WvStringList::Iter word(words);
00069
00070
00071
00072
00073
WvFile kinfo(
"/proc/net/route", O_RDONLY);
00074 kinfo.
getline(0);
00075
while ((line = kinfo.
getline(0)) != NULL)
00076 {
00077
00078
00079 words.zap();
00080 words.
split(line);
00081
00082
if (words.count() < 10)
00083
continue;
00084
00085 word.rewind();
00086 word.next(); ifc = *word;
00087 word.next(); addr = *word;
00088 word.next(); gate = *word;
00089 word.next(); flags = strtoul(*word, NULL, 16);
00090 word.next();
00091 word.next();
00092 word.next(); metric = atoi(*word);
00093 word.next(); mask = *word;
00094
00095
00096
if (!(flags & RTF_UP))
00097
continue;
00098
00099
00100
00101
__u32 a = strtoul(addr, NULL, 16), m = strtoul(mask, NULL, 16);
00102
__u32 g = strtoul(gate, NULL, 16);
00103
WvIPAddr aa(a), mm(m);
00104
WvIPNet net(aa, mm);
00105
WvIPAddr gw(g);
00106
00107 r =
new WvIPRoute(ifc, net, gw, metric,
"default");
00108 append(r,
true);
00109
00110 }
00111
00112
00113
const char *argv[] = {
"ip",
"route",
"list",
"table",
"all", NULL };
00114
WvPipe defaults(argv[0], argv,
false,
true,
false);
00115
while (defaults.
isok() && (line = defaults.
getline(-1)) != NULL)
00116 {
00117
00118
00119 invalid =
false;
00120 ifc = gate = table =
"";
00121 metric = 0;
00122
00123 words.zap();
00124 words.
split(line);
00125
00126
if (words.count() < 3)
00127
continue;
00128
00129 word.rewind();
00130 word.next();
00131
if (*word ==
"broadcast" || *word ==
"local")
00132
continue;
00133
00134
WvIPNet net((*word ==
"default") ?
WvString(
"0/0") : *word);
00135
00136
while (word.next())
00137 {
00138
WvString word1(*word);
00139
if (!word.next())
break;
00140
WvString word2(*word);
00141
00142
if (word1 ==
"table")
00143 {
00144
if (word2 ==
"local")
00145 {
00146 invalid =
true;
00147
break;
00148 }
00149
else
00150 table = word2;
00151 }
00152
else if (word1 ==
"dev")
00153 ifc = word2;
00154
else if (word1 ==
"via")
00155 gate = word2;
00156
else if (word1 ==
"metric")
00157 metric = word2.
num();
00158
else if (word1 ==
"scope")
00159 ;
00160
else if (word1 ==
"proto" && word2 ==
"kernel")
00161 ;
00162
else if (word1 ==
"src")
00163 src = word2;
00164
else
00165
log(WvLog::Debug,
"Unknown keyvalue: '%s' '%s' in (%s)\n",
00166 word1, word2, line);
00167
00168
00169 }
00170
00171
00172
00173
if (!table)
00174
continue;
00175
00176
if (!ifc)
00177 {
00178
log(WvLog::Debug2,
"No interface given for this route; skipped.\n");
00179
continue;
00180 }
00181
00182 r =
new WvIPRoute(ifc, net, gate ?
WvIPAddr(gate) :
WvIPAddr(),
00183 metric, table);
00184
if (!!src)
00185 r->
src = src;
00186 append(r,
true);
00187
00188 }
00189 }
00190
00191
00192 static WvString realtable(
WvIPRoute &r)
00193 {
00194
if (!r.
ip.
is_default() && r.
table ==
"default")
00195
return "main";
00196
else
00197
return r.
table;
00198 }
00199
00200
00201
00202 void WvIPRouteList::set_kernel()
00203 {
00204
WvIPRouteList old_kern;
00205 old_kern.
get_kernel();
00206
00207 Iter oi(old_kern), ni(*
this);
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
for (oi.rewind(); oi.next(); )
00222 {
00223
if (oi->metric == 99)
continue;
00224
00225
for (ni.rewind(); ni.next(); )
00226
if (*ni == *oi)
break;
00227
00228
if (!ni.cur())
00229 {
00230
WvInterface i(oi->ifc);
00231
log(
"Del %s\n", *oi);
00232 i.
delroute(oi->ip, oi->gateway, oi->metric,
realtable(*oi));
00233 }
00234 }
00235
00236
00237
for (ni.rewind(); ni.next(); )
00238 {
00239
for (oi.rewind(); oi.next(); )
00240
if (*oi == *ni)
break;
00241
00242
if (!oi.cur())
00243 {
00244
WvInterface i(ni->ifc);
00245
log(
"Add %s\n", *ni);
00246 i.
addroute(ni->ip, ni->gateway, ni->src, ni->metric,
00247
realtable(*ni));
00248 }
00249 }
00250 }
00251
00252
00253 WvIPRoute *
WvIPRouteList::find(
const WvIPAddr &addr)
00254 {
00255 Iter i(*
this);
00256
00257
for (i.rewind(); i.next(); )
00258 {
00259
if (i->ip.includes(addr))
00260
return &i();
00261 }
00262
00263
return NULL;
00264 }