WvStreams
wvinterface.cc
1/*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4 *
5 * A WvInterface stores information about a particular network interface.
6 */
7
8#include "wvinterface.h"
9#if 1
10// FIXME: this file doesn't compile on anything other than Linux
11
12#include "wvsubproc.h"
13#include "wvfile.h"
14
15#include <sys/ioctl.h>
16#include <sys/socket.h>
17#include <sys/wait.h>
18#include <net/if_arp.h>
19#include <net/route.h>
20#include <unistd.h>
21#include <errno.h>
22#include <linux/sockios.h>
23
24#define _LINUX_IF_H /* Hack to prevent loading linux/if.h */
25#include <linux/wireless.h>
26
27#define min(x,y) ({ \
28 const typeof(x) _x = (x); \
29 const typeof(y) _y = (y); \
30 (void) (&_x == &_y); \
31 _x < _y ? _x : _y; })
32
33WvInterfaceDictBase WvInterfaceDict::slist(15);
34int WvInterfaceDict::links = 0;
35
36
37WvInterface::WvInterface(WvStringParm _name) :
38 err("Net Interface", WvLog::Error), name(_name)
39{
40 my_hwaddr = my_ipaddr = NULL;
41 valid = true;
42}
43
44
45WvInterface::~WvInterface()
46{
47 rescan();
48}
49
50
51int WvInterface::req(int ioctl_num, struct ifreq *ifr)
52{
53 int sock, retval;
54
55 sock = socket(AF_INET, SOCK_STREAM, 0);
56 strncpy(ifr->ifr_name, name, IFNAMSIZ-1);
57 ifr->ifr_name[IFNAMSIZ-1] = 0;
58
59 retval = ioctl(sock, ioctl_num, ifr);
60 if (retval == -1)
61 retval = errno;
62 close(sock);
63 return retval;
64}
65
66// For Wireless Interfaces...
67int WvInterface::req(int ioctl_num, struct iwreq *ifr)
68{
69 int sock, retval;
70
71 sock = socket(AF_INET, SOCK_STREAM, 0);
72 strncpy(ifr->ifr_name, name, IFNAMSIZ-1);
73 ifr->ifr_name[IFNAMSIZ-1] = 0;
74
75 retval = ioctl(sock, ioctl_num, ifr);
76 if (retval)
77 retval = errno;
78 close(sock);
79 return retval;
80}
81
82
83// forget all stored information about the address(es) of this interface
85{
86 if (my_hwaddr)
87 {
88 delete my_hwaddr;
89 my_hwaddr = NULL;
90 }
91
92 if (my_ipaddr)
93 {
94 delete my_ipaddr;
95 my_ipaddr = NULL;
96 }
97}
98
99
100// get the hardware address of this interface
102{
103 struct ifreq ifr;
104
105 if (!my_hwaddr)
106 {
107 if (req(SIOCGIFHWADDR, &ifr))
108 my_hwaddr = new WvStringAddr("Unknown", WvEncap::Unknown);
109 else
110 my_hwaddr = WvAddr::gen(&ifr.ifr_hwaddr);
111 }
112 return *my_hwaddr;
113}
114
115
116// get the local IP net of this interface
118{
119 struct ifreq ifr, ifr2;
120
121 if (!my_ipaddr)
122 {
123 ifr.ifr_addr.sa_family = AF_INET;
124 ifr2.ifr_netmask.sa_family = AF_INET;
125 if (req(SIOCGIFADDR, &ifr) || req(SIOCGIFNETMASK, &ifr2))
126 my_ipaddr = new WvIPNet();
127 else
128 my_ipaddr = new WvIPNet(&ifr.ifr_addr, &ifr2.ifr_netmask);
129 }
130
131 return *my_ipaddr;
132}
133
134
135// get the point-to-point IP address of this interface
137{
138 struct ifreq ifr;
139 ifr.ifr_dstaddr.sa_family = AF_INET;
140 if (!(getflags() & IFF_POINTOPOINT) || req(SIOCGIFDSTADDR, &ifr))
141 return WvIPAddr();
142 else
143 return WvIPAddr(&ifr.ifr_dstaddr);
144}
145
146
148{
149 struct ifreq ifr;
150 int retval = req(SIOCGIFFLAGS, &ifr);
151 if (retval)
152 valid = false;
153 return retval? 0: ifr.ifr_flags;
154}
155
156
157int WvInterface::setflags(int clear, int set)
158{
159 struct ifreq ifr;
160
161 int retval = req(SIOCGIFFLAGS, &ifr);
162 if (retval)
163 return retval;
164 int newflags = (ifr.ifr_flags & ~clear) | set;
165 if (newflags != ifr.ifr_flags)
166 {
167 ifr.ifr_flags = newflags;
168 retval = req(SIOCSIFFLAGS, &ifr);
169 if (retval && retval != EACCES && retval != EPERM)
170 err.perror(WvString("SetFlags %s", name));
171 }
172 return retval;
173}
174
175
176void WvInterface::up(bool enable)
177{
178 setflags(IFF_UP, enable ? IFF_UP : 0);
179 rescan();
180}
181
182
184{
185 return (valid && (getflags() & IFF_UP)) ? 1 : 0;
186}
187
188
189void WvInterface::promisc(bool enable)
190{
191 setflags(IFF_PROMISC, enable ? IFF_PROMISC : 0);
192}
193
194
195int WvInterface::ptp(bool enable, const WvIPNet &addr)
196{
197 struct ifreq ifr;
198 sockaddr *saddr = addr.sockaddr();
199 memcpy(&ifr.ifr_dstaddr, saddr, addr.sockaddr_len());
200
201 int retval = req(SIOCSIFDSTADDR, &ifr);
202 if (retval && retval != EACCES && retval != EPERM)
203 {
204 err.perror(WvString("Set PointoPoint %s", name));
205 return retval;
206 }
207
208 return setflags(IFF_POINTOPOINT, enable ? IFF_POINTOPOINT : 0);
209}
210
211
213{
214 return (getflags() & IFF_PROMISC) ? 1 : 0;
215}
216
217
219{
220 struct ifreq ifr;
221 struct sockaddr *sa;
222 size_t len;
223 int sock;
224 WvIPAddr none;
225
226 if (addr != ipaddr())
227 err(WvLog::Info, "Changing %s address to %s (%s bits)\n", name,
228 addr.base(), addr.bits());
229
230 sock = socket(AF_INET, SOCK_STREAM, 0);
231 strncpy(ifr.ifr_name, name, IFNAMSIZ-1);
232 ifr.ifr_name[IFNAMSIZ-1] = 0;
233 ifr.ifr_addr.sa_family = AF_INET;
234
235 len = min(sizeof(sockaddr), addr.sockaddr_len());
236
237 sa = addr.sockaddr();
238 memcpy(&ifr.ifr_addr, sa, len);
239 delete sa;
240 if (ioctl(sock, SIOCSIFADDR, &ifr))
241 {
242 if (errno != EACCES && errno != EPERM)
243 err.perror(WvString("SetIfAddress %s", name));
244 close(sock);
245 return -1;
246 }
247
248 // 2.1 kernels error when we try to change netmask/broadcast for
249 // a 0.0.0.0 address.
250 if (addr.base() != none)
251 {
252 sa = addr.netmask().sockaddr();
253 memcpy(&ifr.ifr_netmask, sa, len);
254 delete sa;
255 if (ioctl(sock, SIOCSIFNETMASK, &ifr))
256 {
257 if (errno != EACCES && errno != EPERM)
258 err.perror(WvString("SetNetmask %s", name));
259 close(sock);
260 return -1;
261 }
262
263 if (!strchr(name, ':')) // otherwise, an alias, and no broadcast addr!
264 {
265 sa = addr.broadcast().sockaddr();
266 memcpy(&ifr.ifr_broadaddr, sa, len);
267 delete sa;
268 if (ioctl(sock, SIOCSIFBRDADDR, &ifr))
269 {
270 if (errno != EACCES && errno != EPERM)
271 err.perror(WvString("SetBroadcast %s", name));
272 close(sock);
273 return -1;
274 }
275 }
276 }
277
278 // addroute(addr); // not necessary on 2.1 and higher kernels
279 close(sock);
280
281 rescan();
282 return 0;
283}
284
285
287{
288 struct ifreq ifr;
289 ifr.ifr_mtu = mtu;
290 int retval = req(SIOCSIFMTU, &ifr);
291 if (retval && retval != EACCES && retval != EPERM)
292 err.perror(WvString("SetMTU %s", name));
293 return retval;
294}
295
296
298{
299 struct ifreq ifr;
300 sockaddr *saddr = addr.sockaddr();
301 memcpy(& ifr.ifr_hwaddr, saddr, addr.sockaddr_len());
302 delete saddr;
303
304 bool wasup = isup();
305 if (wasup)
306 up(false);
307
308 int retval = req(SIOCSIFHWADDR, &ifr);
309 if (retval && retval != EACCES && retval != EPERM)
310 err.perror(WvString("SetHWAddr %s", name));
311
312 if (wasup)
313 up(true);
314
315 rescan();
316 return retval;
317}
318
319
320// Fill a routing table entry with the given information.
321void WvInterface::fill_rte(struct rtentry *rte, char ifname[17],
322 const WvIPNet &dest, const WvIPAddr &gw,
323 int metric)
324{
325 struct sockaddr *net, *mask, *gwaddr;
326 size_t len;
327 bool is_direct = (gw == WvIPAddr());
328 bool is_host = dest.is_host();
329
330 memset(rte, 0, sizeof(struct rtentry));
331 rte->rt_metric = metric + 1;
332
333 strncpy(ifname, name, 17);
334 ifname[17-1] = 0;
335 rte->rt_dev = ifname;
336
337 len = min(sizeof(sockaddr), dest.sockaddr_len());
338
339 net = dest.network().sockaddr();
340 memcpy(&rte->rt_dst, net, len);
341 delete net;
342
343 if (!is_host)
344 {
345 mask = dest.netmask().sockaddr();
346 memcpy(&rte->rt_genmask, mask, len);
347 delete mask;
348 }
349
350 if (!is_direct)
351 {
352 gwaddr = gw.sockaddr();
353 memcpy(&rte->rt_gateway, gwaddr, len);
354 delete gwaddr;
355 }
356
357 rte->rt_flags = (RTF_UP
358 | (is_host ? RTF_HOST : 0)
359 | (is_direct ? 0 : RTF_GATEWAY));
360}
361
362
363int WvInterface::really_addroute(const WvIPNet &dest, const WvIPAddr &gw,
364 const WvIPAddr &src, int metric, WvStringParm table,
365 bool shutup)
366{
367 struct rtentry rte;
368 char ifname[17];
369 int sock;
370 WvString deststr(dest), gwstr(gw), metr(metric), srcstr(src);
371
372 // FIXME: There has got to be a better way to do this.
373 const char * const argvnosrc[] = {
374 "ip", "route", "add",
375 deststr,
376 "table", table,
377 "dev", name,
378 "via", gwstr,
379 "metric", metr,
380 NULL
381 };
382
383 const char * const argvsrc[] = {
384 "ip", "route", "add",
385 deststr,
386 "table", table,
387 "dev", name,
388 "via", gwstr,
389 "src", srcstr,
390 "metric", metr,
391 NULL
392 };
393
394 WvIPAddr zero;
395 const char * const * argv;
396 if (src != zero)
397 argv = argvsrc;
398 else
399 argv = argvnosrc;
400
401 if (dest.is_default() || table != "default")
402 {
403 err(WvLog::Debug2, "addroute: ");
404 for (int i = 0; argv[i]; i++)
405 err(WvLog::Debug2, "%s ", argv[i]);
406 err(WvLog::Debug2, "\n");
407
408 WvSubProc checkProc;
409 checkProc.startv(*argv, argv);
410 checkProc.wait(-1);
411
412 //if (WvPipe(argv[0], argv, false, false, false).finish() != 242)
413 if (checkProc.estatus != 242)
414 {
415 // added a default route via the subprogram
416 // 242 is the magic "WvPipe could not exec program..." exit code.
417 return 0;
418 }
419 }
420
421 // if we get here, it is not a default route or the 'ip' command is
422 // broken somehow.
423
424 fill_rte(&rte, ifname, dest, gw, metric);
425
426 sock = socket(AF_INET, SOCK_STREAM, 0);
427 if (ioctl(sock, SIOCADDRT, &rte))
428 {
429 if (errno != EACCES && errno != EPERM && errno != EEXIST
430 && errno != ENOENT)
431 {
432 if (!shutup)
433 err.perror(WvString("AddRoute '%s' %s (up=%s)",
434 name, dest, isup()));
435 }
436 close(sock);
437 return -1;
438 }
439
440 close(sock);
441 return 0;
442}
443
444
445int WvInterface::addroute(const WvIPNet &dest, const WvIPAddr &gw,
446 const WvIPAddr &src, int metric, WvStringParm table)
447{
448 WvIPAddr zero;
449 int ret;
450
451 // The kernel (2.4.19) sometimes tries to protect us from ourselves by
452 // not letting us create a route via 'x' if 'x' isn't directly reachable
453 // on the same interface. This is non-helpful to us in some cases,
454 // particularly with FreeSwan's screwy lying kernel routes. Anyway,
455 // the kernel people weren't clever enough to check that the routing
456 // table *stays* self-consistent, so we add an extra route, then we
457 // create our real route, and then we delete the extra route again.
458 // Blah.
459 //
460 // Using metric 255 should make it not the same as any other route.
461 if (gw != zero)
462 really_addroute(gw, zero, zero, 255, "default", true);
463 ret = really_addroute(dest, gw, src, metric, table, false);
464 if (gw != zero)
465 delroute(gw, zero, 255, "default");
466
467 return ret;
468}
469
470
471// add a route with no gateway, ie. direct to interface
472int WvInterface::addroute(const WvIPNet &dest, int metric,
473 WvStringParm table)
474{
475 return addroute(dest, WvIPAddr(), WvIPAddr(), metric, table);
476}
477
478
479int WvInterface::delroute(const WvIPNet &dest, const WvIPAddr &gw,
480 int metric, WvStringParm table)
481{
482 struct rtentry rte;
483 char ifname[17];
484 int sock;
485 WvString deststr(dest), gwstr(gw), metr(metric);
486 const char *argv[] = {
487 "ip", "route", "del",
488 deststr,
489 "table", table,
490 "dev", name,
491 "via", gwstr,
492 "metric", metr,
493 NULL
494 };
495
496 if (dest.is_default() || table != "default")
497 {
498 err(WvLog::Debug2, "delroute: ");
499 for (int i = 0; argv[i]; i++)
500 err(WvLog::Debug2, "%s ", argv[i]);
501 err(WvLog::Debug2, "\n");
502
503 WvSubProc checkProc;
504 checkProc.startv(*argv, (char * const *)argv);
505 checkProc.wait(-1);
506
507 //if (WvPipe(argv[0], argv, false, false, false).finish() == 0)
508 if (!WEXITSTATUS(checkProc.estatus))
509 {
510 // successfully deleted a default route via the subprogram
511 return 0;
512 }
513 }
514
515 fill_rte(&rte, ifname, dest, gw, metric);
516
517 sock = socket(AF_INET, SOCK_STREAM, 0);
518 if (ioctl(sock, SIOCDELRT, &rte))
519 {
520 if (errno != EACCES && errno != EPERM && errno != EEXIST)
521 err.perror(WvString("DelRoute %s", name));
522 close(sock);
523 return -1;
524 }
525
526 close(sock);
527 return 0;
528}
529
530
531// delete a route with no gateway, ie. direct to interface
532int WvInterface::delroute(const WvIPNet &dest, int metric, WvStringParm table)
533{
534 return delroute(dest, WvIPAddr(), metric, table);
535}
536
537
538// add an ARP or proxy ARP entry on this interface
539int WvInterface::addarp(const WvIPNet &dest, const WvAddr &hw, bool proxy)
540{
541 int sock;
542 struct arpreq ar;
543 struct sockaddr *sa;
544 size_t len;
545
546 sa = dest.network().sockaddr();
547 len = min(dest.sockaddr_len(), sizeof(ar.arp_pa));
548 memcpy(&ar.arp_pa, sa, len);
549 delete sa;
550
551 sa = hw.sockaddr();
552 len = min(hw.sockaddr_len(), sizeof(ar.arp_ha));
553 memcpy(&ar.arp_ha, sa, len);
554 delete sa;
555
556 sa = dest.netmask().sockaddr();
557 len = min(dest.sockaddr_len(), sizeof(ar.arp_netmask));
558 memcpy(&ar.arp_netmask, sa, len);
559 delete sa;
560
561 strncpy(ar.arp_dev, name, sizeof(ar.arp_dev));
562
563 ar.arp_flags = (ATF_COM | ATF_PERM
564 | (proxy ? ATF_PUBL : 0)
565 | (proxy && dest.is_host() ? ATF_NETMASK : 0));
566
567 sock = socket(AF_INET, SOCK_STREAM, 0);
568 if (ioctl(sock, SIOCSARP, &ar))
569 {
570 if (errno != EACCES && errno != EPERM)
571 err.perror(WvString("AddARP %s", name));
572 close(sock);
573 return -1;
574 }
575
576 close(sock);
577 return 0;
578}
579
580
582{
583 int f = getflags();
584 return !(f & (IFF_NOARP | IFF_LOOPBACK)) && (f & IFF_BROADCAST);
585}
586
587
588static char *find_ifname(char *line)
589{
590 if (!line) return NULL;
591
592 // skip leading whitespace
593 while (*line==' ') line++;
594
595 // everything before the last colon is the device name
596 char *cptr = strrchr(line, ':');
597 if (!cptr)
598 return NULL;
599 *cptr = 0;
600 return line;
601}
602
603
605
606
607WvInterfaceDict::WvInterfaceDict() : log("Net Interface", WvLog::Info)
608{
609 links++;
610 update();
611}
612
613
614WvInterfaceDict::~WvInterfaceDict()
615{
616 links--;
617
618 if (!links)
619 slist.zap();
620}
621
622
623// auto-fill the list of interfaces using the list from /proc/net/dev.
624//
625// I wish there was a better way to do this, but the SIOCGIFCONF ioctl
626// ignores 'down' interfaces, which is not what we want.
627//
628void WvInterfaceDict::update()
629{
630 int sock;
631 struct ifconf ifconf;
632 char buf[sizeof(ifconf.ifc_req) * 100]; // room for 100 interfaces
633 WvLog err(log.split(WvLog::Error));
634 WvFile procdev("/proc/net/dev", O_RDONLY);
635 char *ifname;
636
637
638 // mark all interfaces in list invalid for now
639 Iter i(*this);
640 for (i.rewind(); i.next(); )
641 i().valid = false;
642
643
644 // get list of all non-aliased interfaces from /proc/net/dev
645
646
647 // skip the two header lines
648 procdev.blocking_getline(-1); procdev.blocking_getline(-1);
649
650 // add/validate existing interfaces
651 while ((ifname = find_ifname(procdev.blocking_getline(-1))) != NULL)
652 {
653 WvString s(ifname);
654 WvInterface *ifc = (*this)[s];
655
656 if (!ifc)
657 {
658 ifc = new WvInterface(ifname);
659 slist.add(ifc, true);
660 log(WvLog::Debug3, "Found %-16s [%s]\n", ifname, ifc->hwaddr());
661 }
662 else
663 ifc->rescan();
664 ifc->valid = true;
665 }
666
667
668 // get list of "up" and aliased interfaces with SIOCGIFCONF ioctl
669
670
671 ifconf.ifc_buf = buf;
672 ifconf.ifc_len = sizeof(buf);
673
674 sock = socket(AF_INET, SOCK_STREAM, 0);
675 if (! ioctl(sock, SIOCGIFCONF, &ifconf))
676 {
677 int count, max = ifconf.ifc_len / sizeof(ifconf.ifc_req[0]);
678
679 for (count = 0; count < max; count++)
680 {
681 struct ifreq &ifr = ifconf.ifc_req[count];
682 WvInterface *ifc = (*this)[ifr.ifr_name];
683
684 if (!ifc)
685 {
686 ifc = new WvInterface(ifr.ifr_name);
687 slist.add(ifc, true);
688 }
689 else
690 ifc->rescan();
691 ifc->valid = true;
692 }
693 }
694 close(sock);
695}
696
697
698// determine if the given address belongs to the local system
699WvString WvInterfaceDict::islocal(const WvAddr &addr)
700{
701 static WvIPAddr bcast("255.255.255.255"); // always a local address!
702
703 if (addr == bcast)
704 return "lo";
705
706 Iter i(*this);
707 for (i.rewind(); i.next(); )
708 {
709 WvInterface &ifc(*i);
710 if (!ifc.valid) continue;
711
712 if (ifc.ipaddr() == addr || ifc.ipaddr().base() == addr
713 || ifc.ipaddr().broadcast() == addr)
714 return ifc.name;
715
716 if (ifc.hwaddr() == addr)
717 return ifc.name;
718 }
719
720 return WvString::null;
721}
722
723
724bool WvInterfaceDict::on_local_net(const WvIPNet &addr)
725{
726 WvIPAddr zero;
727
728 if (islocal(addr))
729 return true;
730
731 Iter i(*this);
732 for (i.rewind(); i.next(); )
733 {
734 WvInterface &ifc = *i;
735 if (!ifc.valid) continue;
736
737 if (ifc.isup() && WvIPAddr(ifc.ipaddr()) != zero
738 && ifc.ipaddr().includes(addr))
739 return true;
740 }
741
742 return false;
743}
744
745#else
746
747WvInterfaceDictBase WvInterfaceDict::slist(15);
748
749int WvInterface::getinfo(struct ifreq *ifr, int ioctl_num) { return 0; }
750void WvInterface::fill_rte(struct rtentry *rte, char *ifname,
751 const WvIPNet &dest, const WvIPAddr &gw,
752 int metric) {}
753
754WvInterface::WvInterface(WvStringParm _name) :err("fake") {}
755WvInterface::~WvInterface() {}
756
757void WvInterface::rescan() {}
758const WvIPNet &WvInterface::ipaddr() { return *(new WvIPNet()); }
759const WvIPAddr WvInterface::dstaddr() { return *(new WvIPAddr()); }
760int WvInterface::getflags() { return 0; }
761int WvInterface::setflags(int clear, int set) { return 0; }
762bool WvInterface::isup() { return true; }
763void WvInterface::up(bool enable) {}
764bool WvInterface::ispromisc() { return true; }
765void WvInterface::promisc(bool enable) {}
766int WvInterface::setipaddr(const WvIPNet &addr) { return 0; }
767int WvInterface::setmtu(int mtu) { return 0; }
768int WvInterface::addroute(const WvIPNet &dest, int metric = 0,
769 WvStringParm table = "default") { return 0; }
770int WvInterface::addroute(const WvIPNet &dest, const WvIPAddr &gw,
771 int metric = 0, WvStringParm table = "default") { return 0; }
772int WvInterface::delroute(const WvIPNet &dest, int metric = 0,
773 WvStringParm table = "default") { return 0; }
774int WvInterface::delroute(const WvIPNet &dest, const WvIPAddr &gw,
775 int metric = 0, WvStringParm table = "default") { return 0; }
776bool WvInterface::isarp() { return true; }
777int WvInterface::addarp(const WvIPNet &proto, const WvAddr &hw, bool proxy)
778 { return 0; }
779
780WvInterfaceDict::WvInterfaceDict() :log("fake") {}
781WvInterfaceDict::~WvInterfaceDict() {}
782
783void WvInterfaceDict::update() {}
784bool WvInterfaceDict::islocal(const WvAddr &addr) { return true; }
785bool WvInterfaceDict::on_local_net(const WvIPNet &addr) { return true; }
786
787#endif
Base class for different address types, each of which will have the ability to convert itself to/from...
Definition: wvaddr.h:119
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
Definition: wvstring.h:94
WvFile implements a stream connected to a file or Unix device.
Definition: wvfile.h:29
An IP address is made up of a "dotted quad" – four decimal numbers in the form www....
Definition: wvaddr.h:250
An IP network comprises two WvIPAddr structures: an address and a netmask.
Definition: wvaddr.h:313
bool includes(const WvIPNet &addr) const
determine whether the given address is already included in this net
Definition: wvaddr.cc:625
int bits() const
weird netmasks such as 255.0.255.0 (easy example) are almost never used – they have '0' bits in the m...
Definition: wvaddr.cc:632
WvIPAddr base() const
Get the 'base IP address' component, netmask, network, and broadcast.
Definition: wvaddr.h:347
bool is_default() const
is this net the default gateway? (0.0.0.0/0)
Definition: wvaddr.h:376
bool is_host() const
is it a plain host? (x.x.x.x/32)
Definition: wvaddr.h:380
A WvInterface manages a particular network interface.
Definition: wvinterface.h:25
int setflags(int clear, int set)
toggle kernel flags on this netdevice.
Definition: wvinterface.cc:157
int setipaddr(const WvIPNet &addr)
Sets the local address, netmask, and broadcast of this interface and set a route to the local net.
Definition: wvinterface.cc:218
const WvIPAddr dstaddr()
get the point-to-point IP address of this interface
Definition: wvinterface.cc:136
bool isarp()
add an ARP entry on this interface
Definition: wvinterface.cc:581
const WvIPNet & ipaddr()
get the local IP net of this interface
Definition: wvinterface.cc:117
int delroute(const WvIPNet &dest, int metric=0, WvStringParm table="default")
delete a route to the given network through this interface.
Definition: wvinterface.cc:532
int ptp(bool enable, const WvIPNet &addr)
turn point-to-point mode on or off.
Definition: wvinterface.cc:195
int req(int ioctl_num, struct ifreq *ifr)
get/set information about an interface
Definition: wvinterface.cc:51
bool isup()
set the interface state up or down.
Definition: wvinterface.cc:183
const WvAddr & hwaddr()
get the hardware address of this interface
Definition: wvinterface.cc:101
int getflags()
get the current kernel flags
Definition: wvinterface.cc:147
void rescan()
forget all stored information about the address(es) of this interface
Definition: wvinterface.cc:84
int setmtu(int mtu)
Sets the MTU of the interface.
Definition: wvinterface.cc:286
int sethwaddr(const WvAddr &addr)
Set the hardware address of this interface.
Definition: wvinterface.cc:297
bool ispromisc()
turn promiscuous (see-all-packets) mode on or off.
Definition: wvinterface.cc:212
int addroute(const WvIPNet &dest, int metric=0, WvStringParm table="default")
add a route to the given network through this interface.
Definition: wvinterface.cc:472
A WvLog stream accepts log messages from applications and forwards them to all registered WvLogRcv's.
Definition: wvlog.h:57
WvLog split(LogLevel _loglevel) const
split off a new WvLog object with the requested loglevel.
Definition: wvlog.h:142
void perror(WvStringParm s)
a useful substitute for the normal C perror() function
Definition: wvlog.h:152
A WvAddr that simply contains a printable string with a user-defined encapsulation type.
Definition: wvaddr.h:162
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:330