summaryrefslogtreecommitdiff
path: root/osdep/LinuxEthernetTap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'osdep/LinuxEthernetTap.cpp')
-rw-r--r--osdep/LinuxEthernetTap.cpp58
1 files changed, 56 insertions, 2 deletions
diff --git a/osdep/LinuxEthernetTap.cpp b/osdep/LinuxEthernetTap.cpp
index 55a6d9f6..9d3773f0 100644
--- a/osdep/LinuxEthernetTap.cpp
+++ b/osdep/LinuxEthernetTap.cpp
@@ -109,7 +109,12 @@ LinuxEthernetTap::LinuxEthernetTap(
if (!recalledDevice) {
int devno = 0;
do {
+#ifdef __SYNOLOGY__
+ devno+=50; // Arbitrary number to prevent interface name conflicts
+ Utils::snprintf(ifr.ifr_name,sizeof(ifr.ifr_name),"eth%d",devno++);
+#else
Utils::snprintf(ifr.ifr_name,sizeof(ifr.ifr_name),"zt%d",devno++);
+#endif
Utils::snprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
} while (stat(procpath,&sbuf) == 0); // try zt#++ until we find one that does not exist
}
@@ -215,16 +220,65 @@ static bool ___removeIp(const std::string &_dev,const InetAddress &ip)
}
}
+bool LinuxEthernetTap::addIpSyn(std::vector<InetAddress> ips)
+{
+ // Here we fill out interface config (ifcfg-dev) to prevent it from being killed
+ std::string filepath = "/etc/sysconfig/network-scripts/ifcfg-"+_dev;
+ std::string cfg_contents = "DEVICE="+_dev+"\nBOOTPROTO=static";
+ int ip4=0,ip6=0,ip4_tot=0,ip6_tot=0;
+
+ long cpid = (long)vfork();
+ if (cpid == 0) {
+ OSUtils::redirectUnixOutputs("/dev/null",(const char *)0);
+ setenv("PATH", "/sbin:/bin:/usr/sbin:/usr/bin", 1);
+ // We must know if there is at least (one) of each protocol version so we
+ // can properly enumerate address/netmask combinations in the ifcfg-dev file
+ for(int i=0; i<ips.size(); i++) {
+ if (ips[i].isV4())
+ ip4_tot++;
+ else
+ ip6_tot++;
+ }
+ // Assemble and write contents of ifcfg-dev file
+ for(int i=0; i<ips.size(); i++) {
+ if (ips[i].isV4()) {
+ std::string numstr4 = ip4_tot > 1 ? std::to_string(ip4) : "";
+ cfg_contents += "\nIPADDR"+numstr4+"="+ips[i].toIpString()
+ + "\nNETMASK"+numstr4+"="+ips[i].netmask().toIpString()+"\n";
+ ip4++;
+ }
+ else {
+ std::string numstr6 = ip6_tot > 1 ? std::to_string(ip6) : "";
+ cfg_contents += "\nIPV6ADDR"+numstr6+"="+ips[i].toIpString()
+ + "\nNETMASK"+numstr6+"="+ips[i].netmask().toIpString()+"\n";
+ ip6++;
+ }
+ }
+ OSUtils::writeFile(filepath.c_str(), cfg_contents.c_str(), cfg_contents.length());
+ // Finaly, add IPs
+ for(int i=0; i<ips.size(); i++){
+ if (ips[i].isV4())
+ ::execlp("ip","ip","addr","add",ips[i].toString().c_str(),"broadcast",ips[i].broadcast().toIpString().c_str(),"dev",_dev.c_str(),(const char *)0);
+ else
+ ::execlp("ip","ip","addr","add",ips[i].toString().c_str(),"dev",_dev.c_str(),(const char *)0);
+ }
+ ::_exit(-1);
+ } else if (cpid > 0) {
+ int exitcode = -1;
+ ::waitpid(cpid,&exitcode,0);
+ return (exitcode == 0);
+ }
+ return true;
+}
+
bool LinuxEthernetTap::addIp(const InetAddress &ip)
{
if (!ip)
return false;
std::vector<InetAddress> allIps(ips());
-#ifndef __SYNOLOGY__
if (std::binary_search(allIps.begin(),allIps.end(),ip))
return true;
-#endif
// Remove and reconfigure if address is the same but netmask is different
for(std::vector<InetAddress>::iterator i(allIps.begin());i!=allIps.end();++i) {