/* 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 <ctype.h>
#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 <str>", "interface name"),
theAliases(this, "aliases <str>","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<const char *> &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<const char *> &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<NetAddr*> &addrs, const InAddress &netmask) {
Array<InAddress> 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<OptGrp*>() << &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<NetAddr*> aliases;
aliasParser.toAddrs(aliases);
InAddress netmask;
aliasParser.netmask(netmask);
addNewAliases(aliases, netmask);
}
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1