summaryrefslogtreecommitdiff
path: root/src/device.c
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2012-11-12 14:07:19 +0200
committerPatrik Flykt <patrik.flykt@linux.intel.com>2012-11-23 12:58:50 +0200
commit8c12ec683a443b72c600751e3496a790bade6981 (patch)
tree42a84cb19b2ac739b7e5661502f9cdc8a292e88c /src/device.c
parent68dde4bb2c3e90a6f48dc48609636228dd186c8c (diff)
downloadconnman-8c12ec683a443b72c600751e3496a790bade6981.tar.gz
connman-8c12ec683a443b72c600751e3496a790bade6981.tar.bz2
connman-8c12ec683a443b72c600751e3496a790bade6981.zip
device: Move device creation func into device.c
The device creation function should be part of device.c and not inet.c. After this change the inet.c can be used by separate vpn daemon.
Diffstat (limited to 'src/device.c')
-rw-r--r--src/device.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/src/device.c b/src/device.c
index fc374f50..5325ed52 100644
--- a/src/device.c
+++ b/src/device.c
@@ -25,6 +25,11 @@
#include <errno.h>
#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <net/ethernet.h>
+#include <net/if.h>
#include "connman.h"
@@ -1132,6 +1137,179 @@ int __connman_device_request_hidden_scan(struct connman_device *device,
identity, passphrase, user_data);
}
+static char *index2ident(int index, const char *prefix)
+{
+ struct ifreq ifr;
+ struct ether_addr eth;
+ char *str;
+ int sk, err, len;
+
+ if (index < 0)
+ return NULL;
+
+ sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ if (sk < 0)
+ return NULL;
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_ifindex = index;
+
+ err = ioctl(sk, SIOCGIFNAME, &ifr);
+
+ if (err == 0)
+ err = ioctl(sk, SIOCGIFHWADDR, &ifr);
+
+ close(sk);
+
+ if (err < 0)
+ return NULL;
+
+ len = prefix ? strlen(prefix) + 18 : 18;
+
+ str = malloc(len);
+ if (!str)
+ return NULL;
+
+ memcpy(&eth, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
+ snprintf(str, len, "%s%02x%02x%02x%02x%02x%02x",
+ prefix ? prefix : "",
+ eth.ether_addr_octet[0],
+ eth.ether_addr_octet[1],
+ eth.ether_addr_octet[2],
+ eth.ether_addr_octet[3],
+ eth.ether_addr_octet[4],
+ eth.ether_addr_octet[5]);
+
+ return str;
+}
+
+static char *index2addr(int index)
+{
+ struct ifreq ifr;
+ struct ether_addr eth;
+ char *str;
+ int sk, err;
+
+ if (index < 0)
+ return NULL;
+
+ sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ if (sk < 0)
+ return NULL;
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_ifindex = index;
+
+ err = ioctl(sk, SIOCGIFNAME, &ifr);
+
+ if (err == 0)
+ err = ioctl(sk, SIOCGIFHWADDR, &ifr);
+
+ close(sk);
+
+ if (err < 0)
+ return NULL;
+
+ str = malloc(18);
+ if (!str)
+ return NULL;
+
+ memcpy(&eth, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
+ snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
+ eth.ether_addr_octet[0],
+ eth.ether_addr_octet[1],
+ eth.ether_addr_octet[2],
+ eth.ether_addr_octet[3],
+ eth.ether_addr_octet[4],
+ eth.ether_addr_octet[5]);
+
+ return str;
+}
+
+struct connman_device *connman_device_create_from_index(int index)
+{
+ enum connman_device_type type;
+ struct connman_device *device;
+ char *devname, *ident = NULL;
+ char *addr = NULL, *name = NULL;
+
+ if (index < 0)
+ return NULL;
+
+ devname = connman_inet_ifname(index);
+ if (devname == NULL)
+ return NULL;
+
+ if (__connman_device_isfiltered(devname) == TRUE) {
+ connman_info("Ignoring interface %s (filtered)", devname);
+ g_free(devname);
+ return NULL;
+ }
+
+ type = __connman_rtnl_get_device_type(index);
+
+ switch (type) {
+ case CONNMAN_DEVICE_TYPE_UNKNOWN:
+ connman_info("Ignoring interface %s (type unknown)", devname);
+ g_free(devname);
+ return NULL;
+ case CONNMAN_DEVICE_TYPE_ETHERNET:
+ case CONNMAN_DEVICE_TYPE_GADGET:
+ case CONNMAN_DEVICE_TYPE_WIFI:
+ case CONNMAN_DEVICE_TYPE_WIMAX:
+ name = index2ident(index, "");
+ addr = index2addr(index);
+ break;
+ case CONNMAN_DEVICE_TYPE_BLUETOOTH:
+ case CONNMAN_DEVICE_TYPE_CELLULAR:
+ case CONNMAN_DEVICE_TYPE_GPS:
+ case CONNMAN_DEVICE_TYPE_VENDOR:
+ name = strdup(devname);
+ break;
+ }
+
+ device = connman_device_create(name, type);
+ if (device == NULL)
+ goto done;
+
+ switch (type) {
+ case CONNMAN_DEVICE_TYPE_UNKNOWN:
+ case CONNMAN_DEVICE_TYPE_VENDOR:
+ case CONNMAN_DEVICE_TYPE_GPS:
+ break;
+ case CONNMAN_DEVICE_TYPE_ETHERNET:
+ case CONNMAN_DEVICE_TYPE_GADGET:
+ ident = index2ident(index, NULL);
+ break;
+ case CONNMAN_DEVICE_TYPE_WIFI:
+ case CONNMAN_DEVICE_TYPE_WIMAX:
+ ident = index2ident(index, NULL);
+ break;
+ case CONNMAN_DEVICE_TYPE_BLUETOOTH:
+ break;
+ case CONNMAN_DEVICE_TYPE_CELLULAR:
+ ident = index2ident(index, NULL);
+ break;
+ }
+
+ connman_device_set_index(device, index);
+ connman_device_set_interface(device, devname);
+
+ if (ident != NULL) {
+ connman_device_set_ident(device, ident);
+ g_free(ident);
+ }
+
+ connman_device_set_string(device, "Address", addr);
+
+done:
+ g_free(devname);
+ g_free(name);
+ g_free(addr);
+
+ return device;
+}
+
connman_bool_t __connman_device_isfiltered(const char *devname)
{
char **pattern;