remove dummy mode
[project/unetd.git] / main.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
4 */
5 #define _GNU_SOURCE
6 #include <unistd.h>
7 #include <arpa/inet.h>
8 #include <libubox/uloop.h>
9 #include <libubox/blobmsg_json.h>
10 #include "unetd.h"
11
12 struct cmdline_network {
13 struct cmdline_network *next;
14 char *data;
15 };
16
17 static struct cmdline_network *cmd_nets;
18 static const char *hosts_file;
19 const char *mssfix_path = UNETD_MSS_BPF_PATH;
20 bool debug;
21
22 static void
23 network_write_hosts(struct network *net, FILE *f)
24 {
25 struct network_host *host;
26 char ip[INET6_ADDRSTRLEN];
27
28 if (!net->net_config.local_host)
29 return;
30
31 avl_for_each_element(&net->hosts, host, node) {
32 inet_ntop(AF_INET6, &host->peer.local_addr, ip, sizeof(ip));
33 fprintf(f, "%s\t%s\n", ip, network_host_name(host));
34 }
35 }
36
37 void unetd_write_hosts(void)
38 {
39 struct network *net;
40 char *tmpfile = NULL;
41 FILE *f;
42 int fd;
43
44 if (!hosts_file)
45 return;
46
47 asprintf(&tmpfile, "%s.XXXXXXXX", hosts_file);
48 fd = mkstemp(tmpfile);
49 if (fd < 0) {
50 perror("mkstemp");
51 goto out;
52 }
53
54 chmod(tmpfile, 0644);
55 f = fdopen(fd, "w");
56 if (!f) {
57 close(fd);
58 goto out;
59 }
60
61 avl_for_each_element(&networks, net, node)
62 network_write_hosts(net, f);
63
64 fclose(f);
65
66 if (rename(tmpfile, hosts_file))
67 unlink(tmpfile);
68
69 out:
70 free(tmpfile);
71 }
72
73 static void add_networks(void)
74 {
75 struct cmdline_network *net;
76 static struct blob_buf b;
77 struct blob_attr *name;
78
79 for (net = cmd_nets; net; net = net->next) {
80 blob_buf_init(&b, 0);
81 if (!blobmsg_add_json_from_string(&b, net->data))
82 continue;
83
84 blobmsg_parse(&network_policy[NETWORK_ATTR_NAME], 1, &name,
85 blobmsg_data(b.head), blobmsg_len(b.head));
86 if (!name)
87 continue;
88
89 unetd_network_add(blobmsg_get_string(name), b.head);
90 }
91
92 blob_buf_free(&b);
93 }
94
95 int main(int argc, char **argv)
96 {
97 struct cmdline_network *net;
98 int ch;
99
100 while ((ch = getopt(argc, argv, "dh:M:N:")) != -1) {
101 switch (ch) {
102 case 'd':
103 debug = true;
104 break;
105 case 'h':
106 hosts_file = optarg;
107 break;
108 case 'N':
109 net = calloc(1, sizeof(*net));
110 net->next = cmd_nets;
111 net->data = optarg;
112 cmd_nets = net;
113 break;
114 case 'M':
115 mssfix_path = optarg;
116 break;
117 }
118 }
119
120 uloop_init();
121 unetd_ubus_init();
122 unetd_write_hosts();
123 add_networks();
124 uloop_run();
125 network_free_all();
126 uloop_done();
127
128 return 0;
129 }