2008-04-15 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-device-802-3-ethernet.h"
39 #include "nm-device-802-11-wireless.h"
40 #include "nm-utils.h"
41
42 /*
43  * nm_generic_init
44  *
45  * Initializes the distribution-specific system backend
46  *
47  */
48 void nm_generic_init (void)
49 {
50         /* Kill any dhclients lying around */
51         nm_system_kill_all_dhcp_daemons ();
52 }
53
54 /*
55  * nm_generic_replace_default_route
56  *
57  * Replace default route with one via the current device
58  *
59  */
60 void
61 nm_generic_device_replace_default_route (const char *iface, guint32 gw, guint32 mss)
62 {
63         char *buf, *addr_str = NULL, *mss_str = NULL;
64
65         g_return_if_fail (iface != NULL);
66
67         if (gw > 0) {
68                 struct in_addr addr = { .s_addr = gw };
69                 char buf2[INET_ADDRSTRLEN + 1];
70
71                 memset (buf2, 0, sizeof (buf2));
72                 inet_ntop (AF_INET, &addr, buf2, INET_ADDRSTRLEN);      
73                 addr_str = g_strdup_printf ("via %s", buf2);
74         }
75
76         if (mss > 0)
77                 mss_str = g_strdup_printf ("advmss %d", mss);
78
79         buf = g_strdup_printf (IP_BINARY_PATH" route replace default %s %s dev %s",
80                                addr_str ? addr_str : "",
81                                mss_str ? mss_str : "",
82                                iface);
83         nm_spawn_process (buf);
84         g_free (buf);
85 }
86
87 /*
88  * nm_generic_device_add_route_via_device_with_iface
89  *
90  * Add route to the given device
91  *
92  */
93 void nm_generic_device_add_route_via_device_with_iface (const char *iface, const char *route)
94 {
95         char    *buf;
96
97         g_return_if_fail (iface != NULL);
98
99         /* Add default gateway */
100         buf = g_strdup_printf (IP_BINARY_PATH" route add %s dev %s", route, iface);
101         nm_spawn_process (buf);
102         g_free (buf);
103 }
104
105
106 /*
107  * nm_generic_device_flush_ip4_addresses
108  *
109  * Flush all network addresses associated with a network device
110  *
111  */
112 void nm_generic_device_flush_ip4_routes (NMDevice *dev)
113 {
114         g_return_if_fail (dev != NULL);
115
116         nm_system_device_flush_ip4_routes_with_iface (nm_device_get_iface (dev));
117 }
118
119 /*
120  * nm_generic_device_flush_ip4_routes_with_iface
121  *
122  * Flush all routes associated with a network device
123  *
124  */
125 void nm_generic_device_flush_ip4_routes_with_iface (const char *iface)
126 {
127         char    *buf;
128
129         g_return_if_fail (iface != NULL);
130
131         /* Remove routing table entries */
132         buf = g_strdup_printf (IP_BINARY_PATH" -4 route flush dev %s", iface);
133         nm_spawn_process (buf);
134         g_free (buf);
135 }
136
137 /*
138  * nm_generic_device_flush_ip4_addresses
139  *
140  * Flush all network addresses associated with a network device
141  *
142  */
143 void nm_generic_device_flush_ip4_addresses (NMDevice *dev)
144 {
145         g_return_if_fail (dev != NULL);
146
147         nm_system_device_flush_ip4_addresses_with_iface (nm_device_get_iface (dev));
148 }
149
150
151 /*
152  * nm_generic_device_flush_ip4_addresses_with_iface
153  *
154  * Flush all network addresses associated with a network device
155  *
156  */
157 void nm_generic_device_flush_ip4_addresses_with_iface (const char *iface)
158 {
159         char    *buf;
160
161         g_return_if_fail (iface != NULL);
162
163         /* Remove all IP addresses for a device */
164         buf = g_strdup_printf (IP_BINARY_PATH" -4 addr flush dev %s", iface);
165         nm_spawn_process (buf);
166         g_free (buf);
167 }
168
169 /*
170  * nm_generic_enable_loopback
171  *
172  * Bring up the loopback interface
173  *
174  */
175 void nm_generic_enable_loopback (void)
176 {
177         nm_spawn_process (IP_BINARY_PATH" link set dev lo up");
178         nm_spawn_process (IP_BINARY_PATH" addr add 127.0.0.1/8 brd 127.255.255.255 dev lo scope host label lo");
179 }
180
181
182 /*
183  * nm_generic_flush_loopback_routes
184  *
185  * Flush all routes associated with the loopback device, because it
186  * sometimes gets the first route for ZeroConf/Link-Local traffic.
187  *
188  */
189 void nm_generic_flush_loopback_routes (void)
190 {
191         nm_system_device_flush_ip4_routes_with_iface ("lo");
192 }
193
194
195 /*
196  * nm_generic_flush_arp_cache
197  *
198  * Flush all entries in the arp cache.
199  *
200  */
201 void nm_generic_flush_arp_cache (void)
202 {
203         nm_spawn_process (IP_BINARY_PATH" neigh flush all");
204 }
205
206
207 /*
208  * nm_generic_kill_all_dhcp_daemons
209  *
210  * Kill all DHCP daemons currently running, done at startup.
211  *
212  */
213 void nm_generic_kill_all_dhcp_daemons (void)
214 {
215 }
216
217
218 /*
219  * nm_generic_update_dns
220  *
221  * Make glibc/nscd aware of any changes to the resolv.conf file by
222  * restarting nscd.
223  *
224  */
225 void nm_generic_update_dns (void)
226 {
227 }
228
229
230 /*
231  * nm_generic_restart_mdns_responder
232  *
233  * Restart the multicast DNS responder so that it knows about new
234  * network interfaces and IP addresses.
235  *
236  */
237 void nm_generic_restart_mdns_responder (void)
238 {
239 }
240
241 /*
242  * nm_generic_set_ip4_config_from_resolv_conf
243  *
244  * Add nameservers and search names from a resolv.conf format file.
245  *
246  */
247 void nm_generic_set_ip4_config_from_resolv_conf (const char *filename, NMIP4Config *ip4_config)
248 {
249         char *  contents = NULL;
250         char ** split_contents = NULL;
251         int             i, len;
252
253         g_return_if_fail (filename != NULL);
254         g_return_if_fail (ip4_config != NULL);
255
256         if (!g_file_get_contents (filename, &contents, NULL, NULL) || (contents == NULL))
257                 return;
258
259         if (!(split_contents = g_strsplit (contents, "\n", 0)))
260                 goto out;
261         
262         len = g_strv_length (split_contents);
263         for (i = 0; i < len; i++)
264         {
265                 char *line = split_contents[i];
266
267                 /* Ignore comments */
268                 if (!line || (line[0] == ';') || (line[0] == '#'))
269                         continue;
270
271                 line = g_strstrip (line);
272                 if ((strncmp (line, "search", 6) == 0) && (strlen (line) > 6))
273                 {
274                         char *searches = g_strdup (line + 7);
275                         char **split_searches = NULL;
276
277                         if (!searches || !strlen (searches))
278                                 continue;
279
280                         /* Allow space-separated search domains */
281                         if ((split_searches = g_strsplit (searches, " ", 0)))
282                         {
283                                 int m, srch_len;
284
285                                 srch_len = g_strv_length (split_searches);
286                                 for (m = 0; m < srch_len; m++)
287                                 {
288                                         if (split_searches[m])
289                                                 nm_ip4_config_add_domain        (ip4_config, split_searches[m]);
290                                 }
291                                 g_strfreev (split_searches);
292                         }
293                         else
294                         {
295                                 /* Only 1 item, add the whole line */
296                                 nm_ip4_config_add_domain        (ip4_config, searches);
297                         }
298
299                         g_free (searches);
300                 }
301                 else if ((strncmp (line, "nameserver", 10) == 0) && (strlen (line) > 10))
302                 {
303                         guint32 addr = (guint32) (inet_addr (line + 11));
304
305                         if (addr != (guint32) -1)
306                                 nm_ip4_config_add_nameserver (ip4_config, addr);
307                 }
308         }
309
310         g_strfreev (split_contents);
311
312 out:
313         g_free (contents);
314 }
315
316
317 /*
318  * nm_generic_device_get_system_config
319  *
320  * Retrieve any relevant configuration info for a particular device
321  * from the system network configuration information.  Clear out existing
322  * info before setting stuff too.
323  *
324  */
325 void* nm_generic_device_get_system_config (NMDevice *dev)
326 {
327         return NULL;
328 }
329
330 /*
331  * nm_generic_device_free_system_config
332  *
333  * Free stored system config data
334  *
335  */
336 void nm_generic_device_free_system_config (NMDevice *dev, void *system_config_data)
337 {
338         return;
339 }
340
341
342 /*
343  * nm_generic_device_get_disabled
344  *
345  * Return whether the distro-specific system config tells us to use
346  * dhcp for this device.
347  *
348  */
349 gboolean nm_generic_device_get_disabled (NMDevice *dev)
350 {
351         return FALSE;
352 }
353
354
355 NMIP4Config *nm_generic_device_new_ip4_system_config (NMDevice *dev)
356 {
357         return NULL;
358 }
359
360 /*
361  * nm_generic_activate_nis
362  *
363  * set up the nis domain and write a yp.conf
364  *
365  */
366 void nm_generic_activate_nis (NMIP4Config *config)
367 {
368 }
369
370 /*
371  * nm_generic_shutdown_nis
372  *
373  * shutdown ypbind
374  *
375  */
376 void nm_generic_shutdown_nis (void)
377 {
378 }
379
380 /*
381  * nm_generic_set_hostname
382  *
383  * set the hostname
384  *
385  */
386 void nm_generic_set_hostname (NMIP4Config *config)
387 {
388 }
389
390 /*
391  * nm_generic_should_modify_resolv_conf
392  *
393  * Can NM update resolv.conf, or is it locked down?
394  */
395 gboolean nm_generic_should_modify_resolv_conf (void)
396 {
397         return TRUE;
398 }
399