5 * Copyright (C) 2007-2014 Intel Corporation. All rights reserved.
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.
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.
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
31 #include <sys/ioctl.h>
32 #include <net/ethernet.h>
37 static GSList *device_list = NULL;
38 static gchar **device_filter = NULL;
39 static gchar **nodevice_filter = NULL;
41 enum connman_pending_type {
47 struct connman_device {
49 enum connman_device_type type;
50 enum connman_pending_type powered_pending; /* Indicates a pending
55 bool scanning[MAX_CONNMAN_SERVICE_TYPES];
63 guint pending_timeout;
65 struct connman_device_driver *driver;
69 struct connman_network *network;
73 static void clear_pending_trigger(struct connman_device *device)
75 if (device->pending_timeout > 0) {
76 g_source_remove(device->pending_timeout);
77 device->pending_timeout = 0;
81 static const char *type2description(enum connman_device_type type)
84 case CONNMAN_DEVICE_TYPE_UNKNOWN:
85 case CONNMAN_DEVICE_TYPE_VENDOR:
87 case CONNMAN_DEVICE_TYPE_ETHERNET:
89 case CONNMAN_DEVICE_TYPE_WIFI:
91 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
93 case CONNMAN_DEVICE_TYPE_GPS:
95 case CONNMAN_DEVICE_TYPE_CELLULAR:
97 case CONNMAN_DEVICE_TYPE_GADGET:
105 static const char *type2string(enum connman_device_type type)
108 case CONNMAN_DEVICE_TYPE_UNKNOWN:
109 case CONNMAN_DEVICE_TYPE_VENDOR:
111 case CONNMAN_DEVICE_TYPE_ETHERNET:
113 case CONNMAN_DEVICE_TYPE_WIFI:
115 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
117 case CONNMAN_DEVICE_TYPE_GPS:
119 case CONNMAN_DEVICE_TYPE_CELLULAR:
121 case CONNMAN_DEVICE_TYPE_GADGET:
129 enum connman_service_type __connman_device_get_service_type(
130 struct connman_device *device)
132 enum connman_device_type type = connman_device_get_type(device);
135 case CONNMAN_DEVICE_TYPE_UNKNOWN:
136 case CONNMAN_DEVICE_TYPE_VENDOR:
137 case CONNMAN_DEVICE_TYPE_GPS:
139 case CONNMAN_DEVICE_TYPE_ETHERNET:
140 return CONNMAN_SERVICE_TYPE_ETHERNET;
141 case CONNMAN_DEVICE_TYPE_WIFI:
142 return CONNMAN_SERVICE_TYPE_WIFI;
143 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
144 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
145 case CONNMAN_DEVICE_TYPE_CELLULAR:
146 return CONNMAN_SERVICE_TYPE_CELLULAR;
147 case CONNMAN_DEVICE_TYPE_GADGET:
148 return CONNMAN_SERVICE_TYPE_GADGET;
152 return CONNMAN_SERVICE_TYPE_UNKNOWN;
155 static bool device_has_service_type(struct connman_device *device,
156 enum connman_service_type service_type)
158 enum connman_service_type device_service_type =
159 __connman_device_get_service_type(device);
162 * For devices whose device_service_type is unknown we should
163 * allow to decide whether they support specific service_type
166 if (device_service_type == CONNMAN_SERVICE_TYPE_UNKNOWN)
169 if (device_service_type == CONNMAN_SERVICE_TYPE_WIFI) {
170 return service_type == CONNMAN_SERVICE_TYPE_WIFI ||
171 service_type == CONNMAN_SERVICE_TYPE_P2P;
174 return service_type == device_service_type;
177 static gboolean device_pending_reset(gpointer user_data)
179 struct connman_device *device = user_data;
181 DBG("device %p", device);
183 /* Power request timedout, reset power pending state. */
184 device->pending_timeout = 0;
185 device->powered_pending = PENDING_NONE;
190 int __connman_device_enable(struct connman_device *device)
194 DBG("device %p", device);
196 if (!device->driver || !device->driver->enable)
199 /* There is an ongoing power disable request. */
200 if (device->powered_pending == PENDING_DISABLE)
203 if (device->powered_pending == PENDING_ENABLE)
206 if (device->powered_pending == PENDING_NONE && device->powered)
209 if (device->index > 0) {
210 err = connman_inet_ifup(device->index);
211 if (err < 0 && err != -EALREADY)
215 device->powered_pending = PENDING_ENABLE;
217 err = device->driver->enable(device);
219 * device gets enabled right away.
220 * Invoke the callback
223 connman_device_set_powered(device, true);
227 if (err == -EALREADY) {
228 /* If device is already powered, but connman is not updated */
229 connman_device_set_powered(device, true);
233 * if err == -EINPROGRESS, then the DBus call to the respective daemon
234 * was successful. We set a 4 sec timeout so if the daemon never
235 * returns a reply, we would reset the pending request.
237 if (err == -EINPROGRESS)
238 device->pending_timeout = g_timeout_add_seconds(4,
239 device_pending_reset, device);
244 int __connman_device_disable(struct connman_device *device)
248 DBG("device %p", device);
250 /* Ongoing power enable request */
251 if (device->powered_pending == PENDING_ENABLE)
254 if (device->powered_pending == PENDING_DISABLE)
257 if (device->powered_pending == PENDING_NONE && !device->powered)
260 device->powered_pending = PENDING_DISABLE;
262 if (device->network) {
263 struct connman_service *service =
264 connman_service_lookup_from_network(device->network);
267 __connman_service_disconnect(service);
269 connman_network_set_connected(device->network, false);
272 if (!device->driver || !device->driver->disable)
275 err = device->driver->disable(device);
276 if (err == 0 || err == -EALREADY) {
277 connman_device_set_powered(device, false);
281 if (err == -EINPROGRESS)
282 device->pending_timeout = g_timeout_add_seconds(4,
283 device_pending_reset, device);
288 static void probe_driver(struct connman_device_driver *driver)
292 DBG("driver %p name %s", driver, driver->name);
294 for (list = device_list; list; list = list->next) {
295 struct connman_device *device = list->data;
300 if (driver->type != device->type)
303 if (driver->probe(device) < 0)
306 device->driver = driver;
308 __connman_technology_add_device(device);
312 static void remove_device(struct connman_device *device)
314 DBG("device %p", device);
316 __connman_device_disable(device);
318 __connman_technology_remove_device(device);
320 if (device->driver->remove)
321 device->driver->remove(device);
323 device->driver = NULL;
326 static void remove_driver(struct connman_device_driver *driver)
330 DBG("driver %p name %s", driver, driver->name);
332 for (list = device_list; list; list = list->next) {
333 struct connman_device *device = list->data;
335 if (device->driver == driver)
336 remove_device(device);
340 bool __connman_device_has_driver(struct connman_device *device)
342 if (!device || !device->driver)
348 static GSList *driver_list = NULL;
350 static gint compare_priority(gconstpointer a, gconstpointer b)
352 const struct connman_device_driver *driver1 = a;
353 const struct connman_device_driver *driver2 = b;
355 return driver2->priority - driver1->priority;
359 * connman_device_driver_register:
360 * @driver: device driver definition
362 * Register a new device driver
364 * Returns: %0 on success
366 int connman_device_driver_register(struct connman_device_driver *driver)
368 DBG("driver %p name %s", driver, driver->name);
370 driver_list = g_slist_insert_sorted(driver_list, driver,
372 probe_driver(driver);
378 * connman_device_driver_unregister:
379 * @driver: device driver definition
381 * Remove a previously registered device driver
383 void connman_device_driver_unregister(struct connman_device_driver *driver)
385 DBG("driver %p name %s", driver, driver->name);
387 driver_list = g_slist_remove(driver_list, driver);
389 remove_driver(driver);
392 static void free_network(gpointer data)
394 struct connman_network *network = data;
396 DBG("network %p", network);
398 __connman_network_set_device(network, NULL);
400 connman_network_unref(network);
403 static void device_destruct(struct connman_device *device)
405 DBG("device %p name %s", device, device->name);
407 clear_pending_trigger(device);
409 g_hash_table_destroy(device->networks);
410 device->networks = NULL;
412 g_free(device->ident);
413 g_free(device->node);
414 g_free(device->name);
415 g_free(device->address);
416 g_free(device->interface);
417 g_free(device->path);
419 g_free(device->last_network);
425 * connman_device_create:
426 * @node: device node name (for example an address)
429 * Allocate a new device of given #type and assign the #node name to it.
431 * Returns: a newly-allocated #connman_device structure
433 struct connman_device *connman_device_create(const char *node,
434 enum connman_device_type type)
436 struct connman_device *device;
438 DBG("node %s type %d", node, type);
440 device = g_try_new0(struct connman_device, 1);
444 DBG("device %p", device);
446 device->refcount = 1;
449 device->name = g_strdup(type2description(device->type));
451 device->networks = g_hash_table_new_full(g_str_hash, g_str_equal,
452 g_free, free_network);
454 device_list = g_slist_prepend(device_list, device);
460 * connman_device_ref:
461 * @device: device structure
463 * Increase reference counter of device
465 struct connman_device *connman_device_ref_debug(struct connman_device *device,
466 const char *file, int line, const char *caller)
468 DBG("%p ref %d by %s:%d:%s()", device, device->refcount + 1,
471 __sync_fetch_and_add(&device->refcount, 1);
477 * connman_device_unref:
478 * @device: device structure
480 * Decrease reference counter of device
482 void connman_device_unref_debug(struct connman_device *device,
483 const char *file, int line, const char *caller)
485 DBG("%p ref %d by %s:%d:%s()", device, device->refcount - 1,
488 if (__sync_fetch_and_sub(&device->refcount, 1) != 1)
491 if (device->driver) {
492 device->driver->remove(device);
493 device->driver = NULL;
496 device_list = g_slist_remove(device_list, device);
498 device_destruct(device);
501 const char *__connman_device_get_type(struct connman_device *device)
503 return type2string(device->type);
507 * connman_device_get_type:
508 * @device: device structure
512 enum connman_device_type connman_device_get_type(struct connman_device *device)
518 * connman_device_set_index:
519 * @device: device structure
520 * @index: index number
522 * Set index number of device
524 void connman_device_set_index(struct connman_device *device, int index)
526 device->index = index;
530 * connman_device_get_index:
531 * @device: device structure
533 * Get index number of device
535 int connman_device_get_index(struct connman_device *device)
537 return device->index;
541 * connman_device_set_interface:
542 * @device: device structure
543 * @interface: interface name
545 * Set interface name of device
547 void connman_device_set_interface(struct connman_device *device,
548 const char *interface)
550 g_free(device->interface);
551 device->interface = g_strdup(interface);
554 const char *str = type2description(device->type);
555 if (str && device->interface)
556 device->name = g_strdup_printf("%s (%s)", str,
562 * connman_device_set_ident:
563 * @device: device structure
564 * @ident: unique identifier
566 * Set unique identifier of device
568 void connman_device_set_ident(struct connman_device *device,
571 g_free(device->ident);
572 device->ident = g_strdup(ident);
575 const char *connman_device_get_ident(struct connman_device *device)
577 return device->ident;
581 * connman_device_set_powered:
582 * @device: device structure
583 * @powered: powered state
585 * Change power state of device
587 int connman_device_set_powered(struct connman_device *device,
590 struct connman_device_scan_params params;
591 enum connman_service_type type;
594 DBG("device %p powered %d", device, powered);
596 if (device->powered == powered)
599 clear_pending_trigger(device);
601 device->powered_pending = PENDING_NONE;
603 device->powered = powered;
605 type = __connman_device_get_service_type(device);
607 if (!device->powered) {
608 __connman_technology_disabled(type);
612 __connman_technology_enabled(type);
614 for (i = 0; i < MAX_CONNMAN_SERVICE_TYPES; i++)
615 device->scanning[i] = false;
617 if (device->driver && device->driver->scan) {
618 memset(¶ms, 0, sizeof(params));
619 params.type = CONNMAN_SERVICE_TYPE_UNKNOWN;
621 device->driver->scan(device, ¶ms);
627 bool connman_device_get_powered(struct connman_device *device)
629 return device->powered;
632 static int device_scan(enum connman_service_type type,
633 struct connman_device *device,
634 bool force_full_scan)
636 struct connman_device_scan_params params;
638 if (!device->driver || !device->driver->scan)
641 if (!device->powered)
644 memset(¶ms, 0, sizeof(params));
646 params.force_full_scan = force_full_scan;
648 return device->driver->scan(device, ¶ms);
651 int __connman_device_disconnect(struct connman_device *device)
656 DBG("device %p", device);
658 g_hash_table_iter_init(&iter, device->networks);
660 while (g_hash_table_iter_next(&iter, &key, &value)) {
661 struct connman_network *network = value;
663 if (connman_network_get_connecting(network)) {
665 * Skip network in the process of connecting.
666 * This is a workaround for WiFi networks serviced
667 * by the supplicant plugin that hold a reference
668 * to the network. If we disconnect the network
669 * here then the referenced object will not be
670 * registered and usage (like launching DHCP client)
671 * will fail. There is nothing to be gained by
672 * removing the network here anyway.
674 connman_warn("Skipping disconnect of %s, network is connecting.",
675 connman_network_get_identifier(network));
679 __connman_network_disconnect(network);
685 int connman_device_reconnect_service(struct connman_device *device)
687 DBG("device %p", device);
689 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
694 static void mark_network_available(gpointer key, gpointer value,
697 struct connman_network *network = value;
699 connman_network_set_available(network, true);
702 static void mark_network_unavailable(gpointer key, gpointer value,
705 struct connman_network *network = value;
707 if (connman_network_get_connected(network) ||
708 connman_network_get_connecting(network))
711 connman_network_set_available(network, false);
714 static gboolean remove_unavailable_network(gpointer key, gpointer value,
717 struct connman_network *network = value;
719 if (connman_network_get_connected(network) ||
720 connman_network_get_connecting(network))
723 if (connman_network_get_available(network))
729 void __connman_device_cleanup_networks(struct connman_device *device)
731 g_hash_table_foreach_remove(device->networks,
732 remove_unavailable_network, NULL);
735 bool connman_device_get_scanning(struct connman_device *device,
736 enum connman_service_type type)
740 if (type != CONNMAN_SERVICE_TYPE_UNKNOWN)
741 return device->scanning[type];
743 for (i = 0; i < MAX_CONNMAN_SERVICE_TYPES; i++)
744 if (device->scanning[i])
750 void connman_device_reset_scanning(struct connman_device *device)
752 g_hash_table_foreach(device->networks,
753 mark_network_available, NULL);
757 * connman_device_set_scanning:
758 * @device: device structure
759 * @scanning: scanning state
761 * Change scanning state of device
763 int connman_device_set_scanning(struct connman_device *device,
764 enum connman_service_type type, bool scanning)
766 DBG("device %p scanning %d", device, scanning);
768 if (!device->driver || !device->driver->scan)
771 if (type == CONNMAN_SERVICE_TYPE_UNKNOWN)
774 if (device->scanning[type] == scanning)
777 device->scanning[type] = scanning;
780 __connman_technology_scan_started(device);
782 g_hash_table_foreach(device->networks,
783 mark_network_unavailable, NULL);
788 __connman_device_cleanup_networks(device);
790 __connman_technology_scan_stopped(device, type);
792 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
798 * connman_device_set_string:
799 * @device: device structure
800 * @key: unique identifier
801 * @value: string value
803 * Set string value for specific key
805 int connman_device_set_string(struct connman_device *device,
806 const char *key, const char *value)
808 DBG("device %p key %s value %s", device, key, value);
810 if (g_str_equal(key, "Address")) {
811 g_free(device->address);
812 device->address = g_strdup(value);
813 } else if (g_str_equal(key, "Name")) {
814 g_free(device->name);
815 device->name = g_strdup(value);
816 } else if (g_str_equal(key, "Node")) {
817 g_free(device->node);
818 device->node = g_strdup(value);
819 } else if (g_str_equal(key, "Path")) {
820 g_free(device->path);
821 device->path = g_strdup(value);
830 * connman_device_get_string:
831 * @device: device structure
832 * @key: unique identifier
834 * Get string value for specific key
836 const char *connman_device_get_string(struct connman_device *device,
839 DBG("device %p key %s", device, key);
841 if (g_str_equal(key, "Address"))
842 return device->address;
843 else if (g_str_equal(key, "Name"))
845 else if (g_str_equal(key, "Node"))
847 else if (g_str_equal(key, "Interface"))
848 return device->interface;
849 else if (g_str_equal(key, "Path"))
856 * connman_device_add_network:
857 * @device: device structure
858 * @network: network structure
860 * Add new network to the device
862 int connman_device_add_network(struct connman_device *device,
863 struct connman_network *network)
865 const char *identifier = connman_network_get_identifier(network);
867 DBG("device %p network %p", device, network);
872 connman_network_ref(network);
874 __connman_network_set_device(network, device);
876 g_hash_table_replace(device->networks, g_strdup(identifier),
883 * connman_device_get_network:
884 * @device: device structure
885 * @identifier: network identifier
887 * Get network for given identifier
889 struct connman_network *connman_device_get_network(struct connman_device *device,
890 const char *identifier)
892 DBG("device %p identifier %s", device, identifier);
894 return g_hash_table_lookup(device->networks, identifier);
898 * connman_device_remove_network:
899 * @device: device structure
900 * @identifier: network identifier
902 * Remove network for given identifier
904 int connman_device_remove_network(struct connman_device *device,
905 struct connman_network *network)
907 const char *identifier;
909 DBG("device %p network %p", device, network);
914 identifier = connman_network_get_identifier(network);
915 g_hash_table_remove(device->networks, identifier);
920 void __connman_device_set_network(struct connman_device *device,
921 struct connman_network *network)
928 if (device->network == network)
932 name = connman_network_get_string(network, "Name");
933 g_free(device->last_network);
934 device->last_network = g_strdup(name);
936 device->network = network;
938 g_free(device->last_network);
939 device->last_network = NULL;
941 device->network = NULL;
945 static bool match_driver(struct connman_device *device,
946 struct connman_device_driver *driver)
948 if (device->type == driver->type ||
949 driver->type == CONNMAN_DEVICE_TYPE_UNKNOWN)
956 * connman_device_register:
957 * @device: device structure
959 * Register device with the system
961 int connman_device_register(struct connman_device *device)
965 DBG("device %p name %s", device, device->name);
970 for (list = driver_list; list; list = list->next) {
971 struct connman_device_driver *driver = list->data;
973 if (!match_driver(device, driver))
976 DBG("driver %p name %s", driver, driver->name);
978 if (driver->probe(device) == 0) {
979 device->driver = driver;
987 return __connman_technology_add_device(device);
991 * connman_device_unregister:
992 * @device: device structure
994 * Unregister device with the system
996 void connman_device_unregister(struct connman_device *device)
998 DBG("device %p name %s", device, device->name);
1000 if (!device->driver)
1003 remove_device(device);
1007 * connman_device_get_data:
1008 * @device: device structure
1010 * Get private device data pointer
1012 void *connman_device_get_data(struct connman_device *device)
1014 return device->driver_data;
1018 * connman_device_set_data:
1019 * @device: device structure
1020 * @data: data pointer
1022 * Set private device data pointer
1024 void connman_device_set_data(struct connman_device *device, void *data)
1026 device->driver_data = data;
1029 struct connman_device *__connman_device_find_device(
1030 enum connman_service_type type)
1034 for (list = device_list; list; list = list->next) {
1035 struct connman_device *device = list->data;
1036 enum connman_service_type service_type =
1037 __connman_device_get_service_type(device);
1039 if (service_type != type)
1048 struct connman_device *connman_device_find_by_index(int index)
1052 for (list = device_list; list; list = list->next) {
1053 struct connman_device *device = list->data;
1054 if (device->index == index)
1062 * connman_device_set_regdom
1063 * @device: device structure
1064 * @alpha2: string representing regulatory domain
1066 * Set regulatory domain on device basis
1068 int connman_device_set_regdom(struct connman_device *device,
1071 if (!device->driver || !device->driver->set_regdom)
1074 if (!device->powered)
1077 return device->driver->set_regdom(device, alpha2);
1081 * connman_device_regdom_notify
1082 * @device: device structure
1083 * @alpha2: string representing regulatory domain
1085 * Notify on setting regulatory domain on device basis
1087 void connman_device_regdom_notify(struct connman_device *device,
1088 int result, const char *alpha2)
1090 __connman_technology_notify_regdom_by_device(device, result, alpha2);
1093 static int connman_device_request_scan(enum connman_service_type type,
1094 bool force_full_scan)
1096 bool success = false;
1097 int last_err = -ENOSYS;
1102 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1103 case CONNMAN_SERVICE_TYPE_SYSTEM:
1104 case CONNMAN_SERVICE_TYPE_ETHERNET:
1105 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1106 case CONNMAN_SERVICE_TYPE_CELLULAR:
1107 case CONNMAN_SERVICE_TYPE_GPS:
1108 case CONNMAN_SERVICE_TYPE_VPN:
1109 case CONNMAN_SERVICE_TYPE_GADGET:
1111 case CONNMAN_SERVICE_TYPE_WIFI:
1112 case CONNMAN_SERVICE_TYPE_P2P:
1116 for (list = device_list; list; list = list->next) {
1117 struct connman_device *device = list->data;
1119 if (!device_has_service_type(device, type))
1122 err = device_scan(type, device, force_full_scan);
1123 if (err == 0 || err == -EALREADY || err == -EINPROGRESS) {
1127 DBG("device %p err %d", device, err);
1137 int __connman_device_request_scan(enum connman_service_type type)
1139 return connman_device_request_scan(type, false);
1142 int __connman_device_request_scan_full(enum connman_service_type type)
1144 return connman_device_request_scan(type, true);
1147 int __connman_device_request_hidden_scan(struct connman_device *device,
1148 const char *ssid, unsigned int ssid_len,
1149 const char *identity, const char *passphrase,
1150 const char *security, void *user_data)
1152 struct connman_device_scan_params params;
1154 DBG("device %p", device);
1156 if (!device || !device->driver ||
1157 !device->driver->scan)
1160 params.type = CONNMAN_SERVICE_TYPE_UNKNOWN;
1162 params.ssid_len = ssid_len;
1163 params.identity = identity;
1164 params.passphrase = passphrase;
1165 params.security = security;
1166 params.user_data = user_data;
1168 return device->driver->scan(device, ¶ms);
1171 void __connman_device_stop_scan(enum connman_service_type type)
1175 for (list = device_list; list; list = list->next) {
1176 struct connman_device *device = list->data;
1178 if (!device_has_service_type(device, type))
1181 if (device->driver && device->driver->stop_scan)
1182 device->driver->stop_scan(type, device);
1186 static char *index2ident(int index, const char *prefix)
1189 struct ether_addr eth;
1196 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1200 memset(&ifr, 0, sizeof(ifr));
1201 ifr.ifr_ifindex = index;
1203 err = ioctl(sk, SIOCGIFNAME, &ifr);
1206 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
1213 len = prefix ? strlen(prefix) + 18 : 18;
1215 str = g_malloc(len);
1219 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
1220 snprintf(str, len, "%s%02x%02x%02x%02x%02x%02x",
1221 prefix ? prefix : "",
1222 eth.ether_addr_octet[0],
1223 eth.ether_addr_octet[1],
1224 eth.ether_addr_octet[2],
1225 eth.ether_addr_octet[3],
1226 eth.ether_addr_octet[4],
1227 eth.ether_addr_octet[5]);
1232 static char *index2addr(int index)
1235 struct ether_addr eth;
1242 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1246 memset(&ifr, 0, sizeof(ifr));
1247 ifr.ifr_ifindex = index;
1249 err = ioctl(sk, SIOCGIFNAME, &ifr);
1252 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
1263 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
1264 snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
1265 eth.ether_addr_octet[0],
1266 eth.ether_addr_octet[1],
1267 eth.ether_addr_octet[2],
1268 eth.ether_addr_octet[3],
1269 eth.ether_addr_octet[4],
1270 eth.ether_addr_octet[5]);
1275 struct connman_device *connman_device_create_from_index(int index)
1277 enum connman_device_type type;
1278 struct connman_device *device;
1279 char *devname, *ident = NULL;
1280 char *addr = NULL, *name = NULL;
1285 devname = connman_inet_ifname(index);
1289 if (__connman_device_isfiltered(devname)) {
1290 connman_info("Ignoring interface %s (filtered)", devname);
1295 type = __connman_rtnl_get_device_type(index);
1298 case CONNMAN_DEVICE_TYPE_UNKNOWN:
1299 connman_info("Ignoring interface %s (type unknown)", devname);
1302 case CONNMAN_DEVICE_TYPE_ETHERNET:
1303 case CONNMAN_DEVICE_TYPE_GADGET:
1304 case CONNMAN_DEVICE_TYPE_WIFI:
1305 name = index2ident(index, "");
1306 addr = index2addr(index);
1308 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
1309 case CONNMAN_DEVICE_TYPE_CELLULAR:
1310 case CONNMAN_DEVICE_TYPE_GPS:
1311 case CONNMAN_DEVICE_TYPE_VENDOR:
1312 name = g_strdup(devname);
1316 device = connman_device_create(name, type);
1321 case CONNMAN_DEVICE_TYPE_UNKNOWN:
1322 case CONNMAN_DEVICE_TYPE_VENDOR:
1323 case CONNMAN_DEVICE_TYPE_GPS:
1325 case CONNMAN_DEVICE_TYPE_ETHERNET:
1326 case CONNMAN_DEVICE_TYPE_GADGET:
1327 ident = index2ident(index, NULL);
1329 case CONNMAN_DEVICE_TYPE_WIFI:
1330 ident = index2ident(index, NULL);
1332 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
1334 case CONNMAN_DEVICE_TYPE_CELLULAR:
1335 ident = index2ident(index, NULL);
1339 connman_device_set_index(device, index);
1340 connman_device_set_interface(device, devname);
1343 connman_device_set_ident(device, ident);
1347 connman_device_set_string(device, "Address", addr);
1357 bool __connman_device_isfiltered(const char *devname)
1360 char **blacklisted_interfaces;
1366 for (pattern = device_filter, match = false; *pattern; pattern++) {
1367 if (g_pattern_match_simple(*pattern, devname)) {
1374 DBG("ignoring device %s (match)", devname);
1379 if (g_pattern_match_simple("dummy*", devname)) {
1380 DBG("ignoring dummy networking devices");
1384 if (!nodevice_filter)
1387 for (pattern = nodevice_filter; *pattern; pattern++) {
1388 if (g_pattern_match_simple(*pattern, devname)) {
1389 DBG("ignoring device %s (no match)", devname);
1395 if (__connman_inet_isrootnfs_device(devname)) {
1396 DBG("ignoring device %s (rootnfs)", devname);
1400 blacklisted_interfaces =
1401 connman_setting_get_string_list("NetworkInterfaceBlacklist");
1402 if (!blacklisted_interfaces)
1405 for (pattern = blacklisted_interfaces; *pattern; pattern++) {
1406 if (g_str_has_prefix(devname, *pattern)) {
1407 DBG("ignoring device %s (blacklist)", devname);
1415 static void cleanup_devices(void)
1418 * Check what interfaces are currently up and if connman is
1419 * suppose to handle the interface, then cleanup the mess
1420 * related to that interface. There might be weird routes etc
1421 * that are related to that interface and that might confuse
1422 * connmand. So in this case we just turn the interface down
1423 * so that kernel removes routes/addresses automatically and
1424 * then proceed the startup.
1426 * Note that this cleanup must be done before rtnl/detect code
1427 * has activated interface watches.
1433 interfaces = __connman_inet_get_running_interfaces();
1438 for (i = 0; interfaces[i]; i++) {
1441 struct sockaddr_in sin_addr, sin_mask;
1443 filtered = __connman_device_isfiltered(interfaces[i]);
1447 index = connman_inet_ifindex(interfaces[i]);
1451 if (!__connman_inet_get_address_netmask(index, &sin_addr,
1453 char *address = g_strdup(inet_ntoa(sin_addr.sin_addr));
1454 char *netmask = g_strdup(inet_ntoa(sin_mask.sin_addr));
1456 if (__connman_config_address_provisioned(address,
1458 DBG("Skip %s which is already provisioned "
1459 "with %s/%s", interfaces[i], address,
1470 DBG("cleaning up %s index %d", interfaces[i], index);
1472 connman_inet_ifdown(index);
1475 * ConnMan will turn the interface UP automatically so
1476 * no need to do it here.
1480 g_strfreev(interfaces);
1483 int __connman_device_init(const char *device, const char *nodevice)
1488 device_filter = g_strsplit(device, ",", -1);
1491 nodevice_filter = g_strsplit(nodevice, ",", -1);
1498 void __connman_device_cleanup(void)
1502 g_strfreev(nodevice_filter);
1503 g_strfreev(device_filter);