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 char *index2name(int index)
47 sk = socket(PF_INET, SOCK_DGRAM, 0);
51 memset(&ifr, 0, sizeof(ifr));
52 ifr.ifr_ifindex = index;
54 err = ioctl(sk, SIOCGIFNAME, &ifr);
61 return strdup(ifr.ifr_name);
64 static int ipv4_probe(struct connman_element *element)
66 struct connman_service *service;
67 struct connman_ipconfig *ipconfig;
68 struct connman_element *connection;
69 const char *address = NULL, *netmask = NULL, *broadcast = NULL;
70 const char *peer = NULL, *nameserver = NULL, *pac = NULL;
71 char *timeserver = NULL;
72 unsigned char prefixlen;
74 DBG("element %p name %s", element, element->name);
75 connman_element_get_value(element,
76 CONNMAN_PROPERTY_ID_IPV4_ADDRESS, &address);
77 connman_element_get_value(element,
78 CONNMAN_PROPERTY_ID_IPV4_NETMASK, &netmask);
79 connman_element_get_value(element,
80 CONNMAN_PROPERTY_ID_IPV4_BROADCAST, &broadcast);
81 connman_element_get_value(element,
82 CONNMAN_PROPERTY_ID_IPV4_PEER, &peer);
84 connman_element_get_value(element,
85 CONNMAN_PROPERTY_ID_IPV4_NAMESERVER, &nameserver);
86 connman_element_get_value(element,
87 CONNMAN_PROPERTY_ID_IPV4_TIMESERVER, ×erver);
88 connman_element_get_value(element,
89 CONNMAN_PROPERTY_ID_IPV4_PAC, &pac);
91 DBG("address %s", address);
93 DBG("netmask %s", netmask);
94 DBG("broadcast %s", broadcast);
99 prefixlen = __connman_ipconfig_netmask_prefix_len(netmask);
101 if ((__connman_inet_modify_address(RTM_NEWADDR,
102 NLM_F_REPLACE | NLM_F_ACK, element->index,
103 AF_INET, address, peer, prefixlen, broadcast)) < 0)
104 DBG("address setting failed");
106 service = __connman_element_get_service(element);
109 __connman_service_set_proxy_autoconfig(service, pac);
111 if (nameserver != NULL)
112 __connman_service_append_nameserver(service, nameserver);
114 connman_timeserver_append(timeserver);
116 connection = connman_element_create(NULL);
118 connection->type = CONNMAN_ELEMENT_TYPE_CONNECTION;
119 connection->index = element->index;
120 connection->devname = index2name(element->index);
122 ipconfig = __connman_service_get_ipconfig(service);
123 if (ipconfig != NULL)
124 __connman_ipconfig_set_element_ipv6_gateway(
125 ipconfig, connection);
127 if (connman_element_register(connection, element) < 0)
128 connman_element_unref(connection);
133 static void ipv4_remove(struct connman_element *element)
135 const char *address = NULL, *netmask = NULL, *broadcast = NULL;
136 const char *peer = NULL, *nameserver = NULL;
137 char *timeserver = NULL;
138 unsigned char prefixlen;
140 DBG("element %p name %s", element, element->name);
142 connman_element_get_value(element,
143 CONNMAN_PROPERTY_ID_IPV4_ADDRESS, &address);
144 connman_element_get_value(element,
145 CONNMAN_PROPERTY_ID_IPV4_NETMASK, &netmask);
146 connman_element_get_value(element,
147 CONNMAN_PROPERTY_ID_IPV4_BROADCAST, &broadcast);
148 connman_element_get_value(element,
149 CONNMAN_PROPERTY_ID_IPV4_PEER, &peer);
151 connman_element_get_value(element,
152 CONNMAN_PROPERTY_ID_IPV4_NAMESERVER, &nameserver);
153 connman_element_get_value(element,
154 CONNMAN_PROPERTY_ID_IPV4_TIMESERVER, ×erver);
156 connman_timeserver_remove(timeserver);
158 DBG("address %s", address);
159 DBG("peer %s", peer);
160 DBG("netmask %s", netmask);
161 DBG("broadcast %s", broadcast);
163 if (nameserver != NULL) {
164 struct connman_service *service;
166 service = __connman_element_get_service(element);
167 __connman_service_remove_nameserver(service, nameserver);
170 prefixlen = __connman_ipconfig_netmask_prefix_len(netmask);
172 if ((__connman_inet_modify_address(RTM_DELADDR, 0, element->index,
173 AF_INET, address, peer, prefixlen, broadcast) < 0))
174 DBG("address removal failed");
177 static struct connman_driver ipv4_driver = {
179 .type = CONNMAN_ELEMENT_TYPE_IPV4,
180 .priority = CONNMAN_DRIVER_PRIORITY_LOW,
182 .remove = ipv4_remove,
185 int __connman_ipv4_init(void)
187 return connman_driver_register(&ipv4_driver);
190 void __connman_ipv4_cleanup(void)
192 connman_driver_unregister(&ipv4_driver);