Add experimental IPv4 support
authorMarcel Holtmann <marcel@holtmann.org>
Mon, 24 Dec 2007 00:22:43 +0000 (01:22 +0100)
committerMarcel Holtmann <marcel@holtmann.org>
Mon, 24 Dec 2007 00:22:43 +0000 (01:22 +0100)
include/iface.h
plugins/80203.c
plugins/80211.c
plugins/net.c
plugins/net.h

index cc3ab0c..daeaf17 100644 (file)
@@ -26,6 +26,8 @@
 extern "C" {
 #endif
 
+#include <netinet/in.h>
+
 enum connman_iface_type {
        CONNMAN_IFACE_TYPE_UNKNOWN   = 0,
        CONNMAN_IFACE_TYPE_80203     = 1,
@@ -40,6 +42,15 @@ enum connman_iface_flags {
        CONNMAN_IFACE_FLAGS_IPV6                = (1 << 2),
 };
 
+struct connman_ipv4 {
+       struct in_addr address;
+       struct in_addr netmask;
+       struct in_addr gateway;
+       struct in_addr network;
+       struct in_addr broadcast;
+       struct in_addr nameserver;
+};
+
 struct connman_iface {
        struct connman_iface_driver *driver;
        char *path;
@@ -47,6 +58,7 @@ struct connman_iface {
        char *sysfs;
        enum connman_iface_type type;
        enum connman_iface_flags flags;
+       struct connman_ipv4 ipv4;
 };
 
 struct connman_iface_driver {
@@ -54,6 +66,10 @@ struct connman_iface_driver {
        const char *capability;
        int (*probe) (struct connman_iface *iface);
        void (*remove) (struct connman_iface *iface);
+       int (*get_ipv4) (struct connman_iface *iface,
+                                       struct connman_ipv4 *ipv4);
+       int (*set_ipv4) (struct connman_iface *iface,
+                                       struct connman_ipv4 *ipv4);
 };
 
 extern int connman_iface_register(struct connman_iface_driver *driver);
index 6c9f950..e39fcdc 100644 (file)
@@ -24,6 +24,7 @@
 #endif
 
 #include <stdio.h>
+#include <arpa/inet.h>
 
 #include <connman/plugin.h>
 #include <connman/iface.h>
@@ -52,15 +53,34 @@ static int iface_probe(struct connman_iface *iface)
 
 static void iface_remove(struct connman_iface *iface)
 {
-       char *ifname;
+       printf("[802.03] remove interface\n");
 
-       ifname = __net_ifname(iface->sysfs);
-       if (ifname == NULL)
-               return;
+       __net_clear(iface->sysfs);
+}
 
-       printf("[802.03] remove interface %s\n", ifname);
+static int iface_get_ipv4(struct connman_iface *iface,
+                                       struct connman_ipv4 *ipv4)
+{
+       if (__net_ifaddr(iface->sysfs, &ipv4->address) < 0)
+               return -1;
 
-       __net_free(ifname);
+       printf("[802.03] get address %s\n", inet_ntoa(ipv4->address));
+
+       return 0;
+}
+
+static int iface_set_ipv4(struct connman_iface *iface,
+                                       struct connman_ipv4 *ipv4)
+{
+       printf("[802.03] set address %s\n", inet_ntoa(ipv4->address));
+       printf("[802.03] set netmask %s\n", inet_ntoa(ipv4->netmask));
+       printf("[802.03] set gateway %s\n", inet_ntoa(ipv4->gateway));
+
+       __net_set(iface->sysfs, &ipv4->address, &ipv4->netmask,
+                               &ipv4->gateway, &ipv4->broadcast,
+                                               &ipv4->nameserver);
+
+       return 0;
 }
 
 static struct connman_iface_driver iface_driver = {
@@ -68,6 +88,8 @@ static struct connman_iface_driver iface_driver = {
        .capability     = "net.80203",
        .probe          = iface_probe,
        .remove         = iface_remove,
+       .get_ipv4       = iface_get_ipv4,
+       .set_ipv4       = iface_set_ipv4,
 };
 
 static int plugin_init(void)
index 74438db..1fd5aaf 100644 (file)
@@ -24,6 +24,7 @@
 #endif
 
 #include <stdio.h>
+#include <arpa/inet.h>
 
 #include <connman/plugin.h>
 #include <connman/iface.h>
@@ -51,15 +52,34 @@ static int iface_probe(struct connman_iface *iface)
 
 static void iface_remove(struct connman_iface *iface)
 {
-       char *ifname;
+       printf("[802.11] remove interface\n");
 
-       ifname = __net_ifname(iface->sysfs);
-       if (ifname == NULL)
-               return;
+       __net_clear(iface->sysfs);
+}
 
-       printf("[802.11] remove interface %s\n", ifname);
+static int iface_get_ipv4(struct connman_iface *iface,
+                                       struct connman_ipv4 *ipv4)
+{
+       if (__net_ifaddr(iface->sysfs, &ipv4->address) < 0)
+               return -1;
 
-       __net_free(ifname);
+       printf("[802.11] get address %s\n", inet_ntoa(ipv4->address));
+
+       return 0;
+}
+
+static int iface_set_ipv4(struct connman_iface *iface,
+                                       struct connman_ipv4 *ipv4)
+{
+       printf("[802.11] set address %s\n", inet_ntoa(ipv4->address));
+       printf("[802.11] set netmask %s\n", inet_ntoa(ipv4->netmask));
+       printf("[802.11] set gateway %s\n", inet_ntoa(ipv4->gateway));
+
+       __net_set(iface->sysfs, &ipv4->address, &ipv4->netmask,
+                               &ipv4->gateway, &ipv4->broadcast,
+                                               &ipv4->nameserver);
+
+       return 0;
 }
 
 static struct connman_iface_driver iface_driver = {
@@ -67,6 +87,8 @@ static struct connman_iface_driver iface_driver = {
        .capability     = "net.80211",
        .probe          = iface_probe,
        .remove         = iface_remove,
+       .get_ipv4       = iface_get_ipv4,
+       .set_ipv4       = iface_set_ipv4,
 };
 
 static int plugin_init(void)
index 627b4c5..e0aa5a4 100644 (file)
@@ -30,6 +30,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/ioctl.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
 #include <net/if.h>
 
 #include "net.h"
@@ -74,6 +76,39 @@ done:
        return val;
 }
 
+int __net_ifaddr(const char *sysfs, struct in_addr *addr)
+{
+       struct ifreq ifr;
+       int sk, ifindex;
+
+       ifindex = __net_ifindex(sysfs);
+       if (ifindex < 0)
+               return ifindex;
+
+       sk = socket(PF_INET, SOCK_DGRAM, 0);
+       if (sk < 0)
+               return -errno;
+
+       memset(&ifr, 0, sizeof(ifr));
+       ifr.ifr_ifindex = ifindex;
+
+       if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
+               close(sk);
+               return -errno;
+       }
+
+       if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
+               close(sk);
+               return -errno;
+       }
+
+       close(sk);
+
+       *addr = ((struct sockaddr_in *) (&ifr.ifr_addr))->sin_addr;
+
+       return 0;
+}
+
 char *__net_ifname(const char *sysfs)
 {
        struct ifreq ifr;
@@ -83,7 +118,7 @@ char *__net_ifname(const char *sysfs)
        if (ifindex < 0)
                return NULL;
 
-       sk = socket (PF_INET, SOCK_DGRAM, 0);
+       sk = socket(PF_INET, SOCK_DGRAM, 0);
        if (sk < 0)
                return NULL;
 
@@ -105,3 +140,58 @@ void __net_free(void *ptr)
        if (ptr)
                free(ptr);
 }
+
+int __net_clear(const char *sysfs)
+{
+       char *ifname, cmd[128];
+
+       ifname = __net_ifname(sysfs);
+       if (ifname == NULL)
+               return -1;
+
+       sprintf(cmd, "resolvconf -d %s", ifname);
+       printf("[NET] %s\n", cmd);
+       system(cmd);
+
+       sprintf(cmd, "ip addr flush dev %s", ifname);
+       printf("[NET] %s\n", cmd);
+       system(cmd);
+
+       __net_free(ifname);
+
+       return 0;
+}
+
+int __net_set(const char *sysfs, struct in_addr *addr, struct in_addr *mask,
+                               struct in_addr *route, struct in_addr *bcast,
+                                               struct in_addr *namesrv)
+{
+       char *ifname, cmd[128], msk[32], brd[32];
+
+       ifname = __net_ifname(sysfs);
+       if (ifname == NULL)
+               return -1;
+
+       __net_clear(sysfs);
+
+       sprintf(msk, "%s", "24");
+       sprintf(brd, "%s", inet_ntoa(*bcast));
+       sprintf(cmd, "ip addr add %s/%s brd %s dev %s",
+                               inet_ntoa(*addr), msk, brd, ifname);
+       printf("[NET] %s\n", cmd);
+       system(cmd);
+
+       sprintf(cmd, "ip route add default via %s dev %s",
+                                       inet_ntoa(*route), ifname);
+       printf("[NET] %s\n", cmd);
+       system(cmd);
+
+       sprintf(cmd, "echo \"nameserver %s\" | resolvconf -a %s",
+                                       inet_ntoa(*namesrv), ifname);
+       printf("[NET] %s\n", cmd);
+       system(cmd);
+
+       __net_free(ifname);
+
+       return 0;
+}
index 10f46ff..b30ae7c 100644 (file)
  *
  */
 
+int __net_ifaddr(const char *sysfs, struct in_addr *addr);
 char *__net_ifname(const char *sysfs);
 void __net_free(void *ptr);
+
+int __net_clear(const char *sysfs);
+int __net_set(const char *sysfs, struct in_addr *addr, struct in_addr *mask,
+                               struct in_addr *route, struct in_addr *bcast,
+                                               struct in_addr *namesrv);