• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/omcproxy/src/omcproxy.c

  1 /*
  2  * Copyright 2015 Steven Barth <steven at midlink.org>
  3  *
  4  * Licensed under the Apache License, Version 2.0 (the "License");
  5  * you may not use this file except in compliance with the License.
  6  * You may obtain a copy of the License at
  7  *
  8  *  http://www.apache.org/licenses/LICENSE-2.0
  9  *
 10  * Unless required by applicable law or agreed to in writing, software
 11  * distributed under the License is distributed on an "AS IS" BASIS,
 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  * See the License for the specific language governing permissions and
 14  * limitations under the License.
 15  *
 16  */
 17 
 18 #include <stdio.h>
 19 #include <signal.h>
 20 #include <string.h>
 21 #include <stdlib.h>
 22 #include <netdb.h>
 23 #include <net/if.h>
 24 #include <unistd.h>
 25 
 26 #include <libubox/uloop.h>
 27 #include <libubox/blobmsg.h>
 28 
 29 #include "omcproxy.h"
 30 #include "proxy.h"
 31 
 32 int log_level = LOG_WARNING;
 33 
 34 
 35 enum {
 36         PROXY_ATTR_SOURCE,
 37         PROXY_ATTR_SCOPE,
 38         PROXY_ATTR_DEST,
 39         PROXY_ATTR_MAX,
 40 };
 41 
 42 static struct blobmsg_policy proxy_policy[PROXY_ATTR_MAX] = {
 43         [PROXY_ATTR_SOURCE] = { .name = "source", .type = BLOBMSG_TYPE_STRING },
 44         [PROXY_ATTR_SCOPE] = { .name = "scope", .type = BLOBMSG_TYPE_STRING },
 45         [PROXY_ATTR_DEST] = { .name = "dest", .type = BLOBMSG_TYPE_ARRAY },
 46 };
 47 
 48 static int handle_proxy_set(void *data, size_t len)
 49 {
 50         struct blob_attr *tb[PROXY_ATTR_MAX], *c;
 51         blobmsg_parse(proxy_policy, PROXY_ATTR_MAX, tb, data, len);
 52 
 53         const char *name = ((c = tb[PROXY_ATTR_SOURCE])) ? blobmsg_get_string(c) : NULL;
 54         int uplink = 0;
 55         int downlinks[32] = {0};
 56         size_t downlinks_cnt = 0;
 57         enum proxy_flags flags = 0;
 58 
 59         if (!name)
 60                 return -EINVAL;
 61 
 62         if (!(uplink = if_nametoindex(name))) {
 63                 L_WARN("%s(%s): %s", __FUNCTION__, name, strerror(errno));
 64                 return -errno;
 65         }
 66 
 67         if ((c = tb[PROXY_ATTR_SCOPE])) {
 68                 const char *scope = blobmsg_get_string(c);
 69                 if (!strcmp(scope, "global"))
 70                         flags = PROXY_GLOBAL;
 71                 else if (!strcmp(scope, "organization"))
 72                         flags = PROXY_ORGLOCAL;
 73                 else if (!strcmp(scope, "site"))
 74                         flags = PROXY_SITELOCAL;
 75                 else if (!strcmp(scope, "admin"))
 76                         flags = PROXY_ADMINLOCAL;
 77                 else if (!strcmp(scope, "realm"))
 78                         flags = PROXY_REALMLOCAL;
 79 
 80                 if (!flags) {
 81                         L_WARN("%s(%s): invalid scope (%s)", __FUNCTION__, name, scope);
 82                         return -EINVAL;
 83                 }
 84         }
 85 
 86         if ((c = tb[PROXY_ATTR_DEST])) {
 87                 struct blob_attr *d;
 88                 unsigned rem;
 89                 blobmsg_for_each_attr(d, c, rem) {
 90                         if (downlinks_cnt >= 32) {
 91                                 L_WARN("%s(%s): maximum number of destinations exceeded", __FUNCTION__, name);
 92                                 return -EINVAL;
 93                         }
 94 
 95                         const char *n = blobmsg_type(d) == BLOBMSG_TYPE_STRING ? blobmsg_get_string(d) : "";
 96                         if (!(downlinks[downlinks_cnt++] = if_nametoindex(n))) {
 97                                 L_WARN("%s(%s): %s (%s)", __FUNCTION__, name, strerror(errno), blobmsg_get_string(d));
 98                                 return -errno;
 99                         }
100                 }
101         }
102 
103         return proxy_set(uplink, downlinks, downlinks_cnt, flags);
104 }
105 
106 static void handle_signal(__unused int signal)
107 {
108         uloop_end();
109 }
110 
111 static void usage(const char *arg) {
112         fprintf(stderr, "Usage: %s [options] <proxy1> [<proxy2>] [...]\n"
113                         "\nProxy examples:\n"
114                         "eth1,eth2\n"
115                         "eth1,eth2,eth3,scope=organization\n"
116                         "\nProxy options (each option may only occur once):\n"
117                         "       <interface>                     interfaces to proxy (first is uplink)\n"
118                         "       scope=<scope>                   minimum multicast scope to proxy\n"
119                         "               [global,organization,site,admin,realm] (default: global)\n"
120                         "\nOptions:\n"
121                         "       -v                              verbose logging\n"
122                         "       -h                              show this help\n",
123         arg);
124 }
125 
126 int main(int argc, char **argv) {
127         signal(SIGINT, handle_signal);
128         signal(SIGTERM, handle_signal);
129         signal(SIGHUP, SIG_IGN);
130         signal(SIGPIPE, SIG_IGN);
131         openlog("omcproxy", LOG_PERROR, LOG_DAEMON);
132 
133         if (getuid()) {
134                 L_ERR("must be run as root!");
135                 return 2;
136         }
137 
138         uloop_init();
139         bool start = true;
140 
141         for (ssize_t i = 1; i < argc; ++i) {
142                 const char *source = NULL;
143                 const char *scope = NULL;
144                 struct blob_buf b = {NULL, NULL, 0, NULL};
145 
146                 if (!strcmp(argv[i], "-h")) {
147                         usage(argv[0]);
148                         return 1;
149                 } else if (!strncmp(argv[i], "-v", 2)) {
150                         if ((log_level = atoi(&argv[i][2])) <= 0)
151                                 log_level = 7;
152                         continue;
153                 }
154 
155 
156                 blob_buf_init(&b, 0);
157 
158                 void *k = blobmsg_open_array(&b, "dest");
159                 for (char *c = strtok(argv[i], ","); c; c = strtok(NULL, ",")) {
160                         if (!strncmp(c, "scope=", 6)) {
161                                 scope = &c[6];
162                         } else if (!source) {
163                                 source = c;
164                         } else {
165                                 blobmsg_add_string(&b, NULL, c);
166                         }
167                 }
168                 blobmsg_close_array(&b, k);
169 
170                 if (source)
171                         blobmsg_add_string(&b, "source", source);
172 
173                 if (scope)
174                         blobmsg_add_string(&b, "scope", scope);
175 
176                 if (handle_proxy_set(blob_data(b.head), blob_len(b.head))) {
177                         fprintf(stderr, "failed to setup proxy: %s\n", argv[i]);
178                         start = false;
179                 }
180 
181                 blob_buf_free(&b);
182         }
183 
184         if (argc < 2) {
185                 usage(argv[0]);
186                 start = false;
187         }
188 
189         if (start)
190                 uloop_run();
191 
192         proxy_update(true);
193         proxy_flush();
194 
195         uloop_done();
196         return 0;
197 }
198 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt