|
@@ -0,0 +1,614 @@
|
|
|
+#include <string.h>
|
|
|
+#include <regex>
|
|
|
+#include "util.h"
|
|
|
+#include "interfaces.h"
|
|
|
+
|
|
|
+//#define _ETC_NETWORK_INTERFACES "/etc/network/interfaces"
|
|
|
+#define _ETC_NETWORK_INTERFACES "/home/wrk/share/gfanet/libgfanet/res/interfaces"
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+// iface block
|
|
|
+
|
|
|
+static const char *g_pszCfgGroups[] =
|
|
|
+{
|
|
|
+ "auto",
|
|
|
+ "allow-auto",
|
|
|
+ "allow-hotplug",
|
|
|
+ "no-auto-down",
|
|
|
+ "no-scripts"
|
|
|
+};
|
|
|
+
|
|
|
+static const char *g_pszProtos[] =
|
|
|
+{
|
|
|
+ "inet",
|
|
|
+ "inet6",
|
|
|
+ "ipx",
|
|
|
+ "can"
|
|
|
+};
|
|
|
+
|
|
|
+static const char *g_pszMethods[] =
|
|
|
+{
|
|
|
+ "static",
|
|
|
+ "dhcp",
|
|
|
+ "manual",
|
|
|
+ "bootp",
|
|
|
+ "tunnel",
|
|
|
+ "ppp",
|
|
|
+ "wvdial",
|
|
|
+ "ipv4ll",
|
|
|
+ "loopback",
|
|
|
+ "auto" // nur IPv6!
|
|
|
+};
|
|
|
+
|
|
|
+static const char *g_pszCommands[] =
|
|
|
+{
|
|
|
+ "pre-up",
|
|
|
+ "up",
|
|
|
+ "post-up",
|
|
|
+ "down",
|
|
|
+ "pre-down",
|
|
|
+ "post-down"
|
|
|
+};
|
|
|
+
|
|
|
+static const char *g_pszIncludes[] =
|
|
|
+{
|
|
|
+ "source",
|
|
|
+ "source-directory"
|
|
|
+};
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+static const char *_GetIfaceProtoStr(IfaceProtos ip)
|
|
|
+{
|
|
|
+ if(ip >= IFP_Inet && ip <= IFP_Can)
|
|
|
+ return g_pszProtos[ip];
|
|
|
+ return "";
|
|
|
+}
|
|
|
+
|
|
|
+static const char *_GetIfaceMethodStr(IfaceMethods im)
|
|
|
+{
|
|
|
+ if(im >= IFM_Static && im <= IFM_Auto)
|
|
|
+ return g_pszMethods[im];
|
|
|
+ return "";
|
|
|
+}
|
|
|
+
|
|
|
+static const char *_GetIfaceCommandsStr(IfaceCommands ic)
|
|
|
+{
|
|
|
+ if(ic >= IFC_PreUp && ic <= IFC_PostDown)
|
|
|
+ return g_pszCommands[ic];
|
|
|
+ return "";
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+CfgGroup ParseCfgGroup(const std::vector<std::string> &v, ITF_CONFIG_GROUP &icg)
|
|
|
+{
|
|
|
+ if(v.size() < 2)
|
|
|
+ return CG_Unknown;
|
|
|
+
|
|
|
+ CfgGroup g = (CfgGroup)FindStringInList(v[0], g_pszCfgGroups, _countof(g_pszCfgGroups));
|
|
|
+
|
|
|
+ if(g > CG_Unknown)
|
|
|
+ {
|
|
|
+ icg._reset();
|
|
|
+ icg.cfgName = v[0];
|
|
|
+ auto vBeg = v.begin();
|
|
|
+ icg.members.insert(icg.members.begin(), ++vBeg, v.end());
|
|
|
+ }
|
|
|
+ else if(g == CG_Unknown && v[0].size() > 6)
|
|
|
+ {
|
|
|
+ if(!v[0].compare(0, 6, "allow-"))
|
|
|
+ {
|
|
|
+ icg._reset();
|
|
|
+ icg.cfgName = v[0];
|
|
|
+ auto vBeg = v.begin();
|
|
|
+ icg.members.insert(icg.members.begin(), ++vBeg, v.end());
|
|
|
+ g = CG_User;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return g;
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+IfaceProtos GetIfaceProto(const std::string &s)
|
|
|
+{
|
|
|
+ return (IfaceProtos)FindStringInList(s, g_pszProtos, _countof(g_pszProtos));
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+IfaceMethods GetIfaceMethod(const std::string &s)
|
|
|
+{
|
|
|
+ return (IfaceMethods)FindStringInList(s, g_pszMethods, _countof(g_pszMethods));
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+IfaceCommands GetIfaceCommand(const std::string &s)
|
|
|
+{
|
|
|
+ return (IfaceCommands)FindStringInList(s, g_pszCommands, _countof(g_pszCommands));
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+IfaceHdrType ParseIfaceHeader(const std::vector<std::string> &v, ITF_IFACE_BLOCK &ib)
|
|
|
+{
|
|
|
+ auto vSize = v.size();
|
|
|
+
|
|
|
+ if( vSize >= 4 &&
|
|
|
+ !v[0].compare("iface"))
|
|
|
+ {
|
|
|
+ ib._reset();
|
|
|
+ ib.cfgName = v[1];
|
|
|
+
|
|
|
+ int nInheritIdx = 0;
|
|
|
+
|
|
|
+ for(int i = 2; i < std::min((int)(vSize - 1), 5); i++)
|
|
|
+ {
|
|
|
+ if(!v[i].compare("inherits"))
|
|
|
+ {
|
|
|
+ nInheritIdx = i;
|
|
|
+ ib.inheritedFrom = v[i + 1];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!nInheritIdx || nInheritIdx > 2)
|
|
|
+ ib.proto = GetIfaceProto(v[2]);
|
|
|
+ if(!nInheritIdx || nInheritIdx > 3)
|
|
|
+ ib.method = GetIfaceMethod(v[3]);
|
|
|
+ if(nInheritIdx)
|
|
|
+ return IHR_Unknown;
|
|
|
+
|
|
|
+ switch(ib.proto)
|
|
|
+ {
|
|
|
+ case IFP_Inet:
|
|
|
+ if(ib.method >= IFM_Static && ib.method <= IFM_Loopback)
|
|
|
+ return IHR_OK;
|
|
|
+ return IHR_Invalid;
|
|
|
+ case IFP_Inet6:
|
|
|
+ case IFP_Ipx:
|
|
|
+ case IFP_Can:
|
|
|
+ case IFP_Unknown:
|
|
|
+ default:
|
|
|
+ return IHR_Unknown;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return IHR_NoHdr;
|
|
|
+}
|
|
|
+
|
|
|
+bool ParseIfaceCmd(const std::vector<std::string> &v, std::vector<IFACE_COMMAND> &c)
|
|
|
+{
|
|
|
+ auto vSize = v.size();
|
|
|
+
|
|
|
+ if(vSize > 1)
|
|
|
+ {
|
|
|
+ IfaceCommands cmd = GetIfaceCommand(v[0]);
|
|
|
+
|
|
|
+ if(cmd >= IFC_PreUp && cmd <= IFC_PostDown)
|
|
|
+ {
|
|
|
+ IFACE_COMMAND ic;
|
|
|
+ ic.cmd = cmd;
|
|
|
+ ic.args = JoinStringArray(v, 1, -1);
|
|
|
+ c.push_back(ic);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+bool ParseIfaceDesc(const std::vector<std::string> &v, ITF_IFACE_BLOCK &ib)
|
|
|
+{
|
|
|
+ auto vSize = v.size();
|
|
|
+
|
|
|
+ if(vSize > 1)
|
|
|
+ {
|
|
|
+ if(!v[0].compare("description"))
|
|
|
+ {
|
|
|
+ ib.desc = JoinStringArray(v, 1, -1);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+bool ParseIfaceParam(const std::vector<std::string> &v, ITF_IFACE_BLOCK &ib)
|
|
|
+{
|
|
|
+ if(ParseIfaceCmd(v, ib.cmds))
|
|
|
+ return true;
|
|
|
+
|
|
|
+ if(ParseIfaceDesc(v, ib))
|
|
|
+ return true;
|
|
|
+
|
|
|
+ if(ib.proto == IFP_Inet)
|
|
|
+ {
|
|
|
+ switch(ib.method)
|
|
|
+ {
|
|
|
+ case IFM_Static:
|
|
|
+ return ParseIfaceInet4sParam(v, ib.inet4s);
|
|
|
+ case IFM_Dhcp:
|
|
|
+ return ParseIfaceInet4dParam(v, ib.inet4d);
|
|
|
+ case IFM_Manual:
|
|
|
+ return ParseIfaceInet4mParam(v, ib.inet4m);
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+bool ParseMapping(const std::vector<std::string> &v, ITF_MAPPING_BLOCK &mab)
|
|
|
+{
|
|
|
+ if(v.size() > 1 && !v[0].compare("mapping"))
|
|
|
+ {
|
|
|
+ mab._reset();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+bool ParseIncludes(const std::vector<std::string> &v, ITF_INCLUDE_LIST &inc)
|
|
|
+{
|
|
|
+ if(v.size() > 1)
|
|
|
+ {
|
|
|
+ ITF_INCLUDE ii;
|
|
|
+
|
|
|
+ if(!v[0].compare(g_pszIncludes[0]))
|
|
|
+ {
|
|
|
+ ii.inc = II_File;
|
|
|
+ ii.path = JoinStringArray(v, 1, -1);
|
|
|
+ inc.push_back(ii);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else if(!v[0].compare(g_pszIncludes[1]))
|
|
|
+ {
|
|
|
+ ii.inc = II_Directory;
|
|
|
+ ii.path = JoinStringArray(v, 1, -1);
|
|
|
+ inc.push_back(ii);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+void ProcessIface(ETC_NETWORK_INTERFACES &eni)
|
|
|
+{
|
|
|
+ for(auto iti = eni.ibl.begin(); iti != eni.ibl.end(); iti++)
|
|
|
+ {
|
|
|
+ ITF_IFACE_BLOCK &ib = *iti;
|
|
|
+
|
|
|
+ if(ib.proto == IFP_Inet && ib.method == IFM_Static)
|
|
|
+ {
|
|
|
+ if(ib.inet4s.netmask.s_addr)
|
|
|
+ ib.inet4s.netprefix = Mask2Prefix(ib.inet4s.netmask);
|
|
|
+ else if(ib.inet4s.netprefix)
|
|
|
+ ib.inet4s.netmask.s_addr = Prefix2Mask(ib.inet4s.netprefix);
|
|
|
+ else
|
|
|
+ ib.inet4s.netprefix = 24;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+void ProcessGroupMembers(ETC_NETWORK_INTERFACES &eni)
|
|
|
+{
|
|
|
+ // remove double configuration names in a single group
|
|
|
+ for(auto cIt = eni.cgl.begin(); cIt != eni.cgl.end(); cIt++)
|
|
|
+ {
|
|
|
+ ITF_CONFIG_GROUP &icg = *cIt;
|
|
|
+ RemoveDoubleStringsFromVector(icg.members);
|
|
|
+ }
|
|
|
+
|
|
|
+ // remove configuration names that don't have an iface block
|
|
|
+
|
|
|
+ // remove redundant configuration names in equally named groups
|
|
|
+ for(auto cIt1 = eni.cgl.begin(); cIt1 != eni.cgl.end(); cIt1++)
|
|
|
+ {
|
|
|
+ ITF_CONFIG_GROUP &icg1 = *cIt1;
|
|
|
+ for(auto cIt2 = cIt1 + 1; cIt2 != eni.cgl.end(); cIt2++)
|
|
|
+ {
|
|
|
+ ITF_CONFIG_GROUP &icg2 = *cIt2;
|
|
|
+ if(!icg1.cfgName.compare(icg2.cfgName))
|
|
|
+ {
|
|
|
+ for(auto sIt = icg1.members.begin(); sIt != icg1.members.end(); sIt++)
|
|
|
+ {
|
|
|
+ const std::string &sMember1 = *sIt;
|
|
|
+ if(RemoveStringFromVector(sMember1, icg2.members))
|
|
|
+ printf("%s\n", sMember1.c_str());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for(auto iIt = eni.ibl.begin(); iIt != eni.ibl.end(); iIt++)
|
|
|
+ {
|
|
|
+ ITF_IFACE_BLOCK &ibl = *iIt;
|
|
|
+
|
|
|
+ for(auto cIt = eni.cgl.begin(); cIt != eni.cgl.end(); cIt++)
|
|
|
+ {
|
|
|
+ ITF_CONFIG_GROUP &icg = *cIt;
|
|
|
+
|
|
|
+ for(auto sIt = icg.members.begin(); sIt != icg.members.end(); sIt++)
|
|
|
+ {
|
|
|
+ const std::string &sMember = *sIt;
|
|
|
+
|
|
|
+ if(!ibl.cfgName.compare(sMember))
|
|
|
+ {
|
|
|
+ ibl.memberOf.push_back(&icg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+int ParseEtcNetworkInterfaces(ETC_NETWORK_INTERFACES &eni)
|
|
|
+{
|
|
|
+ typedef enum ParseStates
|
|
|
+ {
|
|
|
+ PS_Root,
|
|
|
+ PS_Iface,
|
|
|
+ PS_Mapping
|
|
|
+ }ParseStates;
|
|
|
+
|
|
|
+ static const std::string strRegExComt = "^\\s*#.*";
|
|
|
+ static const std::string strRegExLine = "([^\\s]+)";
|
|
|
+ static const std::regex regc(strRegExComt, std::regex_constants::ECMAScript | std::regex_constants::optimize);
|
|
|
+ static const std::regex regl(strRegExLine, std::regex_constants::ECMAScript | std::regex_constants::optimize);
|
|
|
+ std::string buf;
|
|
|
+
|
|
|
+ eni._reset();
|
|
|
+
|
|
|
+ if(ReadFile(_ETC_NETWORK_INTERFACES, buf) > 0)
|
|
|
+ {
|
|
|
+ ParseStates ps = PS_Root;
|
|
|
+ std::string line;
|
|
|
+ std::istringstream iss(buf);
|
|
|
+ std::istream stm(iss.rdbuf());
|
|
|
+ std::sregex_token_iterator rend;
|
|
|
+ ITF_CONFIG_GROUP icg;
|
|
|
+ ITF_IFACE_BLOCK ib;
|
|
|
+ ITF_MAPPING_BLOCK mab;
|
|
|
+
|
|
|
+ while(std::getline(stm, line))
|
|
|
+ {
|
|
|
+ trim(line);
|
|
|
+
|
|
|
+ if(line.size() > 0)
|
|
|
+ {
|
|
|
+ if(std::regex_match(line, regc))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ CfgGroup cg;
|
|
|
+ IfaceHdrType r1;
|
|
|
+ std::vector<std::string> v;
|
|
|
+
|
|
|
+ if(!SplitString(line, regl, v))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if((r1 = ParseIfaceHeader(v, ib)) != IHR_NoHdr)
|
|
|
+ {
|
|
|
+ eni.ibl.push_back(ib);
|
|
|
+ ps = PS_Iface;
|
|
|
+ }
|
|
|
+ else if((cg = ParseCfgGroup(v, icg)) != CG_Unknown)
|
|
|
+ {
|
|
|
+ eni.cgl.push_back(icg);
|
|
|
+ ps = PS_Root;
|
|
|
+ }
|
|
|
+ else if(ParseMapping(v, mab))
|
|
|
+ {
|
|
|
+ mab.unparsed.push_back(line);
|
|
|
+ eni.mbl.push_back(mab);
|
|
|
+ ps = PS_Mapping;
|
|
|
+ }
|
|
|
+ else if(ParseIncludes(v, eni.inc))
|
|
|
+ {
|
|
|
+ ps = PS_Root;
|
|
|
+ }
|
|
|
+ else if(ps == PS_Iface)
|
|
|
+ {
|
|
|
+ ITF_IFACE_BLOCK &rib = eni.ibl.back();
|
|
|
+ if(!ParseIfaceParam(v, rib))
|
|
|
+ {
|
|
|
+ rib.unparsed.push_back(line);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(ps == PS_Mapping)
|
|
|
+ {
|
|
|
+ ITF_MAPPING_BLOCK &rmab = eni.mbl.back();
|
|
|
+ rmab.unparsed.push_back(line);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ eni.unparsed.push_back(line);
|
|
|
+ printf("%d - %s\n", ps, line.c_str());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ProcessIface(eni);
|
|
|
+ ProcessGroupMembers(eni);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+bool WriteEtcNetworkInterfaces(const ETC_NETWORK_INTERFACES &eni, const char *pszFile)
|
|
|
+{
|
|
|
+ if(!pszFile)
|
|
|
+ pszFile = _ETC_NETWORK_INTERFACES;
|
|
|
+
|
|
|
+ int line;
|
|
|
+ FILE *pf = fopen(pszFile, "wb");
|
|
|
+
|
|
|
+ if(pf)
|
|
|
+ {
|
|
|
+ /////////////////////////////////////////////////////////////////////
|
|
|
+ // write header
|
|
|
+
|
|
|
+ fputs("##############################################################\n", pf);
|
|
|
+ fputs("# interfaces(5) file used by ifup(8) and ifdown(8)\n", pf);
|
|
|
+ fputs("# this file is parsed and rewritten by libgfanet. any existing\n", pf);
|
|
|
+ fputs("# comments will be discarded!\n\n", pf);
|
|
|
+
|
|
|
+ /////////////////////////////////////////////////////////////////////
|
|
|
+ // write mappings
|
|
|
+
|
|
|
+ if(eni.mbl.size() > 0)
|
|
|
+ {
|
|
|
+ fputs("##############################################################\n", pf);
|
|
|
+ fputs("# mapping - not handled by libgfanet\n\n", pf);
|
|
|
+
|
|
|
+ for(auto itm = eni.mbl.begin(); itm != eni.mbl.end(); itm++)
|
|
|
+ {
|
|
|
+ line = 0;
|
|
|
+ const ITF_MAPPING_BLOCK &mb = *itm;
|
|
|
+
|
|
|
+ for(auto its = mb.unparsed.begin(); its != mb.unparsed.end(); its++)
|
|
|
+ {
|
|
|
+ const std::string s = *its;
|
|
|
+ if(line++)
|
|
|
+ fputc('\t', pf);
|
|
|
+ fputs(s.c_str(), pf);
|
|
|
+ fputc('\n', pf);
|
|
|
+ }
|
|
|
+ fputc('\n', pf);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /////////////////////////////////////////////////////////////////////
|
|
|
+ // write config groups
|
|
|
+
|
|
|
+ if(eni.cgl.size() > 0)
|
|
|
+ {
|
|
|
+ fputs("##############################################################\n", pf);
|
|
|
+ fputs("# config groups\n\n", pf);
|
|
|
+
|
|
|
+ for(auto itc = eni.cgl.begin(); itc != eni.cgl.end(); itc++)
|
|
|
+ {
|
|
|
+ line = 0;
|
|
|
+ const ITF_CONFIG_GROUP &cg = *itc;
|
|
|
+
|
|
|
+ if(cg.members.size() > 0)
|
|
|
+ {
|
|
|
+ fputs(cg.cfgName.c_str(), pf);
|
|
|
+
|
|
|
+ for(auto its = cg.members.begin(); its != cg.members.end(); its++)
|
|
|
+ {
|
|
|
+ const std::string &member = *its;
|
|
|
+ fputc(' ', pf);
|
|
|
+ fputs(member.c_str(), pf);
|
|
|
+ }
|
|
|
+ fputc('\n', pf);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ fputc('\n', pf);
|
|
|
+ }
|
|
|
+
|
|
|
+ /////////////////////////////////////////////////////////////////////
|
|
|
+ // write iface
|
|
|
+
|
|
|
+ if(eni.ibl.size() > 0)
|
|
|
+ {
|
|
|
+ fputs("##############################################################\n", pf);
|
|
|
+ fputs("# iface\n\n", pf);
|
|
|
+
|
|
|
+ for(auto iti = eni.ibl.begin(); iti != eni.ibl.end(); iti++)
|
|
|
+ {
|
|
|
+ line = 0;
|
|
|
+ const ITF_IFACE_BLOCK &ib = *iti;
|
|
|
+
|
|
|
+ if(!ib.inheritedFrom.empty())
|
|
|
+ {
|
|
|
+ fprintf(pf, "iface %s", ib.cfgName.c_str());
|
|
|
+ if(ib.proto != IFP_Unknown)
|
|
|
+ {
|
|
|
+ fputc(' ', pf);
|
|
|
+ fputs(_GetIfaceProtoStr(ib.proto), pf);
|
|
|
+ }
|
|
|
+ if(ib.method != IFM_Unknown)
|
|
|
+ {
|
|
|
+ fputc(' ', pf);
|
|
|
+ fputs(_GetIfaceMethodStr(ib.method), pf);
|
|
|
+ }
|
|
|
+ fprintf(pf, " inherits %s\n", ib.inheritedFrom.c_str());
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ fprintf(pf, "iface %s %s %s\n", ib.cfgName.c_str(), _GetIfaceProtoStr(ib.proto), _GetIfaceMethodStr(ib.method));
|
|
|
+
|
|
|
+ if(ib.proto == IFP_Inet)
|
|
|
+ {
|
|
|
+ switch(ib.method)
|
|
|
+ {
|
|
|
+ case IFM_Static:
|
|
|
+ WriteIfaceInet4sParam(pf, ib.inet4s);
|
|
|
+ break;
|
|
|
+ case IFM_Dhcp:
|
|
|
+ WriteIfaceInet4dParam(pf, ib.inet4d);
|
|
|
+ break;
|
|
|
+ case IFM_Manual:
|
|
|
+ WriteIfaceInet4mParam(pf, ib.inet4m);
|
|
|
+ break;
|
|
|
+// case IFM_Loopback:
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(ib.cmds.size() > 0)
|
|
|
+ {
|
|
|
+ for(auto itu = ib.cmds.begin(); itu != ib.cmds.end(); itu++)
|
|
|
+ {
|
|
|
+ const IFACE_COMMAND &cmd = *itu;
|
|
|
+ fputc('\t', pf);
|
|
|
+ fputs(_GetIfaceCommandsStr(cmd.cmd), pf);
|
|
|
+ fputc(' ', pf);
|
|
|
+ fputs(cmd.args.c_str(), pf);
|
|
|
+ fputc('\n', pf);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(ib.unparsed.size() > 0)
|
|
|
+ {
|
|
|
+ fputs("\t# the following entries are not handled by libgfanet:\n", pf);
|
|
|
+ for(auto itu = ib.unparsed.begin(); itu != ib.unparsed.end(); itu++)
|
|
|
+ {
|
|
|
+ const std::string &line = *itu;
|
|
|
+ fputc('\t', pf);
|
|
|
+ fputs(line.c_str(), pf);
|
|
|
+ fputc('\n', pf);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ fputc('\n', pf);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+ fclose(pf);
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|