2 * luci-rpcd - LuCI UBUS RPC server
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.
25 #include <sys/types.h>
27 #include <arpa/inet.h>
32 static struct blob_buf buf
;
33 static struct uci_context
*cursor
;
41 static const struct blobmsg_policy rpc_signal_policy
[__RPC_S_MAX
] = {
42 [RPC_S_PID
] = { .name
= "pid", .type
= BLOBMSG_TYPE_INT32
},
43 [RPC_S_SIGNAL
] = { .name
= "signal", .type
= BLOBMSG_TYPE_INT32
},
52 static const struct blobmsg_policy rpc_init_policy
[__RPC_I_MAX
] = {
53 [RPC_I_NAME
] = { .name
= "name", .type
= BLOBMSG_TYPE_STRING
},
54 [RPC_I_ACTION
] = { .name
= "action", .type
= BLOBMSG_TYPE_STRING
},
59 rpc_errno_status(void)
64 return UBUS_STATUS_PERMISSION_DENIED
;
67 return UBUS_STATUS_INVALID_ARGUMENT
;
70 return UBUS_STATUS_NOT_FOUND
;
73 return UBUS_STATUS_INVALID_ARGUMENT
;
76 return UBUS_STATUS_UNKNOWN_ERROR
;
81 log_read(FILE *log
, int logsize
)
87 logsize
= RPC_LUCI2_DEF_LOGSIZE
;
89 len
= (logsize
> RPC_LUCI2_MAX_LOGSIZE
) ? RPC_LUCI2_MAX_LOGSIZE
: logsize
;
90 logbuf
= blobmsg_alloc_string_buffer(&buf
, "log", len
+ 1);
95 while (logsize
> RPC_LUCI2_MAX_LOGSIZE
)
97 len
= logsize
% RPC_LUCI2_MAX_LOGSIZE
;
100 len
= RPC_LUCI2_MAX_LOGSIZE
;
102 fread(logbuf
, 1, len
, log
);
106 len
= fread(logbuf
, 1, logsize
, log
);
109 blobmsg_add_string_buffer(&buf
);
113 rpc_luci2_system_log(struct ubus_context
*ctx
, struct ubus_object
*obj
,
114 struct ubus_request_data
*req
, const char *method
,
115 struct blob_attr
*msg
)
119 const char *logfile
= NULL
;
121 struct uci_package
*p
;
122 struct uci_element
*e
;
123 struct uci_section
*s
;
124 struct uci_ptr ptr
= { .package
= "system" };
126 uci_load(cursor
, ptr
.package
, &p
);
129 return UBUS_STATUS_NOT_FOUND
;
131 uci_foreach_element(&p
->sections
, e
)
133 s
= uci_to_section(e
);
135 if (strcmp(s
->type
, "system"))
139 ptr
.option
= "log_type";
140 ptr
.section
= e
->name
;
141 uci_lookup_ptr(cursor
, &ptr
, NULL
, true);
145 if (ptr
.o
&& ptr
.o
->type
== UCI_TYPE_STRING
&&
146 !strcmp(ptr
.o
->v
.string
, "file"))
149 ptr
.option
= "log_file";
150 uci_lookup_ptr(cursor
, &ptr
, NULL
, true);
152 if (ptr
.o
&& ptr
.o
->type
== UCI_TYPE_STRING
)
153 logfile
= ptr
.o
->v
.string
;
155 logfile
= "/var/log/messages";
157 if (stat(logfile
, &st
) || !(log
= fopen(logfile
, "r")))
160 logsize
= st
.st_size
;
165 ptr
.option
= "log_size";
166 uci_lookup_ptr(cursor
, &ptr
, NULL
, true);
168 if (ptr
.o
&& ptr
.o
->type
== UCI_TYPE_STRING
)
169 logsize
= atoi(ptr
.o
->v
.string
) * 1024;
171 if (!(log
= popen("logread", "r")))
175 blob_buf_init(&buf
, 0);
177 log_read(log
, logsize
);
180 uci_unload(cursor
, p
);
181 ubus_send_reply(ctx
, req
, buf
.head
);
185 uci_unload(cursor
, p
);
186 return rpc_errno_status();
190 rpc_luci2_system_dmesg(struct ubus_context
*ctx
, struct ubus_object
*obj
,
191 struct ubus_request_data
*req
, const char *method
,
192 struct blob_attr
*msg
)
196 if (!(log
= popen("dmesg", "r")))
197 return rpc_errno_status();
199 blob_buf_init(&buf
, 0);
201 log_read(log
, RPC_LUCI2_MAX_LOGSIZE
);
204 ubus_send_reply(ctx
, req
, buf
.head
);
209 rpc_luci2_process_list(struct ubus_context
*ctx
, struct ubus_object
*obj
,
210 struct ubus_request_data
*req
, const char *method
,
211 struct blob_attr
*msg
)
216 char *pid
, *ppid
, *user
, *stat
, *vsz
, *pvsz
, *pcpu
, *cmd
;
218 if (!(top
= popen("/bin/busybox top -bn1", "r")))
219 return rpc_errno_status();
221 blob_buf_init(&buf
, 0);
222 c
= blobmsg_open_array(&buf
, "processes");
224 while (fgets(line
, sizeof(line
) - 1, top
))
226 pid
= strtok(line
, " ");
228 if (*pid
< '0' || *pid
> '9')
231 ppid
= strtok(NULL
, " ");
232 user
= strtok(NULL
, " ");
233 stat
= strtok(NULL
, " ");
246 vsz
= strtok(stat
+ 4, " ");
247 pvsz
= strtok(NULL
, " ");
248 pcpu
= strtok(NULL
, " ");
249 cmd
= strtok(NULL
, "\n");
254 d
= blobmsg_open_table(&buf
, NULL
);
256 blobmsg_add_u32(&buf
, "pid", atoi(pid
));
257 blobmsg_add_u32(&buf
, "ppid", atoi(ppid
));
258 blobmsg_add_string(&buf
, "user", user
);
259 blobmsg_add_string(&buf
, "stat", stat
);
260 blobmsg_add_u32(&buf
, "vsize", atoi(vsz
) * 1024);
261 blobmsg_add_u32(&buf
, "vsize_percent", atoi(pvsz
));
262 blobmsg_add_u32(&buf
, "cpu_percent", atoi(pcpu
));
263 blobmsg_add_string(&buf
, "command", cmd
);
265 blobmsg_close_table(&buf
, d
);
269 blobmsg_close_array(&buf
, c
);
271 ubus_send_reply(ctx
, req
, buf
.head
);
276 rpc_luci2_process_signal(struct ubus_context
*ctx
, struct ubus_object
*obj
,
277 struct ubus_request_data
*req
, const char *method
,
278 struct blob_attr
*msg
)
281 struct blob_attr
*tb
[__RPC_S_MAX
];
283 blobmsg_parse(rpc_signal_policy
, __RPC_S_MAX
, tb
,
284 blob_data(msg
), blob_len(msg
));
286 if (!tb
[RPC_S_SIGNAL
] || !tb
[RPC_S_PID
])
289 return rpc_errno_status();
292 pid
= blobmsg_get_u32(tb
[RPC_S_PID
]);
293 sig
= blobmsg_get_u32(tb
[RPC_S_SIGNAL
]);
296 return rpc_errno_status();
302 rpc_luci2_init_list(struct ubus_context
*ctx
, struct ubus_object
*obj
,
303 struct ubus_request_data
*req
, const char *method
,
304 struct blob_attr
*msg
)
308 char *p
, path
[PATH_MAX
];
314 if (!(d
= opendir("/etc/init.d")))
315 return rpc_errno_status();
317 blob_buf_init(&buf
, 0);
318 c
= blobmsg_open_array(&buf
, "initscripts");
320 while ((e
= readdir(d
)) != NULL
)
322 snprintf(path
, sizeof(path
) - 1, "/etc/init.d/%s", e
->d_name
);
324 if (stat(path
, &s
) || !S_ISREG(s
.st_mode
) || !(s
.st_mode
& S_IXUSR
))
327 if ((f
= fopen(path
, "r")) != NULL
)
330 p
= fgets(path
, sizeof(path
) - 1, f
);
332 if (!p
|| !strstr(p
, "/etc/rc.common"))
335 t
= blobmsg_open_table(&buf
, NULL
);
337 blobmsg_add_string(&buf
, "name", e
->d_name
);
339 while (fgets(path
, sizeof(path
) - 1, f
))
341 p
= strtok(path
, "= \t");
343 if (!strcmp(p
, "START") && !!(p
= strtok(NULL
, "= \t\n")))
346 blobmsg_add_u32(&buf
, "start", n
);
348 else if (!strcmp(p
, "STOP") && !!(p
= strtok(NULL
, "= \t\n")))
350 blobmsg_add_u32(&buf
, "stop", atoi(p
));
357 snprintf(path
, sizeof(path
) - 1, "/etc/rc.d/S%02d%s",
360 blobmsg_add_u8(&buf
, "enabled",
361 (!stat(path
, &s
) && (s
.st_mode
& S_IXUSR
)));
365 blobmsg_add_u8(&buf
, "enabled", 0);
368 blobmsg_close_table(&buf
, t
);
376 blobmsg_close_array(&buf
, c
);
378 ubus_send_reply(ctx
, req
, buf
.head
);
383 rpc_luci2_init_action(struct ubus_context
*ctx
, struct ubus_object
*obj
,
384 struct ubus_request_data
*req
, const char *method
,
385 struct blob_attr
*msg
)
392 struct blob_attr
*tb
[__RPC_I_MAX
];
394 blobmsg_parse(rpc_init_policy
, __RPC_I_MAX
, tb
,
395 blob_data(msg
), blob_len(msg
));
397 if (!tb
[RPC_I_NAME
] || !tb
[RPC_I_ACTION
])
398 return UBUS_STATUS_INVALID_ARGUMENT
;
400 action
= blobmsg_data(tb
[RPC_I_ACTION
]);
402 if (strcmp(action
, "start") && strcmp(action
, "stop") &&
403 strcmp(action
, "reload") && strcmp(action
, "restart") &&
404 strcmp(action
, "enable") && strcmp(action
, "disable"))
405 return UBUS_STATUS_INVALID_ARGUMENT
;
407 snprintf(path
, sizeof(path
) - 1, "/etc/init.d/%s",
408 (char *)blobmsg_data(tb
[RPC_I_NAME
]));
411 return rpc_errno_status();
413 if (!(s
.st_mode
& S_IXUSR
))
414 return UBUS_STATUS_PERMISSION_DENIED
;
416 switch ((pid
= fork()))
419 return rpc_errno_status();
424 if ((fd
= open("/dev/null", O_RDWR
)) > -1)
435 if (execl(path
, path
, action
, NULL
))
436 return rpc_errno_status();
445 dnsmasq_leasefile(void)
448 struct uci_package
*p
;
449 struct uci_element
*e
;
450 struct uci_section
*s
;
451 struct uci_ptr ptr
= {
454 .option
= "leasefile"
457 uci_load(cursor
, ptr
.package
, &p
);
462 uci_foreach_element(&p
->sections
, e
)
464 s
= uci_to_section(e
);
466 if (strcmp(s
->type
, "dnsmasq"))
469 ptr
.section
= e
->name
;
470 uci_lookup_ptr(cursor
, &ptr
, NULL
, true);
474 if (ptr
.o
&& ptr
.o
->type
== UCI_TYPE_STRING
)
475 leases
= fopen(ptr
.o
->v
.string
, "r");
477 uci_unload(cursor
, p
);
483 rpc_luci2_network_leases(struct ubus_context
*ctx
, struct ubus_object
*obj
,
484 struct ubus_request_data
*req
, const char *method
,
485 struct blob_attr
*msg
)
490 char *ts
, *mac
, *addr
, *name
;
491 time_t now
= time(NULL
);
493 blob_buf_init(&buf
, 0);
494 c
= blobmsg_open_array(&buf
, "leases");
496 leases
= dnsmasq_leasefile();
501 while (fgets(line
, sizeof(line
) - 1, leases
))
503 ts
= strtok(line
, " \t");
504 mac
= strtok(NULL
, " \t");
505 addr
= strtok(NULL
, " \t");
506 name
= strtok(NULL
, " \t");
508 if (!ts
|| !mac
|| !addr
|| !name
)
511 if (strchr(addr
, ':'))
514 d
= blobmsg_open_table(&buf
, NULL
);
516 blobmsg_add_u32(&buf
, "expires", atoi(ts
) - now
);
517 blobmsg_add_string(&buf
, "macaddr", mac
);
518 blobmsg_add_string(&buf
, "ipaddr", addr
);
520 if (strcmp(name
, "*"))
521 blobmsg_add_string(&buf
, "hostname", name
);
523 blobmsg_close_table(&buf
, d
);
529 blobmsg_close_array(&buf
, c
);
530 ubus_send_reply(ctx
, req
, buf
.head
);
536 rpc_luci2_network_leases6(struct ubus_context
*ctx
, struct ubus_object
*obj
,
537 struct ubus_request_data
*req
, const char *method
,
538 struct blob_attr
*msg
)
543 char *ts
, *mac
, *addr
, *name
, *duid
;
544 time_t now
= time(NULL
);
546 blob_buf_init(&buf
, 0);
547 c
= blobmsg_open_array(&buf
, "leases");
549 leases
= fopen("/tmp/hosts/6relayd", "r");
553 while (fgets(line
, sizeof(line
) - 1, leases
))
555 if (strncmp(line
, "# ", 2))
558 strtok(line
+ 2, " \t"); /* iface */
560 duid
= strtok(NULL
, " \t");
562 strtok(NULL
, " \t"); /* iaid */
564 name
= strtok(NULL
, " \t");
565 ts
= strtok(NULL
, " \t");
567 strtok(NULL
, " \t"); /* id */
568 strtok(NULL
, " \t"); /* length */
570 addr
= strtok(NULL
, " \t\n");
575 d
= blobmsg_open_table(&buf
, NULL
);
577 blobmsg_add_u32(&buf
, "expires", atoi(ts
) - now
);
578 blobmsg_add_string(&buf
, "duid", duid
);
579 blobmsg_add_string(&buf
, "ip6addr", addr
);
581 if (strcmp(name
, "-"))
582 blobmsg_add_string(&buf
, "hostname", name
);
584 blobmsg_close_array(&buf
, d
);
591 leases
= dnsmasq_leasefile();
596 while (fgets(line
, sizeof(line
) - 1, leases
))
598 ts
= strtok(line
, " \t");
599 mac
= strtok(NULL
, " \t");
600 addr
= strtok(NULL
, " \t");
601 name
= strtok(NULL
, " \t");
602 duid
= strtok(NULL
, " \t\n");
604 if (!ts
|| !mac
|| !addr
|| !duid
)
607 if (!strchr(addr
, ':'))
610 d
= blobmsg_open_table(&buf
, NULL
);
612 blobmsg_add_u32(&buf
, "expires", atoi(ts
) - now
);
613 blobmsg_add_string(&buf
, "macaddr", mac
);
614 blobmsg_add_string(&buf
, "ip6addr", addr
);
616 if (strcmp(name
, "*"))
617 blobmsg_add_string(&buf
, "hostname", name
);
619 if (strcmp(duid
, "*"))
620 blobmsg_add_string(&buf
, "duid", name
);
622 blobmsg_close_table(&buf
, d
);
629 blobmsg_close_array(&buf
, c
);
630 ubus_send_reply(ctx
, req
, buf
.head
);
636 rpc_luci2_network_ct_count(struct ubus_context
*ctx
, struct ubus_object
*obj
,
637 struct ubus_request_data
*req
, const char *method
,
638 struct blob_attr
*msg
)
643 blob_buf_init(&buf
, 0);
645 if ((f
= fopen("/proc/sys/net/netfilter/nf_conntrack_count", "r")) != NULL
)
647 if (fgets(line
, sizeof(line
) - 1, f
))
648 blobmsg_add_u32(&buf
, "count", atoi(line
));
653 if ((f
= fopen("/proc/sys/net/netfilter/nf_conntrack_max", "r")) != NULL
)
655 if (fgets(line
, sizeof(line
) - 1, f
))
656 blobmsg_add_u32(&buf
, "limit", atoi(line
));
661 ubus_send_reply(ctx
, req
, buf
.head
);
667 rpc_luci2_network_ct_table(struct ubus_context
*ctx
, struct ubus_object
*obj
,
668 struct ubus_request_data
*req
, const char *method
,
669 struct blob_attr
*msg
)
677 blob_buf_init(&buf
, 0);
678 c
= blobmsg_open_array(&buf
, "entries");
680 if ((f
= fopen("/proc/net/nf_conntrack", "r")) != NULL
)
682 while (fgets(line
, sizeof(line
) - 1, f
))
684 d
= blobmsg_open_table(&buf
, NULL
);
685 memset(seen
, 0, sizeof(seen
));
687 for (i
= 0, p
= strtok(line
, " "); p
; i
++, p
= strtok(NULL
, " "))
690 blobmsg_add_u8(&buf
, "ipv6", !strcmp(p
, "ipv6"));
692 blobmsg_add_u32(&buf
, "protocol", atoi(p
));
694 blobmsg_add_u32(&buf
, "expires", atoi(p
));
700 if (!seen
[0] && !strncmp(p
, "src=", 4))
702 blobmsg_add_string(&buf
, "src", p
+ 4);
705 else if (!seen
[1] && !strncmp(p
, "dst=", 4))
707 blobmsg_add_string(&buf
, "dest", p
+ 4);
710 else if (!seen
[2] && !strncmp(p
, "sport=", 6))
712 blobmsg_add_u32(&buf
, "sport", atoi(p
+ 6));
715 else if (!seen
[3] && !strncmp(p
, "dport=", 6))
717 blobmsg_add_u32(&buf
, "dport", atoi(p
+ 6));
720 else if (!strncmp(p
, "packets=", 8))
722 blobmsg_add_u32(&buf
,
723 seen
[4] ? "tx_packets" : "rx_packets",
727 else if (!strncmp(p
, "bytes=", 6))
729 blobmsg_add_u32(&buf
,
730 seen
[5] ? "tx_bytes" : "rx_bytes",
737 blobmsg_close_table(&buf
, d
);
743 blobmsg_close_array(&buf
, c
);
744 ubus_send_reply(ctx
, req
, buf
.head
);
750 rpc_luci2_network_arp_table(struct ubus_context
*ctx
, struct ubus_object
*obj
,
751 struct ubus_request_data
*req
, const char *method
,
752 struct blob_attr
*msg
)
756 char *addr
, *mac
, *dev
, line
[128];
758 blob_buf_init(&buf
, 0);
759 c
= blobmsg_open_array(&buf
, "entries");
761 if ((f
= fopen("/proc/net/arp", "r")) != NULL
)
763 /* skip header line */
764 fgets(line
, sizeof(line
) - 1, f
);
766 while (fgets(line
, sizeof(line
) - 1, f
))
768 addr
= strtok(line
, " \t");
770 strtok(NULL
, " \t"); /* HW type */
771 strtok(NULL
, " \t"); /* Flags */
773 mac
= strtok(NULL
, " \t");
775 strtok(NULL
, " \t"); /* Mask */
777 dev
= strtok(NULL
, " \t\n");
782 d
= blobmsg_open_table(&buf
, NULL
);
783 blobmsg_add_string(&buf
, "ipaddr", addr
);
784 blobmsg_add_string(&buf
, "macaddr", mac
);
785 blobmsg_add_string(&buf
, "device", dev
);
786 blobmsg_close_table(&buf
, d
);
792 blobmsg_close_array(&buf
, c
);
793 ubus_send_reply(ctx
, req
, buf
.head
);
799 put_hexaddr(const char *name
, const char *s
, const char *m
)
803 char as
[sizeof("255.255.255.255/32\0")];
805 a
.s_addr
= strtoul(s
, NULL
, 16);
806 inet_ntop(AF_INET
, &a
, as
, sizeof(as
));
810 for (a
.s_addr
= ntohl(strtoul(m
, NULL
, 16)), bits
= 0;
811 a
.s_addr
& 0x80000000;
815 sprintf(as
+ strlen(as
), "/%u", bits
);
818 blobmsg_add_string(&buf
, name
, as
);
822 rpc_luci2_network_routes(struct ubus_context
*ctx
, struct ubus_object
*obj
,
823 struct ubus_request_data
*req
, const char *method
,
824 struct blob_attr
*msg
)
828 char *dst
, *dmask
, *next
, *metric
, *device
;
832 if (!(routes
= fopen("/proc/net/route", "r")))
833 return rpc_errno_status();
835 blob_buf_init(&buf
, 0);
836 c
= blobmsg_open_array(&buf
, "routes");
838 /* skip header line */
839 fgets(line
, sizeof(line
) - 1, routes
);
841 while (fgets(line
, sizeof(line
) - 1, routes
))
843 device
= strtok(line
, "\t ");
844 dst
= strtok(NULL
, "\t ");
845 next
= strtok(NULL
, "\t ");
847 strtok(NULL
, "\t "); /* flags */
848 strtok(NULL
, "\t "); /* refcount */
849 strtok(NULL
, "\t "); /* usecount */
851 metric
= strtok(NULL
, "\t ");
852 dmask
= strtok(NULL
, "\t ");
857 d
= blobmsg_open_table(&buf
, NULL
);
859 put_hexaddr("target", dst
, dmask
);
860 put_hexaddr("nexthop", next
, NULL
);
862 n
= strtoul(metric
, NULL
, 10);
863 blobmsg_add_u32(&buf
, "metric", n
);
865 blobmsg_add_string(&buf
, "device", device
);
867 blobmsg_close_table(&buf
, d
);
870 blobmsg_close_array(&buf
, c
);
873 ubus_send_reply(ctx
, req
, buf
.head
);
878 put_hex6addr(const char *name
, const char *s
, const char *m
)
882 char as
[INET6_ADDRSTRLEN
+ sizeof("/128")];
885 (((x) <= '9') ? ((x) - '0') : \
886 (((x) <= 'F') ? ((x) - 'A' + 10) : \
889 for (i
= 0; i
< 16; i
++, s
+= 2)
890 a
.s6_addr
[i
] = (16 * hex(*s
)) + hex(*(s
+1));
892 inet_ntop(AF_INET6
, &a
, as
, sizeof(as
));
895 sprintf(as
+ strlen(as
), "/%lu", strtoul(m
, NULL
, 16));
897 blobmsg_add_string(&buf
, name
, as
);
901 rpc_luci2_network_routes6(struct ubus_context
*ctx
, struct ubus_object
*obj
,
902 struct ubus_request_data
*req
, const char *method
,
903 struct blob_attr
*msg
)
907 char *src
, *smask
, *dst
, *dmask
, *next
, *metric
, *flags
, *device
;
911 if (!(routes
= fopen("/proc/net/ipv6_route", "r")))
912 return rpc_errno_status();
914 blob_buf_init(&buf
, 0);
915 c
= blobmsg_open_array(&buf
, "routes");
917 while (fgets(line
, sizeof(line
) - 1, routes
))
919 dst
= strtok(line
, " ");
920 dmask
= strtok(NULL
, " ");
921 src
= strtok(NULL
, " ");
922 smask
= strtok(NULL
, " ");
923 next
= strtok(NULL
, " ");
924 metric
= strtok(NULL
, " ");
926 strtok(NULL
, " "); /* refcount */
927 strtok(NULL
, " "); /* usecount */
929 flags
= strtok(NULL
, " ");
930 device
= strtok(NULL
, " \n");
935 n
= strtoul(flags
, NULL
, 16);
940 d
= blobmsg_open_table(&buf
, NULL
);
942 put_hex6addr("target", dst
, dmask
);
943 put_hex6addr("source", src
, smask
);
944 put_hex6addr("nexthop", next
, NULL
);
946 n
= strtoul(metric
, NULL
, 16);
947 blobmsg_add_u32(&buf
, "metric", n
);
949 blobmsg_add_string(&buf
, "device", device
);
951 blobmsg_close_table(&buf
, d
);
954 blobmsg_close_array(&buf
, c
);
957 ubus_send_reply(ctx
, req
, buf
.head
);
962 int rpc_luci2_api_init(struct ubus_context
*ctx
)
966 static const struct ubus_method luci2_system_methods
[] = {
967 UBUS_METHOD_NOARG("syslog", rpc_luci2_system_log
),
968 UBUS_METHOD_NOARG("dmesg", rpc_luci2_system_dmesg
),
969 UBUS_METHOD_NOARG("process_list", rpc_luci2_process_list
),
970 UBUS_METHOD("process_signal", rpc_luci2_process_signal
,
972 UBUS_METHOD_NOARG("init_list", rpc_luci2_init_list
),
973 UBUS_METHOD("init_action", rpc_luci2_init_action
,
977 static struct ubus_object_type luci2_system_type
=
978 UBUS_OBJECT_TYPE("luci-rpc-luci2-system", luci2_system_methods
);
980 static struct ubus_object system_obj
= {
981 .name
= "luci2.system",
982 .type
= &luci2_system_type
,
983 .methods
= luci2_system_methods
,
984 .n_methods
= ARRAY_SIZE(luci2_system_methods
),
988 static const struct ubus_method luci2_network_methods
[] = {
989 UBUS_METHOD_NOARG("conntrack_count", rpc_luci2_network_ct_count
),
990 UBUS_METHOD_NOARG("conntrack_table", rpc_luci2_network_ct_table
),
991 UBUS_METHOD_NOARG("arp_table", rpc_luci2_network_arp_table
),
992 UBUS_METHOD_NOARG("dhcp_leases", rpc_luci2_network_leases
),
993 UBUS_METHOD_NOARG("dhcp6_leases", rpc_luci2_network_leases6
),
994 UBUS_METHOD_NOARG("routes", rpc_luci2_network_routes
),
995 UBUS_METHOD_NOARG("routes6", rpc_luci2_network_routes6
),
998 static struct ubus_object_type luci2_network_type
=
999 UBUS_OBJECT_TYPE("luci-rpc-luci2-network", luci2_network_methods
);
1001 static struct ubus_object network_obj
= {
1002 .name
= "luci2.network",
1003 .type
= &luci2_network_type
,
1004 .methods
= luci2_network_methods
,
1005 .n_methods
= ARRAY_SIZE(luci2_network_methods
),
1008 cursor
= uci_alloc_context();
1011 return UBUS_STATUS_UNKNOWN_ERROR
;
1013 rv
|= ubus_add_object(ctx
, &system_obj
);
1014 rv
|= ubus_add_object(ctx
, &network_obj
);