Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

wvinterface.cc

Go to the documentation of this file.
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  * 
00005  * A WvInterface stores information about a particular network interface.
00006  */
00007 
00008 #include "wvinterface.h"
00009 #if 1
00010 // FIXME: this file doesn't compile on anything other than Linux
00011 
00012 #include "wvsubproc.h"
00013 #include "wvfile.h"
00014 
00015 #include <sys/ioctl.h>
00016 #include <sys/socket.h>
00017 #include <sys/wait.h>
00018 #include <net/if_arp.h>
00019 #include <net/route.h>
00020 #include <unistd.h>
00021 #include <errno.h>
00022 #include <linux/sockios.h>
00023 #include <linux/wireless.h>
00024 
00025 #define min(x,y) ((x) < (y) ? (x) : (y))
00026 
00027 WvInterfaceDictBase WvInterfaceDict::slist(15);
00028 int WvInterfaceDict::links = 0;
00029 
00030 
00031 WvInterface::WvInterface(WvStringParm _name) :
00032     err("Net Interface", WvLog::Error), name(_name)
00033 {
00034     my_hwaddr = my_ipaddr = NULL;
00035     valid = true;
00036 }
00037 
00038 
00039 WvInterface::~WvInterface()
00040 {
00041     rescan();
00042 }
00043 
00044 
00045 int WvInterface::req(int ioctl_num, struct ifreq *ifr)
00046 {
00047     int sock, retval;
00048 
00049     sock = socket(AF_INET, SOCK_STREAM, 0);
00050     strncpy(ifr->ifr_name, name, IFNAMSIZ-1);
00051     ifr->ifr_name[IFNAMSIZ-1] = 0;
00052     
00053     retval = ioctl(sock, ioctl_num, ifr);
00054     if (retval)
00055         retval = errno;
00056     close(sock);
00057     return retval;
00058 }
00059 
00060 // For Wireless Interfaces...
00061 int WvInterface::req(int ioctl_num, struct iwreq *ifr)
00062 {
00063     int sock, retval;
00064     
00065     sock = socket(AF_INET, SOCK_STREAM, 0);
00066     strncpy(ifr->ifr_name, name, IFNAMSIZ-1);
00067     ifr->ifr_name[IFNAMSIZ-1] = 0;
00068     
00069     retval = ioctl(sock, ioctl_num, ifr);
00070     if (retval)
00071         retval = errno;
00072     close(sock);
00073     return retval;
00074 }
00075                                                 
00076 
00077 // forget all stored information about the address(es) of this interface
00078 void WvInterface::rescan()
00079 {
00080     if (my_hwaddr)
00081     {
00082         delete my_hwaddr;
00083         my_hwaddr = NULL;
00084     }
00085     
00086     if (my_ipaddr)
00087     {
00088         delete my_ipaddr;
00089         my_ipaddr = NULL;
00090     }
00091 }
00092 
00093 
00094 // get the hardware address of this interface
00095 const WvAddr &WvInterface::hwaddr()
00096 {
00097     struct ifreq ifr;
00098     
00099     if (!my_hwaddr)
00100     {
00101         if (req(SIOCGIFHWADDR, &ifr))
00102             my_hwaddr = new WvStringAddr("Unknown", WvEncap::Unknown);
00103         else
00104             my_hwaddr = WvAddr::gen(&ifr.ifr_hwaddr);
00105     }
00106     return *my_hwaddr;
00107 }
00108 
00109 
00110 // get the local IP net of this interface
00111 const WvIPNet &WvInterface::ipaddr()
00112 {
00113     struct ifreq ifr, ifr2;
00114     
00115     if (!my_ipaddr)
00116     {
00117         ifr.ifr_addr.sa_family = AF_INET;
00118         ifr2.ifr_netmask.sa_family = AF_INET;
00119         if (req(SIOCGIFADDR, &ifr) || req(SIOCGIFNETMASK, &ifr2))
00120             my_ipaddr = new WvIPNet();
00121         else
00122             my_ipaddr = new WvIPNet(&ifr.ifr_addr, &ifr2.ifr_netmask);
00123     }
00124     
00125     return *my_ipaddr;
00126 }
00127 
00128 
00129 // get the point-to-point IP address of this interface
00130 const WvIPAddr WvInterface::dstaddr()
00131 {
00132     struct ifreq ifr;
00133     ifr.ifr_dstaddr.sa_family = AF_INET;
00134     if (!(getflags() & IFF_POINTOPOINT) || req(SIOCGIFDSTADDR, &ifr))
00135         return WvIPAddr();
00136     else
00137         return WvIPAddr(&ifr.ifr_dstaddr);
00138 }
00139 
00140 
00141 int WvInterface::getflags()
00142 {
00143     struct ifreq ifr;
00144     int retval = req(SIOCGIFFLAGS, &ifr);
00145     if (retval)
00146         valid = false;
00147     return ifr.ifr_flags;
00148 }
00149 
00150 
00151 int WvInterface::setflags(int clear, int set)
00152 {
00153     struct ifreq ifr;
00154 
00155     int retval = req(SIOCGIFFLAGS, &ifr);
00156     if (retval)
00157         return retval;
00158     int newflags = (ifr.ifr_flags & ~clear) | set;
00159     if (newflags != ifr.ifr_flags)
00160     {
00161         ifr.ifr_flags = newflags;
00162         retval = req(SIOCSIFFLAGS, &ifr);
00163         if (retval && retval != EACCES && retval != EPERM)
00164             err.perror(WvString("SetFlags %s", name));
00165     }
00166     return retval;
00167 }
00168 
00169 
00170 void WvInterface::up(bool enable)
00171 {
00172     setflags(IFF_UP, enable ? IFF_UP : 0);
00173     rescan();
00174 }
00175 
00176 
00177 bool WvInterface::isup()
00178 {
00179     return (valid && (getflags() & IFF_UP)) ? 1 : 0;
00180 }
00181 
00182 
00183 void WvInterface::promisc(bool enable)
00184 {
00185     setflags(IFF_PROMISC, enable ? IFF_PROMISC : 0);
00186 }
00187 
00188 
00189 bool WvInterface::ispromisc()
00190 {
00191     return (getflags() & IFF_PROMISC) ? 1 : 0;
00192 }
00193 
00194 
00195 int WvInterface::setipaddr(const WvIPNet &addr)
00196 {
00197     struct ifreq ifr;
00198     struct sockaddr *sa;
00199     size_t len;
00200     int sock;
00201     WvIPAddr none;
00202     
00203     if (addr != ipaddr())
00204         err(WvLog::Info, "Changing %s address to %s (%s bits)\n", name,
00205             addr.base(), addr.bits());
00206     
00207     sock = socket(AF_INET, SOCK_STREAM, 0);
00208     strncpy(ifr.ifr_name, name, IFNAMSIZ-1);
00209     ifr.ifr_name[IFNAMSIZ-1] = 0;
00210     ifr.ifr_addr.sa_family = AF_INET;
00211 
00212     len = min(sizeof(sockaddr), addr.sockaddr_len());
00213 
00214     sa = addr.sockaddr();
00215     memcpy(&ifr.ifr_addr, sa, len);
00216     delete sa;
00217     if (ioctl(sock, SIOCSIFADDR, &ifr))
00218     {
00219         if (errno != EACCES && errno != EPERM)
00220             err.perror(WvString("SetIfAddress %s", name));
00221         close(sock);
00222         return -1;
00223     }
00224     
00225     // 2.1 kernels error when we try to change netmask/broadcast for
00226     // a 0.0.0.0 address.
00227     if (addr.base() != none)
00228     {
00229         sa = addr.netmask().sockaddr();
00230         memcpy(&ifr.ifr_netmask, sa, len);
00231         delete sa;
00232         if (ioctl(sock, SIOCSIFNETMASK, &ifr))
00233         {
00234             if (errno != EACCES && errno != EPERM)
00235                 err.perror(WvString("SetNetmask %s", name));
00236             close(sock);
00237             return -1;
00238         }
00239         
00240         if (!strchr(name, ':')) // otherwise, an alias, and no broadcast addr!
00241         {
00242             sa = addr.broadcast().sockaddr();
00243             memcpy(&ifr.ifr_broadaddr, sa, len);
00244             delete sa;
00245             if (ioctl(sock, SIOCSIFBRDADDR, &ifr))
00246             {
00247                 if (errno != EACCES && errno != EPERM)
00248                     err.perror(WvString("SetBroadcast %s", name));
00249                 close(sock);
00250                 return -1;
00251             }
00252         }
00253     }
00254     
00255     // addroute(addr); // not necessary on 2.1 and higher kernels
00256     close(sock);
00257 
00258     rescan();
00259     return 0;
00260 }
00261 
00262 
00263 int WvInterface::setmtu(int mtu)
00264 {
00265     struct ifreq ifr;
00266     ifr.ifr_mtu = mtu;
00267     int retval = req(SIOCSIFMTU, &ifr);
00268     if (retval && retval != EACCES && retval != EPERM)
00269         err.perror(WvString("SetMTU %s", name));
00270     return retval;
00271 }
00272 
00273 
00274 int WvInterface::sethwaddr(const WvAddr &addr)
00275 {
00276     struct ifreq ifr;
00277     sockaddr *saddr = addr.sockaddr();
00278     memcpy(& ifr.ifr_hwaddr, saddr, addr.sockaddr_len());
00279     delete saddr;
00280 
00281     bool wasup = isup();
00282     if (wasup)
00283         up(false);
00284         
00285     int retval = req(SIOCSIFHWADDR, &ifr);
00286     if (retval && retval != EACCES && retval != EPERM)
00287         err.perror(WvString("SetHWAddr %s", name));
00288 
00289     if (wasup)
00290         up(true);
00291 
00292     rescan();
00293     return retval;
00294 }
00295 
00296 
00297 // Fill a routing table entry with the given information.
00298 void WvInterface::fill_rte(struct rtentry *rte, char ifname[17],
00299                            const WvIPNet &dest, const WvIPAddr &gw,
00300                            int metric)
00301 {
00302     struct sockaddr *net, *mask, *gwaddr;
00303     size_t len;
00304     bool is_direct = (gw == WvIPAddr());
00305     bool is_host = dest.is_host();
00306     
00307     memset(rte, 0, sizeof(struct rtentry));
00308     rte->rt_metric = metric + 1;
00309     
00310     strncpy(ifname, name, 17);
00311     ifname[17-1] = 0;
00312     rte->rt_dev = ifname;
00313 
00314     len = min(sizeof(sockaddr), dest.sockaddr_len());
00315     
00316     net = dest.network().sockaddr();
00317     memcpy(&rte->rt_dst, net, len);
00318     delete net;
00319     
00320     if (!is_host)
00321     {
00322         mask = dest.netmask().sockaddr();
00323         memcpy(&rte->rt_genmask, mask, len);
00324         delete mask;
00325     }
00326 
00327     if (!is_direct)
00328     {
00329         gwaddr = gw.sockaddr();
00330         memcpy(&rte->rt_gateway, gwaddr, len);
00331         delete gwaddr;
00332     }
00333     
00334     rte->rt_flags = (RTF_UP
00335                     | (is_host ? RTF_HOST : 0)
00336                     | (is_direct ? 0 : RTF_GATEWAY));
00337 }
00338 
00339 
00340 int WvInterface::really_addroute(const WvIPNet &dest, const WvIPAddr &gw,
00341                  const WvIPAddr &src, int metric, WvStringParm table,
00342                  bool shutup)
00343 {
00344     struct rtentry rte;
00345     char ifname[17];
00346     int sock;
00347     WvString deststr(dest), gwstr(gw), metr(metric), srcstr(src);
00348 
00349     // FIXME: There has got to be a better way to do this.
00350     const char * const argvnosrc[] = {
00351         "ip", "route", "add",
00352         deststr,
00353         "table", table,
00354         "dev", name,
00355         "via", gwstr,
00356         "metric", metr,
00357         NULL
00358     };
00359 
00360     const char * const argvsrc[] = {
00361         "ip", "route", "add",
00362         deststr,
00363         "table", table,
00364         "dev", name,
00365         "via", gwstr,
00366         "src", srcstr,
00367         "metric", metr,
00368         NULL
00369     };
00370 
00371     WvIPAddr zero;
00372     const char * const * argv;
00373     if (src != zero)
00374         argv = argvsrc;
00375     else
00376         argv = argvnosrc;
00377 
00378     if (dest.is_default() || table != "default")
00379     {
00380         err(WvLog::Debug2, "addroute: ");
00381         for (int i = 0; argv[i]; i++)
00382             err(WvLog::Debug2, "%s ", argv[i]);
00383         err(WvLog::Debug2, "\n");
00384         
00385         WvSubProc checkProc;
00386         checkProc.startv(*argv, argv);
00387         checkProc.wait(-1);
00388 
00389         //if (WvPipe(argv[0], argv, false, false, false).finish() != 242)
00390         if (checkProc.estatus != 242)
00391         {
00392             // added a default route via the subprogram
00393             // 242 is the magic "WvPipe could not exec program..." exit code.
00394             return 0;
00395         }
00396     }
00397     
00398     // if we get here, it is not a default route or the 'ip' command is
00399     // broken somehow.
00400 
00401     fill_rte(&rte, ifname, dest, gw, metric);
00402     
00403     sock = socket(AF_INET, SOCK_STREAM, 0);
00404     if (ioctl(sock, SIOCADDRT, &rte))
00405     {
00406         if (errno != EACCES && errno != EPERM && errno != EEXIST
00407           && errno != ENOENT)
00408         {
00409             if (!shutup)
00410                 err.perror(WvString("AddRoute '%s' %s (up=%s)",
00411                                     name, dest, isup()));
00412         }
00413         close(sock);
00414         return -1;
00415     }
00416     
00417     close(sock);
00418     return 0;
00419 }
00420 
00421 
00422 int WvInterface::addroute(const WvIPNet &dest, const WvIPAddr &gw,
00423                           const WvIPAddr &src, int metric, WvStringParm table)
00424 {
00425     WvIPAddr zero;
00426     int ret;
00427     
00428     // The kernel (2.4.19) sometimes tries to protect us from ourselves by
00429     // not letting us create a route via 'x' if 'x' isn't directly reachable
00430     // on the same interface.  This is non-helpful to us in some cases,
00431     // particularly with FreeSwan's screwy lying kernel routes.  Anyway,
00432     // the kernel people weren't clever enough to check that the routing
00433     // table *stays* self-consistent, so we add an extra route, then we
00434     // create our real route, and then we delete the extra route again.
00435     // Blah.
00436     // 
00437     // Using metric 255 should make it not the same as any other route.
00438     if (gw != zero)
00439         really_addroute(gw, zero, zero, 255, "default", true);
00440     ret = really_addroute(dest, gw, src, metric, table, false);
00441     if (gw != zero)
00442         delroute(gw, zero, 255, "default");
00443     
00444     return ret;
00445 }
00446 
00447 
00448 // add a route with no gateway, ie. direct to interface
00449 int WvInterface::addroute(const WvIPNet &dest, int metric,
00450                           WvStringParm table)
00451 {
00452     return addroute(dest, WvIPAddr(), WvIPAddr(), metric, table);
00453 }
00454 
00455 
00456 int WvInterface::delroute(const WvIPNet &dest, const WvIPAddr &gw,
00457                           int metric, WvStringParm table)
00458 {
00459     struct rtentry rte;
00460     char ifname[17];
00461     int sock;
00462     WvString deststr(dest), gwstr(gw), metr(metric);
00463     const char *argv[] = {
00464         "ip", "route", "del",
00465         deststr,
00466         "table", table,
00467         "dev", name,
00468         "via", gwstr,
00469         "metric", metr,
00470         NULL
00471     };
00472     
00473     if (dest.is_default() || table != "default")
00474     {
00475         err(WvLog::Debug2, "addroute: ");
00476         for (int i = 0; argv[i]; i++)
00477             err(WvLog::Debug2, "%s ", argv[i]);
00478         err(WvLog::Debug2, "\n");
00479         
00480         WvSubProc checkProc;
00481         checkProc.startv(*argv, (char * const *)argv);
00482         checkProc.wait(-1);
00483 
00484         //if (WvPipe(argv[0], argv, false, false, false).finish() == 0)
00485         if (!WEXITSTATUS(checkProc.estatus))
00486         {
00487             // successfully deleted a default route via the subprogram
00488             return 0;
00489         }
00490     }
00491 
00492     fill_rte(&rte, ifname, dest, gw, metric);
00493     
00494     sock = socket(AF_INET, SOCK_STREAM, 0);
00495     if (ioctl(sock, SIOCDELRT, &rte))
00496     {
00497         if (errno != EACCES && errno != EPERM && errno != EEXIST)
00498             err.perror(WvString("DelRoute %s", name));
00499         close(sock);
00500         return -1;
00501     }
00502     
00503     close(sock);
00504     return 0;
00505 }
00506 
00507 
00508 // delete a route with no gateway, ie. direct to interface
00509 int WvInterface::delroute(const WvIPNet &dest, int metric, WvStringParm table)
00510 {
00511     return delroute(dest, WvIPAddr(), metric, table);
00512 }
00513 
00514 
00515 // add an ARP or proxy ARP entry on this interface
00516 int WvInterface::addarp(const WvIPNet &dest, const WvAddr &hw, bool proxy)
00517 {
00518     int sock;
00519     struct arpreq ar;
00520     struct sockaddr *sa;
00521     size_t len;
00522     
00523     sa = dest.network().sockaddr();
00524     len = min(dest.sockaddr_len(), sizeof(ar.arp_pa));
00525     memcpy(&ar.arp_pa, sa, len);
00526     delete sa;
00527     
00528     sa = hw.sockaddr();
00529     len = min(hw.sockaddr_len(), sizeof(ar.arp_ha));
00530     memcpy(&ar.arp_ha, sa, len);
00531     delete sa;
00532     
00533     sa = dest.netmask().sockaddr();
00534     len = min(dest.sockaddr_len(), sizeof(ar.arp_netmask));
00535     memcpy(&ar.arp_netmask, sa, len);
00536     delete sa;
00537     
00538     strncpy(ar.arp_dev, name, sizeof(ar.arp_dev));
00539     
00540     ar.arp_flags = (ATF_COM | ATF_PERM
00541                     | (proxy ? ATF_PUBL : 0)
00542                     | (proxy && dest.is_host() ? ATF_NETMASK : 0));
00543     
00544     sock = socket(AF_INET, SOCK_STREAM, 0);
00545     if (ioctl(sock, SIOCSARP, &ar))
00546     {
00547         if (errno != EACCES && errno != EPERM)
00548             err.perror(WvString("AddARP %s", name));
00549         close(sock);
00550         return -1;
00551     }
00552     
00553     close(sock);
00554     return 0;
00555 }
00556 
00557 
00558 bool WvInterface::isarp()
00559 {
00560     int f = getflags();
00561     return !(f & (IFF_NOARP | IFF_LOOPBACK)) && (f & IFF_BROADCAST);
00562 }
00563 
00564 
00565 static char *find_ifname(char *line)
00566 {
00567     if (!line) return NULL;
00568     
00569     // skip leading whitespace
00570     while (*line==' ') line++;
00571 
00572     // everything before the last colon is the device name
00573     char *cptr = strrchr(line, ':');
00574     if (!cptr)
00575         return NULL;
00576     *cptr = 0;
00577     return line;
00578 }
00579 
00580 
00581 ////////////////////////////////////////////// WvInterfaceDict
00582 
00583 
00584 WvInterfaceDict::WvInterfaceDict() : log("Net Interface", WvLog::Info)
00585 {
00586     links++;
00587     update();
00588 }
00589 
00590 
00591 WvInterfaceDict::~WvInterfaceDict()
00592 {
00593     links--;
00594     
00595     if (!links)
00596         slist.zap();
00597 }
00598 
00599 
00600 // auto-fill the list of interfaces using the list from /proc/net/dev.
00601 //
00602 // I wish there was a better way to do this, but the SIOCGIFCONF ioctl
00603 // ignores 'down' interfaces, which is not what we want.
00604 //
00605 void WvInterfaceDict::update()
00606 {
00607     int sock;
00608     struct ifconf ifconf;
00609     char buf[sizeof(ifconf.ifc_req) * 100]; // room for 100 interfaces
00610     WvLog err(log.split(WvLog::Error));
00611     WvFile procdev("/proc/net/dev", O_RDONLY);
00612     char *ifname;
00613 
00614         
00615     // mark all interfaces in list invalid for now
00616     Iter i(*this);
00617     for (i.rewind(); i.next(); )
00618         i().valid = false;
00619     
00620 
00621     // get list of all non-aliased interfaces from /proc/net/dev
00622     
00623     
00624     // skip the two header lines
00625     procdev.getline(-1); procdev.getline(-1);
00626     
00627     // add/validate existing interfaces
00628     while ((ifname = find_ifname(procdev.getline(-1))) != NULL)
00629     {
00630         WvString s(ifname);
00631         WvInterface *ifc = (*this)[s];
00632         
00633         if (!ifc)
00634         {
00635             ifc = new WvInterface(ifname);
00636             slist.add(ifc, true);
00637             log(WvLog::Debug3, "Found %-16s  [%s]\n", ifname, ifc->hwaddr());
00638         }
00639         else
00640             ifc->rescan();
00641         ifc->valid = true;
00642     }
00643 
00644     
00645     // get list of "up" and aliased interfaces with SIOCGIFCONF ioctl
00646     
00647     
00648     ifconf.ifc_buf = buf;
00649     ifconf.ifc_len = sizeof(buf);
00650     
00651     sock = socket(AF_INET, SOCK_STREAM, 0);
00652     if (! ioctl(sock, SIOCGIFCONF, &ifconf))
00653     {
00654         int count, max = ifconf.ifc_len / sizeof(ifconf.ifc_req[0]);
00655         
00656         for (count = 0; count < max; count++)
00657         {
00658             struct ifreq &ifr = ifconf.ifc_req[count];
00659             WvInterface *ifc = (*this)[ifr.ifr_name];
00660             
00661             if (!ifc)
00662             {
00663                 ifc = new WvInterface(ifr.ifr_name);
00664                 slist.add(ifc, true);
00665             }
00666             else
00667                 ifc->rescan();
00668             ifc->valid = true;
00669         }
00670     }
00671     close(sock);
00672 }
00673 
00674 
00675 // determine if the given address belongs to the local system
00676 bool WvInterfaceDict::islocal(const WvAddr &addr)
00677 {
00678     static WvIPAddr bcast("255.255.255.255"); // always a local address!
00679     
00680     if (addr == bcast)
00681         return true;
00682     
00683     Iter i(*this);
00684     for (i.rewind(); i.next(); )
00685     {
00686         WvInterface &ifc(*i);
00687         if (!ifc.valid) continue;
00688         
00689         if (ifc.ipaddr() == addr || ifc.ipaddr().base() == addr
00690           || ifc.ipaddr().broadcast() == addr)
00691             return true;
00692 
00693         if (ifc.hwaddr() == addr)
00694             return true;
00695     }
00696     
00697     return false;
00698 }
00699 
00700 
00701 bool WvInterfaceDict::on_local_net(const WvIPNet &addr)
00702 {
00703     WvIPAddr zero;
00704     
00705     if (islocal(addr))
00706         return true;
00707     
00708     Iter i(*this);
00709     for (i.rewind(); i.next(); )
00710     {
00711         WvInterface &ifc = *i;
00712         if (!ifc.valid) continue;
00713         
00714         if (ifc.isup() && WvIPAddr(ifc.ipaddr()) != zero
00715           && ifc.ipaddr().includes(addr))
00716             return true;
00717     }
00718     
00719     return false;
00720 }
00721 
00722 #else
00723 
00724 WvInterfaceDictBase WvInterfaceDict::slist(15);
00725 
00726 int WvInterface::getinfo(struct ifreq *ifr, int ioctl_num) { return 0; }
00727 void WvInterface::fill_rte(struct rtentry *rte, char *ifname,
00728                   const WvIPNet &dest, const WvIPAddr &gw,
00729                   int metric) {}
00730 
00731 WvInterface::WvInterface(WvStringParm _name) :err("fake") {}
00732 WvInterface::~WvInterface() {}
00733 
00734 void WvInterface::rescan() {}
00735 const WvIPNet &WvInterface::ipaddr() { return *(new WvIPNet()); }
00736 const WvIPAddr WvInterface::dstaddr() { return *(new WvIPAddr()); }
00737 int WvInterface::getflags() { return 0; }
00738 int WvInterface::setflags(int clear, int set) { return 0; }
00739 bool WvInterface::isup() { return true; }
00740 void WvInterface::up(bool enable) {}
00741 bool WvInterface::ispromisc() { return true; }
00742 void WvInterface::promisc(bool enable) {}
00743 int WvInterface::setipaddr(const WvIPNet &addr) { return 0; }
00744 int WvInterface::setmtu(int mtu) { return 0; }
00745 int WvInterface::addroute(const WvIPNet &dest, int metric = 0,
00746                  WvStringParm table = "default") { return 0; }
00747 int WvInterface::addroute(const WvIPNet &dest, const WvIPAddr &gw,
00748                  int metric = 0, WvStringParm table = "default") { return 0; }
00749 int WvInterface::delroute(const WvIPNet &dest, int metric = 0,
00750                  WvStringParm table = "default") { return 0; }
00751 int WvInterface::delroute(const WvIPNet &dest, const WvIPAddr &gw,
00752                  int metric = 0, WvStringParm table = "default") { return 0; }
00753 bool WvInterface::isarp() { return true; }
00754 int WvInterface::addarp(const WvIPNet &proto, const WvAddr &hw, bool proxy)
00755                  { return 0; }
00756 
00757 WvInterfaceDict::WvInterfaceDict() :log("fake") {}
00758 WvInterfaceDict::~WvInterfaceDict() {}
00759 
00760 void WvInterfaceDict::update() {}
00761 bool WvInterfaceDict::islocal(const WvAddr &addr) { return true; }
00762 bool WvInterfaceDict::on_local_net(const WvIPNet &addr) { return true; }
00763 
00764 #endif

Generated on Wed Dec 15 15:08:11 2004 for WvStreams by  doxygen 1.3.9.1