summaryrefslogtreecommitdiff
path: root/hscript/network.cc
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2020-07-04 12:47:56 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2020-07-04 12:47:56 -0500
commitf52226ea5635cfe9529e78e553e4f814eeaaaa4d (patch)
tree19cfb7cd16fd572dd30b9f9075261dc8e64eebd9 /hscript/network.cc
parentbfce65d6343b174badae2ab7d1bfed9959d0b753 (diff)
downloadhorizon-f52226ea5635cfe9529e78e553e4f814eeaaaa4d.tar.gz
horizon-f52226ea5635cfe9529e78e553e4f814eeaaaa4d.tar.bz2
horizon-f52226ea5635cfe9529e78e553e4f814eeaaaa4d.tar.xz
horizon-f52226ea5635cfe9529e78e553e4f814eeaaaa4d.zip
hscript: Implement execution of PPPoE for ENI systems
Diffstat (limited to 'hscript/network.cc')
-rw-r--r--hscript/network.cc69
1 files changed, 67 insertions, 2 deletions
diff --git a/hscript/network.cc b/hscript/network.cc
index 224e979..5808730 100644
--- a/hscript/network.cc
+++ b/hscript/network.cc
@@ -20,6 +20,7 @@
# include <string.h> /* strerror */
# include <sys/ioctl.h> /* ioctl, ioctl numbers */
# include <unistd.h> /* close */
+# include "util/filesystem.hh" /* fs for pppoe eni */
#else
/*! The size of Linux interface names. */
# define IFNAMSIZ 16
@@ -509,8 +510,72 @@ bool execute_pppoe_netifrc(const PPPoE &link) {
return true;
}
-bool execute_pppoe_eni(const PPPoE &link) {
+bool execute_pppoe_eni(const PPPoE &link, const Horizon::Script *script) {
+#ifndef HAS_INSTALL_ENV
+ output_error(link.where(), "pppoe: ENI cannot be simulated");
return false;
+#else
+ const auto &params = link.params();
+ const std::string &pppdir{script->targetDirectory() + "/etc/ppp"};
+ const std::string &linkiface{"ppp" + std::to_string(ppp_link_count)};
+ error_code ec;
+
+ fs::create_directories(pppdir + "/peers", ec);
+ if(ec && ec.value() != EEXIST) {
+ output_error(link.where(), "pppoe: cannot create PPP directory",
+ ec.message());
+ return false;
+ }
+
+ std::ofstream config("/tmp/horizon/eni/" + link.iface(),
+ std::ios_base::trunc);
+ if(!config) {
+ output_error(link.where(), "pppoe: couldn't write network "
+ "configuration for " + link.iface());
+ return false;
+ }
+ config << "iface " << linkiface << " inet ppp" << std::endl
+ << "pre-up /sbin/ifconfig " << link.iface() << " up" << std::endl
+ << "provider " << linkiface;
+
+ std::ofstream pppconf(pppdir + "/peers/" + linkiface);
+ if(!pppconf) {
+ output_error(link.where(), "pppoe: couldn't write peer information");
+ return false;
+ }
+
+ pppconf << "plugin rp-pppoe.so" << std::endl
+ << link.iface() << std::endl
+ << "defaultroute" << std::endl
+ << "noauth" << std::endl
+ << "+ipv6" << std::endl;
+
+ for(const auto &cpair : params) {
+ if(cpair.first == "password") continue;
+
+ std::string key{cpair.first};
+ /* rewrite our keys -> pppd keys */
+ if(key == "username") key = "user";
+
+ pppconf << key;
+ if(cpair.second.size() > 0) pppconf << " " << cpair.second;
+ pppconf << std::endl;
+ }
+
+ if(params.find("password") != params.end()) {
+ if(params.find("username") == params.end()) {
+ output_error(link.where(), "pppoe: password without username "
+ "not supported in ENI mode");
+ return false;
+ }
+ std::ofstream secrets(pppdir + "/chap-secrets");
+ secrets << params.at("username") << "\t*\t" << params.at("password")
+ << std::endl;
+ }
+
+ ppp_link_count++;
+ return true;
+#endif
}
bool PPPoE::execute() const {
@@ -521,7 +586,7 @@ bool PPPoE::execute() const {
default:
return execute_pppoe_netifrc(*this);
case NetConfigType::ENI:
- return execute_pppoe_eni(*this);
+ return execute_pppoe_eni(*this, script);
}
}