summaryrefslogtreecommitdiff
path: root/hscript
diff options
context:
space:
mode:
Diffstat (limited to 'hscript')
-rw-r--r--hscript/network.cc114
-rw-r--r--hscript/network.hh25
-rw-r--r--hscript/script.cc3
-rw-r--r--hscript/script_e.cc9
-rw-r--r--hscript/script_i.hh17
-rw-r--r--hscript/script_v.cc4
6 files changed, 167 insertions, 5 deletions
diff --git a/hscript/network.cc b/hscript/network.cc
index 1e915b3..3d847a2 100644
--- a/hscript/network.cc
+++ b/hscript/network.cc
@@ -14,6 +14,7 @@
#include <arpa/inet.h> /* inet_pton */
#include <cstring> /* memcpy */
#include <fstream> /* ofstream for Net write */
+#include <set> /* for PPPoE valid param keys */
#ifdef HAS_INSTALL_ENV
# include <linux/wireless.h> /* struct iwreq */
# include <string.h> /* strerror */
@@ -352,9 +353,7 @@ bool execute_address_eni(const NetAddress *addr) {
return true;
}
-bool NetAddress::execute() const {
- output_info(pos, "netaddress: adding configuration for " + _iface);
-
+NetConfigType::ConfigSystem current_system(const Horizon::Script *script) {
NetConfigType::ConfigSystem system = NetConfigType::Netifrc;
const Key *key = script->getOneValue("netconfigtype");
@@ -363,7 +362,13 @@ bool NetAddress::execute() const {
system = nct->type();
}
- switch(system) {
+ return system;
+}
+
+bool NetAddress::execute() const {
+ output_info(pos, "netaddress: adding configuration for " + _iface);
+
+ switch(current_system(script)) {
case NetConfigType::Netifrc:
default:
return execute_address_netifrc(this);
@@ -373,6 +378,107 @@ bool NetAddress::execute() const {
}
+Key *PPPoE::parseFromData(const std::string &data, const ScriptLocation &pos,
+ int *errors, int *, const Script *script) {
+ std::string::size_type spos, next;
+ std::map<std::string, std::string> params;
+ std::string iface;
+
+ spos = data.find_first_of(' ');
+ iface = data.substr(0, spos);
+ if(iface.length() > IFNAMSIZ) {
+ if(errors) *errors += 1;
+ output_error(pos, "pppoe: invalid interface name '" + iface + "'",
+ "interface names must be 16 characters or less");
+ return nullptr;
+ }
+
+ while(spos != std::string::npos) {
+ std::string key, val;
+ std::string::size_type equals;
+
+ spos++;
+
+ next = data.find_first_of(' ', spos);
+ equals = data.find_first_of('=', spos);
+ if(equals != std::string::npos && equals < next) {
+ key = data.substr(spos, equals - spos);
+ if(next == std::string::npos) {
+ val = data.substr(equals + 1);
+ } else {
+ val = data.substr(equals + 1, next - equals);
+ }
+ } else {
+ if(next == std::string::npos) {
+ key = data.substr(spos);
+ } else {
+ key = data.substr(spos, next - spos);
+ }
+ }
+
+ params[key] = val;
+
+ spos = next;
+ }
+
+ return new PPPoE(script, pos, iface, params);
+}
+
+bool PPPoE::validate() const {
+ bool valid = true;
+ const std::set<std::string> valid_keys = {"mtu", "username", "password",
+ "lcp-echo-interval",
+ "lcp-echo-failure"};
+
+ for(const auto &elem : this->params()) {
+ if(valid_keys.find(elem.first) == valid_keys.end()) {
+ output_error(this->pos, "pppoe: invalid parameter", elem.first);
+ valid = false;
+ }
+ }
+
+ return valid;
+}
+
+static int ppp_link_count = 0;
+
+bool execute_pppoe_netifrc(const PPPoE *link) {
+ std::ofstream ethconfig("/tmp/horizon/netifrc/config_" + link->iface(),
+ std::ios_base::trunc);
+ if(!ethconfig) {
+ output_error(link->where(), "pppoe: couldn't write network "
+ "configuration for " + link->iface());
+ return false;
+ }
+
+ ethconfig << "null";
+
+ std::string linkiface{"ppp" + std::to_string(ppp_link_count)};
+
+ std::ofstream config("/tmp/horizon/netifrc/config_" + linkiface);
+ if(!config) {
+ output_error(link->where(), "pppoe: couldn't write network "
+ "configuration for " + linkiface);
+ return false;
+ }
+ config << "ppp";
+ return true;
+}
+
+bool PPPoE::execute() const {
+ output_info(pos, "pppoe: adding configuration for " + _iface);
+
+ switch(current_system(script)) {
+ case NetConfigType::Netifrc:
+ default:
+ return execute_pppoe_netifrc(this);
+ case NetConfigType::ENI:
+ /* eni */
+ return false;
+ }
+}
+
+
Key *Nameserver::parseFromData(const std::string &data,
const ScriptLocation &pos, int *errors, int *,
const Script *script) {
diff --git a/hscript/network.hh b/hscript/network.hh
index 18ffc34..2ed40ca 100644
--- a/hscript/network.hh
+++ b/hscript/network.hh
@@ -13,6 +13,8 @@
#ifndef __HSCRIPT_NETWORK_HH_
#define __HSCRIPT_NETWORK_HH_
+#include <map>
+
#include "key.hh"
#include "util/output.hh"
@@ -93,6 +95,29 @@ public:
bool execute() const override;
};
+class PPPoE : public Key {
+private:
+ const std::string _iface;
+ const std::map<std::string, std::string> _params;
+
+ PPPoE(const Script *_sc, const ScriptLocation &_pos, const std::string &_i,
+ const std::map<std::string, std::string> &_p) : Key(_sc, _pos),
+ _iface(_i), _params(_p) {}
+public:
+ static Key *parseFromData(const std::string &, const ScriptLocation &,
+ int*, int*, const Script *);
+
+ /*! Retrieve the interface to which this PPPoE link is associated. */
+ const std::string iface() const { return this->_iface; }
+ /*! Retrieve the parameters for this PPPoE link. */
+ const std::map<std::string, std::string> params() const {
+ return this->_params;
+ }
+
+ bool validate() const override;
+ bool execute() const override;
+};
+
class Nameserver : public StringKey {
private:
Nameserver(const Script *_s, const ScriptLocation &_pos,
diff --git a/hscript/script.cc b/hscript/script.cc
index 897d5d4..20ccbe5 100644
--- a/hscript/script.cc
+++ b/hscript/script.cc
@@ -58,6 +58,7 @@ const std::map<std::string, key_parse_fn> valid_keys = {
{"netaddress", &NetAddress::parseFromData},
{"nameserver", &Nameserver::parseFromData},
{"netssid", &NetSSID::parseFromData},
+ {"pppoe", &PPPoE::parseFromData},
{"username", &Username::parseFromData},
{"useralias", &UserAlias::parseFromData},
@@ -98,6 +99,8 @@ bool Script::ScriptPrivate::store_key(const std::string &key_name, Key *obj,
std::unique_ptr<NetSSID> ssid(dynamic_cast<NetSSID *>(obj));
this->ssids.push_back(std::move(ssid));
return true;
+ } else if(key_name == "pppoe") {
+ return store_pppoe(obj, pos, errors, warnings, opts);
} else if(key_name == "hostname") {
return store_hostname(obj, pos, errors, warnings, opts);
} else if(key_name == "pkginstall") {
diff --git a/hscript/script_e.cc b/hscript/script_e.cc
index 866a836..87ade0f 100644
--- a/hscript/script_e.cc
+++ b/hscript/script_e.cc
@@ -287,7 +287,7 @@ bool Script::execute() const {
}
bool dhcp = false;
- if(!internal->addresses.empty()) {
+ if(!internal->addresses.empty() || !internal->pppoes.empty()) {
fs::path conf_dir, targ_netconf_dir, targ_netconf_file;
switch(netconfsys) {
case NetConfigType::Netifrc:
@@ -319,6 +319,13 @@ bool Script::execute() const {
if(addr->type() == NetAddress::DHCP) dhcp = true;
}
+ int pppcnt = 0;
+ for(auto &ppp_link : internal->pppoes) {
+ EXECUTE_OR_FAIL("pppoe", ppp_link);
+ ifaces.insert(ppp_link->iface());
+ ifaces.insert("ppp" + std::to_string(pppcnt++));
+ }
+
std::ostringstream conf;
if(netconfsys == NetConfigType::ENI) {
diff --git a/hscript/script_i.hh b/hscript/script_i.hh
index abe56ec..b82b807 100644
--- a/hscript/script_i.hh
+++ b/hscript/script_i.hh
@@ -72,6 +72,8 @@ struct Script::ScriptPrivate {
std::vector< std::unique_ptr<Nameserver> > nses;
/*! Wireless networking configuration */
std::vector< std::unique_ptr<NetSSID> > ssids;
+ /*! PPPoE configuration */
+ std::vector< std::unique_ptr<PPPoE> > pppoes;
/*! APK repositories */
std::vector< std::unique_ptr<Repository> > repos;
@@ -153,6 +155,21 @@ struct Script::ScriptPrivate {
return true;
}
+ bool store_pppoe(Key *obj, const ScriptLocation &pos, int *errors,
+ int *, const ScriptOptions &) {
+ PPPoE *ppp = dynamic_cast<PPPoE *>(obj);
+ for(const auto &ppplink : pppoes) {
+ if(ppplink->iface() == ppp->iface()) {
+ DUPLICATE_ERROR(ppplink, "pppoe", ppplink->iface());
+ return false;
+ }
+ }
+
+ std::unique_ptr<PPPoE> uppp(ppp);
+ pppoes.push_back(std::move(uppp));
+ return true;
+ }
+
bool store_hostname(Key* obj, const ScriptLocation &pos, int *errors,
int *, const ScriptOptions &) {
if(hostname) {
diff --git a/hscript/script_v.cc b/hscript/script_v.cc
index 1fc3726..41f1756 100644
--- a/hscript/script_v.cc
+++ b/hscript/script_v.cc
@@ -252,6 +252,10 @@ bool Horizon::Script::validate() const {
if(!ssid->validate()) failures++;
}
+ for(auto &pppoe : internal->pppoes) {
+ if(!pppoe->validate()) failures++;
+ }
+
/* REQ: Runner.Validate.hostname */
if(!internal->hostname->validate()) failures++;