2007-08-28 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 "NetworkManagerGeneric.h"
33 #include "NetworkManagerSystem.h"
34 #include "NetworkManagerUtils.h"
35 #include "nm-device.h"
36 #include "nm-device-802-3-ethernet.h"
37 #include "nm-device-802-11-wireless.h"
38 #include "nm-utils.h"
39
40 /*
41  * nm_generic_init
42  *
43  * Initializes the distribution-specific system backend
44  *
45  */
46 void nm_generic_init (void)
47 {
48         /* Kill any dhclients lying around */
49         nm_system_kill_all_dhcp_daemons ();
50 }
51
52 /*
53  * nm_generic_device_add_default_route_via_device
54  *
55  * Add default route to the given device
56  *
57  */
58 void nm_generic_device_add_default_route_via_device (NMDevice *dev)
59 {
60         g_return_if_fail (dev != NULL);
61
62         nm_system_device_add_default_route_via_device_with_iface (nm_device_get_iface (dev));
63 }
64
65
66 /*
67  * nm_generic_device_add_default_route_via_device_with_iface
68  *
69  * Add default route to the given device
70  *
71  */
72 void nm_generic_device_add_default_route_via_device_with_iface (const char *iface)
73 {
74         char    *buf;
75
76         g_return_if_fail (iface != NULL);
77
78         /* Add default gateway */
79         buf = g_strdup_printf (IP_BINARY_PATH" route add default dev %s", iface);
80         nm_spawn_process (buf);
81         g_free (buf);
82 }
83
84 /*
85  * nm_generic_device_add_route_via_device_with_iface
86  *
87  * Add route to the given device
88  *
89  */
90 void nm_generic_device_add_route_via_device_with_iface (const char *iface, const char *route)
91 {
92         char    *buf;
93
94         g_return_if_fail (iface != NULL);
95
96         /* Add default gateway */
97         buf = g_strdup_printf (IP_BINARY_PATH" route add %s dev %s", route, iface);
98         nm_spawn_process (buf);
99         g_free (buf);
100 }
101
102
103 /*
104  * nm_generic_device_flush_addresses
105  *
106  * Flush all network addresses associated with a network device
107  *
108  */
109 void nm_generic_device_flush_routes (NMDevice *dev)
110 {
111         g_return_if_fail (dev != NULL);
112
113         nm_system_device_flush_routes_with_iface (nm_device_get_iface (dev));
114 }
115
116 /*
117  * nm_generic_device_flush_routes_with_iface
118  *
119  * Flush all routes associated with a network device
120  *
121  */
122 void nm_generic_device_flush_routes_with_iface (const char *iface)
123 {
124         char    *buf;
125
126         g_return_if_fail (iface != NULL);
127
128         /* Remove routing table entries */
129         buf = g_strdup_printf (IP_BINARY_PATH" route flush dev %s", iface);
130         nm_spawn_process (buf);
131         g_free (buf);
132 }
133
134 /*
135  * nm_generic_device_flush_addresses
136  *
137  * Flush all network addresses associated with a network device
138  *
139  */
140 void nm_generic_device_flush_addresses (NMDevice *dev)
141 {
142         g_return_if_fail (dev != NULL);
143
144         nm_system_device_flush_addresses_with_iface (nm_device_get_iface (dev));
145 }
146
147
148 /*
149  * nm_generic_device_flush_addresses_with_iface
150  *
151  * Flush all network addresses associated with a network device
152  *
153  */
154 void nm_generic_device_flush_addresses_with_iface (const char *iface)
155 {
156         char    *buf;
157
158         g_return_if_fail (iface != NULL);
159
160         /* Remove all IP addresses for a device */
161         buf = g_strdup_printf (IP_BINARY_PATH" addr flush dev %s", iface);
162         nm_spawn_process (buf);
163         g_free (buf);
164 }
165
166 /*
167  * nm_generic_enable_loopback
168  *
169  * Bring up the loopback interface
170  *
171  */
172 void nm_generic_enable_loopback (void)
173 {
174         nm_spawn_process (IP_BINARY_PATH" link set dev lo up");
175         nm_spawn_process (IP_BINARY_PATH" addr add 127.0.0.1/8 brd 127.255.255.255 dev lo scope host label loopback");
176 }
177
178
179 /*
180  * nm_generic_flush_loopback_routes
181  *
182  * Flush all routes associated with the loopback device, because it
183  * sometimes gets the first route for ZeroConf/Link-Local traffic.
184  *
185  */
186 void nm_generic_flush_loopback_routes (void)
187 {
188         nm_system_device_flush_routes_with_iface ("lo");
189 }
190
191
192 /*
193  * nm_generic_delete_default_route
194  *
195  * Remove the old default route in preparation for a new one
196  *
197  */
198 void nm_generic_delete_default_route (void)
199 {
200         nm_spawn_process (IP_BINARY_PATH" route del default");
201 }
202
203
204 /*
205  * nm_generic_flush_arp_cache
206  *
207  * Flush all entries in the arp cache.
208  *
209  */
210 void nm_generic_flush_arp_cache (void)
211 {
212         nm_spawn_process (IP_BINARY_PATH" neigh flush all");
213 }
214
215
216 /*
217  * nm_generic_kill_all_dhcp_daemons
218  *
219  * Kill all DHCP daemons currently running, done at startup.
220  *
221  */
222 void nm_generic_kill_all_dhcp_daemons (void)
223 {
224 }
225
226
227 /*
228  * nm_generic_update_dns
229  *
230  * Make glibc/nscd aware of any changes to the resolv.conf file by
231  * restarting nscd.
232  *
233  */
234 void nm_generic_update_dns (void)
235 {
236 }
237
238
239 /*
240  * nm_generic_restart_mdns_responder
241  *
242  * Restart the multicast DNS responder so that it knows about new
243  * network interfaces and IP addresses.
244  *
245  */
246 void nm_generic_restart_mdns_responder (void)
247 {
248 }
249
250
251 /*
252  * nm_generic_device_add_ip6_link_address
253  *
254  * Add a default link-local IPv6 address to a device.
255  *
256  */
257 void nm_generic_device_add_ip6_link_address (NMDevice *dev)
258 {
259         char *buf;
260         struct ether_addr hw_addr;
261         unsigned char eui[8];
262
263         if (NM_IS_DEVICE_802_3_ETHERNET (dev))
264                 nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &hw_addr);
265         else if (NM_IS_DEVICE_802_11_WIRELESS (dev))
266                 nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &hw_addr);
267
268         memcpy (eui, &(hw_addr.ether_addr_octet), sizeof (hw_addr.ether_addr_octet));
269         memmove(eui+5, eui+3, 3);
270         eui[3] = 0xff;
271         eui[4] = 0xfe;
272         eui[0] ^= 2;
273
274         /* Add the default link-local IPv6 address to a device */
275         buf = g_strdup_printf (IP_BINARY_PATH" -6 addr add fe80::%x%02x:%x%02x:%x%02x:%x%02x/64 dev %s",
276                          eui[0], eui[1], eui[2], eui[3],
277                          eui[4], eui[5],
278                          eui[6], eui[7], nm_device_get_iface (dev));
279         nm_spawn_process (buf);
280         g_free (buf);
281 }
282
283 /*
284  * nm_generic_set_ip4_config_from_resolv_conf
285  *
286  * Add nameservers and search names from a resolv.conf format file.
287  *
288  */
289 void nm_generic_set_ip4_config_from_resolv_conf (const char *filename, NMIP4Config *ip4_config)
290 {
291         char *  contents = NULL;
292         char ** split_contents = NULL;
293         int             i, len;
294
295         g_return_if_fail (filename != NULL);
296         g_return_if_fail (ip4_config != NULL);
297
298         if (!g_file_get_contents (filename, &contents, NULL, NULL) || (contents == NULL))
299                 return;
300
301         if (!(split_contents = g_strsplit (contents, "\n", 0)))
302                 goto out;
303         
304         len = g_strv_length (split_contents);
305         for (i = 0; i < len; i++)
306         {
307                 char *line = split_contents[i];
308
309                 /* Ignore comments */
310                 if (!line || (line[0] == ';') || (line[0] == '#'))
311                         continue;
312
313                 line = g_strstrip (line);
314                 if ((strncmp (line, "search", 6) == 0) && (strlen (line) > 6))
315                 {
316                         char *searches = g_strdup (line + 7);
317                         char **split_searches = NULL;
318
319                         if (!searches || !strlen (searches))
320                                 continue;
321
322                         /* Allow space-separated search domains */
323                         if ((split_searches = g_strsplit (searches, " ", 0)))
324                         {
325                                 int m, srch_len;
326
327                                 srch_len = g_strv_length (split_searches);
328                                 for (m = 0; m < srch_len; m++)
329                                 {
330                                         if (split_searches[m])
331                                                 nm_ip4_config_add_domain        (ip4_config, split_searches[m]);
332                                 }
333                                 g_strfreev (split_searches);
334                         }
335                         else
336                         {
337                                 /* Only 1 item, add the whole line */
338                                 nm_ip4_config_add_domain        (ip4_config, searches);
339                         }
340
341                         g_free (searches);
342                 }
343                 else if ((strncmp (line, "nameserver", 10) == 0) && (strlen (line) > 10))
344                 {
345                         guint32 addr = (guint32) (inet_addr (line + 11));
346
347                         if (addr != (guint32) -1)
348                                 nm_ip4_config_add_nameserver (ip4_config, addr);
349                 }
350         }
351
352         g_strfreev (split_contents);
353
354 out:
355         g_free (contents);
356 }
357
358
359 /*
360  * nm_generic_device_get_system_config
361  *
362  * Retrieve any relevant configuration info for a particular device
363  * from the system network configuration information.  Clear out existing
364  * info before setting stuff too.
365  *
366  */
367 void* nm_generic_device_get_system_config (NMDevice *dev)
368 {
369         return NULL;
370 }
371
372 /*
373  * nm_generic_device_free_system_config
374  *
375  * Free stored system config data
376  *
377  */
378 void nm_generic_device_free_system_config (NMDevice *dev, void *system_config_data)
379 {
380         return;
381 }
382
383
384 /*
385  * nm_generic_device_get_use_dhcp
386  *
387  * Return whether the distro-specific system config tells us to use
388  * dhcp for this device.
389  *
390  */
391 gboolean nm_generic_device_get_use_dhcp (NMDevice *dev)
392 {
393         return TRUE;
394 }
395
396
397 /*
398  * nm_generic_device_get_disabled
399  *
400  * Return whether the distro-specific system config tells us to use
401  * dhcp for this device.
402  *
403  */
404 gboolean nm_generic_device_get_disabled (NMDevice *dev)
405 {
406         return FALSE;
407 }
408
409
410 NMIP4Config *nm_generic_device_new_ip4_system_config (NMDevice *dev)
411 {
412         return NULL;
413 }
414
415 void nm_generic_deactivate_all_dialup (GSList *list)
416 {
417 }
418
419 gboolean nm_generic_deactivate_dialup (GSList *list, const char *dialup)
420 {
421         return FALSE;
422 }
423
424 gboolean nm_generic_activate_dialup (GSList *list, const char *dialup)
425 {
426         return FALSE;
427 }
428
429 GSList * nm_generic_get_dialup_config (void)
430 {
431         return NULL;
432 }
433
434 /*
435  * nm_generic_activate_nis
436  *
437  * set up the nis domain and write a yp.conf
438  *
439  */
440 void nm_generic_activate_nis (NMIP4Config *config)
441 {
442 }
443
444 /*
445  * nm_generic_shutdown_nis
446  *
447  * shutdown ypbind
448  *
449  */
450 void nm_generic_shutdown_nis (void)
451 {
452 }
453
454 /*
455  * nm_generic_set_hostname
456  *
457  * set the hostname
458  *
459  */
460 void nm_generic_set_hostname (NMIP4Config *config)
461 {
462 }
463
464 /*
465  * nm_generic_should_modify_resolv_conf
466  *
467  * Can NM update resolv.conf, or is it locked down?
468  */
469 gboolean nm_generic_should_modify_resolv_conf (void)
470 {
471         return TRUE;
472 }
473
474
475 /*
476  * nm_generic_get_mtu
477  *
478  * Return a user-provided or system-mandated MTU for this device or zero if
479  * no such MTU is provided.
480  */
481 guint32 nm_generic_get_mtu (NMDevice *dev)
482 {
483         return 0;
484 }