Commit 4effde93 by Lorenzo Martinico

Add shill_wrapper

The shill network manager in Chrom*OS automatically overwrites the Accept Router Advertisements preference to default even if forwarding.
Since Re6st machines act as routers, we do not want this to happen, hence Grandenet wil set it to Accept.
To avoid a race condition, however, we redirect all file write to the approrpriate preference file to go to /dev/null.
Adapted by
1 parent 5cb542c2
......@@ -197,7 +197,7 @@ else
if [[ $( status shill | grep running ) ]] ; then
stop shill
start shill BLACKLISTED_DEVICES="${blacklist_option}"
"${BASH_SOURCE%/*}"/shill_wrapper start shill BLACKLISTED_DEVICES="${blacklist_option}"
# wait a bit for the interfaces to be back
for i in {0..4} ; do
echo -n "." ; sleep 1
/* shill_wrapper - prevents shill from writing the IPv6 WiFi AcceptRouterAdvertisement preference */
* Copyright (C) 2018 Lorenzo Martinico <>
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/* Needed for RTLD_NEXT */
#define _GNU_SOURCE
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/auxv.h>
#define ORIGINAL_CONF_PATH "/proc/sys/net/ipv6/conf/wlan0/accept_ra"
/* Standard O_TMPFILE includes O_DIRECTORY bit, but we do not want to call
* va_arg if O_DIRECTORY is set alone. Hence, define a "purer" O_TMPFILE. */
#define PURE_O_TMPFILE (020000000)
/* And sanity-check when O_TMPFILE is defined. */
#if defined(O_TMPFILE) && (O_TMPFILE & PURE_O_TMPFILE) == 0
#error PURE_O_TMPFILE is incorrectly defined
static int (*original_open)(const char *, int, ...);
static FILE *(*original_fopen)(const char *, const char *);
/* Call dlsym(RTLD_NEXT, name), abort()'ing with informative message to
* stderr if it cannot be found. */
static inline void *dlsym_or_abort(const char *name) {
char *error;
void *symbol;
dlerror(); /* Clear any previous error */
symbol = dlsym(RTLD_NEXT, name);
if (!symbol && (error = dlerror())) {
dprintf(STDERR_FILENO, "Error loading '%s': %s\n", name, error);
return symbol;
static void init(void) {
original_open = dlsym_or_abort("open");
original_fopen = dlsym_or_abort("fopen");
int open(const char *__file, int __oflag, ...) {
if (!original_open)
if (!strcmp(__file, ORIGINAL_CONF_PATH))
__file = "/dev/null";
if (__oflag & (O_CREAT | PURE_O_TMPFILE)) {
va_list ap;
mode_t mode;
va_start(ap, __oflag);
mode = va_arg(ap, mode_t);
return (*original_open)(__file, __oflag, mode);
return (*original_open)(__file, __oflag);
FILE *fopen(const char *path, const char *mode) {
if (!original_fopen)
if (!strcmp(path, ORIGINAL_CONF_PATH))
path = "/dev/null";
return (*original_fopen)(path, mode);
int main(int argc, char *argv[]) {
char *ld_preload, *p;
int ret = -1;
if (argc <= 1)
dprintf(STDERR_FILENO, "usage: shill_wrapper start shill [<args>]\n");
else {
ld_preload = realpath((char *)getauxval(AT_EXECFN), NULL);
if (!ld_preload)
p = "realpath";
else {
if ((p = getenv("LD_PRELOAD"))) {
size_t n = strlen(ld_preload);
ld_preload = realloc(ld_preload, n + strlen(p) + 2);
ld_preload[n++] = ':';
strcpy(ld_preload + n, p);
ret = setenv("LD_PRELOAD", ld_preload, 1);
if (ret)
p = "setenv";
else {
ret = execvp(argv[1], &argv[1]);
p = "execvp";
return ret;
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!