=== modified file 'plugins.d/mandos-client.c' --- plugins.d/mandos-client.c 2009-09-17 11:22:28 +0000 +++ plugins.d/mandos-client.c 2010-08-10 19:08:24 +0000 @@ -125,6 +125,8 @@ static const char mandos_protocol_version[] = "1"; const char *argp_program_version = "mandos-client " VERSION; const char *argp_program_bug_address = ""; +static const char sys_class_net[] = "/sys/class/net"; +char *connect_to = NULL; /* Used for passing in values through the Avahi callback functions */ typedef struct { @@ -974,6 +976,80 @@ errno = old_errno; } +/* + * This function determines if a directory entry in /sys/class/net + * corresponds to an acceptable network device. + * (This function is passed to scandir(3) as a filter function.) + */ +int good_interface(const struct dirent *if_entry){ + ssize_t ssret; + char *flagname = NULL; + int ret = asprintf(&flagname, "%s/%s/flags", sys_class_net, + if_entry->d_name); + if(ret < 0){ + perror("asprintf"); + return 0; + } + if(if_entry->d_name[0] == '.'){ + return 0; + } + int flags_fd = (int)TEMP_FAILURE_RETRY(open(flagname, O_RDONLY)); + if(flags_fd == -1){ + perror("open"); + return 0; + } + typedef short ifreq_flags; /* ifreq.ifr_flags in netdevice(7) */ + /* read line from flags_fd */ + ssize_t to_read = (sizeof(ifreq_flags)*2)+3; /* "0x1003\n" */ + char *flagstring = malloc((size_t)to_read); + if(flagstring == NULL){ + perror("malloc"); + close(flags_fd); + return 0; + } + while(to_read > 0){ + ssret = (ssize_t)TEMP_FAILURE_RETRY(read(flags_fd, flagstring, + (size_t)to_read)); + if(ssret == -1){ + perror("read"); + free(flagstring); + close(flags_fd); + return 0; + } + to_read -= ssret; + if(ssret == 0){ + break; + } + } + close(flags_fd); + intmax_t tmpmax; + char *tmp; + errno = 0; + tmpmax = strtoimax(flagstring, &tmp, 0); + if(errno != 0 or tmp == flagstring or (*tmp != '\0' + and not (isspace(*tmp))) + or tmpmax != (ifreq_flags)tmpmax){ + free(flagstring); + return 0; + } + free(flagstring); + ifreq_flags flags = (ifreq_flags)tmpmax; + /* Reject the loopback device */ + if(flags & IFF_LOOPBACK){ + return 0; + } + /* Accept point-to-point devices only if connect_to is specified */ + if(connect_to != NULL and (flags & IFF_POINTOPOINT)){ + return 1; + } + /* Otherwise, reject non-broadcast-capable devices */ + if(not (flags & IFF_BROADCAST)){ + return 0; + } + /* Accept this device */ + return 1; +} + int main(int argc, char *argv[]){ AvahiSServiceBrowser *sb = NULL; int error; @@ -981,13 +1057,12 @@ intmax_t tmpmax; char *tmp; int exitcode = EXIT_SUCCESS; - const char *interface = "eth0"; + const char *interface = ""; struct ifreq network; int sd = -1; bool take_down_interface = false; uid_t uid; gid_t gid; - char *connect_to = NULL; char tempdir[] = "/tmp/mandosXXXXXX"; bool tempdir_created = false; AvahiIfIndex if_index = AVAHI_IF_UNSPEC; @@ -1123,6 +1198,28 @@ if(not debug){ avahi_set_log_function(empty_log); } + + if(interface[0] == '\0'){ + struct dirent **direntries; + ret = scandir(sys_class_net, &direntries, good_interface, + alphasort); + if(ret >= 1){ + /* Pick the first good interface */ + interface = strdup(direntries[0]->d_name); + if(interface == NULL){ + perror("malloc"); + free(direntries); + exitcode = EXIT_FAILURE; + goto end; + } + free(direntries); + } else { + free(direntries); + fprintf(stderr, "Could not find a network interface\n"); + exitcode = EXIT_FAILURE; + goto end; + } + } /* Initialize Avahi early so avahi_simple_poll_quit() can be called from the signal handler */ @@ -1199,7 +1296,7 @@ } /* If the interface is down, bring it up */ - if(interface[0] != '\0'){ + if(strcmp(interface, "none") != 0){ if_index = (AvahiIfIndex) if_nametoindex(interface); if(if_index == 0){ fprintf(stderr, "No such interface: \"%s\"\n", interface); === modified file 'plugins.d/mandos-client.xml' --- plugins.d/mandos-client.xml 2009-02-09 02:01:13 +0000 +++ plugins.d/mandos-client.xml 2010-08-10 19:08:24 +0000 @@ -202,8 +202,9 @@ Network interface that will be brought up and scanned for - Mandos servers to connect to. The default is - eth0. + Mandos servers to connect to. The default is the empty + string, which will automatically choose an appropriate + interface. If the option is used, this @@ -220,10 +221,11 @@ by this program. - NAME can be the empty string; - this will not use any specific interface, and will not - bring up an interface on startup. This is not - recommended, and only meant for advanced users. + NAME can be the string + none; this will not use + any specific interface, and will not bring up an interface + on startup. This is not recommended, and only meant for + advanced users.