// 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); }
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; }
/* * 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 }
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); } }
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; }
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; } }
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; }
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; }
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; }
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; }
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; }
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; }
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); } } } }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; } }
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; }
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; }
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; }