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