2 * firewall3 - 3rd OpenWrt UCI firewall implementation
4 * Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 static struct ubus_context
*ctx
= NULL
;
25 fw3_ubus_connect(void)
27 ctx
= ubus_connect(NULL
);
32 fw3_ubus_disconnect(void)
41 static struct fw3_address
*
42 parse_subnet(enum fw3_family family
, struct blob_attr
*dict
, int rem
)
44 struct blob_attr
*cur
;
45 struct fw3_address
*addr
;
47 addr
= malloc(sizeof(*addr
));
52 memset(addr
, 0, sizeof(*addr
));
55 addr
->family
= family
;
57 __blob_for_each_attr(cur
, dict
, rem
)
59 if (!strcmp(blobmsg_name(cur
), "address"))
60 inet_pton(family
== FW3_FAMILY_V4
? AF_INET
: AF_INET6
,
61 blobmsg_data(cur
), &addr
->address
.v6
);
63 else if (!strcmp(blobmsg_name(cur
), "mask"))
64 addr
->mask
= be32_to_cpu(*(uint32_t *)blobmsg_data(cur
));
71 parse_subnets(struct list_head
*head
, enum fw3_family family
,
72 struct blob_attr
*list
, int rem
)
74 struct blob_attr
*cur
;
75 struct fw3_address
*addr
;
77 __blob_for_each_attr(cur
, list
, rem
)
79 addr
= parse_subnet(family
, blobmsg_data(cur
), blobmsg_data_len(cur
));
82 list_add_tail(&addr
->list
, head
);
88 struct fw3_device
*dev
;
89 struct list_head
*addr
;
93 invoke_cb(struct ubus_request
*req
, int type
, struct blob_attr
*msg
)
97 struct blob_attr
*cur
;
98 struct dev_addr
*da
= (struct dev_addr
*)req
->priv
;
99 struct fw3_device
*dev
= da
->dev
;
105 __blob_for_each_attr(cur
, blob_data(msg
), rem
)
107 data
= blobmsg_data(cur
);
109 if (dev
&& !strcmp(blobmsg_name(cur
), "device") && !dev
->name
[0])
110 snprintf(dev
->name
, sizeof(dev
->name
), "%s", data
);
111 else if (dev
&& !strcmp(blobmsg_name(cur
), "l3_device"))
112 snprintf(dev
->name
, sizeof(dev
->name
), "%s", data
);
113 else if (!dev
&& !strcmp(blobmsg_name(cur
), "ipv4-address"))
114 parse_subnets(da
->addr
, FW3_FAMILY_V4
,
115 blobmsg_data(cur
), blobmsg_data_len(cur
));
116 else if (!dev
&& (!strcmp(blobmsg_name(cur
), "ipv6-address") ||
117 !strcmp(blobmsg_name(cur
), "ipv6-prefix-assignment")))
118 parse_subnets(da
->addr
, FW3_FAMILY_V6
,
119 blobmsg_data(cur
), blobmsg_data_len(cur
));
123 dev
->set
= !!dev
->name
[0];
127 invoke_common(const char *net
, bool dev
)
131 static struct dev_addr da
;
136 memset(&da
, 0, sizeof(da
));
139 da
.dev
= malloc(sizeof(*da
.dev
));
141 da
.addr
= malloc(sizeof(*da
.addr
));
143 if ((dev
&& !da
.dev
) || (!dev
&& !da
.addr
))
147 memset(da
.dev
, 0, sizeof(*da
.dev
));
149 INIT_LIST_HEAD(da
.addr
);
151 snprintf(path
, sizeof(path
), "network.interface.%s", net
);
153 if (ubus_lookup_id(ctx
, path
, &id
))
156 if (ubus_invoke(ctx
, id
, "status", NULL
, invoke_cb
, &da
, 500))
159 if (dev
&& da
.dev
->set
)
161 else if (!dev
&& !list_empty(da
.addr
))
175 fw3_ubus_device(const char *net
)
177 return invoke_common(net
, true);
181 fw3_ubus_address(const char *net
)
183 return invoke_common(net
, false);
187 fw3_ubus_address_free(struct list_head
*list
)
189 struct fw3_address
*addr
, *tmp
;
191 list_for_each_entry_safe(addr
, tmp
, list
, list
)
193 list_del(&addr
->list
);