PageRenderTime 66ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/connman/src/rtnl.c

https://github.com/lpotter/connman
C | 1687 lines | 1289 code | 321 blank | 77 comment | 232 complexity | 207de3b4dcd5620d94ee18275664bdfe MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. *
  3. * Connection Manager
  4. *
  5. * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  19. *
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <errno.h>
  25. #include <stdio.h>
  26. #include <unistd.h>
  27. #include <string.h>
  28. #include <sys/socket.h>
  29. #include <sys/ioctl.h>
  30. #include <arpa/inet.h>
  31. #include <netinet/ether.h>
  32. #include <netinet/icmp6.h>
  33. #include <net/if_arp.h>
  34. #include <linux/if.h>
  35. #include <linux/netlink.h>
  36. #include <linux/rtnetlink.h>
  37. #include <linux/wireless.h>
  38. #include <glib.h>
  39. #include "connman.h"
  40. #include "log.h"
  41. #ifndef ARPHDR_PHONET_PIPE
  42. #define ARPHDR_PHONET_PIPE (821)
  43. #endif
  44. #ifndef ARPHRD_RAWIP
  45. #define ARPHRD_RAWIP (530)
  46. #endif
  47. #define print(arg...) do { if (0) DBG(arg); } while (0)
  48. //#define print(arg...) DBG(arg)
  49. struct watch_data {
  50. unsigned int id;
  51. int index;
  52. connman_rtnl_link_cb_t newlink;
  53. void *user_data;
  54. };
  55. static GSList *watch_list = NULL;
  56. static unsigned int watch_id = 0;
  57. static GSList *update_list = NULL;
  58. static guint update_interval = G_MAXUINT;
  59. static guint update_timeout = 0;
  60. struct interface_data {
  61. int index;
  62. char *ident;
  63. enum connman_service_type service_type;
  64. enum connman_device_type device_type;
  65. };
  66. static GHashTable *interface_list = NULL;
  67. static void free_interface(gpointer data)
  68. {
  69. struct interface_data *interface = data;
  70. __connman_technology_remove_interface(interface->service_type,
  71. interface->index, interface->ident);
  72. g_free(interface->ident);
  73. g_free(interface);
  74. }
  75. static bool ether_blacklisted(const char *name)
  76. {
  77. if (!name)
  78. return true;
  79. if (__connman_device_isfiltered(name))
  80. return true;
  81. return false;
  82. }
  83. static bool wext_interface(char *ifname)
  84. {
  85. struct iwreq wrq;
  86. int fd, err;
  87. fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
  88. if (fd < 0)
  89. return false;
  90. memset(&wrq, 0, sizeof(wrq));
  91. strncpy(wrq.ifr_name, ifname, sizeof(wrq.ifr_name) - 1);
  92. err = ioctl(fd, SIOCGIWNAME, &wrq);
  93. close(fd);
  94. if (err < 0)
  95. return false;
  96. return true;
  97. }
  98. static void read_uevent(struct interface_data *interface)
  99. {
  100. char *filename, *name, line[128];
  101. bool found_devtype;
  102. FILE *f;
  103. name = connman_inet_ifname(interface->index);
  104. if (ether_blacklisted(name)) {
  105. interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
  106. interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
  107. } else {
  108. interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
  109. interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
  110. }
  111. filename = g_strdup_printf("/sys/class/net/%s/uevent", name);
  112. f = fopen(filename, "re");
  113. g_free(filename);
  114. if (!f) {
  115. interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
  116. interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
  117. goto out;
  118. }
  119. found_devtype = false;
  120. while (fgets(line, sizeof(line), f)) {
  121. char *pos;
  122. pos = strchr(line, '\n');
  123. if (!pos)
  124. continue;
  125. pos[0] = '\0';
  126. if (strncmp(line, "DEVTYPE=", 8) != 0)
  127. continue;
  128. found_devtype = true;
  129. if (strcmp(line + 8, "wlan") == 0) {
  130. interface->service_type = CONNMAN_SERVICE_TYPE_WIFI;
  131. interface->device_type = CONNMAN_DEVICE_TYPE_WIFI;
  132. } else if (strcmp(line + 8, "wwan") == 0) {
  133. interface->service_type = CONNMAN_SERVICE_TYPE_CELLULAR;
  134. interface->device_type = CONNMAN_DEVICE_TYPE_CELLULAR;
  135. } else if (strcmp(line + 8, "bluetooth") == 0) {
  136. interface->service_type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
  137. interface->device_type = CONNMAN_DEVICE_TYPE_BLUETOOTH;
  138. } else if (strcmp(line + 8, "gadget") == 0) {
  139. interface->service_type = CONNMAN_SERVICE_TYPE_GADGET;
  140. interface->device_type = CONNMAN_DEVICE_TYPE_GADGET;
  141. } else {
  142. interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
  143. interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
  144. }
  145. }
  146. fclose(f);
  147. if (found_devtype)
  148. goto out;
  149. /* We haven't got a DEVTYPE, let's check if it's a wireless device */
  150. if (wext_interface(name)) {
  151. interface->service_type = CONNMAN_SERVICE_TYPE_WIFI;
  152. interface->device_type = CONNMAN_DEVICE_TYPE_WIFI;
  153. connman_error("%s runs an unsupported 802.11 driver", name);
  154. }
  155. out:
  156. g_free(name);
  157. }
  158. enum connman_device_type __connman_rtnl_get_device_type(int index)
  159. {
  160. struct interface_data *interface;
  161. interface = g_hash_table_lookup(interface_list,
  162. GINT_TO_POINTER(index));
  163. if (!interface)
  164. return CONNMAN_DEVICE_TYPE_UNKNOWN;
  165. return interface->device_type;
  166. }
  167. /**
  168. * connman_rtnl_add_newlink_watch:
  169. * @index: network device index
  170. * @callback: callback function
  171. * @user_data: callback data;
  172. *
  173. * Add a new RTNL watch for newlink events
  174. *
  175. * Returns: %0 on failure and a unique id on success
  176. */
  177. unsigned int connman_rtnl_add_newlink_watch(int index,
  178. connman_rtnl_link_cb_t callback, void *user_data)
  179. {
  180. struct watch_data *watch;
  181. watch = g_try_new0(struct watch_data, 1);
  182. if (!watch)
  183. return 0;
  184. watch->id = ++watch_id;
  185. watch->index = index;
  186. watch->newlink = callback;
  187. watch->user_data = user_data;
  188. watch_list = g_slist_prepend(watch_list, watch);
  189. DBG("id %d", watch->id);
  190. if (callback) {
  191. unsigned int flags = __connman_ipconfig_get_flags_from_index(index);
  192. if (flags > 0)
  193. callback(flags, 0, user_data);
  194. }
  195. return watch->id;
  196. }
  197. /**
  198. * connman_rtnl_remove_watch:
  199. * @id: watch identifier
  200. *
  201. * Remove the RTNL watch for the identifier
  202. */
  203. void connman_rtnl_remove_watch(unsigned int id)
  204. {
  205. GSList *list;
  206. DBG("id %d", id);
  207. if (id == 0)
  208. return;
  209. for (list = watch_list; list; list = list->next) {
  210. struct watch_data *watch = list->data;
  211. if (watch->id == id) {
  212. watch_list = g_slist_remove(watch_list, watch);
  213. g_free(watch);
  214. break;
  215. }
  216. }
  217. }
  218. static void trigger_rtnl(int index, void *user_data)
  219. {
  220. struct connman_rtnl *rtnl = user_data;
  221. if (rtnl->newlink) {
  222. unsigned short type = __connman_ipconfig_get_type_from_index(index);
  223. unsigned int flags = __connman_ipconfig_get_flags_from_index(index);
  224. rtnl->newlink(type, index, flags, 0);
  225. }
  226. if (rtnl->newgateway) {
  227. const char *gateway =
  228. __connman_ipconfig_get_gateway_from_index(index,
  229. CONNMAN_IPCONFIG_TYPE_ALL);
  230. if (gateway)
  231. rtnl->newgateway(index, gateway);
  232. }
  233. }
  234. static GSList *rtnl_list = NULL;
  235. static gint compare_priority(gconstpointer a, gconstpointer b)
  236. {
  237. const struct connman_rtnl *rtnl1 = a;
  238. const struct connman_rtnl *rtnl2 = b;
  239. return rtnl2->priority - rtnl1->priority;
  240. }
  241. /**
  242. * connman_rtnl_register:
  243. * @rtnl: RTNL module
  244. *
  245. * Register a new RTNL module
  246. *
  247. * Returns: %0 on success
  248. */
  249. int connman_rtnl_register(struct connman_rtnl *rtnl)
  250. {
  251. DBG("rtnl %p name %s", rtnl, rtnl->name);
  252. rtnl_list = g_slist_insert_sorted(rtnl_list, rtnl,
  253. compare_priority);
  254. __connman_ipconfig_foreach(trigger_rtnl, rtnl);
  255. return 0;
  256. }
  257. /**
  258. * connman_rtnl_unregister:
  259. * @rtnl: RTNL module
  260. *
  261. * Remove a previously registered RTNL module
  262. */
  263. void connman_rtnl_unregister(struct connman_rtnl *rtnl)
  264. {
  265. DBG("rtnl %p name %s", rtnl, rtnl->name);
  266. rtnl_list = g_slist_remove(rtnl_list, rtnl);
  267. }
  268. static const char *operstate2str(unsigned char operstate)
  269. {
  270. switch (operstate) {
  271. case IF_OPER_UNKNOWN:
  272. return "UNKNOWN";
  273. case IF_OPER_NOTPRESENT:
  274. return "NOT-PRESENT";
  275. case IF_OPER_DOWN:
  276. return "DOWN";
  277. case IF_OPER_LOWERLAYERDOWN:
  278. return "LOWER-LAYER-DOWN";
  279. case IF_OPER_TESTING:
  280. return "TESTING";
  281. case IF_OPER_DORMANT:
  282. return "DORMANT";
  283. case IF_OPER_UP:
  284. return "UP";
  285. }
  286. return "";
  287. }
  288. static bool extract_link(struct ifinfomsg *msg, int bytes,
  289. struct ether_addr *address, const char **ifname,
  290. unsigned int *mtu, unsigned char *operstate,
  291. struct rtnl_link_stats64 *stats)
  292. {
  293. struct rtattr *attr;
  294. for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
  295. attr = RTA_NEXT(attr, bytes)) {
  296. switch (attr->rta_type) {
  297. case IFLA_ADDRESS:
  298. if (address)
  299. memcpy(address, RTA_DATA(attr), ETH_ALEN);
  300. break;
  301. case IFLA_IFNAME:
  302. if (ifname)
  303. *ifname = RTA_DATA(attr);
  304. break;
  305. case IFLA_MTU:
  306. if (mtu)
  307. *mtu = *((unsigned int *) RTA_DATA(attr));
  308. break;
  309. case IFLA_STATS64:
  310. if (stats)
  311. memcpy(stats, RTA_DATA(attr),
  312. sizeof(struct rtnl_link_stats64));
  313. break;
  314. case IFLA_OPERSTATE:
  315. if (operstate)
  316. *operstate = *((unsigned char *) RTA_DATA(attr));
  317. break;
  318. case IFLA_LINKMODE:
  319. break;
  320. case IFLA_WIRELESS:
  321. return false;
  322. }
  323. }
  324. return true;
  325. }
  326. static void process_newlink(unsigned short type, int index, unsigned flags,
  327. unsigned change, struct ifinfomsg *msg, int bytes)
  328. {
  329. struct ether_addr address = {{ 0, 0, 0, 0, 0, 0 }};
  330. struct rtnl_link_stats64 stats;
  331. unsigned char operstate = 0xff;
  332. struct interface_data *interface;
  333. const char *ifname = NULL;
  334. unsigned int mtu = 0;
  335. char ident[13], str[18];
  336. GSList *list;
  337. memset(&stats, 0, sizeof(stats));
  338. if (!extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, &stats))
  339. return;
  340. snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x",
  341. address.ether_addr_octet[0],
  342. address.ether_addr_octet[1],
  343. address.ether_addr_octet[2],
  344. address.ether_addr_octet[3],
  345. address.ether_addr_octet[4],
  346. address.ether_addr_octet[5]);
  347. snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
  348. address.ether_addr_octet[0],
  349. address.ether_addr_octet[1],
  350. address.ether_addr_octet[2],
  351. address.ether_addr_octet[3],
  352. address.ether_addr_octet[4],
  353. address.ether_addr_octet[5]);
  354. if (flags & IFF_SLAVE) {
  355. DBG("%s {newlink} ignoring slave, index %d address %s",
  356. ifname, index, str);
  357. return;
  358. }
  359. switch (type) {
  360. case ARPHRD_ETHER:
  361. case ARPHRD_LOOPBACK:
  362. case ARPHDR_PHONET_PIPE:
  363. case ARPHRD_PPP:
  364. case ARPHRD_RAWIP:
  365. case ARPHRD_NONE:
  366. __connman_ipconfig_newlink(index, type, flags,
  367. str, mtu, &stats);
  368. break;
  369. }
  370. DBG("%s {newlink} index %d address %s mtu %u",
  371. ifname, index, str, mtu);
  372. if (operstate != 0xff)
  373. DBG("%s {newlink} index %d operstate %u <%s>",
  374. ifname, index, operstate,
  375. operstate2str(operstate));
  376. interface = g_hash_table_lookup(interface_list, GINT_TO_POINTER(index));
  377. if (!interface) {
  378. interface = g_new0(struct interface_data, 1);
  379. interface->index = index;
  380. interface->ident = g_strdup(ident);
  381. g_hash_table_insert(interface_list,
  382. GINT_TO_POINTER(index), interface);
  383. if (type == ARPHRD_ETHER)
  384. read_uevent(interface);
  385. } else
  386. interface = NULL;
  387. for (list = rtnl_list; list; list = list->next) {
  388. struct connman_rtnl *rtnl = list->data;
  389. if (rtnl->newlink)
  390. rtnl->newlink(type, index, flags, change);
  391. }
  392. /*
  393. * The interface needs to be added after the newlink call.
  394. * The newlink will create the technology when needed and
  395. * __connman_technology_add_interface() expects the
  396. * technology to be there already.
  397. */
  398. if (interface)
  399. __connman_technology_add_interface(interface->service_type,
  400. interface->index, interface->ident);
  401. for (list = watch_list; list; list = list->next) {
  402. struct watch_data *watch = list->data;
  403. if (watch->index != index)
  404. continue;
  405. if (watch->newlink)
  406. watch->newlink(flags, change, watch->user_data);
  407. }
  408. }
  409. static void process_dellink(unsigned short type, int index, unsigned flags,
  410. unsigned change, struct ifinfomsg *msg, int bytes)
  411. {
  412. struct rtnl_link_stats64 stats;
  413. unsigned char operstate = 0xff;
  414. const char *ifname = NULL;
  415. GSList *list;
  416. memset(&stats, 0, sizeof(stats));
  417. if (!extract_link(msg, bytes, NULL, &ifname, NULL, &operstate, &stats))
  418. return;
  419. if (operstate != 0xff)
  420. DBG("%s {dellink} index %d operstate %u <%s>",
  421. ifname, index, operstate,
  422. operstate2str(operstate));
  423. for (list = rtnl_list; list; list = list->next) {
  424. struct connman_rtnl *rtnl = list->data;
  425. if (rtnl->dellink)
  426. rtnl->dellink(type, index, flags, change);
  427. }
  428. switch (type) {
  429. case ARPHRD_ETHER:
  430. case ARPHRD_LOOPBACK:
  431. case ARPHDR_PHONET_PIPE:
  432. case ARPHRD_PPP:
  433. case ARPHRD_NONE:
  434. __connman_ipconfig_dellink(index, &stats);
  435. break;
  436. }
  437. g_hash_table_remove(interface_list, GINT_TO_POINTER(index));
  438. }
  439. static void extract_ipv4_addr(struct ifaddrmsg *msg, int bytes,
  440. const char **label,
  441. struct in_addr *local,
  442. struct in_addr *address,
  443. struct in_addr *broadcast)
  444. {
  445. struct rtattr *attr;
  446. for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
  447. attr = RTA_NEXT(attr, bytes)) {
  448. switch (attr->rta_type) {
  449. case IFA_ADDRESS:
  450. if (address)
  451. *address = *((struct in_addr *) RTA_DATA(attr));
  452. break;
  453. case IFA_LOCAL:
  454. if (local)
  455. *local = *((struct in_addr *) RTA_DATA(attr));
  456. break;
  457. case IFA_BROADCAST:
  458. if (broadcast)
  459. *broadcast = *((struct in_addr *) RTA_DATA(attr));
  460. break;
  461. case IFA_LABEL:
  462. if (label)
  463. *label = RTA_DATA(attr);
  464. break;
  465. }
  466. }
  467. }
  468. static void extract_ipv6_addr(struct ifaddrmsg *msg, int bytes,
  469. struct in6_addr *addr,
  470. struct in6_addr *local)
  471. {
  472. struct rtattr *attr;
  473. for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
  474. attr = RTA_NEXT(attr, bytes)) {
  475. switch (attr->rta_type) {
  476. case IFA_ADDRESS:
  477. if (addr)
  478. *addr = *((struct in6_addr *) RTA_DATA(attr));
  479. break;
  480. case IFA_LOCAL:
  481. if (local)
  482. *local = *((struct in6_addr *) RTA_DATA(attr));
  483. break;
  484. }
  485. }
  486. }
  487. static void process_newaddr(unsigned char family, unsigned char prefixlen,
  488. int index, struct ifaddrmsg *msg, int bytes)
  489. {
  490. struct in_addr ipv4_addr = { INADDR_ANY };
  491. struct in6_addr ipv6_address, ipv6_local;
  492. const char *label = NULL;
  493. void *src;
  494. char ip_string[INET6_ADDRSTRLEN];
  495. if (family == AF_INET) {
  496. extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL);
  497. src = &ipv4_addr;
  498. } else if (family == AF_INET6) {
  499. extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local);
  500. if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address))
  501. return;
  502. src = &ipv6_address;
  503. } else {
  504. return;
  505. }
  506. if (!inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN))
  507. return;
  508. __connman_ipconfig_newaddr(index, family, label,
  509. prefixlen, ip_string);
  510. if (family == AF_INET6) {
  511. /*
  512. * Re-create RDNSS configured servers if there are any
  513. * for this interface. This is done because we might
  514. * have now properly configured interface with proper
  515. * autoconfigured address.
  516. */
  517. __connman_resolver_redo_servers(index);
  518. }
  519. }
  520. static void process_deladdr(unsigned char family, unsigned char prefixlen,
  521. int index, struct ifaddrmsg *msg, int bytes)
  522. {
  523. struct in_addr ipv4_addr = { INADDR_ANY };
  524. struct in6_addr ipv6_address, ipv6_local;
  525. const char *label = NULL;
  526. void *src;
  527. char ip_string[INET6_ADDRSTRLEN];
  528. if (family == AF_INET) {
  529. extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL);
  530. src = &ipv4_addr;
  531. } else if (family == AF_INET6) {
  532. extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local);
  533. if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address))
  534. return;
  535. src = &ipv6_address;
  536. } else {
  537. return;
  538. }
  539. if (!inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN))
  540. return;
  541. __connman_ipconfig_deladdr(index, family, label,
  542. prefixlen, ip_string);
  543. }
  544. static void extract_ipv4_route(struct rtmsg *msg, int bytes, int *index,
  545. struct in_addr *dst,
  546. struct in_addr *gateway)
  547. {
  548. struct rtattr *attr;
  549. for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
  550. attr = RTA_NEXT(attr, bytes)) {
  551. switch (attr->rta_type) {
  552. case RTA_DST:
  553. if (dst)
  554. *dst = *((struct in_addr *) RTA_DATA(attr));
  555. break;
  556. case RTA_GATEWAY:
  557. if (gateway)
  558. *gateway = *((struct in_addr *) RTA_DATA(attr));
  559. break;
  560. case RTA_OIF:
  561. if (index)
  562. *index = *((int *) RTA_DATA(attr));
  563. break;
  564. }
  565. }
  566. }
  567. static void extract_ipv6_route(struct rtmsg *msg, int bytes, int *index,
  568. struct in6_addr *dst,
  569. struct in6_addr *gateway)
  570. {
  571. struct rtattr *attr;
  572. for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
  573. attr = RTA_NEXT(attr, bytes)) {
  574. switch (attr->rta_type) {
  575. case RTA_DST:
  576. if (dst)
  577. *dst = *((struct in6_addr *) RTA_DATA(attr));
  578. break;
  579. case RTA_GATEWAY:
  580. if (gateway)
  581. *gateway =
  582. *((struct in6_addr *) RTA_DATA(attr));
  583. break;
  584. case RTA_OIF:
  585. if (index)
  586. *index = *((int *) RTA_DATA(attr));
  587. break;
  588. }
  589. }
  590. }
  591. static void process_newroute(unsigned char family, unsigned char scope,
  592. struct rtmsg *msg, int bytes)
  593. {
  594. GSList *list;
  595. char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
  596. int index = -1;
  597. if (family == AF_INET) {
  598. struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
  599. extract_ipv4_route(msg, bytes, &index, &dst, &gateway);
  600. inet_ntop(family, &dst, dststr, sizeof(dststr));
  601. inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
  602. __connman_ipconfig_newroute(index, family, scope, dststr,
  603. gatewaystr);
  604. /* skip host specific routes */
  605. if (scope != RT_SCOPE_UNIVERSE &&
  606. !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
  607. return;
  608. if (dst.s_addr != INADDR_ANY)
  609. return;
  610. } else if (family == AF_INET6) {
  611. struct in6_addr dst = IN6ADDR_ANY_INIT,
  612. gateway = IN6ADDR_ANY_INIT;
  613. extract_ipv6_route(msg, bytes, &index, &dst, &gateway);
  614. inet_ntop(family, &dst, dststr, sizeof(dststr));
  615. inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
  616. __connman_ipconfig_newroute(index, family, scope, dststr,
  617. gatewaystr);
  618. /* skip host specific routes */
  619. if (scope != RT_SCOPE_UNIVERSE &&
  620. !(scope == RT_SCOPE_LINK &&
  621. IN6_IS_ADDR_UNSPECIFIED(&dst)))
  622. return;
  623. if (!IN6_IS_ADDR_UNSPECIFIED(&dst))
  624. return;
  625. } else
  626. return;
  627. for (list = rtnl_list; list; list = list->next) {
  628. struct connman_rtnl *rtnl = list->data;
  629. if (rtnl->newgateway)
  630. rtnl->newgateway(index, gatewaystr);
  631. }
  632. }
  633. static void process_delroute(unsigned char family, unsigned char scope,
  634. struct rtmsg *msg, int bytes)
  635. {
  636. GSList *list;
  637. char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
  638. int index = -1;
  639. if (family == AF_INET) {
  640. struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
  641. extract_ipv4_route(msg, bytes, &index, &dst, &gateway);
  642. inet_ntop(family, &dst, dststr, sizeof(dststr));
  643. inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
  644. __connman_ipconfig_delroute(index, family, scope, dststr,
  645. gatewaystr);
  646. /* skip host specific routes */
  647. if (scope != RT_SCOPE_UNIVERSE &&
  648. !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
  649. return;
  650. if (dst.s_addr != INADDR_ANY)
  651. return;
  652. } else if (family == AF_INET6) {
  653. struct in6_addr dst = IN6ADDR_ANY_INIT,
  654. gateway = IN6ADDR_ANY_INIT;
  655. extract_ipv6_route(msg, bytes, &index, &dst, &gateway);
  656. inet_ntop(family, &dst, dststr, sizeof(dststr));
  657. inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
  658. __connman_ipconfig_delroute(index, family, scope, dststr,
  659. gatewaystr);
  660. /* skip host specific routes */
  661. if (scope != RT_SCOPE_UNIVERSE &&
  662. !(scope == RT_SCOPE_LINK &&
  663. IN6_IS_ADDR_UNSPECIFIED(&dst)))
  664. return;
  665. if (!IN6_IS_ADDR_UNSPECIFIED(&dst))
  666. return;
  667. } else
  668. return;
  669. for (list = rtnl_list; list; list = list->next) {
  670. struct connman_rtnl *rtnl = list->data;
  671. if (rtnl->delgateway)
  672. rtnl->delgateway(index, gatewaystr);
  673. }
  674. }
  675. static inline void print_ether(struct rtattr *attr, const char *name)
  676. {
  677. int len = (int) RTA_PAYLOAD(attr);
  678. if (len == ETH_ALEN) {
  679. struct ether_addr eth;
  680. memcpy(&eth, RTA_DATA(attr), ETH_ALEN);
  681. print(" attr %s (len %d) %s\n", name, len, ether_ntoa(&eth));
  682. } else
  683. print(" attr %s (len %d)\n", name, len);
  684. }
  685. static inline void print_inet(struct rtattr *attr, const char *name,
  686. unsigned char family)
  687. {
  688. int len = (int) RTA_PAYLOAD(attr);
  689. if (family == AF_INET && len == sizeof(struct in_addr)) {
  690. struct in_addr addr;
  691. addr = *((struct in_addr *) RTA_DATA(attr));
  692. print(" attr %s (len %d) %s\n", name, len, inet_ntoa(addr));
  693. } else
  694. print(" attr %s (len %d)\n", name, len);
  695. }
  696. static inline void print_string(struct rtattr *attr, const char *name)
  697. {
  698. print(" attr %s (len %d) %s\n", name, (int) RTA_PAYLOAD(attr),
  699. (char *) RTA_DATA(attr));
  700. }
  701. static inline void print_byte(struct rtattr *attr, const char *name)
  702. {
  703. print(" attr %s (len %d) 0x%02x\n", name, (int) RTA_PAYLOAD(attr),
  704. *((unsigned char *) RTA_DATA(attr)));
  705. }
  706. static inline void print_integer(struct rtattr *attr, const char *name)
  707. {
  708. print(" attr %s (len %d) %d\n", name, (int) RTA_PAYLOAD(attr),
  709. *((int *) RTA_DATA(attr)));
  710. }
  711. static inline void print_attr(struct rtattr *attr, const char *name)
  712. {
  713. int len = (int) RTA_PAYLOAD(attr);
  714. if (name && len > 0)
  715. print(" attr %s (len %d)\n", name, len);
  716. else
  717. print(" attr %d (len %d)\n", attr->rta_type, len);
  718. }
  719. static void rtnl_link(struct nlmsghdr *hdr)
  720. {
  721. struct ifinfomsg *msg;
  722. struct rtattr *attr;
  723. int bytes;
  724. msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
  725. bytes = IFLA_PAYLOAD(hdr);
  726. print("ifi_index %d ifi_flags 0x%04x", msg->ifi_index, msg->ifi_flags);
  727. for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
  728. attr = RTA_NEXT(attr, bytes)) {
  729. switch (attr->rta_type) {
  730. case IFLA_ADDRESS:
  731. print_ether(attr, "address");
  732. break;
  733. case IFLA_BROADCAST:
  734. print_ether(attr, "broadcast");
  735. break;
  736. case IFLA_IFNAME:
  737. print_string(attr, "ifname");
  738. break;
  739. case IFLA_MTU:
  740. print_integer(attr, "mtu");
  741. break;
  742. case IFLA_LINK:
  743. print_attr(attr, "link");
  744. break;
  745. case IFLA_QDISC:
  746. print_attr(attr, "qdisc");
  747. break;
  748. case IFLA_STATS64:
  749. print_attr(attr, "stats");
  750. break;
  751. case IFLA_COST:
  752. print_attr(attr, "cost");
  753. break;
  754. case IFLA_PRIORITY:
  755. print_attr(attr, "priority");
  756. break;
  757. case IFLA_MASTER:
  758. print_attr(attr, "master");
  759. break;
  760. case IFLA_WIRELESS:
  761. print_attr(attr, "wireless");
  762. break;
  763. case IFLA_PROTINFO:
  764. print_attr(attr, "protinfo");
  765. break;
  766. case IFLA_TXQLEN:
  767. print_integer(attr, "txqlen");
  768. break;
  769. case IFLA_MAP:
  770. print_attr(attr, "map");
  771. break;
  772. case IFLA_WEIGHT:
  773. print_attr(attr, "weight");
  774. break;
  775. case IFLA_OPERSTATE:
  776. print_byte(attr, "operstate");
  777. break;
  778. case IFLA_LINKMODE:
  779. print_byte(attr, "linkmode");
  780. break;
  781. default:
  782. print_attr(attr, NULL);
  783. break;
  784. }
  785. }
  786. }
  787. static void rtnl_newlink(struct nlmsghdr *hdr)
  788. {
  789. struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
  790. rtnl_link(hdr);
  791. if (hdr->nlmsg_type == IFLA_WIRELESS)
  792. connman_warn_once("Obsolete WEXT WiFi driver detected");
  793. process_newlink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
  794. msg->ifi_change, msg, IFA_PAYLOAD(hdr));
  795. }
  796. static void rtnl_dellink(struct nlmsghdr *hdr)
  797. {
  798. struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
  799. rtnl_link(hdr);
  800. process_dellink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
  801. msg->ifi_change, msg, IFA_PAYLOAD(hdr));
  802. }
  803. static void rtnl_addr(struct nlmsghdr *hdr)
  804. {
  805. struct ifaddrmsg *msg;
  806. struct rtattr *attr;
  807. int bytes;
  808. msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
  809. bytes = IFA_PAYLOAD(hdr);
  810. print("ifa_family %d ifa_index %d", msg->ifa_family, msg->ifa_index);
  811. for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
  812. attr = RTA_NEXT(attr, bytes)) {
  813. switch (attr->rta_type) {
  814. case IFA_ADDRESS:
  815. print_inet(attr, "address", msg->ifa_family);
  816. break;
  817. case IFA_LOCAL:
  818. print_inet(attr, "local", msg->ifa_family);
  819. break;
  820. case IFA_LABEL:
  821. print_string(attr, "label");
  822. break;
  823. case IFA_BROADCAST:
  824. print_inet(attr, "broadcast", msg->ifa_family);
  825. break;
  826. case IFA_ANYCAST:
  827. print_attr(attr, "anycast");
  828. break;
  829. case IFA_CACHEINFO:
  830. print_attr(attr, "cacheinfo");
  831. break;
  832. case IFA_MULTICAST:
  833. print_attr(attr, "multicast");
  834. break;
  835. default:
  836. print_attr(attr, NULL);
  837. break;
  838. }
  839. }
  840. }
  841. static void rtnl_newaddr(struct nlmsghdr *hdr)
  842. {
  843. struct ifaddrmsg *msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
  844. rtnl_addr(hdr);
  845. process_newaddr(msg->ifa_family, msg->ifa_prefixlen, msg->ifa_index,
  846. msg, IFA_PAYLOAD(hdr));
  847. }
  848. static void rtnl_deladdr(struct nlmsghdr *hdr)
  849. {
  850. struct ifaddrmsg *msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
  851. rtnl_addr(hdr);
  852. process_deladdr(msg->ifa_family, msg->ifa_prefixlen, msg->ifa_index,
  853. msg, IFA_PAYLOAD(hdr));
  854. }
  855. static void rtnl_route(struct nlmsghdr *hdr)
  856. {
  857. struct rtmsg *msg;
  858. struct rtattr *attr;
  859. int bytes;
  860. msg = (struct rtmsg *) NLMSG_DATA(hdr);
  861. bytes = RTM_PAYLOAD(hdr);
  862. print("rtm_family %d rtm_table %d rtm_protocol %d",
  863. msg->rtm_family, msg->rtm_table, msg->rtm_protocol);
  864. print("rtm_scope %d rtm_type %d rtm_flags 0x%04x",
  865. msg->rtm_scope, msg->rtm_type, msg->rtm_flags);
  866. for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
  867. attr = RTA_NEXT(attr, bytes)) {
  868. switch (attr->rta_type) {
  869. case RTA_DST:
  870. print_inet(attr, "dst", msg->rtm_family);
  871. break;
  872. case RTA_SRC:
  873. print_inet(attr, "src", msg->rtm_family);
  874. break;
  875. case RTA_IIF:
  876. print_string(attr, "iif");
  877. break;
  878. case RTA_OIF:
  879. print_integer(attr, "oif");
  880. break;
  881. case RTA_GATEWAY:
  882. print_inet(attr, "gateway", msg->rtm_family);
  883. break;
  884. case RTA_PRIORITY:
  885. print_attr(attr, "priority");
  886. break;
  887. case RTA_PREFSRC:
  888. print_inet(attr, "prefsrc", msg->rtm_family);
  889. break;
  890. case RTA_METRICS:
  891. print_attr(attr, "metrics");
  892. break;
  893. case RTA_TABLE:
  894. print_integer(attr, "table");
  895. break;
  896. default:
  897. print_attr(attr, NULL);
  898. break;
  899. }
  900. }
  901. }
  902. static bool is_route_rtmsg(struct rtmsg *msg)
  903. {
  904. if (msg->rtm_table != RT_TABLE_MAIN)
  905. return false;
  906. if (msg->rtm_protocol != RTPROT_BOOT &&
  907. msg->rtm_protocol != RTPROT_KERNEL)
  908. return false;
  909. if (msg->rtm_type != RTN_UNICAST)
  910. return false;
  911. return true;
  912. }
  913. static void rtnl_newroute(struct nlmsghdr *hdr)
  914. {
  915. struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
  916. rtnl_route(hdr);
  917. if (is_route_rtmsg(msg))
  918. process_newroute(msg->rtm_family, msg->rtm_scope,
  919. msg, RTM_PAYLOAD(hdr));
  920. }
  921. static void rtnl_delroute(struct nlmsghdr *hdr)
  922. {
  923. struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
  924. rtnl_route(hdr);
  925. if (is_route_rtmsg(msg))
  926. process_delroute(msg->rtm_family, msg->rtm_scope,
  927. msg, RTM_PAYLOAD(hdr));
  928. }
  929. static void *rtnl_nd_opt_rdnss(struct nd_opt_hdr *opt, guint32 *lifetime,
  930. int *nr_servers)
  931. {
  932. guint32 *optint = (void *)opt;
  933. if (opt->nd_opt_len < 3)
  934. return NULL;
  935. if (*lifetime > ntohl(optint[1]))
  936. *lifetime = ntohl(optint[1]);
  937. /* nd_opt_len is in units of 8 bytes. The header is 1 unit (8 bytes)
  938. and each address is another 2 units (16 bytes).
  939. So the number of addresses (given rounding) is nd_opt_len/2 */
  940. *nr_servers = opt->nd_opt_len / 2;
  941. /* And they start 8 bytes into the packet, or two guint32s in. */
  942. return optint + 2;
  943. }
  944. static const char **rtnl_nd_opt_dnssl(struct nd_opt_hdr *opt, guint32 *lifetime)
  945. {
  946. const char **domains = NULL;
  947. guint32 *optint = (void *)opt;
  948. unsigned char *optc = (void *)&optint[2];
  949. int data_len = (opt->nd_opt_len * 8) - 8;
  950. int nr_domains = 0;
  951. int i, tmp;
  952. if (*lifetime > ntohl(optint[1]))
  953. *lifetime = ntohl(optint[1]);
  954. /* Turn it into normal strings by converting the length bytes into '.',
  955. and count how many search domains there are while we're at it. */
  956. i = 0;
  957. while (i < data_len) {
  958. if (optc[i] > 0x3f) {
  959. DBG("DNSSL contains compressed elements in violation of RFC6106");
  960. return NULL;
  961. }
  962. if (optc[i] == 0) {
  963. nr_domains++;
  964. i++;
  965. /* Check for double zero */
  966. if (i < data_len && optc[i] == 0)
  967. break;
  968. continue;
  969. }
  970. tmp = i;
  971. i += optc[i] + 1;
  972. if (i >= data_len) {
  973. DBG("DNSSL data overflows option length");
  974. return NULL;
  975. }
  976. optc[tmp] = '.';
  977. }
  978. domains = g_try_new0(const char *, nr_domains + 1);
  979. if (!domains)
  980. return NULL;
  981. /* Now point to the normal strings, missing out the leading '.' that
  982. each of them will have now. */
  983. for (i = 0; i < nr_domains; i++) {
  984. domains[i] = (char *)optc + 1;
  985. optc += strlen((char *)optc) + 1;
  986. }
  987. return domains;
  988. }
  989. static void rtnl_newnduseropt(struct nlmsghdr *hdr)
  990. {
  991. struct nduseroptmsg *msg = (struct nduseroptmsg *) NLMSG_DATA(hdr);
  992. struct nd_opt_hdr *opt;
  993. guint32 lifetime = -1;
  994. const char **domains = NULL;
  995. struct in6_addr *servers = NULL;
  996. int i, nr_servers = 0;
  997. int msglen = msg->nduseropt_opts_len;
  998. int index;
  999. DBG("family %d index %d len %d type %d code %d",
  1000. msg->nduseropt_family, msg->nduseropt_ifindex,
  1001. msg->nduseropt_opts_len, msg->nduseropt_icmp_type,
  1002. msg->nduseropt_icmp_code);
  1003. if (msg->nduseropt_family != AF_INET6 ||
  1004. msg->nduseropt_icmp_type != ND_ROUTER_ADVERT ||
  1005. msg->nduseropt_icmp_code != 0)
  1006. return;
  1007. index = msg->nduseropt_ifindex;
  1008. if (index < 0)
  1009. return;
  1010. for (opt = (void *)&msg[1];
  1011. msglen > 0;
  1012. msglen -= opt->nd_opt_len * 8,
  1013. opt = ((void *)opt) + opt->nd_opt_len*8) {
  1014. DBG("remaining %d nd opt type %d len %d\n",
  1015. msglen, opt->nd_opt_type, opt->nd_opt_len);
  1016. if (opt->nd_opt_type == 25) { /* ND_OPT_RDNSS */
  1017. char buf[40];
  1018. servers = rtnl_nd_opt_rdnss(opt, &lifetime,
  1019. &nr_servers);
  1020. for (i = 0; i < nr_servers; i++) {
  1021. if (!inet_ntop(AF_INET6, servers + i, buf,
  1022. sizeof(buf)))
  1023. continue;
  1024. connman_resolver_append_lifetime(index,
  1025. NULL, buf, lifetime);
  1026. }
  1027. } else if (opt->nd_opt_type == 31) { /* ND_OPT_DNSSL */
  1028. g_free(domains);
  1029. domains = rtnl_nd_opt_dnssl(opt, &lifetime);
  1030. for (i = 0; domains && domains[i]; i++)
  1031. connman_resolver_append_lifetime(index,
  1032. domains[i], NULL, lifetime);
  1033. }
  1034. }
  1035. g_free(domains);
  1036. }
  1037. static const char *type2string(uint16_t type)
  1038. {
  1039. switch (type) {
  1040. case NLMSG_NOOP:
  1041. return "NOOP";
  1042. case NLMSG_ERROR:
  1043. return "ERROR";
  1044. case NLMSG_DONE:
  1045. return "DONE";
  1046. case NLMSG_OVERRUN:
  1047. return "OVERRUN";
  1048. case RTM_GETLINK:
  1049. return "GETLINK";
  1050. case RTM_NEWLINK:
  1051. return "NEWLINK";
  1052. case RTM_DELLINK:
  1053. return "DELLINK";
  1054. case RTM_GETADDR:
  1055. return "GETADDR";
  1056. case RTM_NEWADDR:
  1057. return "NEWADDR";
  1058. case RTM_DELADDR:
  1059. return "DELADDR";
  1060. case RTM_GETROUTE:
  1061. return "GETROUTE";
  1062. case RTM_NEWROUTE:
  1063. return "NEWROUTE";
  1064. case RTM_DELROUTE:
  1065. return "DELROUTE";
  1066. case RTM_NEWNDUSEROPT:
  1067. return "NEWNDUSEROPT";
  1068. default:
  1069. return "UNKNOWN";
  1070. }
  1071. }
  1072. static GIOChannel *channel = NULL;
  1073. struct rtnl_request {
  1074. struct nlmsghdr hdr;
  1075. struct rtgenmsg msg;
  1076. };
  1077. #define RTNL_REQUEST_SIZE (sizeof(struct nlmsghdr) + sizeof(struct rtgenmsg))
  1078. static GSList *request_list = NULL;
  1079. static guint32 request_seq = 0;
  1080. static struct rtnl_request *find_request(guint32 seq)
  1081. {
  1082. GSList *list;
  1083. for (list = request_list; list; list = list->next) {
  1084. struct rtnl_request *req = list->data;
  1085. if (req->hdr.nlmsg_seq == seq)
  1086. return req;
  1087. }
  1088. return NULL;
  1089. }
  1090. static int send_request(struct rtnl_request *req)
  1091. {
  1092. struct sockaddr_nl addr;
  1093. int sk;
  1094. DBG("%s len %d type %d flags 0x%04x seq %d",
  1095. type2string(req->hdr.nlmsg_type),
  1096. req->hdr.nlmsg_len, req->hdr.nlmsg_type,
  1097. req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
  1098. sk = g_io_channel_unix_get_fd(channel);
  1099. memset(&addr, 0, sizeof(addr));
  1100. addr.nl_family = AF_NETLINK;
  1101. return sendto(sk, req, req->hdr.nlmsg_len, 0,
  1102. (struct sockaddr *) &addr, sizeof(addr));
  1103. }
  1104. static int queue_request(struct rtnl_request *req)
  1105. {
  1106. request_list = g_slist_append(request_list, req);
  1107. if (g_slist_length(request_list) > 1)
  1108. return 0;
  1109. return send_request(req);
  1110. }
  1111. static int process_response(guint32 seq)
  1112. {
  1113. struct rtnl_request *req;
  1114. DBG("seq %d", seq);
  1115. req = find_request(seq);
  1116. if (req) {
  1117. request_list = g_slist_remove(request_list, req);
  1118. g_free(req);
  1119. }
  1120. req = g_slist_nth_data(request_list, 0);
  1121. if (!req)
  1122. return 0;
  1123. return send_request(req);
  1124. }
  1125. static void rtnl_message(void *buf, size_t len)
  1126. {
  1127. DBG("buf %p len %zd", buf, len);
  1128. while (len > 0) {
  1129. struct nlmsghdr *hdr = buf;
  1130. struct nlmsgerr *err;
  1131. if (!NLMSG_OK(hdr, len))
  1132. break;
  1133. DBG("%s len %d type %d flags 0x%04x seq %d pid %d",
  1134. type2string(hdr->nlmsg_type),
  1135. hdr->nlmsg_len, hdr->nlmsg_type,
  1136. hdr->nlmsg_flags, hdr->nlmsg_seq,
  1137. hdr->nlmsg_pid);
  1138. switch (hdr->nlmsg_type) {
  1139. case NLMSG_NOOP:
  1140. case NLMSG_OVERRUN:
  1141. return;
  1142. case NLMSG_DONE:
  1143. process_response(hdr->nlmsg_seq);
  1144. return;
  1145. case NLMSG_ERROR:
  1146. err = NLMSG_DATA(hdr);
  1147. DBG("error %d (%s)", -err->error,
  1148. strerror(-err->error));
  1149. return;
  1150. case RTM_NEWLINK:
  1151. rtnl_newlink(hdr);
  1152. break;
  1153. case RTM_DELLINK:
  1154. rtnl_dellink(hdr);
  1155. break;
  1156. case RTM_NEWADDR:
  1157. rtnl_newaddr(hdr);
  1158. break;
  1159. case RTM_DELADDR:
  1160. rtnl_deladdr(hdr);
  1161. break;
  1162. case RTM_NEWROUTE:
  1163. rtnl_newroute(hdr);
  1164. break;
  1165. case RTM_DELROUTE:
  1166. rtnl_delroute(hdr);
  1167. break;
  1168. case RTM_NEWNDUSEROPT:
  1169. rtnl_newnduseropt(hdr);
  1170. break;
  1171. }
  1172. len -= hdr->nlmsg_len;
  1173. buf += hdr->nlmsg_len;
  1174. }
  1175. }
  1176. static gboolean netlink_event(GIOChannel *chan, GIOCondition cond, gpointer data)
  1177. {
  1178. unsigned char buf[4096];
  1179. struct sockaddr_nl nladdr;
  1180. socklen_t addr_len = sizeof(nladdr);
  1181. ssize_t status;
  1182. int fd;
  1183. if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
  1184. return FALSE;
  1185. memset(buf, 0, sizeof(buf));
  1186. memset(&nladdr, 0, sizeof(nladdr));
  1187. fd = g_io_channel_unix_get_fd(chan);
  1188. status = recvfrom(fd, buf, sizeof(buf), 0,
  1189. (struct sockaddr *) &nladdr, &addr_len);
  1190. if (status < 0) {
  1191. if (errno == EINTR || errno == EAGAIN)
  1192. return TRUE;
  1193. return FALSE;
  1194. }
  1195. if (status == 0)
  1196. return FALSE;
  1197. if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
  1198. DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
  1199. return TRUE;
  1200. }
  1201. rtnl_message(buf, status);
  1202. return TRUE;
  1203. }
  1204. static int send_getlink(void)
  1205. {
  1206. struct rtnl_request *req;
  1207. DBG("");
  1208. req = g_try_malloc0(RTNL_REQUEST_SIZE);
  1209. if (!req)
  1210. return -ENOMEM;
  1211. req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
  1212. req->hdr.nlmsg_type = RTM_GETLINK;
  1213. req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
  1214. req->hdr.nlmsg_pid = 0;
  1215. req->hdr.nlmsg_seq = request_seq++;
  1216. req->msg.rtgen_family = AF_INET;
  1217. return queue_request(req);
  1218. }
  1219. static int send_getaddr(void)
  1220. {
  1221. struct rtnl_request *req;
  1222. DBG("");
  1223. req = g_try_malloc0(RTNL_REQUEST_SIZE);
  1224. if (!req)
  1225. return -ENOMEM;
  1226. req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
  1227. req->hdr.nlmsg_type = RTM_GETADDR;
  1228. req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
  1229. req->hdr.nlmsg_pid = 0;
  1230. req->hdr.nlmsg_seq = request_seq++;
  1231. req->msg.rtgen_family = AF_INET;
  1232. return queue_request(req);
  1233. }
  1234. static int send_getroute(void)
  1235. {
  1236. struct rtnl_request *req;
  1237. DBG("");
  1238. req = g_try_malloc0(RTNL_REQUEST_SIZE);
  1239. if (!req)
  1240. return -ENOMEM;
  1241. req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
  1242. req->hdr.nlmsg_type = RTM_GETROUTE;
  1243. req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
  1244. req->hdr.nlmsg_pid = 0;
  1245. req->hdr.nlmsg_seq = request_seq++;
  1246. req->msg.rtgen_family = AF_INET;
  1247. return queue_request(req);
  1248. }
  1249. static gboolean update_timeout_cb(gpointer user_data)
  1250. {
  1251. __connman_rtnl_request_update();
  1252. return TRUE;
  1253. }
  1254. static void update_interval_callback(guint min)
  1255. {
  1256. if (update_timeout > 0)
  1257. g_source_remove(update_timeout);
  1258. if (min < G_MAXUINT) {
  1259. update_interval = min;
  1260. update_timeout = g_timeout_add_seconds(update_interval,
  1261. update_timeout_cb, NULL);
  1262. } else {
  1263. update_timeout = 0;
  1264. update_interval = G_MAXUINT;
  1265. }
  1266. }
  1267. static gint compare_interval(gconstpointer a, gconstpointer b)
  1268. {
  1269. guint val_a = GPOINTER_TO_UINT(a);
  1270. guint val_b = GPOINTER_TO_UINT(b);
  1271. return val_a - val_b;
  1272. }
  1273. unsigned int __connman_rtnl_update_interval_add(unsigned int interval)
  1274. {
  1275. guint min;
  1276. if (interval == 0)
  1277. return 0;
  1278. update_list = g_slist_insert_sorted(update_list,
  1279. GUINT_TO_POINTER(interval), compare_interval);
  1280. min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
  1281. if (min < update_interval) {
  1282. update_interval_callback(min);
  1283. __connman_rtnl_request_update();
  1284. }
  1285. return update_interval;
  1286. }
  1287. unsigned int __connman_rtnl_update_interval_remove(unsigned int interval)
  1288. {
  1289. guint min = G_MAXUINT;
  1290. if (interval == 0)
  1291. return 0;
  1292. update_list = g_slist_remove(update_list, GINT_TO_POINTER(interval));
  1293. if (update_list)
  1294. min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
  1295. if (min > update_interval)
  1296. update_interval_callback(min);
  1297. return min;
  1298. }
  1299. int __connman_rtnl_request_update(void)
  1300. {
  1301. return send_getlink();
  1302. }
  1303. int __connman_rtnl_init(void)
  1304. {
  1305. struct sockaddr_nl addr;
  1306. int sk;
  1307. DBG("");
  1308. interface_list = g_hash_table_new_full(g_direct_hash, g_direct_equal,
  1309. NULL, free_interface);
  1310. sk = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
  1311. if (sk < 0)
  1312. return -1;
  1313. memset(&addr, 0, sizeof(addr));
  1314. addr.nl_family = AF_NETLINK;
  1315. addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE |
  1316. RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE |
  1317. (1<<(RTNLGRP_ND_USEROPT-1));
  1318. if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  1319. close(sk);
  1320. return -1;
  1321. }
  1322. channel = g_io_channel_unix_new(sk);
  1323. g_io_channel_set_close_on_unref(channel, TRUE);
  1324. g_io_channel_set_encoding(channel, NULL, NULL);
  1325. g_io_channel_set_buffered(channel, FALSE);
  1326. g_io_add_watch(channel, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
  1327. netlink_event, NULL);
  1328. return 0;
  1329. }
  1330. void __connman_rtnl_start(void)
  1331. {
  1332. DBG("");
  1333. send_getlink();
  1334. send_getaddr();
  1335. send_getroute();
  1336. }
  1337. void __connman_rtnl_cleanup(void)
  1338. {
  1339. GSList *list;
  1340. DBG("");
  1341. for (list = watch_list; list; list = list->next) {
  1342. struct watch_data *watch = list->data;
  1343. DBG("removing watch %d", watch->id);
  1344. g_free(watch);
  1345. list->data = NULL;
  1346. }
  1347. g_slist_free(watch_list);
  1348. watch_list = NULL;
  1349. g_slist_free(update_list);
  1350. update_list = NULL;
  1351. for (list = request_list; list; list = list->next) {
  1352. struct rtnl_request *req = list->data;
  1353. DBG("%s len %d type %d flags 0x%04x seq %d",
  1354. type2string(req->hdr.nlmsg_type),
  1355. req->hdr.nlmsg_len, req->hdr.nlmsg_type,
  1356. req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
  1357. g_free(req);
  1358. list->data = NULL;
  1359. }
  1360. g_slist_free(request_list);
  1361. request_list = NULL;
  1362. g_io_channel_shutdown(channel, TRUE, NULL);
  1363. g_io_channel_unref(channel);
  1364. channel = NULL;
  1365. g_hash_table_destroy(interface_list);
  1366. }