From: Daniel Wagner <[email protected]>
This is Samuel's work.
---
include/element.h | 1 +
include/property.h | 1 +
src/connection.c | 8 +++++++-
src/connman.h | 1 +
src/element.c | 6 ++++++
src/inet.c | 27 ++++++++++++++++++++-------
src/ipv4.c | 12 ++++++++----
src/provider.c | 8 ++++++++
8 files changed, 52 insertions(+), 12 deletions(-)
diff --git a/include/element.h b/include/element.h
index 05aa06d..08e4a85 100644
--- a/include/element.h
+++ b/include/element.h
@@ -104,6 +104,7 @@ struct connman_element {
struct {
enum connman_ipconfig_method method;
gchar *address;
+ gchar *destination;
gchar *netmask;
gchar *gateway;
gchar *network;
diff --git a/include/property.h b/include/property.h
index 4581ec1..43f13ce 100644
--- a/include/property.h
+++ b/include/property.h
@@ -45,6 +45,7 @@ enum connman_property_id {
CONNMAN_PROPERTY_ID_IPV4_METHOD,
CONNMAN_PROPERTY_ID_IPV4_ADDRESS,
+ CONNMAN_PROPERTY_ID_IPV4_DESTINATION,
CONNMAN_PROPERTY_ID_IPV4_NETMASK,
CONNMAN_PROPERTY_ID_IPV4_GATEWAY,
CONNMAN_PROPERTY_ID_IPV4_BROADCAST,
diff --git a/src/connection.c b/src/connection.c
index 0e7a790..83fb9ce 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -288,7 +288,13 @@ static int connection_probe(struct connman_element
*element)
CONNMAN_PROPERTY_ID_IPV6_GATEWAY, &ipv6_gateway);
connman_element_get_value(element,
- CONNMAN_PROPERTY_ID_IPV4_ADDRESS, &vpn_ip);
+ CONNMAN_PROPERTY_ID_IPV4_DESTINATION, &vpn_ip);
+
+ if (vpn_ip == NULL)
+ connman_element_get_value(element,
+ CONNMAN_PROPERTY_ID_IPV4_ADDRESS, &vpn_ip);
+
+ DBG("vpn_ip %s", vpn_ip);
connman_element_get_value(element,
CONNMAN_PROPERTY_ID_DOMAINNAME, &domainname);
diff --git a/src/connman.h b/src/connman.h
index 2fa1129..4894183 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -107,6 +107,7 @@ void __connman_task_cleanup(void);
int __connman_inet_modify_address(int cmd, int flags, int index, int family,
const char *address,
+ const char *destination,
unsigned char prefixlen,
const char *broadcast);
diff --git a/src/element.c b/src/element.c
index a5700f2..39516fa 100644
--- a/src/element.c
+++ b/src/element.c
@@ -777,6 +777,12 @@ int connman_element_get_value(struct connman_element
*element,
id, value);
*((char **) value) = element->ipv4.address;
break;
+ case CONNMAN_PROPERTY_ID_IPV4_DESTINATION:
+ if (element->ipv4.destination == NULL)
+ return connman_element_get_value(element->parent,
+ id, value);
+ *((char **) value) = element->ipv4.destination;
+ break;
case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
if (element->ipv4.netmask == NULL)
return connman_element_get_value(element->parent,
diff --git a/src/inet.c b/src/inet.c
index 15c0138..3fe04e1 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -66,18 +66,20 @@ static int add_rtattr(struct nlmsghdr *n, size_t
max_length, int type,
int __connman_inet_modify_address(int cmd, int flags,
int index, int family,
const char *address,
+ const char *destination,
unsigned char prefixlen,
const char *broadcast)
{
uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
+ RTA_LENGTH(sizeof(struct in6_addr)) +
RTA_LENGTH(sizeof(struct in6_addr))];
struct nlmsghdr *header;
struct sockaddr_nl nl_addr;
struct ifaddrmsg *ifaddrmsg;
struct in6_addr ipv6_addr;
- struct in_addr ipv4_addr, ipv4_bcast;
+ struct in_addr ipv4_addr, ipv4_dest, ipv4_bcast;
int sk, err;
DBG("");
@@ -113,6 +115,15 @@ int __connman_inet_modify_address(int cmd, int flags,
ipv4_bcast.s_addr = ipv4_addr.s_addr |
htonl(0xfffffffflu >> prefixlen);
+ if (destination != NULL) {
+ if (inet_pton(AF_INET, destination, &ipv4_dest) < 1)
+ return -1;
+
+ if ((err = add_rtattr(header, sizeof(request),
IFA_ADDRESS,
+ &ipv4_dest, sizeof(ipv4_dest))) < 0)
+ return err;
+ }
+
if ((err = add_rtattr(header, sizeof(request), IFA_LOCAL,
&ipv4_addr, sizeof(ipv4_addr))) < 0)
return err;
@@ -542,7 +553,7 @@ int connman_inet_set_ipv6_address(int index,
if ((__connman_inet_modify_address(RTM_NEWADDR,
NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
- address, prefix_len, NULL)) < 0) {
+ address, NULL, prefix_len, NULL)) < 0) {
connman_error("Set IPv6 address error");
return -1;
}
@@ -553,7 +564,7 @@ int connman_inet_set_ipv6_address(int index,
int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
{
unsigned char prefix_len;
- const char *address, *broadcast;
+ const char *address, *broadcast, *destination;
if (ipaddress->local == NULL)
return -1;
@@ -561,12 +572,13 @@ int connman_inet_set_address(int index, struct
connman_ipaddress *ipaddress)
prefix_len = ipaddress->prefixlen;
address = ipaddress->local;
broadcast = ipaddress->broadcast;
+ destination = ipaddress->peer;
DBG("index %d address %s prefix_len %d", index, address, prefix_len);
if ((__connman_inet_modify_address(RTM_NEWADDR,
NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
- address, prefix_len, broadcast)) < 0) {
+ address, destination, prefix_len,
broadcast)) < 0) {
DBG("address setting failed");
return -1;
}
@@ -580,7 +592,7 @@ int connman_inet_clear_ipv6_address(int index, const char
*address,
DBG("index %d address %s prefix_len %d", index, address, prefix_len);
if ((__connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
- address, prefix_len, NULL)) < 0) {
+ address, NULL, prefix_len, NULL)) < 0) {
connman_error("Clear IPv6 address error");
return -1;
}
@@ -591,16 +603,17 @@ int connman_inet_clear_ipv6_address(int index, const char
*address,
int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
{
unsigned char prefix_len;
- const char *address, *broadcast;
+ const char *address, *broadcast, *destination;
prefix_len = ipaddress->prefixlen;
address = ipaddress->local;
broadcast = ipaddress->broadcast;
+ destination = ipaddress->peer;
DBG("index %d address %s prefix_len %d", index, address, prefix_len);
if ((__connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
- address, prefix_len, broadcast)) < 0) {
+ address, destination, prefix_len,
broadcast)) < 0) {
DBG("address removal failed");
return -1;
}
diff --git a/src/ipv4.c b/src/ipv4.c
index c73f651..4c36067 100644
--- a/src/ipv4.c
+++ b/src/ipv4.c
@@ -67,7 +67,7 @@ static int ipv4_probe(struct connman_element *element)
struct connman_ipconfig *ipconfig;
struct connman_element *connection;
const char *address = NULL, *netmask = NULL, *broadcast = NULL;
- const char *nameserver = NULL, *pac = NULL;
+ const char *destination = NULL, *nameserver = NULL, *pac = NULL;
char *timeserver = NULL;
unsigned char prefixlen;
@@ -78,6 +78,8 @@ static int ipv4_probe(struct connman_element *element)
CONNMAN_PROPERTY_ID_IPV4_NETMASK, &netmask);
connman_element_get_value(element,
CONNMAN_PROPERTY_ID_IPV4_BROADCAST, &broadcast);
+ connman_element_get_value(element,
+ CONNMAN_PROPERTY_ID_IPV4_DESTINATION,
&destination);
connman_element_get_value(element,
CONNMAN_PROPERTY_ID_IPV4_NAMESERVER, &nameserver);
@@ -97,7 +99,7 @@ static int ipv4_probe(struct connman_element *element)
if ((__connman_inet_modify_address(RTM_NEWADDR,
NLM_F_REPLACE | NLM_F_ACK, element->index,
- AF_INET, address, prefixlen, broadcast)) < 0)
+ AF_INET, address, destination, prefixlen,
broadcast)) < 0)
DBG("address setting failed");
service = __connman_element_get_service(element);
@@ -130,7 +132,7 @@ static int ipv4_probe(struct connman_element *element)
static void ipv4_remove(struct connman_element *element)
{
const char *address = NULL, *netmask = NULL, *broadcast = NULL;
- const char *nameserver = NULL;
+ const char *destination = NULL, *nameserver = NULL;
char *timeserver = NULL;
unsigned char prefixlen;
@@ -142,6 +144,8 @@ static void ipv4_remove(struct connman_element *element)
CONNMAN_PROPERTY_ID_IPV4_NETMASK, &netmask);
connman_element_get_value(element,
CONNMAN_PROPERTY_ID_IPV4_BROADCAST, &broadcast);
+ connman_element_get_value(element,
+ CONNMAN_PROPERTY_ID_IPV4_DESTINATION,
&destination);
connman_element_get_value(element,
CONNMAN_PROPERTY_ID_IPV4_NAMESERVER, &nameserver);
@@ -164,7 +168,7 @@ static void ipv4_remove(struct connman_element *element)
prefixlen = __connman_ipconfig_netmask_prefix_len(netmask);
if ((__connman_inet_modify_address(RTM_DELADDR, 0, element->index,
- AF_INET, address, prefixlen, broadcast) < 0))
+ AF_INET, address, destination, prefixlen,
broadcast) < 0))
DBG("address removal failed");
}
diff --git a/src/provider.c b/src/provider.c
index 69536f7..51fa6e5 100644
--- a/src/provider.c
+++ b/src/provider.c
@@ -84,6 +84,9 @@ static int connman_provider_setup_vpn_ipv4(struct
connman_provider *provider,
g_free(element->ipv4.address);
element->ipv4.address = g_strdup(provider->element.ipv4.address);
+ g_free(element->ipv4.destination);
+ element->ipv4.destination =
g_strdup(provider->element.ipv4.destination);
+
g_free(element->ipv4.netmask);
element->ipv4.netmask = g_strdup(provider->element.ipv4.netmask);
@@ -185,12 +188,14 @@ int __connman_provider_connect(struct connman_provider
*provider)
DBG("provider %p", provider);
g_free(provider->element.ipv4.address);
+ g_free(provider->element.ipv4.destination);
g_free(provider->element.ipv4.netmask);
g_free(provider->element.ipv4.gateway);
g_free(provider->element.ipv4.broadcast);
g_free(provider->element.ipv4.pac);
provider->element.ipv4.address = NULL;
+ provider->element.ipv4.destination = NULL;
provider->element.ipv4.netmask = NULL;
provider->element.ipv4.gateway = NULL;
provider->element.ipv4.broadcast = NULL;
@@ -609,6 +614,9 @@ int connman_provider_set_string(struct connman_provider
*provider,
} else if (g_str_equal(key, "Address") == TRUE) {
g_free(provider->element.ipv4.address);
provider->element.ipv4.address = g_strdup(value);
+ } else if (g_str_equal(key, "Destination") == TRUE) {
+ g_free(provider->element.ipv4.destination);
+ provider->element.ipv4.destination = g_strdup(value);
} else if (g_str_equal(key, "Netmask") == TRUE) {
g_free(provider->element.ipv4.netmask);
provider->element.ipv4.netmask = g_strdup(value);
--
1.7.2.3
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman