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.
int setipaddr(const WvIPNet &addr)
Sets the local address, netmask, and broadcast of this interface and set a route to the local net.
const WvIPAddr dstaddr()
get the point-to-point IP address of this interface
bool isarp()
add an ARP entry on this interface
const WvIPNet & ipaddr()
get the local IP net of this interface
int delroute(const WvIPNet &dest, int metric=0, WvStringParm table="default")
delete a route to the given network through this interface.
int ptp(bool enable, const WvIPNet &addr)
turn point-to-point mode on or off.
int req(int ioctl_num, struct ifreq *ifr)
get/set information about an interface
bool isup()
set the interface state up or down.
const WvAddr & hwaddr()
get the hardware address of this interface
int getflags()
get the current kernel flags
void rescan()
forget all stored information about the address(es) of this interface
int setmtu(int mtu)
Sets the MTU of the interface.
int sethwaddr(const WvAddr &addr)
Set the hardware address of this interface.
bool ispromisc()
turn promiscuous (see-all-packets) mode on or off.
int addroute(const WvIPNet &dest, int metric=0, WvStringParm table="default")
add a route to the given network through this interface.
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