From: Marcel Holtmann Date: Mon, 24 Dec 2007 00:22:43 +0000 (+0100) Subject: Add experimental IPv4 support X-Git-Tag: 0.1~477 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b93a99e200eaec8c8b0943531e11bffe86d3122d;p=platform%2Fupstream%2Fconnman.git Add experimental IPv4 support --- diff --git a/include/iface.h b/include/iface.h index cc3ab0c..daeaf17 100644 --- a/include/iface.h +++ b/include/iface.h @@ -26,6 +26,8 @@ extern "C" { #endif +#include + 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); diff --git a/plugins/80203.c b/plugins/80203.c index 6c9f950..e39fcdc 100644 --- a/plugins/80203.c +++ b/plugins/80203.c @@ -24,6 +24,7 @@ #endif #include +#include #include #include @@ -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) diff --git a/plugins/80211.c b/plugins/80211.c index 74438db..1fd5aaf 100644 --- a/plugins/80211.c +++ b/plugins/80211.c @@ -24,6 +24,7 @@ #endif #include +#include #include #include @@ -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) diff --git a/plugins/net.c b/plugins/net.c index 627b4c5..e0aa5a4 100644 --- a/plugins/net.c +++ b/plugins/net.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #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; +} diff --git a/plugins/net.h b/plugins/net.h index 10f46ff..b30ae7c 100644 --- a/plugins/net.h +++ b/plugins/net.h @@ -19,5 +19,11 @@ * */ +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);