123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
- * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
- */
- #define _GNU_SOURCE
- #include <unistd.h>
- #include <arpa/inet.h>
- #include <libubox/uloop.h>
- #include <libubox/blobmsg_json.h>
- #include "unetd.h"
- struct cmdline_network {
- struct cmdline_network *next;
- char *data;
- };
- static struct cmdline_network *cmd_nets;
- static const char *hosts_file;
- const char *mssfix_path = UNETD_MSS_BPF_PATH;
- const char *data_dir = UNETD_DATA_DIR;
- int global_pex_port = UNETD_GLOBAL_PEX_PORT;
- bool debug;
- static void
- network_write_hosts(struct network *net, FILE *f)
- {
- struct network_host *host;
- char ip[INET6_ADDRSTRLEN];
- if (!net->net_config.local_host)
- return;
- avl_for_each_element(&net->hosts, host, node) {
- inet_ntop(AF_INET6, &host->peer.local_addr, ip, sizeof(ip));
- fprintf(f, "%s\t%s%s%s\n", ip, network_host_name(host),
- net->config.domain ? "." : "",
- net->config.domain ? net->config.domain : "");
- }
- }
- void unetd_write_hosts(void)
- {
- struct network *net;
- char *tmpfile = NULL;
- FILE *f;
- int fd;
- if (!hosts_file)
- return;
- if (asprintf(&tmpfile, "%s.XXXXXXXX", hosts_file) < 0)
- return;
- fd = mkstemp(tmpfile);
- if (fd < 0) {
- perror("mkstemp");
- goto out;
- }
- chmod(tmpfile, 0644);
- f = fdopen(fd, "w");
- if (!f) {
- close(fd);
- goto out;
- }
- avl_for_each_element(&networks, net, node)
- network_write_hosts(net, f);
- fclose(f);
- if (rename(tmpfile, hosts_file))
- unlink(tmpfile);
- out:
- free(tmpfile);
- }
- static void add_networks(void)
- {
- struct cmdline_network *net;
- static struct blob_buf b;
- struct blob_attr *name;
- for (net = cmd_nets; net; net = net->next) {
- blob_buf_init(&b, 0);
- if (!blobmsg_add_json_from_string(&b, net->data))
- continue;
- blobmsg_parse(&network_policy[NETWORK_ATTR_NAME], 1, &name,
- blobmsg_data(b.head), blobmsg_len(b.head));
- if (!name)
- continue;
- unetd_network_add(blobmsg_get_string(name), b.head);
- }
- blob_buf_free(&b);
- }
- int main(int argc, char **argv)
- {
- struct cmdline_network *net;
- const char *unix_socket = NULL;
- int ch;
- while ((ch = getopt(argc, argv, "D:dh:u:M:N:P:")) != -1) {
- switch (ch) {
- case 'D':
- data_dir = optarg;
- break;
- case 'd':
- debug = true;
- break;
- case 'h':
- hosts_file = optarg;
- break;
- case 'N':
- net = calloc(1, sizeof(*net));
- net->next = cmd_nets;
- net->data = optarg;
- cmd_nets = net;
- break;
- case 'M':
- mssfix_path = optarg;
- break;
- case 'P':
- global_pex_port = atoi(optarg);
- break;
- case 'u':
- unix_socket = optarg;
- break;
- }
- }
- uloop_init();
- unetd_ubus_init();
- unetd_write_hosts();
- global_pex_open(unix_socket);
- add_networks();
- uloop_run();
- pex_close();
- network_free_all();
- uloop_done();
- return 0;
- }
|