2008-08-07 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 along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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_enable_loopback
49  *
50  * Bring up the loopback interface
51  *
52  */
53 void nm_generic_enable_loopback (void)
54 {
55         struct nl_handle *      nlh = NULL;
56         struct rtnl_addr *      addr = NULL;
57         struct nl_addr *        nl_addr = NULL;
58         guint32                 binaddr = 0;
59         int                     iface_idx = -1;
60         int                     err;
61
62         nm_system_device_set_up_down_with_iface ("lo", TRUE);
63
64         nlh = nm_netlink_get_default_handle ();
65         if (!nlh)
66                 return;
67
68         iface_idx = nm_netlink_iface_to_index ("lo");
69         if (iface_idx < 0)
70                 return;
71
72         addr = rtnl_addr_alloc ();
73         if (!addr)
74                 return;
75
76         binaddr = htonl (0x7f000001); /* 127.0.0.1 */
77         nl_addr = nl_addr_build (AF_INET, &binaddr, sizeof(binaddr));
78         if (!nl_addr)
79                 goto out;
80         rtnl_addr_set_local (addr, nl_addr);
81         nl_addr_put (nl_addr);
82
83         binaddr = htonl (0x7fffffff); /* 127.255.255.255 */
84         nl_addr = nl_addr_build (AF_INET, &binaddr, sizeof(binaddr));
85         if (!nl_addr)
86                 goto out;
87         rtnl_addr_set_broadcast (addr, nl_addr);
88         nl_addr_put (nl_addr);
89
90         rtnl_addr_set_prefixlen (addr, 8);
91         rtnl_addr_set_ifindex (addr, iface_idx);
92         rtnl_addr_set_scope (addr, RT_SCOPE_HOST);
93         rtnl_addr_set_label (addr, "lo");
94
95         if ((err = rtnl_addr_add (nlh, addr, 0)) < 0)
96                 nm_warning ("error %d returned from rtnl_addr_add():\n%s", err, nl_geterror());
97 out:
98         if (addr)
99                 rtnl_addr_put (addr);
100 }
101
102 /*
103  * nm_generic_update_dns
104  *
105  * Make glibc/nscd aware of any changes to the resolv.conf file by
106  * restarting nscd.
107  *
108  */
109 void nm_generic_update_dns (void)
110 {
111 }
112
113 /*
114  * nm_generic_set_ip4_config_from_resolv_conf
115  *
116  * Add nameservers and search names from a resolv.conf format file.
117  *
118  */
119 void nm_generic_set_ip4_config_from_resolv_conf (const char *filename, NMIP4Config *ip4_config)
120 {
121         char *  contents = NULL;
122         char ** split_contents = NULL;
123         int             i, len;
124
125         g_return_if_fail (filename != NULL);
126         g_return_if_fail (ip4_config != NULL);
127
128         if (!g_file_get_contents (filename, &contents, NULL, NULL) || (contents == NULL))
129                 return;
130
131         if (!(split_contents = g_strsplit (contents, "\n", 0)))
132                 goto out;
133         
134         len = g_strv_length (split_contents);
135         for (i = 0; i < len; i++)
136         {
137                 char *line = split_contents[i];
138
139                 /* Ignore comments */
140                 if (!line || (line[0] == ';') || (line[0] == '#'))
141                         continue;
142
143                 line = g_strstrip (line);
144                 if ((strncmp (line, "search", 6) == 0) && (strlen (line) > 6))
145                 {
146                         char *searches = g_strdup (line + 7);
147                         char **split_searches = NULL;
148
149                         if (!searches || !strlen (searches))
150                                 continue;
151
152                         /* Allow space-separated search domains */
153                         if ((split_searches = g_strsplit (searches, " ", 0)))
154                         {
155                                 int m, srch_len;
156
157                                 srch_len = g_strv_length (split_searches);
158                                 for (m = 0; m < srch_len; m++)
159                                 {
160                                         if (split_searches[m])
161                                                 nm_ip4_config_add_domain        (ip4_config, split_searches[m]);
162                                 }
163                                 g_strfreev (split_searches);
164                         }
165                         else
166                         {
167                                 /* Only 1 item, add the whole line */
168                                 nm_ip4_config_add_domain        (ip4_config, searches);
169                         }
170
171                         g_free (searches);
172                 }
173                 else if ((strncmp (line, "nameserver", 10) == 0) && (strlen (line) > 10))
174                 {
175                         guint32 addr = (guint32) (inet_addr (line + 11));
176
177                         if (addr != (guint32) -1)
178                                 nm_ip4_config_add_nameserver (ip4_config, addr);
179                 }
180         }
181
182         g_strfreev (split_contents);
183
184 out:
185         g_free (contents);
186 }
187
188
189 /*
190  * nm_generic_device_get_system_config
191  *
192  * Retrieve any relevant configuration info for a particular device
193  * from the system network configuration information.  Clear out existing
194  * info before setting stuff too.
195  *
196  */
197 void* nm_generic_device_get_system_config (NMDevice *dev)
198 {
199         return NULL;
200 }
201
202 /*
203  * nm_generic_device_free_system_config
204  *
205  * Free stored system config data
206  *
207  */
208 void nm_generic_device_free_system_config (NMDevice *dev, void *system_config_data)
209 {
210         return;
211 }
212
213
214 /*
215  * nm_generic_device_get_disabled
216  *
217  * Return whether the distro-specific system config tells us to use
218  * dhcp for this device.
219  *
220  */
221 gboolean nm_generic_device_get_disabled (NMDevice *dev)
222 {
223         return FALSE;
224 }
225
226
227 NMIP4Config *nm_generic_device_new_ip4_system_config (NMDevice *dev)
228 {
229         return NULL;
230 }
231
232 /*
233  * nm_generic_activate_nis
234  *
235  * set up the nis domain and write a yp.conf
236  *
237  */
238 void nm_generic_activate_nis (NMIP4Config *config)
239 {
240 }
241
242 /*
243  * nm_generic_shutdown_nis
244  *
245  * shutdown ypbind
246  *
247  */
248 void nm_generic_shutdown_nis (void)
249 {
250 }
251
252 /*
253  * nm_generic_set_hostname
254  *
255  * set the hostname
256  *
257  */
258 void nm_generic_set_hostname (NMIP4Config *config)
259 {
260 }
261
262 /*
263  * nm_generic_should_modify_resolv_conf
264  *
265  * Can NM update resolv.conf, or is it locked down?
266  */
267 gboolean nm_generic_should_modify_resolv_conf (void)
268 {
269         return TRUE;
270 }
271