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