1 /*
2 * $Id$
3 *
4 * Copyright (c) 2008, 2009, 2010
5 * Sten Spans <sten@blinkenlights.nl>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 #include "common.h"
21 #include "util.h"
22 #include "proto/protos.h"
23 #include "child.h"
24 #include <sys/un.h>
25 #include <time.h>
26
27 #ifdef HAVE_LIBMNL
28 #include <libmnl/libmnl.h>
29 #include <linux/rtnetlink.h>
30 #elif defined(HAVE_NET_ROUTE_H)
31 #include <net/route.h>
32 #ifndef LINK_STATE_IS_UP
33 #define LINK_STATE_IS_UP(_s) \
34 ((_s) >= LINK_STATE_UP || (_s) == LINK_STATE_UNKNOWN)
35 #endif
36 #endif
37 #ifdef HAVE_NET_IF_TYPES_H
38 #include <net/if_types.h>
39 #endif /* HAVE_NET_IF_TYPES_H */
40
41 int sargc = 0;
42 char **sargv = NULL;
43
44 struct nhead netifs;
45 struct ehead exclifs;
46 struct mhead mqueue;
47 struct my_sysinfo sysinfo;
48 extern struct proto protos[];
49
child_init(int reqfd,int msgfd,int ifc,char * ifl[],struct passwd * pwd)50 void child_init(int reqfd, int msgfd, int ifc, char *ifl[],
51 struct passwd *pwd) {
52
53 // events
54 struct child_send_args args = { .index = NETIF_INDEX_MAX };
55 struct event evq, eva, evl;
56 struct event ev_sigterm, ev_sigint;
57
58 // parent socket
59 extern int msock;
60 int lsock, csock = -1;
61 struct sockaddr_un usock;
62 mode_t old_umask;
63
64 sargc = ifc;
65 sargv = ifl;
66
67 // init the queues
68 TAILQ_INIT(&netifs);
69 TAILQ_INIT(&mqueue);
70
71 // configure command socket
72 msock = reqfd;
73
74 // configure unix socket
75 if (!(options & (OPT_DEBUG|OPT_ONCE))) {
76
77 csock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
78 // XXX: make do with a stream and hope for the best
79 if ((csock == -1) && (errno == EPROTONOSUPPORT))
80 csock = my_socket(AF_UNIX, SOCK_STREAM, 0);
81 if (csock == -1)
82 my_fatale("failed to create socket");
83
84 memset(&usock, 0, sizeof(usock));
85 usock.sun_family = AF_UNIX;
86 strlcpy(usock.sun_path, PACKAGE_SOCKET, sizeof(usock.sun_path));
87
88 old_umask = umask(S_IXUSR|S_IRWXG|S_IRWXO);
89
90 if ((unlink(PACKAGE_SOCKET) == -1) && (errno != ENOENT))
91 my_fatale("failed to remove " PACKAGE_SOCKET);
92 if (bind(csock, (struct sockaddr *)&usock, SUN_LEN(&usock)) == -1)
93 my_fatale("failed to bind " PACKAGE_SOCKET);
94 if (options & OPT_RECV) {
95 if (listen(csock, 10) == -1)
96 my_fatale("failed to listen on " PACKAGE_SOCKET);
97 }
98
99 if (chmod(PACKAGE_SOCKET, S_IRWXU|S_IRWXG) == -1)
100 my_fatale("failed to chmod " PACKAGE_SOCKET);
101 if (chown(PACKAGE_SOCKET, -1, pwd->pw_gid) == -1)
102 my_fatal("failed to chown " PACKAGE_SOCKET);
103
104 umask(old_umask);
105 }
106
107 // initalize the events and netifs
108 event_init();
109 netif_init();
110
111 // drop privileges
112 if (!(options & OPT_DEBUG)) {
113 my_chroot(PACKAGE_CHROOT_DIR);
114 my_drop_privs(pwd);
115 my_rlimit_child();
116 }
117
118 // proctitle
119 setproctitle("child");
120
121 // startup message
122 my_log(CRIT, PACKAGE_STRING " running");
123
124 // create and run the transmit event
125 event_set(&args.event, msgfd, 0, (void *)child_send, &args);
126 child_send(msgfd, EV_TIMEOUT, &args);
127
128 if (options & OPT_ONCE)
129 exit(EXIT_SUCCESS);
130
131 if (options & OPT_RECV) {
132 // listen for messages from the parent
133 event_set(&evq, msgfd, EV_READ|EV_PERSIST, (void *)child_queue, NULL);
134 event_add(&evq, NULL);
135
136 signal_set(&ev_sigint, SIGINT, child_free, NULL);
137 signal_set(&ev_sigterm, SIGTERM, child_free, NULL);
138 signal_add(&ev_sigint, NULL);
139 signal_add(&ev_sigterm, NULL);
140
141 // accept cli connections
142 if (csock != -1) {
143 event_set(&eva, csock, EV_READ|EV_PERSIST,
144 (void *)child_cli_accept, NULL);
145 event_add(&eva, NULL);
146 }
147 }
148
149 // create link fd
150 if ((lsock = child_link_fd()) != -1) {
151 event_set(&evl, lsock, EV_READ|EV_PERSIST,
152 child_link, (void *)&msgfd);
153 event_add(&evl, NULL);
154 }
155
156 // wait for events
157 event_dispatch();
158
159 // not reached
160 my_fatal("child event-loop failed");
161 }
162
child_send(int fd,short event,struct child_send_args * args)163 void child_send(int fd, short event, struct child_send_args *args) {
164 struct parent_msg msg;
165 struct netif *netif = NULL, *subif = NULL, *linkif = NULL;
166 ssize_t len;
167
168 // bail early on known flapping interfaces
169 if (args->index != NETIF_INDEX_MAX) {
170 linkif = netif_byindex(&netifs, args->index);
171 if (linkif && (linkif->link_event > 3))
172 goto out;
173 }
174
175 // update netifs
176 my_log(INFO, "fetching all interfaces");
177
178 // no configured ethernet interfaces found
179 if (netif_fetch(sargc, sargv, &sysinfo, &netifs) == 0)
180 goto out;
181
182 // no interface matching the given ifindex found
183 if (args->index != NETIF_INDEX_MAX) {
184 if ((linkif = netif_byindex(&netifs, args->index)) == NULL)
185 goto out;
186 }
187
188 while ((netif = netif_iter(netif, &netifs)) != NULL) {
189
190 // skip special interfaces
191 if (netif->type < NETIF_REGULAR)
192 continue;
193 if ((netif->type == NETIF_WIRELESS) && !(options & OPT_WIRELESS))
194 continue;
195 if ((netif->type == NETIF_TAP) && !(options & OPT_TAP))
196 continue;
197
198 // skip excluded interfaces
199 if (netif_excluded(netif, &exclifs))
200 continue;
201
202 my_log(INFO, "starting loop with interface %s", netif->name);
203
204 while ((subif = subif_iter(subif, netif)) != NULL) {
205
206 // handle a given ifindex
207 if (args->index != NETIF_INDEX_MAX) {
208 if (args->index != subif->index)
209 continue;
210 subif->link_event++;
211 } else {
212 subif->link_event = 0;
213 }
214
215 // skip special interfaces
216 if (subif->type < NETIF_REGULAR)
217 continue;
218 if ((subif->type == NETIF_WIRELESS) && !(options & OPT_WIRELESS))
219 continue;
220 if ((subif->type == NETIF_TAP) && !(options & OPT_TAP))
221 continue;
222
223 // skip excluded interfaces
224 if (netif_excluded(subif, &exclifs))
225 continue;
226
227 // populate msg
228 memset(&msg, 0, sizeof(msg));
229 msg.index = subif->index;
230
231 // explicitly listen when recv is enabled
232 if ((options & OPT_RECV) && (subif->protos == 0)) {
233 struct parent_req mreq = {};
234 mreq.op = PARENT_OPEN;
235 mreq.index = subif->index;
236 my_mreq(&mreq);
237 }
238
239 // fetch interface media status
240 my_log(INFO, "fetching %s media details", subif->name);
241 if (netif_media(subif) == EXIT_FAILURE)
242 my_log(CRIT, "error fetching interface media details");
243
244 // bail if sending packets is disabled
245 if (!(options & OPT_SEND))
246 continue;
247
248 // generate and send packets
249 for (int p = 0; protos[p].name != NULL; p++) {
250
251 // only enabled protos
252 if (!(protos[p].enabled) && !(netif->protos & (1 << p)))
253 continue;
254
255 // clear packet
256 memset(msg.msg, 0, ETHER_MAX_LEN);
257
258 my_log(INFO, "building %s packet for %s",
259 protos[p].name, subif->name);
260 msg.proto = p;
261 msg.len = protos[p].build(p, msg.msg, subif,
262 &netifs, &sysinfo);
263
264 if (msg.len == 0) {
265 my_log(CRIT, "can't generate %s packet for %s",
266 protos[p].name, subif->name);
267 continue;
268 }
269
270 // zero the src when sending on a backup subif
271 if ((netif->bonding_mode == NETIF_BONDING_FAILOVER) &&
272 (subif->child != NETIF_CHILD_ACTIVE))
273 memset(msg.msg + ETHER_ADDR_LEN, 0, ETHER_ADDR_LEN);
274
275 // write it to the wire.
276 my_log(INFO, "sending %s packet (%zu bytes) on %s",
277 protos[p].name, msg.len, subif->name);
278 len = write(fd, &msg, PARENT_MSG_LEN(msg.len));
279 if (len < PARENT_MSG_MIN || len != PARENT_MSG_LEN(msg.len))
280 my_fatale("only %zi bytes written", len);
281 }
282 }
283 }
284
285 out:
286 if (event != EV_TIMEOUT)
287 return;
288
289 // delete old messages
290 if (options & OPT_RECV)
291 child_expire();
292
293 // schedule the next run
294 struct timeval tv = { .tv_sec = SLEEPTIME };
295 event_add(&args->event, &tv);
296 }
297
child_queue(int fd,short __unused (event))298 void child_queue(int fd, short __unused(event)) {
299 struct parent_msg rmsg = {};
300 struct parent_msg *msg = NULL, *qmsg = NULL, *pmsg = NULL;
301 struct netif *subif, *netif;
302 struct ether_hdr *ether;
303 time_t now;
304 ssize_t len;
305
306 my_log(INFO, "receiving message from parent");
307 if ((len = read(fd, &rmsg, PARENT_MSG_MAX)) == -1)
308 return;
309 if (len < PARENT_MSG_MIN || len != PARENT_MSG_LEN(rmsg.len))
310 return;
311 if ((now = time(NULL)) == (time_t)-1)
312 return;
313
314 assert(rmsg.proto < PROTO_MAX);
315 assert(rmsg.len <= ETHER_MAX_LEN);
316
317 // skip unknown interfaces
318 if ((subif = netif_byindex(&netifs, rmsg.index)) == NULL)
319 return;
320 strlcpy(rmsg.name, subif->name, sizeof(rmsg.name));
321
322 // skip locally generated packets
323 ether = (struct ether_hdr *)rmsg.msg;
324 if (netif_byaddr(&netifs, ether->src) != NULL)
325 return;
326
327 // decode message
328 my_log(INFO, "decoding advertisement");
329 rmsg.decode = DECODE_STR;
330 if (protos[rmsg.proto].decode(&rmsg) == 0) {
331 peer_free(rmsg.peer);
332 return;
333 }
334
335 // add current timestamp unless it's a shutdown msg
336 if (rmsg.ttl)
337 rmsg.received = now;
338
339 // fetch the parent netif
340 if (subif->parent)
341 netif = subif->parent;
342 else
343 netif = subif;
344
345 TAILQ_FOREACH(qmsg, &mqueue, entries) {
346 // match ifindex
347 if (rmsg.index != qmsg->index)
348 continue;
349 // save a pointer if the message peer matches
350 if (memcmp(rmsg.msg + ETHER_ADDR_LEN, qmsg->msg + ETHER_ADDR_LEN,
351 ETHER_ADDR_LEN) == 0)
352 pmsg = qmsg;
353 // match protocol
354 if (rmsg.proto != qmsg->proto)
355 continue;
356 // identical source & destination
357 if (memcmp(rmsg.msg, qmsg->msg, ETHER_ADDR_LEN * 2) != 0)
358 continue;
359
360 msg = qmsg;
361 break;
362 }
363
364 if (msg != NULL) {
365 // free the old peer decode
366 peer_free(msg->peer);
367 // copy everything upto the tailq_entry
368 memcpy(msg, &rmsg, offsetof(struct parent_msg, entries));
369 } else {
370 char *hostname = NULL;
371
372 msg = my_malloc(PARENT_MSG_SIZ);
373 memcpy(msg, &rmsg, offsetof(struct parent_msg, entries));
374 // group messages per peer
375 if (pmsg)
376 TAILQ_INSERT_AFTER(&mqueue, pmsg, msg, entries);
377 else
378 TAILQ_INSERT_TAIL(&mqueue, msg, entries);
379
380 hostname = msg->peer[PEER_HOSTNAME];
381 if (hostname)
382 my_log(CRIT, "new peer %s (%s) on interface %s",
383 hostname, protos[msg->proto].name, netif->name);
384 }
385
386 // handle shutdowns via child_expire
387 if (!msg->ttl) {
388 child_expire();
389 return;
390 }
391
392 // update ifdescr
393 if (options & OPT_IFDESCR)
394 netif_descr(subif, &mqueue);
395
396 // return unless we need to enable the received protocol
397 if (!(options & OPT_AUTO) || (netif->protos & (1 << msg->proto)))
398 return;
399
400 // only enable if subif or netif are listed
401 if (options & OPT_ARGV) {
402 if (!(subif->argv) && !(netif->argv))
403 return;
404 }
405
406 my_log(CRIT, "enabling %s on interface %s",
407 protos[msg->proto].name, netif->name);
408 netif->protos |= (1 << msg->proto);
409 }
410
child_expire()411 void child_expire() {
412 time_t now;
413 struct parent_msg *msg = NULL, *nmsg = NULL;
414 struct netif *netif = NULL, *subif = NULL;
415 char *hostname = NULL;
416
417 if ((now = time(NULL)) == (time_t)-1)
418 return;
419
420 // remove expired messages
421 TAILQ_FOREACH_SAFE(msg, &mqueue, entries, nmsg) {
422 if (likely((msg->received + msg->ttl) >= now))
423 continue;
424 if (unlikely(msg->lock))
425 continue;
426
427 hostname = msg->peer[PEER_HOSTNAME];
428 if (hostname)
429 my_log(CRIT, "removing peer %s (%s)",
430 hostname, protos[msg->proto].name);
431
432 // mark the interface
433 if ((subif = netif_byindex(&netifs, msg->index)) != NULL)
434 subif->update = 1;
435
436 TAILQ_REMOVE(&mqueue, msg, entries);
437 peer_free(msg->peer);
438 free(msg);
439 }
440
441 // update interfaces
442 TAILQ_FOREACH(subif, &netifs, entries) {
443 if (likely(!subif->update))
444 continue;
445
446 // fetch the parent netif
447 if (subif->parent)
448 netif = subif->parent;
449 else
450 netif = subif;
451
452 // update protos
453 if (options & OPT_AUTO)
454 netif_protos(netif, &mqueue);
455
456 // update ifdescr
457 if (options & OPT_IFDESCR)
458 netif_descr(subif, &mqueue);
459
460 subif->update = 0;
461 }
462 }
463
child_free(int __unused (sig),short __unused (event),void __unused (* arg))464 void child_free(int __unused(sig), short __unused(event), void __unused(*arg)) {
465 struct parent_msg *msg = NULL, *nmsg = NULL;
466
467 TAILQ_FOREACH_SAFE(msg, &mqueue, entries, nmsg) {
468 TAILQ_REMOVE(&mqueue, msg, entries);
469 peer_free(msg->peer);
470 free(msg);
471 }
472 exit(EXIT_SUCCESS);
473 }
474
child_cli_accept(int socket,short __unused (event))475 void child_cli_accept(int socket, short __unused(event)) {
476 int fd, sndbuf = PARENT_MSG_MAX * 10;
477 struct sockaddr sa;
478 socklen_t addrlen = sizeof(sa);
479 struct child_session *session = NULL;
480 struct timeval tv = { .tv_sec = 1 };
481
482 if ((fd = accept(socket, &sa, &addrlen)) == -1) {
483 my_log(WARN, "cli connection failed");
484 return;
485 }
486
487 my_nonblock(fd);
488 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) == -1)
489 my_loge(WARN, "failed to set sndbuf");
490
491 session = my_malloc(sizeof(struct child_session));
492 event_set(&session->event, fd, EV_WRITE, (void *)child_cli_write, session);
493 event_add(&session->event, &tv);
494 }
495
child_cli_write(int fd,short event,struct child_session * sess)496 void child_cli_write(int fd, short event, struct child_session *sess) {
497 struct parent_msg *msg = sess->msg;
498 struct timeval tv = { .tv_sec = 1 };
499
500 if (event == EV_TIMEOUT)
501 goto cleanup;
502
503 // grab the first message
504 if (!msg)
505 msg = TAILQ_FIRST(&mqueue);
506 // or release
507 else
508 msg->lock--;
509
510 for (; msg != NULL; msg = TAILQ_NEXT(msg, entries)) {
511 if (write(fd, msg, PARENT_MSG_MAX) != -1)
512 continue;
513
514 // bail unless non-block
515 if (errno != EAGAIN)
516 break;
517
518 // schedule a new event
519 msg->lock++;
520 sess->msg = msg;
521 event_set(&sess->event, fd, EV_WRITE, (void *)child_cli_write, sess);
522 event_add(&sess->event, &tv);
523 return;
524 }
525
526 cleanup:
527 event_del(&sess->event);
528 free(sess);
529 close(fd);
530 }
531
532 #ifdef HAVE_LIBMNL
533 struct mnl_socket *nl;
534 #endif
535
child_link_fd()536 int child_link_fd() {
537
538 #ifdef HAVE_LIBMNL
539 nl = mnl_socket_open(NETLINK_ROUTE);
540 if (nl == NULL)
541 return -1;
542
543 if (mnl_socket_bind(nl, RTMGRP_LINK, MNL_SOCKET_AUTOPID) < 0) {
544 mnl_socket_close(nl);
545 return -1;
546 }
547 my_nonblock(mnl_socket_get_fd(nl));
548
549 return mnl_socket_get_fd(nl);
550 #endif
551
552 #if defined(HAVE_NET_ROUTE_H) && defined(RTM_IFINFO)
553 int fd;
554
555 if ((fd = socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
556 return fd;
557
558 #if defined(ROUTE_MSGFILTER)
559 unsigned int rtfilter = ROUTE_FILTER(RTM_IFINFO);
560 if (setsockopt(fd, PF_ROUTE, ROUTE_MSGFILTER,
561 &rtfilter, sizeof(rtfilter)) == -1) {
562 close(fd);
563 fd = -1;
564 }
565 #endif
566
567 return fd;
568 #endif
569
570 return -1;
571 }
572
573 #ifdef HAVE_LIBMNL
child_link_cb(const struct nlmsghdr * nlh,void * msgfd)574 static int child_link_cb(const struct nlmsghdr *nlh, void *msgfd) {
575 struct ifinfomsg *ifm = mnl_nlmsg_get_payload(nlh);
576 int ifi_flags = IFF_RUNNING|IFF_LOWER_UP;
577 struct child_send_args args = {};
578
579 if (ifm->ifi_type != ARPHRD_ETHER)
580 goto out;
581 if ((ifm->ifi_flags & ifi_flags) != ifi_flags)
582 goto out;
583
584 my_log(INFO, "invoking child_send");
585 args.index = ifm->ifi_index;
586 child_send(*(int*)msgfd, 0, &args);
587
588 out:
589 return MNL_CB_OK;
590 }
591 #endif
child_link(int __unused (fd),short __unused (event),void * msgfd)592 void child_link(int __unused(fd), short __unused(event), void *msgfd) {
593
594 #ifdef HAVE_LIBMNL
595 char buf[MNL_SOCKET_BUFFER_SIZE];
596 int ret;
597
598 my_log(INFO, "reading link event");
599 while ((ret = mnl_socket_recvfrom(nl, buf, sizeof(buf))) > 0) {
600 ret = mnl_cb_run(buf, ret, 0, 0, child_link_cb, msgfd);
601 if (ret <= 0)
602 break;
603 }
604
605 return;
606 #endif
607
608 #if defined(HAVE_NET_ROUTE_H) && defined(RTM_IFINFO)
609
610 char msg[2048] = {};
611 struct if_msghdr ifm;
612 struct rt_msghdr *rtm = (struct rt_msghdr *)&msg;
613 int len, ifm_flags = IFF_RUNNING|IFF_UP;
614
615 my_log(INFO, "reading link event");
616 len = read(fd, msg, sizeof(msg));
617
618 if (len < sizeof(struct rt_msghdr) ||
619 (rtm->rtm_version != RTM_VERSION) ||
620 (rtm->rtm_type != RTM_IFINFO))
621 return;
622
623 memcpy(&ifm, rtm, sizeof(ifm));
624 if (ifm.ifm_data.ifi_type != IFT_ETHER)
625 return;
626 if ((ifm.ifm_flags & ifm_flags) != ifm_flags)
627 return;
628 #if defined(LINK_STATE_UP)
629 if (!LINK_STATE_IS_UP(ifm.ifm_data.ifi_link_state))
630 return;
631 #endif
632
633 my_log(INFO, "invoking child_send");
634 struct child_send_args args = { .index = ifm.ifm_index };
635 child_send(*(int*)msgfd, 0, &args);
636 #endif
637 }
638
639