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