Update copyright information
[connman] / plugins / ethernet.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
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 version 2 as
9  *  published by the Free Software Foundation.
10  *
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.
15  *
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
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <errno.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <sys/ioctl.h>
30 #include <sys/socket.h>
31 #include <linux/if.h>
32 #include <linux/netlink.h>
33 #include <linux/rtnetlink.h>
34
35 #include <glib.h>
36
37 #define CONNMAN_API_SUBJECT_TO_CHANGE
38 #include <connman/plugin.h>
39 #include <connman/device.h>
40 #include <connman/rtnl.h>
41 #include <connman/log.h>
42
43 #include "inet.h"
44
45 struct ethernet_data {
46         int index;
47         unsigned flags;
48 };
49
50 static GSList *ethernet_list = NULL;
51
52 static void ethernet_newlink(unsigned short type, int index,
53                                         unsigned flags, unsigned change)
54 {
55         GSList *list;
56
57         DBG("index %d flags %ld change %ld", index, flags, change);
58
59         for (list = ethernet_list; list; list = list->next) {
60                 struct connman_device *device = list->data;
61                 struct ethernet_data *ethernet;
62
63                 ethernet = connman_device_get_data(device);
64                 if (ethernet == NULL)
65                         continue;
66
67                 if (ethernet->index != index)
68                         continue;
69
70                 if ((ethernet->flags & IFF_UP) != (flags & IFF_UP)) {
71                         if (flags & IFF_UP) {
72                                 DBG("power on");
73                                 connman_device_set_powered(device, TRUE);
74                         } else {
75                                 DBG("power off");
76                                 connman_device_set_powered(device, FALSE);
77                         }
78                 }
79
80                 if ((ethernet->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
81                         if (flags & IFF_LOWER_UP) {
82                                 DBG("carrier on");
83                                 connman_device_set_carrier(device, TRUE);
84                         } else {
85                                 DBG("carrier off");
86                                 connman_device_set_carrier(device, FALSE);
87                         }
88                 }
89
90                 ethernet->flags = flags;
91         }
92 }
93
94 static struct connman_rtnl ethernet_rtnl = {
95         .name           = "ethernet",
96         .newlink        = ethernet_newlink,
97 };
98
99 static int ethernet_probe(struct connman_device *device)
100 {
101         struct ethernet_data *ethernet;
102
103         DBG("device %p", device);
104
105         ethernet = g_try_new0(struct ethernet_data, 1);
106         if (ethernet == NULL)
107                 return -ENOMEM;
108
109         ethernet_list = g_slist_append(ethernet_list, device);
110
111         connman_device_set_data(device, ethernet);
112
113         ethernet->index = connman_device_get_index(device);
114
115         connman_rtnl_send_getlink();
116
117         return 0;
118 }
119
120 static void ethernet_remove(struct connman_device *device)
121 {
122         struct ethernet_data *ethernet = connman_device_get_data(device);
123
124         DBG("device %p", device);
125
126         connman_device_set_data(device, NULL);
127
128         ethernet_list = g_slist_remove(ethernet_list, device);
129
130         g_free(ethernet);
131 }
132
133 static int ethernet_enable(struct connman_device *device)
134 {
135         struct ethernet_data *ethernet = connman_device_get_data(device);
136
137         DBG("device %p", device);
138
139         return inet_ifup(ethernet->index);
140 }
141
142 static int ethernet_disable(struct connman_device *device)
143 {
144         struct ethernet_data *ethernet = connman_device_get_data(device);
145
146         DBG("device %p", device);
147
148         return inet_ifdown(ethernet->index);
149 }
150
151 static struct connman_device_driver ethernet_driver = {
152         .name           = "ethernet",
153         .type           = CONNMAN_DEVICE_TYPE_ETHERNET,
154         .probe          = ethernet_probe,
155         .remove         = ethernet_remove,
156         .enable         = ethernet_enable,
157         .disable        = ethernet_disable,
158 };
159
160 static int ethernet_init(void)
161 {
162         int err;
163
164         err = connman_rtnl_register(&ethernet_rtnl);
165         if (err < 0)
166                 return err;
167
168         err = connman_device_driver_register(&ethernet_driver);
169         if (err < 0) {
170                 connman_rtnl_unregister(&ethernet_rtnl);
171                 return err;
172         }
173
174         return 0;
175 }
176
177 static void ethernet_exit(void)
178 {
179         connman_device_driver_unregister(&ethernet_driver);
180
181         connman_rtnl_unregister(&ethernet_rtnl);
182 }
183
184 CONNMAN_PLUGIN_DEFINE(ethernet, "Ethernet interface plugin", VERSION,
185                                                 ethernet_init, ethernet_exit)