Пример #1
1
// ubus call test_ubus helloworld '{"id":1,"msg":"hello","array":["a","b"]}' 
static int test_hello(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req,
	const char *method, struct blob_attr *msg)
{
	struct blob_attr *tb[__HELLO_MAX];
	int tmp_id;
	char *tmp_msg = NULL;
	int len;
	struct blob_attr *attr;
	void *arr;

	blobmsg_parse(hello_policy, __HELLO_MAX, tb, blob_data(msg), blob_len(msg));
	
	
	blob_buf_init(&b, 0);

	if(tb[HELLO_ID])
	{
		tmp_id = blobmsg_get_u32(tb[HELLO_ID]);
		blobmsg_add_u32(&b, "id", tmp_id); 
	}

	if(tb[HELLO_MSG])
	{
		tmp_msg = blobmsg_get_string(tb[HELLO_MSG]);
		blobmsg_add_string(&b, "msg", tmp_msg);
	}

	
	if(tb[HELLO_ARRAY] && blobmsg_type(tb[HELLO_ARRAY]) == BLOBMSG_TYPE_ARRAY)
	{
		arr = blobmsg_open_array(&b, "array");		
		len = blobmsg_data_len(tb[HELLO_ARRAY]);
		__blob_for_each_attr(attr, blobmsg_data(tb[HELLO_ARRAY]), len)
		{
			if (blobmsg_type(attr) == BLOBMSG_TYPE_STRING)
			{
				char *tmp = blobmsg_get_string(attr);
				blobmsg_add_blob(&b, attr);
				printf("array=%s\n", tmp);
			}
		}
		blobmsg_close_array(&b, arr);
	}
Пример #2
0
static int
handle_notify(struct ubus_context *ctx, struct ubus_object *obj,
		struct ubus_request_data *req, const char *method,
		struct blob_attr *msg)
{
	char *str;
	int msg_level;
	const char *info;

	struct blob_attr *tb[__MAN_ALERT_MAX];

	blobmsg_parse(alert_policy, ARRAY_SIZE(alert_policy), tb, blob_data(msg), blob_len(msg));

	if(!tb[MAN_ALERT_MSG_LEVEL] || !tb[MAN_ALERT_MSG_INFO]){
		fprintf(stderr, "Received illegal notification\n");
		return -1;
	}
	msg_level = blobmsg_get_u16(tb[MAN_ALERT_MSG_LEVEL]);
	info = blobmsg_get_string(tb[MAN_ALERT_MSG_INFO]);

/*
	str = blobmsg_format_json(msg, true);
	fprintf(stderr, "Received notification '%s': %s\n", method, str);
	free(str);
*/
	asyncResult->notify_cb( method, msg_level, info);	

	return 0;
}
Пример #3
0
/*
 *	add ports to aggregation group.
 *	msg : {"aggid":xxx,
 *			"ports": [
 *				{"portNumber":x},
 *				{"portNumber":x},
 *				{"portNumber":x}
 *			]
 *		  }
 * */
static int aggregation_add_port(struct ubus_context *ctx, struct ubus_object *obj,
		      struct ubus_request_data *req, const char *method,
		      struct blob_attr *msg)
{
	struct blob_attr *tb[__AGGREGATION_ADD_PORT_MAX];
	//struct blob_attr *tbPortList[__AGGREGATION_ADD_PORT_LIST_MAX];
	char *dev = NULL;
	int aggID;
	struct blob_attr *cur;
	int portCnt = 0;
	int rem;
	struct portAttr port;
	//TODO:

	blobmsg_parse(aggregation_add_port_policy, ARRAY_SIZE(aggregation_add_port_policy), tb, blob_data(msg), blob_len(msg));
	
	if(!tb[AGGREGATION_ADD_PORT_GROUP_ID] || !tb[AGGREGATION_ADD_PORT_PORTS])
		return UBUS_STATUS_INVALID_ARGUMENT;

	aggID = blobmsg_get_u32(tb[AGGREGATION_ADD_PORT_GROUP_ID]);
	

	if(tb[AGGREGATION_ADD_PORT_DEVICE])
		dev = blobmsg_get_string(tb[AGGREGATION_ADD_PORT_DEVICE]);

	cur = tb[AGGREGATION_ADD_PORT_GROUP_ID];

	blobmsg_for_each_attr(cur,tb[AGGREGATION_ADD_PORT_PORTS], rem) {
		//get port number
		get_port_attr(&port, cur);
	//	printf("%s, port = %x\n",__func__, port.number);
		// TODO: add port to aggid
	}
Пример #4
0
static void create_vlan_callback(struct ubus_request *req, int type, struct blob_attr *msg)
{
	char *str = NULL;
	struct Rmsg;
	struct blob_attr *tb[__FRAMEWORK_MAX];
	struct json_object *new_obj;

	blobmsg_parse(framework_result_policy, ARRAY_SIZE(framework_result_policy), tb, blob_data(msg), blob_len(msg));
	Rmsg.msg = blobmsg_get_string(tb[FRAMEWORK_RESULT_MSG]);
	Rmsg.resCode = (int)blobmsg_get_u16(tb[FRAMEWORK_RESULT_CODE]);

	new_obj = json_tokener_parse(Rmsg.msg);

	if(Rmsg.resCode == LR_ERR_NONE){
		/* success add new vlan entry */
		if(new_obj){
			struct json_object *o = json_object_object_get(new_obj,"vlanID");
			u16 vid = json_object_get_int(o);
			new_vlan_software(vid);
			json_object_put(o);
			json_object_put(new_obj);
			Rmsg.msg = "";
		}

	}
	if((asyncResult == NULL) || (asyncResult->result_data_cb == NULL)){
		str = blobmsg_format_json(msg, true);
		printf("%s\n",str);
		free(str);
	}else{
		asyncResult->result_data_cb(&Rmsg);
	}
}
Пример #5
0
static struct fw3_address *
parse_subnet(enum fw3_family family, struct blob_attr *dict, int rem)
{
	struct blob_attr *cur;
	struct fw3_address *addr;

	addr = calloc(1, sizeof(*addr));
	if (!addr)
		return NULL;

	addr->set = true;
	addr->family = family;

	__blob_for_each_attr(cur, dict, rem)
	{
		if (!strcmp(blobmsg_name(cur), "address"))
			inet_pton(family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
			          blobmsg_get_string(cur), &addr->address.v6);

		else if (!strcmp(blobmsg_name(cur), "mask"))
			fw3_bitlen2netmask(family, blobmsg_get_u32(cur), &addr->mask.v6);
	}

	return addr;
}
Пример #6
0
static void blobmsg_format_element(struct blob_attr *data, int next_indent)
{
	switch (blobmsg_type(data)) {
	case BLOBMSG_TYPE_UNSPEC:
		printf("null\n");
		break;
	case BLOBMSG_TYPE_STRING:
		printf("%s\n", blobmsg_get_string(data));
		break;
	case BLOBMSG_TYPE_BOOL:
		printf("%s\n", blobmsg_get_u8(data) ? "true" : "false");
		break;
	case BLOBMSG_TYPE_INT16:
		printf("%d\n", blobmsg_get_u16(data));
		break;
	case BLOBMSG_TYPE_INT32:
		printf("%d\n", blobmsg_get_u32(data));
		break;
	case BLOBMSG_TYPE_INT64:
		printf("%"PRIu64"\n", blobmsg_get_u64(data));
		break;
	case BLOBMSG_TYPE_TABLE:
	case BLOBMSG_TYPE_ARRAY:
		blobmsg_format_std_indent(data, next_indent);
		break;
	}
}
Пример #7
0
static int aggregation_create_group(struct ubus_context *ctx, struct ubus_object *obj,
		      struct ubus_request_data *req, const char *method,
		      struct blob_attr *msg)
{
	struct blob_attr *tb[__AGGREGATION_GROUP_MAX];
	char *dev = NULL;
	int aggID;
	char *aggType = NULL;
	char *aggDesc = NULL;


	blobmsg_parse(aggregation_group_policy, ARRAY_SIZE(aggregation_group_policy), tb, blob_data(msg), blob_len(msg));
	
	if(!tb[AGGREGATION_GROUP_ID])
		return UBUS_STATUS_INVALID_ARGUMENT;

	aggID = blobmsg_get_u32(tb[AGGREGATION_GROUP_ID]);

	if(tb[AGGREGATION_GROUP_DEVICE])
		dev = blobmsg_get_string(tb[AGGREGATION_GROUP_DEVICE]);

	if(tb[AGGREGATION_GROUP_TYPE])
		aggType = blobmsg_get_string(tb[AGGREGATION_GROUP_TYPE]);

	if(tb[AGGREGATION_GROUP_DESC])
		aggDesc = blobmsg_get_string(tb[AGGREGATION_GROUP_DESC]);

	// TODO:do create new aggregation group.
	// dev used when system have more 1 VxBOX device.
	DPRINTF("%s received create aggregation group message: \ 
dev = %s, aggid = %d, aggType=%s, aggDesc=%s \n", obj->name, dev, aggID,aggType, aggDesc);


	blob_buf_init(&b, 0);
	blobmsg_add_u16(&b, "aggregation id",aggID);
	if (aggType)
		blobmsg_add_string(&b, "aggregation type",aggType);
	if (aggDesc)
		blobmsg_add_string(&b, "aggregation description",aggDesc);
//	TODO: add other attr
	
	req->deferred = false;
	ubus_send_reply(ctx, req, b.head);
	return 0;

}
Пример #8
0
Файл: conf.c Проект: Oryon/pimbd
static int conf_rpa_mod(conf conf, char *data, size_t len, __unused struct blob_buf *reply, bool del)
{
	struct blob_attr *tb[CONF_RPA_MAX];
	struct in6_addr rpa;
	struct in6_addr gr;
	uint8_t plen;

	if(blobmsg_parse(conf_rpa_attrs, CONF_RPA_MAX, tb, data, len) ||
			!tb[CONF_RPA_RPA] || !addr_pton(&rpa, blobmsg_get_string(tb[CONF_RPA_RPA])) ||
			!tb[CONF_RPA_GROUPS] || !prefix_pton(&gr, &plen, blobmsg_get_string(tb[CONF_RPA_GROUPS])) ||
			!addr_is_multicast(&gr) || tb[CONF_RPA_RPL_JP])
		return -EINVAL;

	if(del)
		pim_rpa_del(conf->pim, &rpa, &gr, plen);
	else
		pim_rpa_add(conf->pim, &rpa, &gr, plen);
	return 0;
}
Пример #9
0
void get_port_attr(struct portAttr *port, struct blob_attr *msg)
{
	struct blob_attr *tb[__PORT_MAX];
	int portNum;
	blobmsg_parse(port_policy, ARRAY_SIZE(port_policy), tb, blobmsg_data(msg), blobmsg_len(msg));
	if(tb[AGG_PORT_NUMBER])
		port->number =  blobmsg_get_u32(tb[AGG_PORT_NUMBER]);
	if(tb[AGG_PORT_ALIAS])
		port->alias =  blobmsg_get_string(tb[AGG_PORT_ALIAS]);
	return;
}
Пример #10
0
Файл: conf.c Проект: Oryon/pimbd
static int conf_rpa_flush(struct ipc_user *u, char *data, size_t len, __unused struct blob_buf *reply)
{
	conf conf = container_of(u, conf_s, ipc_users[CONF_IPC_RPA_FLUSH]);
	struct blob_attr *tb[CONF_RPA_MAX];
	struct in6_addr rpa;

	if(blobmsg_parse(conf_rpa_attrs, CONF_RPA_MAX, tb, data, len) ||
			!tb[CONF_RPA_RPA] || !addr_pton(&rpa, blobmsg_get_string(tb[CONF_RPA_RPA])) ||
			tb[CONF_RPA_GROUPS] || tb[CONF_RPA_RPL_JP])
		return -EINVAL;

	pim_rpa_update(conf->pim, &rpa);
	pim_rpa_flush(conf->pim, &rpa);
	return 0;
}
Пример #11
0
Файл: conf.c Проект: Oryon/pimbd
static int conf_rpa_set(struct ipc_user *u, char *data, size_t len, __unused struct blob_buf *reply)
{
	conf conf = container_of(u, conf_s, ipc_users[CONF_IPC_RPA_SET]);
	struct blob_attr *tb[CONF_RPA_MAX];
	struct in6_addr rpa;

	if(blobmsg_parse(conf_rpa_attrs, CONF_RPA_MAX, tb, data, len) ||
			!tb[CONF_RPA_RPA] || !addr_pton(&rpa, blobmsg_get_string(tb[CONF_RPA_RPA])) ||
			tb[CONF_RPA_GROUPS])
		return -1;

	if(tb[CONF_RPA_RPL_JP])
		pim_rpa_set_rpl_jp(conf->pim, &rpa, blobmsg_get_u8(tb[CONF_RPA_RPL_JP]));

	return 0;
}
Пример #12
0
static int nand_set(struct ubus_context *ctx, struct ubus_object *obj,
			struct ubus_request_data *req, const char *method,
			struct blob_attr *msg)
{
	struct blob_attr *tb[__NAND_MAX];

	if (!msg)
		return UBUS_STATUS_INVALID_ARGUMENT;

	blobmsg_parse(nand_policy, __NAND_MAX, tb, blob_data(msg), blob_len(msg));
	if (!tb[NAND_PATH])
		return UBUS_STATUS_INVALID_ARGUMENT;

	procd_spawn_upgraded(blobmsg_get_string(tb[NAND_PATH]));
	fprintf(stderr, "Yikees, something went wrong. no /sbin/upgraded ?\n");
	return 0;
}
Пример #13
0
static void vlanlist_checkout_callback(struct ubus_request *req, int type, struct blob_attr *msg)
{
	char *str = NULL;
	struct Rmsg;
	struct blob_attr *tb[__FRAMEWORK_MAX];
	struct json_object *new_obj;

	blobmsg_parse(framework_result_policy, ARRAY_SIZE(framework_result_policy), tb, blob_data(msg), blob_len(msg));
	Rmsg.msg = blobmsg_get_string(tb[FRAMEWORK_RESULT_MSG]);
	Rmsg.resCode = (int)blobmsg_get_u16(tb[FRAMEWORK_RESULT_CODE]);

	//printf("%s\n", Rmsg.msg);
	new_obj = json_tokener_parse(Rmsg.msg);
	if(Rmsg.resCode != LR_ERR_NONE){
		if(new_obj){
			const char *errmsg = NULL;
			struct json_object *o = json_object_object_get(new_obj,"ERROR");
			errmsg = json_object_get_string(o);
			if(errmsg != NULL)
				fprintf(stderr,"%s",errmsg);
			json_object_put(o);
			json_object_put(new_obj);
		}
	}else{
		if(new_obj){
			struct json_object *o = json_object_object_get(new_obj, "vlanlist");
			// vlanlist is a array
			if(json_object_is_type(o, json_type_array)){
				int length=json_object_array_length(o);
				int i = 0;
				u16 *pVids = (u16 *)malloc(sizeof(u16) * length);
				for(i=0; i<length; i++) {
					json_object *val=json_object_array_get_idx(o,i);
					*(pVids+i) = json_object_get_int(val);
				}
				copy_vlanlist_software(pVids, length);
				free(pVids);
			}

		}
	}

}
Пример #14
0
Файл: juci.c Проект: schuza/juci
static bool
menu_files(struct blob_attr *files)
{
	int rem;
	bool empty = true;
	struct stat s;
	struct blob_attr *file;

	blobmsg_for_each_attr(file, files, rem)
	{
		empty = false;

		if (blobmsg_type(file) != BLOBMSG_TYPE_STRING)
			continue;

		if (stat(blobmsg_get_string(file), &s) || !S_ISREG(s.st_mode))
			continue;

		return true;
	}
Пример #15
0
static int aggregation_set_sys_pri(struct ubus_context *ctx, struct ubus_object *obj,
		      struct ubus_request_data *req, const char *method,
		      struct blob_attr *msg)
{
	struct blob_attr *tb[__AGGREGATION_PRI_MAX];
	char *dev = NULL;
	int sysPri;
	int fds[2];

	blobmsg_parse(aggregation_sys_pri_policy, ARRAY_SIZE(aggregation_sys_pri_policy), tb, blob_data(msg), blob_len(msg));
	
	if(!tb[AGGREGATION_SYS_PRI])
		return UBUS_STATUS_INVALID_ARGUMENT;

	if(tb[AGGREGATION_DEVICE])
		dev = blobmsg_get_string(tb[AGGREGATION_DEVICE]);


	sysPri = blobmsg_get_u32(tb[AGGREGATION_SYS_PRI]);


	// TODO:do set aggregation system priority.
	// dev used when system have more 1 VxBOX device.
	DPRINTF("%s received set aggregation system priority message: \ 
dev = %s, system Priority = %d \n", obj->name, dev, sysPri);


//	ubus_defer_request(ctx, req, &hreq->req);

	blob_buf_init(&b, 0);
//	blobmsg_add_string(&b, "device",dev);
	blobmsg_add_u16(&b, "system priority",sysPri);
//	TODO: add other attr
	
	req->deferred = false;
	ubus_send_reply(ctx, req, b.head);
	

	return 0;
}
Пример #16
0
static void swVlan_result_data(struct ubus_request *req, int type, struct blob_attr *msg)
{
	char *str = NULL;
	struct Rmsg;
	struct blob_attr *tb[__FRAMEWORK_MAX];

	//pthread_mutex_lock(&gClient->client_cb_mutex);
	blobmsg_parse(framework_result_policy, ARRAY_SIZE(framework_result_policy), tb, blob_data(msg), blob_len(msg));
	Rmsg.msg = blobmsg_get_string(tb[FRAMEWORK_RESULT_MSG]);
	Rmsg.resCode = blobmsg_get_u16(tb[FRAMEWORK_RESULT_CODE]);
	
	if((asyncResult == NULL) || (asyncResult->result_data_cb == NULL)){
		str = blobmsg_format_json(msg, true);
		printf("%s\n",str);
		free(str);
	}else{
		asyncResult->result_data_cb(&Rmsg);
	}
	//pthread_mutex_unlock(&gClient->client_cb_mutex);

	return;
}
Пример #17
0
Файл: conf.c Проект: Oryon/pimbd
static int conf_proxy_mod(conf conf, char *data, size_t len, __unused struct blob_buf *reply, bool del)
{
	struct blob_attr* tb[CONF_PROXY_MAX];
	int iport;
	const char* saddr;
	struct in6_addr addr;

	if (blobmsg_parse(conf_proxy_attrs, CONF_PROXY_MAX, tb, data, len))
		return -1;

	if(!tb[CONF_PROXY_ADDR] || !tb[CONF_PROXY_PORT] ||
			!(saddr = blobmsg_get_string(tb[CONF_PROXY_ADDR])) ||
			!(iport = blobmsg_get_u32(tb[CONF_PROXY_PORT])))
		return -EINVAL;
	if(!(addr_pton(&addr, saddr)) || iport >= 65535 || iport <= 0)
		return -EINVAL;

	if(del) {
		pim_ctl_del_proxy(conf->pim, &addr, (in_port_t) iport);
	} else {
		pim_ctl_add_proxy(conf->pim, &addr, (in_port_t) iport);
	}
	return 0;
}
Пример #18
0
Файл: conf.c Проект: Oryon/pimbd
static int conf_link_set(struct ipc_user *u, char *data, size_t len, __unused struct blob_buf *reply)
{
	conf conf = container_of(u, conf_s, ipc_users[CONF_IPC_LINK_SET]);
	struct blob_attr *tb[CONF_LINK_MAX];
	iface_flags flags = 0, flags_mod = 0;
	iface i;
	int ret = 0;

	if(blobmsg_parse(conf_link_attrs, CONF_LINK_MAX, tb, data, len) ||
			!tb[CONF_LINK_DEV])
		return -EINVAL;

	if(tb[CONF_LINK_LLQC] || tb[CONF_LINK_ROBUSTNESS]) {
		return -EOPNOTSUPP;
	}

	if(!(i = iface_get_byname(conf->igs, blobmsg_get_string(tb[CONF_LINK_DEV]), 1)))
		return -ENOMEM;

	iface_ref(i);

#define _(attr, flag) \
		if(attr) { \
			flags_mod |= flag; \
			if(blobmsg_get_bool(attr)) { \
				flags |= flag; \
			} else { \
				flags &= ~(flag); \
			} \
		}\

	_(tb[CONF_LINK_PIM], IFACE_FLAG_PIM);
	_(tb[CONF_LINK_SSBIDIR], IFACE_FLAG_SSBIDIR);
	_(tb[CONF_LINK_MLD], IFACE_FLAG_MLD_QUERIER);
	_(tb[CONF_LINK_IGMP], IFACE_FLAG_IGMP_QUERIER);

#undef _

	if(tb[CONF_LINK_PROXY]) {
		char *s = NULL;
		char *port = NULL;
		struct in6_addr addr;
		if(!(s = blobmsg_get_string(tb[CONF_LINK_PROXY])))
			return -EINVAL;

		if(!strcmp(s, "off")) {
			flags_mod |= IFACE_FLAG_PROXY;
			flags &= ~(IFACE_FLAG_PROXY);
		} else if(!(port = strchr(s, ' ')) || strchr(port + 1, ' ')) {
			return -EINVAL;
		} else {
			*port = '\0';
			port++;
			int p;
			if((sscanf(port, "%d", &p) != 1) || p >= 65536 || p<=0 || !addr_pton(&addr, s))
				return -EINVAL;

			if(i->proxy_port != p || addr_cmp(&i->proxy_addr, &addr)) {
				addr_cpy(&i->proxy_addr, &addr);
				i->proxy_port = (in_port_t) p;
				flags_mod |= IFACE_FLAG_PROXY;
				flags |= IFACE_FLAG_PROXY;
			}
		}
	}

	conf_set_iface_flags(i, flags, flags_mod);

	if(tb[CONF_LINK_HELLO]) {
		int hello = blobmsg_get_u32(tb[CONF_LINK_HELLO]);
		conf_set_ifvalue(i, CIFV_PIM_HELLO_PERIOD_MS, (hello>0)?hello:INT_MIN);
	}

	if(tb[CONF_LINK_JOIN]) {
		int join = blobmsg_get_u32(tb[CONF_LINK_JOIN]);
		conf_set_ifvalue(i, CIFV_PIM_US_T_PERIODIC_MS, (join>0)?join:INT_MIN);
	}

	iface_unref(i);
	return ret;
}
Пример #19
0
Файл: conf.c Проект: Oryon/pimbd
int conf_group_set(struct ipc_user *u, char *data, size_t len, __unused struct blob_buf *reply)
{
	conf conf = container_of(u, conf_s, ipc_users[CONF_IPC_GROUP_SET]);
	ifgroups igs = conf->igs;
	pim pim = conf->pim;
	struct blob_attr *tb[CONF_G_MAX];
	struct in6_addr grp, src;
	group g = NULL;
	source s = NULL;
	gsource gs = NULL;
	iface i = NULL;
	ifgroup ig = NULL;
	ifgsource ifgs = NULL;
	int join = 0, listen = 0, local = 0;
	char *str;
	int ret = 0;

	if(blobmsg_parse(conf_g_attrs, CONF_G_MAX, tb, data, len) ||
			!tb[CONF_G_GROUP] || !addr_pton(&grp, blobmsg_get_string(tb[CONF_G_GROUP])) ||
			!addr_is_multicast(&grp) ||
			(tb[CONF_G_SRC] && !addr_pton(&src, blobmsg_get_string(tb[CONF_G_SRC]))) ||
			(tb[CONF_G_LISTENER] && !tb[CONF_G_DEV]))
		return -EINVAL;

	if(tb[CONF_G_PIM]) {
		if(!(str = blobmsg_get_string(tb[CONF_G_PIM])))
			return -EINVAL;
		else if (!strcmp(str, "join"))
			join = PIM_JOIN;
		else if(!strcmp(str, "prune"))
			join = PIM_PRUNE;
		else if(!strcmp(str, "none"))
			join = PIM_NONE;
		else
			return -EINVAL;
	}

	if(tb[CONF_G_LISTENER]) {
		if(!(str = blobmsg_get_string(tb[CONF_G_LISTENER])))
			return -EINVAL;
		else if (!strcmp(str, "include"))
			listen = PIM_JOIN;
		else if(!strcmp(str, "exclude"))
			listen = PIM_PRUNE;
		else if(!strcmp(str, "none"))
			listen = PIM_NONE;
		else
			return -EINVAL;
	}

	if(tb[CONF_G_LOCAL]) {
		if(!(str = blobmsg_get_string(tb[CONF_G_LOCAL])))
			return -EINVAL;
		else if (!strcmp(str, "include"))
			local = PIM_JOIN;
		else if(!strcmp(str, "exclude"))
			local = PIM_PRUNE;
		else if(!strcmp(str, "none"))
			local = PIM_NONE;
		else
			return -EINVAL;
	}

	if((tb[CONF_G_LOCAL] && !tb[CONF_G_DEV]) ||
			(tb[CONF_G_LISTENER] && !tb[CONF_G_DEV]))
		return -EINVAL;

	if((tb[CONF_G_GROUP] && (!(g = group_get(igs, &grp, 1)) || !group_ref(g))) ||
			(tb[CONF_G_SRC] && ((!(s = source_get(igs, &src, 1)) || !group_ref(s)) ||
					(!(gs = gsource_get(g, s, 1)) || !gsource_ref(gs)))) ||
			(tb[CONF_G_DEV] && ((!(i = iface_get_byname(igs, blobmsg_get_string(tb[CONF_G_DEV]), 1)) || !iface_ref(i)) ||
							(!(ig = ifgroup_get(i, g, 1)) || !ifgroup_ref(ig)))) ||
							(ig && gs && (!(ifgs = ifgsource_get(ig, gs, 1)) || !ifgsource_ref(ifgs)))) {
		ret = -ENOMEM;
		goto out;
	}

	if(tb[CONF_G_PIM]) {
		if(gs) {
			L_INFO("Set configuration of gsource "GSOURCE_L" - pim_join_desired : %s", GSOURCE_LA(gs), PIM_STATE_STR(join));
			if(!gs->conf_join_desired)
				gsource_ref(gs);
			gs->conf_join_desired = join;
			pim_gsource_conf_changed(pim, gs);
			if(!gs->conf_join_desired)
				gsource_unref(gs);
		} else {
			L_INFO("Set configuration of group "GROUP_L" - pim_join_desired : %s", GROUP_LA(g), PIM_STATE_STR(join));
			if(!g->conf_join_desired)
				group_ref(g);
			g->conf_join_desired = join;
			pim_group_conf_changed(pim, g);
			if(!g->conf_join_desired)
				group_unref(g);
		}
	}

	if(tb[CONF_G_LOCAL]) {
		L_INFO("Set configuration of ifgroup "IFGROUP_L" - local_exclude : %d", IFGROUP_LA(ig), (local == PIM_PRUNE));
		if(!ig->conf_local_exclude)
			ifgroup_ref(ig);
		ig->conf_local_exclude = !!(local == PIM_PRUNE);
		pim_ifgroup_conf_changed(pim, ig);
		if(!ig->conf_local_exclude)
			ifgroup_unref(ig);
	}

	if (tb[CONF_G_LISTENER]) {
		if(ifgs) {
			listener_update_G_S(ifgs, LISTENER_CONF, listen == PIM_JOIN, listen == PIM_PRUNE);
		} else {
			listener_update_G(ig, LISTENER_CONF, listen == PIM_PRUNE);
		}
	}

out:
	if(ifgs)
		ifgsource_unref(ifgs);
	if(gs)
		gsource_unref(gs);
	if(ig)
		ifgroup_unref(ig);
	if(g)
		group_unref(g);
	if(s)
		source_unref(s);
	if(i)
		iface_unref(i);
	return ret;
}
Пример #20
0
static struct device_addr *
parse_address_item(struct blob_attr *attr, bool v6, bool ext)
{
	struct device_addr *addr;
	struct blob_attr *tb[__ADDR_MAX];
	struct blob_attr *cur;

	if (blobmsg_type(attr) != BLOBMSG_TYPE_TABLE)
		return NULL;

	addr = alloc_device_addr(v6, ext);
	if (!addr)
		return NULL;

	blobmsg_parse(proto_ip_addr, __ADDR_MAX, tb, blobmsg_data(attr), blobmsg_data_len(attr));

	addr->mask = v6 ? 128 : 32;
	if ((cur = tb[ADDR_MASK])) {
		unsigned int new_mask;

		new_mask = parse_netmask_string(blobmsg_data(cur), v6);
		if (new_mask > addr->mask)
			goto error;

		addr->mask = new_mask;
	}

	cur = tb[ADDR_IPADDR];
	if (!cur)
		goto error;

	if (!inet_pton(v6 ? AF_INET6 : AF_INET, blobmsg_data(cur), &addr->addr))
		goto error;

	if ((cur = tb[ADDR_OFFLINK]) && blobmsg_get_bool(cur))
		addr->flags |= DEVADDR_OFFLINK;

	if (!v6) {
		if ((cur = tb[ADDR_BROADCAST]) &&
		    !inet_pton(AF_INET, blobmsg_data(cur), &addr->broadcast))
			goto error;
		if ((cur = tb[ADDR_PTP]) &&
		    !inet_pton(AF_INET, blobmsg_data(cur), &addr->point_to_point))
			goto error;
	} else {
		time_t now = system_get_rtime();
		if ((cur = tb[ADDR_PREFERRED])) {
			int64_t preferred = blobmsg_get_u32(cur);
			int64_t preferred_until = preferred + (int64_t)now;
			if (preferred_until <= LONG_MAX && preferred != 0xffffffffLL)
				addr->preferred_until = preferred_until;
		}

		if ((cur = tb[ADDR_VALID])) {
			int64_t valid = blobmsg_get_u32(cur);
			int64_t valid_until = valid + (int64_t)now;
			if (valid_until <= LONG_MAX && valid != 0xffffffffLL)
				addr->valid_until = valid_until;

		}

		if (addr->valid_until) {
			if (!addr->preferred_until)
				addr->preferred_until = addr->valid_until;
			else if (addr->preferred_until > addr->valid_until)
				goto error;
		}

		if ((cur = tb[ADDR_CLASS]))
			addr->pclass = strdup(blobmsg_get_string(cur));
	}

	return addr;

error:
	free(addr);
	return NULL;
}
Пример #21
0
static void
ubus_process_invoke(struct ubus_context *ctx, struct ubus_msghdr *hdr,
		    struct ubus_object *obj, struct blob_attr **attrbuf)
{
	printf("-> [obj] ubus_process_invoke\n");

	struct ubus_request_data req = {
		.fd = -1,
	};
	int method;
	int ret;
	bool no_reply = false;

	if (!obj) {
		ret = UBUS_STATUS_NOT_FOUND;
		goto send;
	}

	if (!attrbuf[UBUS_ATTR_METHOD]) {
		ret = UBUS_STATUS_INVALID_ARGUMENT;
		goto send;
	}

	if (attrbuf[UBUS_ATTR_NO_REPLY])
		no_reply = blob_get_int8(attrbuf[UBUS_ATTR_NO_REPLY]);

	req.peer = hdr->peer;
	req.seq = hdr->seq;
	req.object = obj->id;
	if (attrbuf[UBUS_ATTR_USER] && attrbuf[UBUS_ATTR_GROUP]) {
		req.acl.user = blobmsg_get_string(attrbuf[UBUS_ATTR_USER]);
		req.acl.group = blobmsg_get_string(attrbuf[UBUS_ATTR_GROUP]);
		req.acl.object = obj->name;
	}
	for (method = 0; method < obj->n_methods; method++)
		if (!obj->methods[method].name ||
		    !strcmp(obj->methods[method].name,
		            blob_data(attrbuf[UBUS_ATTR_METHOD])))
			goto found;

	/* not found */
	ret = UBUS_STATUS_METHOD_NOT_FOUND;
	goto send;

found:
	ret = obj->methods[method].handler(ctx, obj, &req,
					   blob_data(attrbuf[UBUS_ATTR_METHOD]),
					   attrbuf[UBUS_ATTR_DATA]);
	if (req.deferred || no_reply)
		return;

send:
	ubus_complete_deferred_request(ctx, &req, ret);
}

void __hidden ubus_process_obj_msg(struct ubus_context *ctx, struct ubus_msghdr_buf *buf)
{
	void (*cb)(struct ubus_context *, struct ubus_msghdr *,
		   struct ubus_object *, struct blob_attr **);
	struct ubus_msghdr *hdr = &buf->hdr;
	struct blob_attr **attrbuf;
	struct ubus_object *obj;
	uint32_t objid;
	void *prev_data = NULL;

	attrbuf = ubus_parse_msg(buf->data);
	if (!attrbuf[UBUS_ATTR_OBJID])
		return;

	objid = blob_get_u32(attrbuf[UBUS_ATTR_OBJID]);
	obj = avl_find_element(&ctx->objects, &objid, obj, avl);

	switch (hdr->type) {
	case UBUS_MSG_INVOKE:
		cb = ubus_process_invoke;
		break;
	case UBUS_MSG_UNSUBSCRIBE:
		cb = ubus_process_unsubscribe;
		break;
	case UBUS_MSG_NOTIFY:
		cb = ubus_process_notify;
		break;
	default:
		return;
	}

	if (buf == &ctx->msgbuf) {
		prev_data = buf->data;
		buf->data = NULL;
	}

	cb(ctx, hdr, obj, attrbuf);

	if (prev_data) {
		if (buf->data)
			free(prev_data);
		else
			buf->data = prev_data;
	}
}
Пример #22
0
static int
rpc_rrdns_lookup(struct ubus_context *ctx, struct ubus_object *obj,
                 struct ubus_request_data *req, const char *method,
                 struct blob_attr *msg)
{
    int port = 53, limit = RRDNS_DEF_LIMIT, timeout = RRDNS_DEF_TIMEOUT;
    struct blob_attr *tb[__RPC_L_MAX];
    struct rrdns_context *rctx;
    const char *server = NULL;

    blobmsg_parse(rpc_lookup_policy, __RPC_L_MAX, tb,
                  blob_data(msg), blob_len(msg));

    if (tb[RPC_L_PORT])
        port = blobmsg_get_u16(tb[RPC_L_PORT]);

    if (tb[RPC_L_LIMIT])
        limit = blobmsg_get_u32(tb[RPC_L_LIMIT]);

    if (tb[RPC_L_TIMEOUT])
        timeout = blobmsg_get_u32(tb[RPC_L_TIMEOUT]);

    if (tb[RPC_L_SERVER])
        server = blobmsg_get_string(tb[RPC_L_SERVER]);


    if (!tb[RPC_L_ADDRS])
        return UBUS_STATUS_INVALID_ARGUMENT;

    if (port <= 0)
        return UBUS_STATUS_INVALID_ARGUMENT;

    if (limit <= 0 || limit > RRDNS_MAX_LIMIT)
        return UBUS_STATUS_INVALID_ARGUMENT;

    if (timeout <= 0 || timeout > RRDNS_MAX_TIMEOUT)
        return UBUS_STATUS_INVALID_ARGUMENT;


    if (!server || !*server)
        server = rrdns_find_nameserver();

    if (!server)
        return UBUS_STATUS_NOT_FOUND;

    rctx = calloc(1, sizeof(*rctx));

    if (!rctx)
        return UBUS_STATUS_UNKNOWN_ERROR;

    rctx->socket.fd = usock(USOCK_UDP, server, usock_port(port));

    if (rctx->socket.fd < 0) {
        free(rctx);
        return UBUS_STATUS_UNKNOWN_ERROR;
    }

    rctx->context = ctx;
    rctx->addr_cur = blobmsg_data(tb[RPC_L_ADDRS]);
    rctx->addr_rem = blobmsg_data_len(tb[RPC_L_ADDRS]);

    avl_init(&rctx->request_ids, rrdns_cmp_id, false, NULL);
    avl_init(&rctx->request_addrs, rrdns_cmp_addr, false, NULL);

    rctx->timeout.cb = rrdns_handle_timeout;
    uloop_timeout_set(&rctx->timeout, timeout);

    rctx->socket.cb = rrdns_handle_response;
    uloop_fd_add(&rctx->socket, ULOOP_READ);

    blob_buf_init(&rctx->blob, 0);

    while (limit--)
        rrdns_next_query(rctx);

    ubus_defer_request(ctx, req, &rctx->request);

    return UBUS_STATUS_OK;
}
Пример #23
0
static int
rrdns_next_query(struct rrdns_context *rctx)
{
    const char *addr = NULL, *hex = "0123456789abcdef";
    struct rrdns_request *req;
    int i, alen, family;
    char *p, dname[73];

    union {
        unsigned char uchar[4];
        struct in6_addr in6;
        struct in_addr in;
    } a = { };

    union {
        unsigned char buf[512];
        HEADER hdr;
    } msg;

    if (rctx->addr_rem > 0 &&
            blob_pad_len(rctx->addr_cur) <= rctx->addr_rem &&
            blob_pad_len(rctx->addr_cur) >= sizeof(struct blob_attr)) {

        addr = blobmsg_get_string(rctx->addr_cur);
        rctx->addr_rem -= blob_pad_len(rctx->addr_cur);
        rctx->addr_cur = blob_next(rctx->addr_cur);
    }

    if (!addr)
        return 0;

    if (inet_pton(AF_INET6, addr, &a.in6)) {
        memset(dname, 0, sizeof(dname));

        for (i = 0, p = dname; i < 16; i++) {
            *p++ = hex[a.in6.s6_addr[15-i] % 16];
            *p++ = '.';
            *p++ = hex[a.in6.s6_addr[15-i] / 16];
            *p++ = '.';
        }

        p += snprintf(p, p - dname - 1, "ip6.arpa");

        family = AF_INET6;
        alen = p - dname;
    }
    else if (inet_pton(AF_INET, addr, &a.in)) {
        family = AF_INET;
        alen = snprintf(dname, sizeof(dname), "%u.%u.%u.%u.in-addr.arpa",
                        a.uchar[3], a.uchar[2], a.uchar[1], a.uchar[0]);
    }
    else {
        return -EINVAL;
    }

    alen = res_mkquery(QUERY, dname, C_IN, T_PTR, NULL, 0, NULL,
                       msg.buf, sizeof(msg.buf));

    if (alen < 0)
        return alen;

    if (avl_find(&rctx->request_addrs, &a.in6))
        return -ENOTUNIQ;

    if (send(rctx->socket.fd, msg.buf, alen, 0) != alen)
        return -errno;

    req = calloc(1, sizeof(*req));

    if (!req)
        return -ENOMEM;

    req->id = msg.hdr.id;
    req->by_id.key = &req->id;
    avl_insert(&rctx->request_ids, &req->by_id);

    req->family = family;
    req->addr.in6 = a.in6;
    req->by_addr.key = &req->addr.in6;
    avl_insert(&rctx->request_addrs, &req->by_addr);

    return 0;
}
Пример #24
0
static int log_notify(struct blob_attr *msg)
{
	struct blob_attr *tb[__LOG_MAX];
	struct stat s;
	char buf[512];
	uint32_t p;
	char *str;
	time_t t;
	char *c, *m;
	int ret = 0;

	if (sender.fd < 0)
		return 0;

	blobmsg_parse(log_policy, ARRAY_SIZE(log_policy), tb, blob_data(msg), blob_len(msg));
	if (!tb[LOG_ID] || !tb[LOG_PRIO] || !tb[LOG_SOURCE] || !tb[LOG_TIME] || !tb[LOG_MSG])
		return 1;

	if ((log_type == LOG_FILE) && log_size && (!stat(log_file, &s)) && (s.st_size > log_size)) {
		char *old = malloc(strlen(log_file) + 5);

		close(sender.fd);
		if (old) {
			sprintf(old, "%s.old", log_file);
			rename(log_file, old);
			free(old);
		}
		sender.fd = open(log_file, O_CREAT | O_WRONLY | O_APPEND, 0600);
		if (sender.fd < 0) {
			fprintf(stderr, "failed to open %s: %s\n", log_file, strerror(errno));
			exit(-1);
		}
	}

	m = blobmsg_get_string(tb[LOG_MSG]);
	t = blobmsg_get_u64(tb[LOG_TIME]) / 1000;
	c = ctime(&t);
	p = blobmsg_get_u32(tb[LOG_PRIO]);
	c[strlen(c) - 1] = '\0';
	str = blobmsg_format_json(msg, true);
	if (log_type == LOG_NET) {
		int err;

		snprintf(buf, sizeof(buf), "<%u>", p);
		strncat(buf, c + 4, 16);
		if (hostname) {
			strncat(buf, hostname, sizeof(buf) - strlen(buf) - 1);
			strncat(buf, " ", sizeof(buf) - strlen(buf) - 1);
		}
		if (log_prefix) {
			strncat(buf, log_prefix, sizeof(buf) - strlen(buf) - 1);
			strncat(buf, ": ", sizeof(buf) - strlen(buf) - 1);
		}
		if (blobmsg_get_u32(tb[LOG_SOURCE]) == SOURCE_KLOG)
			strncat(buf, "kernel: ", sizeof(buf) - strlen(buf) - 1);
		strncat(buf, m, sizeof(buf) - strlen(buf) - 1);
		if (log_udp)
			err = write(sender.fd, buf, strlen(buf));
		else {
			size_t buflen = strlen(buf);
			if (!log_trailer_null)
				buf[buflen] = '\n';
			err = send(sender.fd, buf, buflen + 1, 0);
		}

		if (err < 0) {
			syslog(LOG_INFO, "failed to send log data to %s:%s via %s\n",
				log_ip, log_port, (log_udp) ? ("udp") : ("tcp"));
			uloop_fd_delete(&sender);
			close(sender.fd);
			sender.fd = -1;
			uloop_timeout_set(&retry, 1000);
		}
	} else {
		snprintf(buf, sizeof(buf), "%s %s.%s%s %s\n",
			c, getcodetext(LOG_FAC(p) << 3, facilitynames), getcodetext(LOG_PRI(p), prioritynames),
			(blobmsg_get_u32(tb[LOG_SOURCE])) ? ("") : (" kernel:"), m);
		ret = write(sender.fd, buf, strlen(buf));
	}

	free(str);
	if (log_type == LOG_FILE)
		fsync(sender.fd);

	return ret;
}