3 (c) 2010 Gregor Riepl <onitake@gmail.com>
5 Tethering utility for Maemo
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 3 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <netinet/in.h>
25 #define MTETHERD_DEVICE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_MTETHERD_DEVICE, MTetherDDevicePrivate))
27 G_DEFINE_TYPE(MTetherDDevice, mtetherd_device, G_TYPE_OBJECT);
29 // Host order 192.168.255.0
30 static const in_addr_t HOST_BASE_ADDRESS = 0xc0a8ff00;
31 // Host order 255.255.255.252
32 static const in_addr_t HOST_NETMASK = 0xfffffffc;
34 static const in_addr_t HOST_ROUTER = 0x00000002;
36 static const in_addr_t HOST_DHCP = 0x00000001;
38 struct _MTetherDDevicePrivate {
48 static void mtetherd_device_finalize(GObject *object) {
49 MTetherDDevice *self = MTETHERD_DEVICE(object);
51 if (self && self->priv) {
52 g_free(self->priv->interface);
53 g_free(self->priv->udi);
57 static void mtetherd_device_class_init(MTetherDDeviceClass *klass) {
58 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
60 gobject_class->finalize = mtetherd_device_finalize;
61 g_type_class_add_private(klass, sizeof(MTetherDDevicePrivate));
64 static void mtetherd_device_init(MTetherDDevice *self) {
65 self->priv = MTETHERD_DEVICE_GET_PRIVATE(self);
68 self->priv->interface = NULL;
69 self->priv->udi = NULL;
71 self->priv->netmask = 0;
72 self->priv->dhcp_start = 0;
73 self->priv->dhcp_end = 0;
77 static void mtetherd_device_set_interface(MTetherDDevice *self, const gchar *interface) {
79 if (self->priv->interface) {
80 g_free(self->priv->interface);
83 size_t len = strlen(interface);
84 self->priv->interface = g_malloc(len + 1);
86 for (i = 0, j = 0; i < len; i++) {
87 if (g_ascii_isalnum(interface[i])) {
88 self->priv->interface[j] = interface[i];
92 self->priv->interface[j] = '\0';
97 static void mtetherd_device_set_udi(MTetherDDevice *self, const gchar *udi) {
99 if (self->priv->udi) {
100 g_free(self->priv->udi);
103 size_t len = strlen(udi);
104 self->priv->udi = g_malloc(len + 1);
106 for (i = 0, j = 0; i < len; i++) {
107 if (g_ascii_isalnum(udi[i]) || g_ascii_ispunct(udi[i])) {
108 self->priv->udi[j] = udi[i];
112 self->priv->udi[j] = '\0';
117 static void mtetherd_device_set_index(MTetherDDevice *self, guint index) {
118 if (self && self->priv) {
119 // Maximum is 63, we need four addresses per subnet
121 in_addr_t subnet = HOST_BASE_ADDRESS | (index << 2);
122 in_addr_t addr = subnet | HOST_ROUTER;
123 in_addr_t start = subnet | HOST_DHCP;
124 self->priv->addr = htonl(addr);
125 self->priv->netmask = htonl(HOST_NETMASK);
126 self->priv->dhcp_start = htonl(start);
127 self->priv->dhcp_end = htonl(addr);
129 g_warning("Invalid subnet index: %u (0..63 expected)", index);
134 MTetherDDevice *mtetherd_device_new(const gchar *interface, const gchar *udi, guint index) {
135 MTetherDDevice *self = MTETHERD_DEVICE(g_object_new(TYPE_MTETHERD_DEVICE, NULL));
137 if (self && self->priv) {
138 mtetherd_device_set_interface(self, interface);
139 mtetherd_device_set_udi(self, udi);
140 mtetherd_device_set_index(self, index);
146 static gint mtetherd_device_find_udi(gconstpointer a, gconstpointer b) {
147 const MTetherDDevice *self = MTETHERD_DEVICE(a);
148 const gchar *udi = (const gchar *) b;
151 if (g_strcmp0(self->priv->udi, udi) == 0) {
158 MTetherDDevice *mtetherd_device_find(GList *list, const gchar *udi) {
159 GList *entry = g_list_find_custom(list, udi, mtetherd_device_find_udi);
161 return MTETHERD_DEVICE(entry->data);