netinterfaces.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  1. #include <signal.h>
  2. #include "netinterfaces.h"
  3. #include "debug.h"
  4. #ifndef _countof
  5. #define _countof(a) (sizeof(a) / sizeof(*a))
  6. #endif // _countof
  7. #define _IS_VALID_BYTE_VALUE(b) (((b) >= 0) && ((b) <= 255))
  8. template<typename T>
  9. static bool _IsPowerOf2(T x)
  10. {
  11. return x && !(x & (x - 1));
  12. }
  13. template<typename T>
  14. static unsigned int _BitCount(T n)
  15. {
  16. unsigned int count = 0;
  17. while(n)
  18. {
  19. count++;
  20. n &= (n - 1);
  21. }
  22. return count;
  23. }
  24. template<typename T>
  25. static int _BitNumber(T n)
  26. {
  27. if(!n || !_IsPowerOf2(n))
  28. return -1;
  29. int count = 0;
  30. while(n)
  31. {
  32. count++;
  33. n >>= 1;
  34. }
  35. return count - 1;
  36. }
  37. static int _Mask2Prefix(const struct in_addr &in)
  38. {
  39. return _BitCount(in.s_addr);
  40. }
  41. static in_addr_t _Prefix2Mask(int prefix)
  42. {
  43. return htonl(~((1 << (32 - prefix)) - 1));
  44. }
  45. static bool _IsValidNetmask(const struct in_addr &in)
  46. {
  47. return _IsPowerOf2(~ntohl(in.s_addr) + 1);
  48. }
  49. /////////////////////////////////////////////////////////////////////////////
  50. #define _FLAG_TO_ENUM(f) (_BitNumber(f))
  51. #define _ENUM_TO_FLAG(e) (0x00000001 << e)
  52. /////////////////////////////////////////////////////////////////////////////
  53. NetInterfaces::NetInterfaces(QObject *pParent) : QObject(pParent),
  54. m_itfFilterAF(Interface::AF_Unknown),
  55. m_itfFilterMethod(Interface::IM_Unknown),
  56. m_bIfUpDownInProgress(false),
  57. m_ifUpDownPid(-1)
  58. {
  59. setObjectName("NetInterfaces");
  60. m_mutex.Create(true);
  61. m_itfFilterName.clear();
  62. }
  63. NetInterfaces::~NetInterfaces(void)
  64. {
  65. reset();
  66. m_mutex.Release();
  67. }
  68. void NetInterfaces::classBegin()
  69. {
  70. if(!initialize())
  71. {
  72. reportError("NetInterfaces::initialize failed!");
  73. }
  74. }
  75. void NetInterfaces::componentComplete()
  76. {
  77. }
  78. void NetInterfaces::reset(void)
  79. {
  80. Interface *pItf;
  81. for(int i = 0; i < m_interfaces.count(); i++)
  82. {
  83. if((pItf = m_interfaces.at(i)))
  84. delete pItf;
  85. }
  86. m_interfaces.clear();
  87. emit interfacesChanged();
  88. emit filteredInterfacesChanged();
  89. m_eni._reset();
  90. }
  91. bool NetInterfaces::initialize(void)
  92. {
  93. bool bRet;
  94. reset();
  95. if((bRet = ::ParseEtcNetworkInterfaces(m_eni)))
  96. {
  97. for(auto it = m_eni.ibl.begin(); it != m_eni.ibl.end(); it++)
  98. {
  99. ITF_IFACE_BLOCK &ibl = *it;
  100. m_interfaces.append(new Interface(ibl, static_cast<NotificationSink&>(*this), this));
  101. }
  102. emit interfacesChanged();
  103. emit filteredInterfacesChanged();
  104. }
  105. return bRet;
  106. }
  107. bool NetInterfaces::save(void)
  108. {
  109. return ::WriteEtcNetworkInterfaces(m_eni, NULL);
  110. }
  111. bool NetInterfaces::saveAs(const QString &path)
  112. {
  113. if(!path.length())
  114. return false;
  115. std::string p = path.toStdString();
  116. const char *pszPath = p.c_str();
  117. return ::WriteEtcNetworkInterfaces(m_eni, pszPath);
  118. }
  119. void NetInterfaces::reportError(const char *pszFormatStr, ...)
  120. {
  121. va_list args;
  122. va_start(args, pszFormatStr);
  123. QString qs = QString::vasprintf(pszFormatStr, args);
  124. va_end (args);
  125. m_mutex.Lock();
  126. emit error(qs);
  127. m_mutex.Unlock();
  128. }
  129. void NetInterfaces::filterPropertyChanged(void) const
  130. {
  131. emit filteredInterfacesChanged();
  132. }
  133. void NetInterfaces::selConfigChanged(Interface* pi, unsigned int cfgOld, unsigned int cfgNew)
  134. {
  135. unsigned long id = pi->getID();
  136. unsigned int diff = cfgOld ^ cfgNew;
  137. unsigned int add = cfgNew & diff;
  138. unsigned int rem = cfgOld & diff;
  139. for(int mask = Interface::SC_Auto; mask < Interface::SC_Invalid; mask <<= 1)
  140. {
  141. if(add & mask)
  142. ::AddInterfaceToCfgGroup(m_eni, id, (CfgGroup)_FLAG_TO_ENUM(mask));
  143. if(rem & mask)
  144. ::RemoveInterfaceFromCfgGroup(m_eni, id, (CfgGroup)_FLAG_TO_ENUM(mask));
  145. }
  146. }
  147. Interface* NetInterfaces::newInterface(QString name, int af, int method)
  148. {
  149. if(name.isNull() || name.isEmpty())
  150. {
  151. reportError("Invalid or empty interface name!");
  152. return NULL;
  153. }
  154. if(!_IsPowerOf2(af) || (af <= Interface::AF_Unknown) || (af >= Interface::AF_Invalid))
  155. {
  156. reportError("Invalid address family: %d!", af);
  157. return NULL;
  158. }
  159. if(!_IsPowerOf2(method) || (method <= Interface::IM_Unknown) || (method >= Interface::IM_Invalid))
  160. {
  161. reportError("Invalid method: %d!", method);
  162. return NULL;
  163. }
  164. m_eni.ibl.emplace_back();
  165. ITF_IFACE_BLOCK &rib = m_eni.ibl.back();
  166. rib.cfgName = name.toStdString();
  167. rib.proto = (IfaceProtos)_FLAG_TO_ENUM(af);
  168. rib.method = (IfaceMethods)_FLAG_TO_ENUM(method);
  169. Interface *pi = new Interface(rib, static_cast<NotificationSink&>(*this), this);
  170. m_interfaces.append(pi);
  171. emit interfacesChanged();
  172. emit filteredInterfacesChanged();
  173. return pi;
  174. }
  175. void NetInterfaces::removeInterface(Interface *pi)
  176. {
  177. if(!pi)
  178. {
  179. reportError("NetInterfaces::removeInterface: An attempt was made to remove an invalid interface!");
  180. return;
  181. }
  182. m_mutex.Lock();
  183. if(GetIfUpDownInProgress())
  184. {
  185. m_mutex.Unlock();
  186. reportError("NetInterfaces::removeInterface: Interface start/stop in progress! Please try again later!");
  187. return;
  188. }
  189. m_mutex.Unlock();
  190. unsigned long id = pi->getID();
  191. int selCfg = pi->getSelCfg();
  192. for(int i = 0; i < m_interfaces.count(); i++)
  193. {
  194. Interface *pil = m_interfaces.at(i);
  195. if(pil->getID() == id)
  196. {
  197. m_interfaces.removeAt(i);
  198. emit interfacesChanged();
  199. emit filteredInterfacesChanged();
  200. delete pil;
  201. for(int mask = Interface::SC_Auto; mask < Interface::SC_Invalid; mask <<= 1)
  202. {
  203. if(selCfg & mask)
  204. ::RemoveInterfaceFromCfgGroup(m_eni, id, (CfgGroup)_FLAG_TO_ENUM(mask));
  205. }
  206. ::RemoveInterfaceBlock(m_eni, id);
  207. break;
  208. }
  209. }
  210. }
  211. bool NetInterfaces::SetInterlockedIfUpDownInProgress(void)
  212. {
  213. m_mutex.Lock();
  214. if(m_bIfUpDownInProgress)
  215. {
  216. m_mutex.Unlock();
  217. return false;
  218. }
  219. m_bIfUpDownInProgress = true;
  220. m_mutex.Unlock();
  221. return true;
  222. }
  223. void NetInterfaces::onIfUpDown(const char *pszMsg, void *pCtx)
  224. {
  225. if(pCtx)
  226. {
  227. NetInterfaces *pThis = static_cast<NetInterfaces*>(pCtx);
  228. pThis->m_mutex.Lock();
  229. emit pThis->ifUpDown(pszMsg);
  230. pThis->m_mutex.Unlock();
  231. }
  232. }
  233. void NetInterfaces::onIfUpCompleted(int nExitCode, void *pCtx)
  234. {
  235. if(pCtx)
  236. {
  237. LPIF_UPDOWN_CONTEXT piudc = static_cast<LPIF_UPDOWN_CONTEXT>(pCtx);
  238. piudc->pThis->m_mutex.Lock();
  239. emit piudc->pThis->ifUpDownCompleted(piudc->ctx, nExitCode);
  240. piudc->pThis->SetIfUpDownInProgress(false);
  241. piudc->pThis->SetIfUpDownPid(-1);
  242. piudc->pThis->m_mutex.Unlock();
  243. delete piudc;
  244. }
  245. }
  246. void NetInterfaces::onIfDownCompleted(int nExitCode, void *pCtx)
  247. {
  248. if(pCtx)
  249. {
  250. LPIF_UPDOWN_CONTEXT piudc = static_cast<LPIF_UPDOWN_CONTEXT>(pCtx);
  251. piudc->pThis->m_mutex.Lock();
  252. emit piudc->pThis->ifUpDownCompleted(piudc->ctx, nExitCode);
  253. piudc->pThis->SetIfUpDownInProgress(false);
  254. piudc->pThis->SetIfUpDownPid(-1);
  255. piudc->pThis->m_mutex.Unlock();
  256. delete piudc;
  257. }
  258. }
  259. void NetInterfaces::onIfRestartCompleted(int nExitCode, void *pCtx)
  260. {
  261. if(pCtx)
  262. {
  263. LPIF_UPDOWN_CONTEXT piudc = static_cast<LPIF_UPDOWN_CONTEXT>(pCtx);
  264. if(piudc->ctx == UDC_Stop && !nExitCode) // ifdown succeeded
  265. {
  266. int nRet;
  267. piudc->ctx = UDC_Start;
  268. if((nRet = ::IfUpAsync(piudc->pi->getName(), piudc->pThis->m_ifUpDownPid, &NetInterfaces::onIfRestartCompleted, static_cast<void*>(piudc), &NetInterfaces::onIfUpDown, static_cast<void*>(piudc->pThis))))
  269. {
  270. piudc->pThis->m_mutex.Lock();
  271. piudc->pThis->reportError("NetInterfaces::onIfRestartCompleted: IfUpAsync failed with code: %d", nRet);
  272. emit piudc->pThis->ifUpDownCompleted(UDC_Restart, nRet);
  273. piudc->pThis->SetIfUpDownPid(-1);
  274. piudc->pThis->SetIfUpDownInProgress(false);
  275. piudc->pThis->m_mutex.Unlock();
  276. delete piudc;
  277. }
  278. return;
  279. }
  280. piudc->pThis->m_mutex.Lock();
  281. emit piudc->pThis->ifUpDownCompleted(UDC_Restart, nExitCode);
  282. piudc->pThis->SetIfUpDownPid(-1);
  283. piudc->pThis->SetIfUpDownInProgress(false);
  284. piudc->pThis->m_mutex.Unlock();
  285. delete piudc;
  286. }
  287. }
  288. bool NetInterfaces::startInterface(Interface *pi)
  289. {
  290. if(!pi)
  291. {
  292. reportError("NetInterfaces::stopInterface: Invalid interface!");
  293. return false;
  294. }
  295. int nRet;
  296. if(!SetInterlockedIfUpDownInProgress())
  297. {
  298. reportError("NetInterfaces::startInterface: IfUp/Down already in progress!");
  299. return false;
  300. }
  301. LPIF_UPDOWN_CONTEXT piudc = new IF_UPDOWN_CONTEXT;
  302. piudc->pThis = this;
  303. piudc->pi = pi;
  304. piudc->ctx = UDC_Start;
  305. if((nRet = ::IfUpAsync(pi->getName(), m_ifUpDownPid, &NetInterfaces::onIfUpCompleted, static_cast<void*>(piudc), &NetInterfaces::onIfUpDown, static_cast<void*>(this))))
  306. {
  307. m_mutex.Lock();
  308. reportError("NetInterfaces::startInterface: IfUpAsync failed with code: %d", nRet);
  309. emit ifUpDownCompleted(UDC_Start, -3);
  310. SetIfUpDownInProgress(false);
  311. SetIfUpDownPid(-1);
  312. m_mutex.Unlock();
  313. delete piudc;
  314. return false;
  315. }
  316. return true;
  317. }
  318. bool NetInterfaces::stopInterface(Interface *pi)
  319. {
  320. if(!pi)
  321. {
  322. reportError("NetInterfaces::stopInterface: Invalid interface!");
  323. return false;
  324. }
  325. int nRet;
  326. if(!SetInterlockedIfUpDownInProgress())
  327. {
  328. reportError("NetInterfaces::stopInterface: IfUp/Down already in progress!");
  329. return false;
  330. }
  331. LPIF_UPDOWN_CONTEXT piudc = new IF_UPDOWN_CONTEXT;
  332. piudc->pThis = this;
  333. piudc->pi = pi;
  334. piudc->ctx = UDC_Stop;
  335. if((nRet = ::IfDownAsync(pi->getName(), m_ifUpDownPid, &NetInterfaces::onIfDownCompleted, static_cast<void*>(piudc), &NetInterfaces::onIfUpDown, static_cast<void*>(this))))
  336. {
  337. m_mutex.Lock();
  338. reportError("NetInterfaces::stopInterface: IfDownAsync failed with code: %d", nRet);
  339. emit ifUpDownCompleted(UDC_Stop, -3);
  340. SetIfUpDownInProgress(false);
  341. SetIfUpDownPid(-1);
  342. m_mutex.Unlock();
  343. delete piudc;
  344. return false;
  345. }
  346. return true;
  347. }
  348. bool NetInterfaces::restartInterface(Interface *pi)
  349. {
  350. if(!pi)
  351. {
  352. reportError("NetInterfaces::restartInterface: Invalid interface!");
  353. return false;
  354. }
  355. int nRet;
  356. if(!SetInterlockedIfUpDownInProgress())
  357. {
  358. reportError("NetInterfaces::restartInterface: IfUp/Down already in progress!");
  359. return false;
  360. }
  361. LPIF_UPDOWN_CONTEXT piudc = new IF_UPDOWN_CONTEXT;
  362. piudc->pThis = this;
  363. piudc->pi = pi;
  364. piudc->ctx = UDC_Stop;
  365. if((nRet = ::IfDownAsync(pi->getName(), m_ifUpDownPid, &NetInterfaces::onIfRestartCompleted, static_cast<void*>(piudc), &NetInterfaces::onIfUpDown, static_cast<void*>(this))))
  366. {
  367. m_mutex.Lock();
  368. reportError("NetInterfaces::restartInterface: IfDownAsync failed with code: %d", nRet);
  369. emit ifUpDownCompleted(UDC_Restart, -3);
  370. SetIfUpDownInProgress(false);
  371. SetIfUpDownPid(-1);
  372. m_mutex.Unlock();
  373. delete piudc;
  374. return false;
  375. }
  376. return true;
  377. }
  378. bool NetInterfaces::cancelStartStopInterface(void)
  379. {
  380. m_mutex.Lock();
  381. pid_t pid = GetIfUpDownPid();
  382. bool bCancel = GetIfUpDownInProgress() && (pid != -1);
  383. if(bCancel)
  384. {
  385. // bCancel = !kill(-pid, SIGKILL);
  386. bCancel = !system("killall -SIGTERM ifup");
  387. }
  388. m_mutex.Unlock();
  389. return bCancel;
  390. }
  391. QQmlListProperty<Interface> NetInterfaces::interfaces(void)
  392. {
  393. return QQmlListProperty<Interface>(this, m_interfaces);
  394. }
  395. QQmlListProperty<Interface> NetInterfaces::filteredInterfaces(void)
  396. {
  397. m_filteredInterfaces.clear();
  398. for(int i = 0; i < m_interfaces.count(); i++)
  399. {
  400. Interface *pi = m_interfaces.at(i);
  401. const ITF_IFACE_BLOCK &ibl = pi->getIface();
  402. if( (m_itfFilterName.isNull() || m_itfFilterName.isEmpty() || (m_itfFilterName == ibl.cfgName.c_str())) &&
  403. (_ENUM_TO_FLAG(ibl.proto) & m_itfFilterAF) &&
  404. (_ENUM_TO_FLAG(ibl.method) & m_itfFilterMethod))
  405. {
  406. m_filteredInterfaces.append(pi);
  407. }
  408. }
  409. return QQmlListProperty<Interface>(this, m_filteredInterfaces);
  410. }
  411. const QString& NetInterfaces::itfFilterName(void) const
  412. {
  413. return m_itfFilterName;
  414. }
  415. void NetInterfaces::setItfFilterName(const QString &val)
  416. {
  417. if(val != m_itfFilterName)
  418. {
  419. m_itfFilterName = val;
  420. emit itfFilterNameChanged(m_itfFilterName);
  421. emit filteredInterfacesChanged();
  422. }
  423. }
  424. int NetInterfaces::itfFilterAF(void) const
  425. {
  426. return m_itfFilterAF;
  427. }
  428. void NetInterfaces::setItfFilterAF(int af)
  429. {
  430. if(af < Interface::AF_Unknown || af >= Interface::AF_Invalid)
  431. {
  432. reportError("Invalid address family filter: %d!", af);
  433. return;
  434. }
  435. if(m_itfFilterAF != af)
  436. {
  437. m_itfFilterAF = af;
  438. emit itfFilterAFChanged(af);
  439. emit filteredInterfacesChanged();
  440. }
  441. }
  442. int NetInterfaces::itfFilterMethod(void) const
  443. {
  444. return m_itfFilterMethod;
  445. }
  446. void NetInterfaces::setItfFilterMethod(int method)
  447. {
  448. if(method < Interface::IM_Unknown || method >= Interface::IM_Invalid)
  449. {
  450. reportError("Invalid method filter: %d!", method);
  451. return;
  452. }
  453. if(m_itfFilterMethod != method)
  454. {
  455. m_itfFilterMethod = method;
  456. emit itfFilterMethodChanged(method);
  457. emit filteredInterfacesChanged();
  458. }
  459. }
  460. int NetInterfaces::getInterfaceSelConfig(Interface &ri)
  461. {
  462. int mask = 0;
  463. ::EnumInterfaceCfgGroups(m_eni, ri.getID(),
  464. [] (CfgGroup cg, void *pCtx) -> void
  465. {
  466. if(cg > CG_Unknown)
  467. {
  468. int *m = (int*)pCtx;
  469. *m |= _ENUM_TO_FLAG(cg);
  470. }
  471. }, &mask);
  472. return mask;
  473. }
  474. bool NetInterfaces::ifUpDownInProgress(void) const
  475. {
  476. return m_bIfUpDownInProgress;
  477. }
  478. /////////////////////////////////////////////////////////////////////////////
  479. Interface::Interface(ITF_IFACE_BLOCK &ifb, NotificationSink &notifyer, QObject *pParent) : QObject(pParent),
  480. m_ifb(ifb),
  481. m_inet(ifb, notifyer, this),
  482. m_rNotifyer(notifyer),
  483. m_selCfg(notifyer.getInterfaceSelConfig(*this))
  484. {
  485. setObjectName("Interface");
  486. }
  487. Interface::~Interface(void)
  488. {
  489. }
  490. QString Interface::name(void) const
  491. {
  492. return QString::fromStdString(m_ifb.cfgName);
  493. }
  494. QString Interface::afName(void) const
  495. {
  496. return ::GetIfaceProtoStr(m_ifb.proto);
  497. }
  498. int Interface::af(void) const
  499. {
  500. return (int)_ENUM_TO_FLAG(m_ifb.proto);
  501. }
  502. void Interface::setAf(int af)
  503. {
  504. if(!_IsPowerOf2(af) || (af < Interface::AF_Unknown) || (af >= Interface::AF_Invalid))
  505. {
  506. m_rNotifyer.reportError("Invalid address family: %d!", af);
  507. return;
  508. }
  509. IfaceProtos proto = (IfaceProtos)_FLAG_TO_ENUM(af);
  510. if(m_ifb.proto != proto)
  511. {
  512. m_ifb.proto = proto;
  513. emit afChanged(af);
  514. emit afNameChanged();
  515. m_rNotifyer.filterPropertyChanged();
  516. }
  517. }
  518. QString Interface::methodName(void) const
  519. {
  520. return ::GetIfaceMethodStr(m_ifb.method);
  521. }
  522. int Interface::method(void) const
  523. {
  524. return (int)_ENUM_TO_FLAG(m_ifb.method);
  525. }
  526. void Interface::setMethod(int method)
  527. {
  528. if(!_IsPowerOf2(method) || (method < Interface::IM_Unknown) || (method >= Interface::IM_Invalid))
  529. {
  530. m_rNotifyer.reportError("Invalid interface method: %d!", method);
  531. return;
  532. }
  533. IfaceMethods meth = (IfaceMethods)_FLAG_TO_ENUM(method);
  534. if(m_ifb.method != meth)
  535. {
  536. m_ifb.method = meth;
  537. emit methodChanged(meth);
  538. emit methodNameChanged();
  539. m_rNotifyer.filterPropertyChanged();
  540. }
  541. }
  542. int Interface::selCfg(void) const
  543. {
  544. return m_selCfg;
  545. }
  546. void Interface::setSelCfg(int cfg)
  547. {
  548. if(cfg < SC_None || cfg >= SC_Invalid)
  549. {
  550. m_rNotifyer.reportError("Invalid start/selection configuration: 0x%X!", cfg);
  551. return;
  552. }
  553. if(m_selCfg != cfg)
  554. {
  555. m_rNotifyer.selConfigChanged(this, m_selCfg, cfg);
  556. m_selCfg = cfg;
  557. emit selCfgChanged(cfg);
  558. }
  559. }
  560. Inet* Interface::inet(void)
  561. {
  562. return &m_inet;
  563. }
  564. /////////////////////////////////////////////////////////////////////////////
  565. Inet::Inet(ITF_IFACE_BLOCK &ifb, NotificationSink &notifyer, QObject *pParent) : QObject(pParent),
  566. m_static(ifb.inet4s, notifyer, this),
  567. m_dhcp(ifb.inet4d, notifyer, this),
  568. m_rNotifyer(notifyer)
  569. {
  570. setObjectName("Inet");
  571. }
  572. Inet::~Inet(void)
  573. {
  574. }
  575. Static* Inet::stat(void)
  576. {
  577. return &m_static;
  578. }
  579. Dhcp* Inet::dhcp(void)
  580. {
  581. return &m_dhcp;
  582. }
  583. /////////////////////////////////////////////////////////////////////////////
  584. Static::Static(IFACE_INET_STATIC &itfs, NotificationSink &notifyer, QObject *pParent) : QObject(pParent),
  585. m_itfs(itfs),
  586. m_rNotifyer(notifyer),
  587. m_ipAddr(itfs.addr, notifyer, this),
  588. m_netmask(itfs.netmask, notifyer, this, _IsValidNetmask),
  589. m_gateway(itfs.gate, notifyer, this),
  590. m_bcastAddr(itfs.bcast, notifyer, this),
  591. m_ptpAddr(itfs.pointopoint, notifyer, this)
  592. {
  593. setObjectName("Static");
  594. for(size_t i = 0; i < _countof(m_itfs.namesvr); i++)
  595. {
  596. IPv4Address *addr = new IPv4Address(m_itfs.namesvr[i], notifyer, this);
  597. m_dnsList.append(addr);
  598. }
  599. QObject::connect(&m_netmask, SIGNAL(addressChanged(const QString&)), this, SLOT(netmaskChanged(const QString&)));
  600. }
  601. Static::~Static(void)
  602. {
  603. IPv4Address *addr;
  604. for(int i = 0; i < m_dnsList.count(); i++)
  605. {
  606. if((addr = m_dnsList.at(i)))
  607. delete addr;
  608. }
  609. }
  610. IPv4Address* Static::ipAddress(void)
  611. {
  612. return &m_ipAddr;
  613. }
  614. IPv4Address* Static::netMask(void)
  615. {
  616. return &m_netmask;
  617. }
  618. IPv4Address* Static::gateway(void)
  619. {
  620. return &m_gateway;
  621. }
  622. IPv4Address* Static::bcastAddress(void)
  623. {
  624. return &m_bcastAddr;
  625. }
  626. IPv4Address* Static::ptpAddress(void)
  627. {
  628. return &m_ptpAddr;
  629. }
  630. QQmlListProperty<IPv4Address> Static::dnsServer(void)
  631. {
  632. return QQmlListProperty<IPv4Address>(this, m_dnsList);
  633. }
  634. int Static::metric(void) const
  635. {
  636. return m_itfs.metric;
  637. }
  638. void Static::setMetric(int metric)
  639. {
  640. if(m_itfs.metric != metric)
  641. {
  642. m_itfs.metric = metric;
  643. emit metricChanged(metric);
  644. }
  645. }
  646. int Static::mtu(void) const
  647. {
  648. return m_itfs.mtu;
  649. }
  650. void Static::setMtu(int mtu)
  651. {
  652. if(m_itfs.mtu != mtu)
  653. {
  654. m_itfs.mtu = mtu;
  655. emit mtuChanged(mtu);
  656. }
  657. }
  658. int Static::netPrefix(void) const
  659. {
  660. return m_itfs.netprefix;
  661. }
  662. void Static::setNetPrefix(int netprefix)
  663. {
  664. if(netprefix < 0 || netprefix > 32)
  665. {
  666. m_rNotifyer.reportError("Invalid net prefix: %d!", netprefix);
  667. return;
  668. }
  669. if(m_itfs.netprefix != (unsigned int)netprefix)
  670. {
  671. struct in_addr in;
  672. in.s_addr = _Prefix2Mask(netprefix);
  673. m_netmask.setProperty("address", QVariant(inet_ntoa(in)));
  674. }
  675. }
  676. void Static::netmaskChanged(const QString &mask)
  677. {
  678. struct in_addr in;
  679. std::string sa = mask.toStdString();
  680. if( inet_aton(sa.c_str(), &in) &&
  681. _IsValidNetmask(in))
  682. {
  683. m_itfs.netprefix = _Mask2Prefix(in);
  684. emit netPrefixChanged(m_itfs.netprefix);
  685. }
  686. else
  687. {
  688. m_rNotifyer.reportError("Invalid net mask: %s!", sa.c_str());
  689. m_netmask.setProperty("address", QVariant("255.255.255.0"));
  690. }
  691. }
  692. /////////////////////////////////////////////////////////////////////////////
  693. Dhcp::Dhcp(IFACE_INET_DHCP &itfd, NotificationSink &notifyer, QObject *pParent) : QObject(pParent), m_itfd(itfd), m_rNotifyer(notifyer)
  694. {
  695. setObjectName("Dhcp");
  696. }
  697. Dhcp::~Dhcp(void)
  698. {
  699. }
  700. /////////////////////////////////////////////////////////////////////////////
  701. IPv4Address::IPv4Address(struct in_addr &addr, NotificationSink &notifyer, QObject *pParent, PFN_ADDRESS_VALIDATOR pfnAddrValidator) : QObject(pParent),
  702. m_addr(addr),
  703. m_pfnAddrValidator(pfnAddrValidator),
  704. m_rNotifyer(notifyer)
  705. {
  706. setObjectName("IPv4Address");
  707. }
  708. IPv4Address::~IPv4Address(void)
  709. {
  710. }
  711. QString IPv4Address::address(void) const
  712. {
  713. return inet_ntoa(m_addr);
  714. }
  715. int IPv4Address::b0(void) const
  716. {
  717. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  718. return (int)pb[0];
  719. }
  720. int IPv4Address::b1(void) const
  721. {
  722. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  723. return (int)pb[1];
  724. }
  725. int IPv4Address::b2(void) const
  726. {
  727. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  728. return (int)pb[2];
  729. }
  730. int IPv4Address::b3(void) const
  731. {
  732. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  733. return (int)pb[3];
  734. }
  735. void IPv4Address::setAddress(const QString &addr)
  736. {
  737. struct in_addr newAddr, oldAddr;
  738. std::string sa = addr.toStdString();
  739. if(!inet_aton(sa.c_str(), &newAddr))
  740. {
  741. m_rNotifyer.reportError("Invalid IP address: '%s'!", sa.c_str());
  742. return;
  743. }
  744. if(m_pfnAddrValidator && !(*m_pfnAddrValidator)(newAddr))
  745. {
  746. m_rNotifyer.reportError("Invalid address: '%s'!", sa.c_str());
  747. return;
  748. }
  749. if(m_addr.s_addr != newAddr.s_addr)
  750. {
  751. oldAddr.s_addr = m_addr.s_addr;
  752. m_addr.s_addr = newAddr.s_addr;
  753. unsigned char *pb1 = (unsigned char*)&oldAddr.s_addr;
  754. unsigned char *pb2 = (unsigned char*)&newAddr.s_addr;
  755. if(pb1[0] != pb2[0])
  756. emit b0Changed(pb2[0]);
  757. if(pb1[1] != pb2[1])
  758. emit b1Changed(pb2[1]);
  759. if(pb1[2] != pb2[2])
  760. emit b2Changed(pb2[2]);
  761. if(pb1[3] != pb2[3])
  762. emit b3Changed(pb2[3]);
  763. emit addressChanged(address());
  764. }
  765. }
  766. void IPv4Address::setB0(int b)
  767. {
  768. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  769. if(!_IS_VALID_BYTE_VALUE(b))
  770. {
  771. m_rNotifyer.reportError("Invalid IP address byte 0: '%d'!", b);
  772. return;
  773. }
  774. if(b == (int)pb[0])
  775. return;
  776. pb[0] = (unsigned char)b;
  777. emit b0Changed(b);
  778. emit addressChanged(address());
  779. }
  780. void IPv4Address::setB1(int b)
  781. {
  782. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  783. if(!_IS_VALID_BYTE_VALUE(b))
  784. {
  785. m_rNotifyer.reportError("Invalid IP address byte 1: '%d'!", b);
  786. return;
  787. }
  788. if(b == (int)pb[1])
  789. return;
  790. pb[1] = (unsigned char)b;
  791. emit b1Changed(b);
  792. emit addressChanged(address());
  793. }
  794. void IPv4Address::setB2(int b)
  795. {
  796. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  797. if(!_IS_VALID_BYTE_VALUE(b))
  798. {
  799. m_rNotifyer.reportError("Invalid IP address byte 2: '%d'!", b);
  800. return;
  801. }
  802. if(b == (int)pb[2])
  803. return;
  804. pb[2] = (unsigned char)b;
  805. emit b2Changed(b);
  806. emit addressChanged(address());
  807. }
  808. void IPv4Address::setB3(int b)
  809. {
  810. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  811. if(!_IS_VALID_BYTE_VALUE(b))
  812. {
  813. m_rNotifyer.reportError("Invalid IP address byte 3: '%d'!", b);
  814. return;
  815. }
  816. if(b == (int)pb[3])
  817. return;
  818. pb[3] = (unsigned char)b;
  819. emit b3Changed(b);
  820. emit addressChanged(address());
  821. }