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 }