5 * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 #include <sys/ioctl.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
33 #include <asm/types.h>
34 #include <linux/netlink.h>
35 #include <linux/rtnetlink.h>
39 static int ipv4_probe(struct connman_element *element)
41 struct connman_service *service;
42 struct connman_ipconfig *ipconfig;
43 struct connman_element *connection;
44 const char *address = NULL, *netmask = NULL, *broadcast = NULL;
45 const char *peer = NULL, *nameserver = NULL, *pac = NULL;
46 char *timeserver = NULL;
47 unsigned char prefixlen;
49 DBG("element %p name %s", element, element->name);
50 connman_element_get_value(element,
51 CONNMAN_PROPERTY_ID_IPV4_ADDRESS, &address);
52 connman_element_get_value(element,
53 CONNMAN_PROPERTY_ID_IPV4_NETMASK, &netmask);
54 connman_element_get_value(element,
55 CONNMAN_PROPERTY_ID_IPV4_BROADCAST, &broadcast);
56 connman_element_get_value(element,
57 CONNMAN_PROPERTY_ID_IPV4_PEER, &peer);
59 connman_element_get_value(element,
60 CONNMAN_PROPERTY_ID_IPV4_NAMESERVER, &nameserver);
61 connman_element_get_value(element,
62 CONNMAN_PROPERTY_ID_IPV4_TIMESERVER, ×erver);
63 connman_element_get_value(element,
64 CONNMAN_PROPERTY_ID_IPV4_PAC, &pac);
66 DBG("address %s", address);
68 DBG("netmask %s", netmask);
69 DBG("broadcast %s", broadcast);
74 prefixlen = __connman_ipconfig_netmask_prefix_len(netmask);
76 if ((__connman_inet_modify_address(RTM_NEWADDR,
77 NLM_F_REPLACE | NLM_F_ACK, element->index,
78 AF_INET, address, peer, prefixlen, broadcast)) < 0)
79 DBG("address setting failed");
81 service = __connman_element_get_service(element);
84 __connman_service_set_proxy_autoconfig(service, pac);
86 if (nameserver != NULL)
87 __connman_service_append_nameserver(service, nameserver);
89 connman_timeserver_append(timeserver);
91 connection = connman_element_create(NULL);
93 connection->type = CONNMAN_ELEMENT_TYPE_CONNECTION;
94 connection->index = element->index;
95 connection->devname = connman_inet_ifname(element->index);
97 ipconfig = __connman_service_get_ip6config(service);
99 __connman_ipconfig_set_element_ipv6_gateway(
100 ipconfig, connection);
102 if (connman_element_register(connection, element) < 0)
103 connman_element_unref(connection);
108 static void ipv4_remove(struct connman_element *element)
110 const char *address = NULL, *netmask = NULL, *broadcast = NULL;
111 const char *peer = NULL, *nameserver = NULL;
112 char *timeserver = NULL;
113 unsigned char prefixlen;
115 DBG("element %p name %s", element, element->name);
117 connman_element_get_value(element,
118 CONNMAN_PROPERTY_ID_IPV4_ADDRESS, &address);
119 connman_element_get_value(element,
120 CONNMAN_PROPERTY_ID_IPV4_NETMASK, &netmask);
121 connman_element_get_value(element,
122 CONNMAN_PROPERTY_ID_IPV4_BROADCAST, &broadcast);
123 connman_element_get_value(element,
124 CONNMAN_PROPERTY_ID_IPV4_PEER, &peer);
126 connman_element_get_value(element,
127 CONNMAN_PROPERTY_ID_IPV4_NAMESERVER, &nameserver);
128 connman_element_get_value(element,
129 CONNMAN_PROPERTY_ID_IPV4_TIMESERVER, ×erver);
131 connman_timeserver_remove(timeserver);
133 DBG("address %s", address);
134 DBG("peer %s", peer);
135 DBG("netmask %s", netmask);
136 DBG("broadcast %s", broadcast);
138 if (nameserver != NULL) {
139 struct connman_service *service;
141 service = __connman_element_get_service(element);
142 __connman_service_remove_nameserver(service, nameserver);
145 prefixlen = __connman_ipconfig_netmask_prefix_len(netmask);
147 if ((__connman_inet_modify_address(RTM_DELADDR, 0, element->index,
148 AF_INET, address, peer, prefixlen, broadcast) < 0))
149 DBG("address removal failed");
151 connman_element_unref(element);
154 static struct connman_driver ipv4_driver = {
156 .type = CONNMAN_ELEMENT_TYPE_IPV4,
157 .priority = CONNMAN_DRIVER_PRIORITY_LOW,
159 .remove = ipv4_remove,
162 int __connman_ipv4_init(void)
166 return connman_driver_register(&ipv4_driver);
169 void __connman_ipv4_cleanup(void)
171 connman_driver_unregister(&ipv4_driver);