2008-06-10 Dan Williams <dcbw@redhat.com>
[NetworkManager.git] / src / backends / NetworkManagerGeneric.c
1 /* NetworkManager -- Network link manager
2  *
3  * Timothee Lecomte <timothee.lecomte@ens.fr>
4  *
5  * Heavily based on NetworkManagerRedhat.c by Dan Williams <dcbw@redhat.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  *
21  * (C) Copyright 2004 Red Hat, Inc.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <sys/types.h>
30 #include <signal.h>
31 #include <arpa/inet.h>
32 #include <string.h>
33
34 #include "NetworkManagerGeneric.h"
35 #include "NetworkManagerSystem.h"
36 #include "NetworkManagerUtils.h"
37 #include "nm-device.h"
38 #include "nm-utils.h"
39 #include "nm-netlink.h"
40
41 /* Because of a bug in libnl, rtnl.h should be included before route.h */
42 #include <netlink/route/rtnl.h>
43
44 #include <netlink/route/addr.h>
45 #include <netlink/netlink.h>
46
47 /*
48  * nm_generic_init
49  *
50  * Initializes the distribution-specific system backend
51  *
52  */
53 void nm_generic_init (void)
54 {
55         /* Kill any dhclients lying around */
56         nm_system_kill_all_dhcp_daemons ();
57 }
58
59 /*
60  * nm_generic_enable_loopback
61  *
62  * Bring up the loopback interface
63  *
64  */
65 void nm_generic_enable_loopback (void)
66 {
67         struct nl_handle *      nlh = NULL;
68         struct rtnl_addr *      addr = NULL;
69         struct nl_addr *        nl_addr = NULL;
70         guint32                 binaddr = 0;
71         int                     iface_idx = -1;
72         int                     err;
73
74         nm_system_device_set_up_down_with_iface ("lo", TRUE);
75
76         nlh = nm_netlink_get_default_handle ();
77         if (!nlh)
78                 return;
79
80         iface_idx = nm_netlink_iface_to_index ("lo");
81         if (iface_idx < 0)
82                 return;
83
84         addr = rtnl_addr_alloc ();
85         if (!addr)
86                 return;
87
88         binaddr = htonl (0x7f000001); /* 127.0.0.1 */
89         nl_addr = nl_addr_build (AF_INET, &binaddr, sizeof(binaddr));
90         if (!nl_addr)
91                 goto out;
92         rtnl_addr_set_local (addr, nl_addr);
93         nl_addr_put (nl_addr);
94
95         binaddr = htonl (0x7fffffff); /* 127.255.255.255 */
96         nl_addr = nl_addr_build (AF_INET, &binaddr, sizeof(binaddr));
97         if (!nl_addr)
98                 goto out;
99         rtnl_addr_set_broadcast (addr, nl_addr);
100         nl_addr_put (nl_addr);
101
102         rtnl_addr_set_prefixlen (addr, 8);
103         rtnl_addr_set_ifindex (addr, iface_idx);
104         rtnl_addr_set_scope (addr, RT_SCOPE_HOST);
105         rtnl_addr_set_label (addr, "lo");
106
107         if ((err = rtnl_addr_add (nlh, addr, 0)) < 0)
108                 nm_warning ("error %d returned from rtnl_addr_add():\n%s", err, nl_geterror());
109 out:
110         if (addr)
111                 rtnl_addr_put (addr);
112 }
113
114 /*
115  * nm_generic_kill_all_dhcp_daemons
116  *
117  * Kill all DHCP daemons currently running, done at startup.
118  *
119  */
120 void nm_generic_kill_all_dhcp_daemons (void)
121 {
122 }
123
124
125 /*
126  * nm_generic_update_dns
127  *
128  * Make glibc/nscd aware of any changes to the resolv.conf file by
129  * restarting nscd.
130  *
131  */
132 void nm_generic_update_dns (void)
133 {
134 }
135
136 /*
137  * nm_generic_set_ip4_config_from_resolv_conf
138  *
139  * Add nameservers and search names from a resolv.conf format file.
140  *
141  */
142 void nm_generic_set_ip4_config_from_resolv_conf (const char *filename, NMIP4Config *ip4_config)
143 {
144         char *  contents = NULL;
145         char ** split_contents = NULL;
146         int             i, len;
147
148         g_return_if_fail (filename != NULL);
149         g_return_if_fail (ip4_config != NULL);
150
151         if (!g_file_get_contents (filename, &contents, NULL, NULL) || (contents == NULL))
152                 return;
153
154         if (!(split_contents = g_strsplit (contents, "\n", 0)))
155                 goto out;
156         
157         len = g_strv_length (split_contents);
158         for (i = 0; i < len; i++)
159         {
160                 char *line = split_contents[i];
161
162                 /* Ignore comments */
163                 if (!line || (line[0] == ';') || (line[0] == '#'))
164                         continue;
165
166                 line = g_strstrip (line);
167                 if ((strncmp (line, "search", 6) == 0) && (strlen (line) > 6))
168                 {
169                         char *searches = g_strdup (line + 7);
170                         char **split_searches = NULL;
171
172                         if (!searches || !strlen (searches))
173                                 continue;
174
175                         /* Allow space-separated search domains */
176                         if ((split_searches = g_strsplit (searches, " ", 0)))
177                         {
178                                 int m, srch_len;
179
180                                 srch_len = g_strv_length (split_searches);
181                                 for (m = 0; m < srch_len; m++)
182                                 {
183                                         if (split_searches[m])
184                                                 nm_ip4_config_add_domain        (ip4_config, split_searches[m]);
185                                 }
186                                 g_strfreev (split_searches);
187                         }
188                         else
189                         {
190                                 /* Only 1 item, add the whole line */
191                                 nm_ip4_config_add_domain        (ip4_config, searches);
192                         }
193
194                         g_free (searches);
195                 }
196                 else if ((strncmp (line, "nameserver", 10) == 0) && (strlen (line) > 10))
197                 {
198                         guint32 addr = (guint32) (inet_addr (line + 11));
199
200                         if (addr != (guint32) -1)
201                                 nm_ip4_config_add_nameserver (ip4_config, addr);
202                 }
203         }
204
205         g_strfreev (split_contents);
206
207 out:
208         g_free (contents);
209 }
210
211
212 /*
213  * nm_generic_device_get_system_config
214  *
215  * Retrieve any relevant configuration info for a particular device
216  * from the system network configuration information.  Clear out existing
217  * info before setting stuff too.
218  *
219  */
220 void* nm_generic_device_get_system_config (NMDevice *dev)
221 {
222         return NULL;
223 }
224
225 /*
226  * nm_generic_device_free_system_config
227  *
228  * Free stored system config data
229  *
230  */
231 void nm_generic_device_free_system_config (NMDevice *dev, void *system_config_data)
232 {
233         return;
234 }
235
236
237 /*
238  * nm_generic_device_get_disabled
239  *
240  * Return whether the distro-specific system config tells us to use
241  * dhcp for this device.
242  *
243  */
244 gboolean nm_generic_device_get_disabled (NMDevice *dev)
245 {
246         return FALSE;
247 }
248
249
250 NMIP4Config *nm_generic_device_new_ip4_system_config (NMDevice *dev)
251 {
252         return NULL;
253 }
254
255 /*
256  * nm_generic_activate_nis
257  *
258  * set up the nis domain and write a yp.conf
259  *
260  */
261 void nm_generic_activate_nis (NMIP4Config *config)
262 {
263 }
264
265 /*
266  * nm_generic_shutdown_nis
267  *
268  * shutdown ypbind
269  *
270  */
271 void nm_generic_shutdown_nis (void)
272 {
273 }
274
275 /*
276  * nm_generic_set_hostname
277  *
278  * set the hostname
279  *
280  */
281 void nm_generic_set_hostname (NMIP4Config *config)
282 {
283 }
284
285 /*
286  * nm_generic_should_modify_resolv_conf
287  *
288  * Can NM update resolv.conf, or is it locked down?
289  */
290 gboolean nm_generic_should_modify_resolv_conf (void)
291 {
292         return TRUE;
293 }
294