From f6894721181f66414f91463b1baa83a7a68e19f0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 26 Jun 2009 12:23:12 +0200 Subject: [PATCH] Add some more INET helpers --- include/inet.h | 7 +++ src/inet.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) diff --git a/include/inet.h b/include/inet.h index 3aacbdc..1f80b74 100644 --- a/include/inet.h +++ b/include/inet.h @@ -26,6 +26,8 @@ extern "C" { #endif +#include + #include extern int connman_inet_ifindex(const char *name); @@ -36,6 +38,11 @@ extern int connman_inet_ifdown(int index); extern struct connman_device *connman_inet_create_device(int index); +extern int connman_inet_set_address(int index, struct in_addr address, + struct in_addr netmask, struct in_addr broadcast); +extern int connman_inet_clear_address(int index); +extern int connman_inet_set_gateway(int index, struct in_addr gateway); + #ifdef __cplusplus } #endif diff --git a/src/inet.c b/src/inet.c index 56ccc59..7789286 100644 --- a/src/inet.c +++ b/src/inet.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include #include #include @@ -415,3 +417,161 @@ struct connman_device *connman_inet_create_device(int index) return device; } + +int connman_inet_set_address(int index, struct in_addr address, + struct in_addr netmask, struct in_addr broadcast) +{ + struct ifreq ifr; + struct sockaddr_in *addr; + int sk, err; + + sk = socket(PF_INET, SOCK_DGRAM, 0); + if (sk < 0) + return -1; + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_ifindex = index; + + if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) { + close(sk); + return -1; + } + + DBG("ifname %s", ifr.ifr_name); + + addr = (struct sockaddr_in *) &ifr.ifr_addr; + addr->sin_family = AF_INET; + addr->sin_addr = address; + + err = ioctl(sk, SIOCSIFADDR, &ifr); + + if (err < 0) + DBG("address setting failed (%s)", strerror(errno)); + + addr = (struct sockaddr_in *) &ifr.ifr_netmask; + addr->sin_family = AF_INET; + addr->sin_addr = netmask; + + err = ioctl(sk, SIOCSIFNETMASK, &ifr); + + if (err < 0) + DBG("netmask setting failed (%s)", strerror(errno)); + + addr = (struct sockaddr_in *) &ifr.ifr_broadaddr; + addr->sin_family = AF_INET; + addr->sin_addr = broadcast; + + err = ioctl(sk, SIOCSIFBRDADDR, &ifr); + + if (err < 0) + DBG("broadcast setting failed (%s)", strerror(errno)); + + close(sk); + + return 0; +} + +int connman_inet_clear_address(int index) +{ + struct ifreq ifr; + struct sockaddr_in *addr; + int sk, err; + + sk = socket(PF_INET, SOCK_DGRAM, 0); + if (sk < 0) + return -1; + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_ifindex = index; + + if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) { + close(sk); + return -1; + } + + DBG("ifname %s", ifr.ifr_name); + + addr = (struct sockaddr_in *) &ifr.ifr_addr; + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = INADDR_ANY; + + //err = ioctl(sk, SIOCDIFADDR, &ifr); + err = ioctl(sk, SIOCSIFADDR, &ifr); + + close(sk); + + if (err < 0 && errno != EADDRNOTAVAIL) { + DBG("address removal failed (%s)", strerror(errno)); + return -1; + } + + return 0; +} + +int connman_inet_set_gateway(int index, struct in_addr gateway) +{ + struct ifreq ifr; + struct rtentry rt; + struct sockaddr_in *addr; + int sk, err; + + sk = socket(PF_INET, SOCK_DGRAM, 0); + if (sk < 0) + return -1; + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_ifindex = index; + + if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) { + close(sk); + return -1; + } + + DBG("ifname %s", ifr.ifr_name); + + memset(&rt, 0, sizeof(rt)); + rt.rt_flags = RTF_UP | RTF_HOST; + + addr = (struct sockaddr_in *) &rt.rt_dst; + addr->sin_family = AF_INET; + addr->sin_addr = gateway; + + addr = (struct sockaddr_in *) &rt.rt_gateway; + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = INADDR_ANY; + + addr = (struct sockaddr_in *) &rt.rt_genmask; + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = INADDR_ANY; + + rt.rt_dev = ifr.ifr_name; + + err = ioctl(sk, SIOCADDRT, &rt); + if (err < 0) + connman_error("Setting host gateway route failed (%s)", + strerror(errno)); + + memset(&rt, 0, sizeof(rt)); + rt.rt_flags = RTF_UP | RTF_GATEWAY; + + addr = (struct sockaddr_in *) &rt.rt_dst; + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = INADDR_ANY; + + addr = (struct sockaddr_in *) &rt.rt_gateway; + addr->sin_family = AF_INET; + addr->sin_addr = gateway; + + addr = (struct sockaddr_in *) &rt.rt_genmask; + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = INADDR_ANY; + + err = ioctl(sk, SIOCADDRT, &rt); + if (err < 0) + connman_error("Setting default route failed (%s)", + strerror(errno)); + + close(sk); + + return err; +} -- 2.7.4