netinterfaces.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. #include "netinterfaces.h"
  2. #include "../debug.h"
  3. #ifndef _countof
  4. #define _countof(a) (sizeof(a) / sizeof(*a))
  5. #endif // _countof
  6. #define _IS_VALID_BYTE_VALUE(b) (((b) >= 0) && ((b) <= 255))
  7. template<typename T>
  8. static bool _IsPowerOf2(T x)
  9. {
  10. return x && !(x & (x - 1));
  11. }
  12. template<typename T>
  13. static unsigned int _BitCount(T n)
  14. {
  15. unsigned int count = 0;
  16. while(n)
  17. {
  18. count++;
  19. n &= (n - 1);
  20. }
  21. return count;
  22. }
  23. template<typename T>
  24. static int _BitNumber(T n)
  25. {
  26. if(!n || !_IsPowerOf2(n))
  27. return -1;
  28. int count = 0;
  29. while(n)
  30. {
  31. count++;
  32. n >>= 1;
  33. }
  34. return count - 1;
  35. }
  36. static int _Mask2Prefix(const struct in_addr &in)
  37. {
  38. return _BitCount(in.s_addr);
  39. }
  40. static in_addr_t _Prefix2Mask(int prefix)
  41. {
  42. return htonl(~((1 << (32 - prefix)) - 1));
  43. }
  44. static bool _IsValidNetmask(const struct in_addr &in)
  45. {
  46. return _IsPowerOf2(~ntohl(in.s_addr) + 1);
  47. }
  48. /////////////////////////////////////////////////////////////////////////////
  49. #define _FLAG_TO_ENUM(f) (_BitNumber(f))
  50. #define _ENUM_TO_FLAG(e) (0x00000001 << e)
  51. /////////////////////////////////////////////////////////////////////////////
  52. NetInterfaces::NetInterfaces(QObject *pParent) : QObject(pParent)
  53. {
  54. setObjectName("NetInterfaces");
  55. m_itfFilterAF = Interface::AF_Unknown;
  56. m_itfFilterMethod = Interface::IM_Unknown;
  57. m_itfFilterName.clear();
  58. }
  59. NetInterfaces::~NetInterfaces(void)
  60. {
  61. reset();
  62. }
  63. void NetInterfaces::classBegin()
  64. {
  65. if(!initialize())
  66. {
  67. emitError("NetInterfaces::initialize failed!");
  68. }
  69. }
  70. void NetInterfaces::componentComplete()
  71. {
  72. }
  73. void NetInterfaces::reset(void)
  74. {
  75. Interface *pItf;
  76. for(int i = 0; i < m_interfaces.count(); i++)
  77. {
  78. if((pItf = m_interfaces.at(i)))
  79. delete pItf;
  80. }
  81. m_interfaces.clear();
  82. emit interfacesChanged();
  83. emit filteredInterfacesChanged();
  84. m_eni._reset();
  85. }
  86. bool NetInterfaces::initialize(void)
  87. {
  88. bool bRet;
  89. reset();
  90. if((bRet = ::ParseEtcNetworkInterfaces(m_eni)))
  91. {
  92. for(auto it = m_eni.ibl.begin(); it != m_eni.ibl.end(); it++)
  93. {
  94. ITF_IFACE_BLOCK &ibl = *it;
  95. m_interfaces.append(new Interface(ibl, static_cast<const NotificationSink&>(*this), this));
  96. }
  97. emit interfacesChanged();
  98. emit filteredInterfacesChanged();
  99. }
  100. return bRet;
  101. }
  102. bool NetInterfaces::save(void)
  103. {
  104. return ::WriteEtcNetworkInterfaces(m_eni, NULL);
  105. }
  106. bool NetInterfaces::saveAs(const QString &path)
  107. {
  108. if(!path.length())
  109. return false;
  110. std::string p = path.toStdString();
  111. const char *pszPath = p.c_str();
  112. return ::WriteEtcNetworkInterfaces(m_eni, pszPath);
  113. }
  114. void NetInterfaces::emitError(const char *pszFormatStr, ...) const
  115. {
  116. va_list args;
  117. va_start(args, pszFormatStr);
  118. QString qs = QString::vasprintf(pszFormatStr, args);
  119. va_end (args);
  120. emit error(qs);
  121. }
  122. void NetInterfaces::filterPropertyChanged(void) const
  123. {
  124. emit filteredInterfacesChanged();
  125. }
  126. Interface* NetInterfaces::newInterface(QString name, int af, int method)
  127. {
  128. if(name.isNull() || name.isEmpty())
  129. {
  130. emitError("Invalid or empty interface name!");
  131. return NULL;
  132. }
  133. if(!_IsPowerOf2(af) || (af <= Interface::AF_Unknown) || (af >= Interface::AF_Invalid))
  134. {
  135. emitError("Invalid address family: %d!", af);
  136. return NULL;
  137. }
  138. if(!_IsPowerOf2(method) || (method <= Interface::IM_Unknown) || (method >= Interface::IM_Invalid))
  139. {
  140. emitError("Invalid method: %d!", method);
  141. return NULL;
  142. }
  143. m_eni.ibl.emplace_back();
  144. ITF_IFACE_BLOCK &rib = m_eni.ibl.back();
  145. rib.cfgName = name.toStdString();
  146. rib.proto = (IfaceProtos)_FLAG_TO_ENUM(af);
  147. rib.method = (IfaceMethods)_FLAG_TO_ENUM(method);
  148. Interface *pi = new Interface(rib, static_cast<const NotificationSink&>(*this), this);
  149. m_interfaces.append(pi);
  150. emit interfacesChanged();
  151. emit filteredInterfacesChanged();
  152. return pi;
  153. }
  154. void NetInterfaces::removeInterface(Interface *pi)
  155. {
  156. if(!pi)
  157. {
  158. emitError("%s: Attempt to remove invalid interface!", __FUNCTION__);
  159. return;
  160. }
  161. unsigned long id = pi->getID();
  162. for(int i = 0; i < m_interfaces.count(); i++)
  163. {
  164. Interface *pil = m_interfaces.at(i);
  165. if(pil->getID() == id)
  166. {
  167. m_interfaces.removeAt(i);
  168. emit interfacesChanged();
  169. emit filteredInterfacesChanged();
  170. delete pil;
  171. ::RemoveInterfaceBlock(m_eni, id);
  172. break;
  173. }
  174. }
  175. }
  176. QQmlListProperty<Interface> NetInterfaces::interfaces(void)
  177. {
  178. return QQmlListProperty<Interface>(this, m_interfaces);
  179. }
  180. QQmlListProperty<Interface> NetInterfaces::filteredInterfaces(void)
  181. {
  182. m_filteredInterfaces.clear();
  183. for(int i = 0; i < m_interfaces.count(); i++)
  184. {
  185. Interface *pi = m_interfaces.at(i);
  186. const ITF_IFACE_BLOCK &ibl = pi->getIface();
  187. if( (m_itfFilterName.isNull() || m_itfFilterName.isEmpty() || (m_itfFilterName == ibl.cfgName.c_str())) &&
  188. (_ENUM_TO_FLAG(ibl.proto) & m_itfFilterAF) &&
  189. (_ENUM_TO_FLAG(ibl.method) & m_itfFilterMethod))
  190. {
  191. m_filteredInterfaces.append(pi);
  192. }
  193. }
  194. return QQmlListProperty<Interface>(this, m_filteredInterfaces);
  195. }
  196. const QString& NetInterfaces::itfFilterName(void) const
  197. {
  198. return m_itfFilterName;
  199. }
  200. void NetInterfaces::setItfFilterName(const QString &val)
  201. {
  202. if(val != m_itfFilterName)
  203. {
  204. m_itfFilterName = val;
  205. emit itfFilterNameChanged(m_itfFilterName);
  206. emit filteredInterfacesChanged();
  207. }
  208. }
  209. int NetInterfaces::itfFilterAF(void) const
  210. {
  211. return m_itfFilterAF;
  212. }
  213. void NetInterfaces::setItfFilterAF(int af)
  214. {
  215. if(af < Interface::AF_Unknown || af >= Interface::AF_Invalid)
  216. {
  217. emitError("Invalid address family filter: %d!", af);
  218. return;
  219. }
  220. if(m_itfFilterAF != af)
  221. {
  222. m_itfFilterAF = af;
  223. emit itfFilterAFChanged(af);
  224. emit filteredInterfacesChanged();
  225. }
  226. }
  227. int NetInterfaces::itfFilterMethod(void) const
  228. {
  229. return m_itfFilterMethod;
  230. }
  231. void NetInterfaces::setItfFilterMethod(int method)
  232. {
  233. if(method < Interface::IM_Unknown || method >= Interface::IM_Invalid)
  234. {
  235. emitError("Invalid method filter: %d!", method);
  236. return;
  237. }
  238. if(m_itfFilterMethod != method)
  239. {
  240. m_itfFilterMethod = method;
  241. emit itfFilterMethodChanged(method);
  242. emit filteredInterfacesChanged();
  243. }
  244. }
  245. /////////////////////////////////////////////////////////////////////////////
  246. Interface::Interface(ITF_IFACE_BLOCK &ifb, const NotificationSink &notifyer, QObject *pParent) : QObject(pParent),
  247. m_ifb(ifb),
  248. m_inet(ifb, notifyer, this),
  249. m_rNotifyer(notifyer)
  250. {
  251. setObjectName("Interface");
  252. }
  253. Interface::~Interface(void)
  254. {
  255. }
  256. QString Interface::name(void) const
  257. {
  258. return QString::fromStdString(m_ifb.cfgName);
  259. }
  260. QString Interface::afName(void) const
  261. {
  262. return ::GetIfaceProtoStr(m_ifb.proto);
  263. }
  264. int Interface::af(void) const
  265. {
  266. return (int)_ENUM_TO_FLAG(m_ifb.proto);
  267. }
  268. void Interface::setAf(int af)
  269. {
  270. if(!_IsPowerOf2(af) || (af < Interface::AF_Unknown) || (af >= Interface::AF_Invalid))
  271. {
  272. m_rNotifyer.emitError("Invalid address family: %d!", af);
  273. return;
  274. }
  275. IfaceProtos proto = (IfaceProtos)_FLAG_TO_ENUM(af);
  276. if(m_ifb.proto != proto)
  277. {
  278. m_ifb.proto = proto;
  279. emit afChanged(af);
  280. emit afNameChanged();
  281. m_rNotifyer.filterPropertyChanged();
  282. }
  283. }
  284. QString Interface::methodName(void) const
  285. {
  286. return ::GetIfaceMethodStr(m_ifb.method);
  287. }
  288. int Interface::method(void) const
  289. {
  290. return (int)_ENUM_TO_FLAG(m_ifb.method);
  291. }
  292. void Interface::setMethod(int method)
  293. {
  294. if(!_IsPowerOf2(method) || (method < Interface::IM_Unknown) || (method >= Interface::IM_Invalid))
  295. {
  296. m_rNotifyer.emitError("Invalid interface method: %d!", method);
  297. return;
  298. }
  299. IfaceMethods meth = (IfaceMethods)_FLAG_TO_ENUM(method);
  300. if(m_ifb.method != meth)
  301. {
  302. m_ifb.method = meth;
  303. emit methodChanged(meth);
  304. emit methodNameChanged();
  305. m_rNotifyer.filterPropertyChanged();
  306. }
  307. }
  308. Inet* Interface::inet(void)
  309. {
  310. return &m_inet;
  311. }
  312. /////////////////////////////////////////////////////////////////////////////
  313. Inet::Inet(ITF_IFACE_BLOCK &ifb, const NotificationSink &notifyer, QObject *pParent) : QObject(pParent),
  314. m_static(ifb.inet4s, notifyer, this),
  315. m_dhcp(ifb.inet4d, notifyer, this),
  316. m_rNotifyer(notifyer)
  317. {
  318. setObjectName("Inet");
  319. }
  320. Inet::~Inet(void)
  321. {
  322. }
  323. Static* Inet::stat(void)
  324. {
  325. return &m_static;
  326. }
  327. Dhcp* Inet::dhcp(void)
  328. {
  329. return &m_dhcp;
  330. }
  331. /////////////////////////////////////////////////////////////////////////////
  332. Static::Static(IFACE_INET_STATIC &itfs, const NotificationSink &notifyer, QObject *pParent) : QObject(pParent),
  333. m_itfs(itfs),
  334. m_rNotifyer(notifyer),
  335. m_ipAddr(itfs.addr, notifyer, this),
  336. m_netmask(itfs.netmask, notifyer, this, _IsValidNetmask),
  337. m_gateway(itfs.gate, notifyer, this),
  338. m_bcastAddr(itfs.bcast, notifyer, this),
  339. m_ptpAddr(itfs.pointopoint, notifyer, this)
  340. {
  341. setObjectName("Static");
  342. for(size_t i = 0; i < _countof(m_itfs.namesvr); i++)
  343. {
  344. IPv4Address *addr = new IPv4Address(m_itfs.namesvr[i], notifyer, this);
  345. m_dnsList.append(addr);
  346. }
  347. QObject::connect(&m_netmask, SIGNAL(addressChanged(const QString&)), this, SLOT(netmaskChanged(const QString&)));
  348. }
  349. Static::~Static(void)
  350. {
  351. IPv4Address *addr;
  352. for(int i = 0; i < m_dnsList.count(); i++)
  353. {
  354. if((addr = m_dnsList.at(i)))
  355. delete addr;
  356. }
  357. }
  358. IPv4Address* Static::ipAddress(void)
  359. {
  360. return &m_ipAddr;
  361. }
  362. IPv4Address* Static::netMask(void)
  363. {
  364. return &m_netmask;
  365. }
  366. IPv4Address* Static::gateway(void)
  367. {
  368. return &m_gateway;
  369. }
  370. IPv4Address* Static::bcastAddress(void)
  371. {
  372. return &m_bcastAddr;
  373. }
  374. IPv4Address* Static::ptpAddress(void)
  375. {
  376. return &m_ptpAddr;
  377. }
  378. QQmlListProperty<IPv4Address> Static::dnsServer(void)
  379. {
  380. return QQmlListProperty<IPv4Address>(this, m_dnsList);
  381. }
  382. int Static::metric(void) const
  383. {
  384. return m_itfs.metric;
  385. }
  386. void Static::setMetric(int metric)
  387. {
  388. if(m_itfs.metric != metric)
  389. {
  390. m_itfs.metric = metric;
  391. emit metricChanged(metric);
  392. }
  393. }
  394. int Static::mtu(void) const
  395. {
  396. return m_itfs.mtu;
  397. }
  398. void Static::setMtu(int mtu)
  399. {
  400. if(m_itfs.mtu != mtu)
  401. {
  402. m_itfs.mtu = mtu;
  403. emit mtuChanged(mtu);
  404. }
  405. }
  406. int Static::netPrefix(void) const
  407. {
  408. return m_itfs.netprefix;
  409. }
  410. void Static::setNetPrefix(int netprefix)
  411. {
  412. if(netprefix < 0 || netprefix > 32)
  413. {
  414. m_rNotifyer.emitError("Invalid net prefix: %d!", netprefix);
  415. return;
  416. }
  417. if(m_itfs.netprefix != (unsigned int)netprefix)
  418. {
  419. struct in_addr in;
  420. in.s_addr = _Prefix2Mask(netprefix);
  421. m_netmask.setProperty("address", QVariant(inet_ntoa(in)));
  422. }
  423. }
  424. void Static::netmaskChanged(const QString &mask)
  425. {
  426. struct in_addr in;
  427. std::string sa = mask.toStdString();
  428. if( inet_aton(sa.c_str(), &in) &&
  429. _IsValidNetmask(in))
  430. {
  431. m_itfs.netprefix = _Mask2Prefix(in);
  432. emit netPrefixChanged(m_itfs.netprefix);
  433. }
  434. else
  435. {
  436. m_rNotifyer.emitError("Invalid net mask: %s!", sa.c_str());
  437. m_netmask.setProperty("address", QVariant("255.255.255.0"));
  438. }
  439. }
  440. /////////////////////////////////////////////////////////////////////////////
  441. Dhcp::Dhcp(IFACE_INET_DHCP &itfd, const NotificationSink &notifyer, QObject *pParent) : QObject(pParent), m_itfd(itfd), m_rNotifyer(notifyer)
  442. {
  443. setObjectName("Dhcp");
  444. }
  445. Dhcp::~Dhcp(void)
  446. {
  447. }
  448. /////////////////////////////////////////////////////////////////////////////
  449. IPv4Address::IPv4Address(struct in_addr &addr, const NotificationSink &notifyer, QObject *pParent, PFN_ADDRESS_VALIDATOR pfnAddrValidator) : QObject(pParent),
  450. m_addr(addr),
  451. m_pfnAddrValidator(pfnAddrValidator),
  452. m_rNotifyer(notifyer)
  453. {
  454. setObjectName("IPv4Address");
  455. }
  456. IPv4Address::~IPv4Address(void)
  457. {
  458. }
  459. QString IPv4Address::address(void) const
  460. {
  461. return inet_ntoa(m_addr);
  462. }
  463. int IPv4Address::b0(void) const
  464. {
  465. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  466. return (int)pb[0];
  467. }
  468. int IPv4Address::b1(void) const
  469. {
  470. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  471. return (int)pb[1];
  472. }
  473. int IPv4Address::b2(void) const
  474. {
  475. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  476. return (int)pb[2];
  477. }
  478. int IPv4Address::b3(void) const
  479. {
  480. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  481. return (int)pb[3];
  482. }
  483. void IPv4Address::setAddress(const QString &addr)
  484. {
  485. struct in_addr newAddr, oldAddr;
  486. std::string sa = addr.toStdString();
  487. if(!inet_aton(sa.c_str(), &newAddr))
  488. {
  489. m_rNotifyer.emitError("Invalid IP address: '%s'!", sa.c_str());
  490. return;
  491. }
  492. if(m_pfnAddrValidator && !(*m_pfnAddrValidator)(newAddr))
  493. {
  494. m_rNotifyer.emitError("Invalid address: '%s'!", sa.c_str());
  495. return;
  496. }
  497. if(m_addr.s_addr != newAddr.s_addr)
  498. {
  499. oldAddr.s_addr = m_addr.s_addr;
  500. m_addr.s_addr = newAddr.s_addr;
  501. unsigned char *pb1 = (unsigned char*)&oldAddr.s_addr;
  502. unsigned char *pb2 = (unsigned char*)&newAddr.s_addr;
  503. if(pb1[0] != pb2[0])
  504. emit b0Changed(pb2[0]);
  505. if(pb1[1] != pb2[1])
  506. emit b1Changed(pb2[1]);
  507. if(pb1[2] != pb2[2])
  508. emit b2Changed(pb2[2]);
  509. if(pb1[3] != pb2[3])
  510. emit b3Changed(pb2[3]);
  511. emit addressChanged(address());
  512. }
  513. }
  514. void IPv4Address::setB0(int b)
  515. {
  516. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  517. if(!_IS_VALID_BYTE_VALUE(b))
  518. {
  519. m_rNotifyer.emitError("Invalid IP address byte 0: '%d'!", b);
  520. return;
  521. }
  522. if(b == (int)pb[0])
  523. return;
  524. pb[0] = (unsigned char)b;
  525. emit b0Changed(b);
  526. emit addressChanged(address());
  527. }
  528. void IPv4Address::setB1(int b)
  529. {
  530. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  531. if(!_IS_VALID_BYTE_VALUE(b))
  532. {
  533. m_rNotifyer.emitError("Invalid IP address byte 1: '%d'!", b);
  534. return;
  535. }
  536. if(b == (int)pb[1])
  537. return;
  538. pb[1] = (unsigned char)b;
  539. emit b1Changed(b);
  540. emit addressChanged(address());
  541. }
  542. void IPv4Address::setB2(int b)
  543. {
  544. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  545. if(!_IS_VALID_BYTE_VALUE(b))
  546. {
  547. m_rNotifyer.emitError("Invalid IP address byte 2: '%d'!", b);
  548. return;
  549. }
  550. if(b == (int)pb[2])
  551. return;
  552. pb[2] = (unsigned char)b;
  553. emit b2Changed(b);
  554. emit addressChanged(address());
  555. }
  556. void IPv4Address::setB3(int b)
  557. {
  558. unsigned char *pb = (unsigned char*)&m_addr.s_addr;
  559. if(!_IS_VALID_BYTE_VALUE(b))
  560. {
  561. m_rNotifyer.emitError("Invalid IP address byte 3: '%d'!", b);
  562. return;
  563. }
  564. if(b == (int)pb[3])
  565. return;
  566. pb[3] = (unsigned char)b;
  567. emit b3Changed(b);
  568. emit addressChanged(address());
  569. }