Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | 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 Tue Oct 5 01:09:20 2004 for WvStreams by doxygen 1.3.7