/* Web Polygraph http://www.web-polygraph.org/ * (C) 2003-2006 The Measurement Factory * Licensed under the Apache License, Version 2.0 */ #include "base/polygraph.h" #include #include "xstd/h/net/if.h" #include "xstd/h/iostream.h" #include "xstd/h/iomanip.h" #include "xstd/NetIface.h" #include "xstd/gadgets.h" #include "base/CmdLine.h" #include "base/opts.h" #include "base/polyOpts.h" #include "pgl/PglNetAddrRange.h" class MyOpts: public OptGrp { public: MyOpts(): theHelpOpt(this, "help", "list of options"), theVersOpt(this, "version", "package version info"), theIfName(this, "if ", "interface name"), theAliases(this, "aliases ","ip(s) or ip range(s) to set as aliases") {} virtual bool validate() const; virtual ostream &printAnonym(ostream &os) const; virtual bool parseAnonym(const Array &opts); virtual bool canParseAnonym() const { return true; } public: HelpOpt theHelpOpt; VersionOpt theVersOpt; StrOpt theIfName; StrArrOpt theAliases; }; static MyOpts TheOpts; static NetIface *TheIface = 0; /* MyOpt */ ostream &MyOpts::printAnonym(ostream &os) const { return os << "[interface_name] [alias] ..."; } bool MyOpts::parseAnonym(const Array &opts) { if (!opts.count()) return true; int aliasStart = 0; if (!isdigit(*opts[0])) { theIfName.val(opts[0]); aliasStart = 1; } for (int i = aliasStart; i < opts.count(); ++i) theAliases.addItem(opts[i]); return true; } bool MyOpts::validate() const { if (!theIfName) cerr << "interface name is not specified" << endl; else return true; return false; } static void configureLogs(int prec) { configureStream(cout, prec); configureStream(cerr, prec); configureStream(clog, prec); } static void configure() { Socket::Configure(); configureLogs(2); TheIface = new NetIface; TheIface->name(TheOpts.theIfName); } static void getPrimaryAddress() { NetIface::Primaries addrs; if (!TheIface->primaries(addrs)) { clog << TheIface->name() << ": cannot get primary address(es) of " << "the network interface" << endl; return; } if (addrs.vFour) { clog << TheIface->name() << ": primary IPv4 address is " << addrs.vFour << endl; } if (addrs.vSix) { clog << TheIface->name() << ": primary IPv6 address is " << addrs.vSix << endl; } } static void delOldAliases() { const int delCount = TheIface->delAliases(); Must(delCount >= 0); clog << TheIface->name() << ": deleted " << delCount << " old aliases" << endl; } static void addNewAliases(const Array &addrs, const InAddress &netmask) { Array aliases(addrs.count()); for (int i = 0; i < addrs.count(); ++i) aliases.append(addrs[i]->addrN()); Must(TheIface->addAliases(aliases, netmask)); static int newCount = 0; newCount += aliases.count(); clog << TheIface->name() << ": created " << aliases.count() << " new aliases " << "( " << newCount << " total )" << endl; } int main(int argc, char *argv[]) { CmdLine cmd; cmd.configure(Array() << &TheOpts); if (!cmd.parse(argc, argv) || !TheOpts.validate()) return -1; configure(); clog << TheOpts.theIfName << ": "; if (TheOpts.theAliases) TheOpts.theAliases.report(clog << "reseting aliases to "); else clog << "no new alias specified; will just delete old ones."; clog << endl; getPrimaryAddress(); delOldAliases(); for (int i = 0; i < TheOpts.theAliases.val().count(); ++i) { const String &alias = *TheOpts.theAliases.val()[i]; PglNetAddrRange aliasParser; if (!aliasParser.parse(alias)) { cerr << TheOpts.theIfName << ": malformed alias: `" << alias << "' alias" << endl; return -2; } Array aliases; aliasParser.toAddrs(aliases); InAddress netmask; aliasParser.netmask(netmask); addNewAliases(aliases, netmask); } return 0; }