Esempio n. 1
0
int kill_wpa_supplicant(void)
{
    pid_t wpa_pid;
    FILE *fp;

    fp = (fopen(WPAPID, "r"));
    if (fp == NULL) {
        di_warning("Couldn't read Wpasupplicant pid file, not trying to kill.");
        return 0;
    }
    else {
        if (fscanf(fp, "%d", &wpa_pid) != 1) {
            di_warning("Couldn't read pid from Wpasupplicant pid file, not trying to kill.");
            return 0;
        }
        fclose(fp);
    }
      if ((kill(wpa_pid, SIGTERM)) == 0)
          return 0;
      else {
          kill(wpa_pid, SIGKILL);
          unlink(WPAPID);
          return 0;
      }
}
Esempio n. 2
0
int netcfg_wireless_set_wep (struct debconfclient * client, struct netcfg_interface *interface)
{
    wireless_config wconf;
    char* rv = NULL;
    int ret, keylen, err = 0;
    unsigned char buf [IW_ENCODING_TOKEN_MAX + 1];
    struct iwreq wrq;

    iw_get_basic_config (wfd, interface->name, &wconf);

    debconf_subst(client, "netcfg/wireless_wep", "iface", interface->name);
    debconf_input (client, "high", "netcfg/wireless_wep");
    ret = debconf_go(client);

    if (ret == CMD_GOBACK)
        return GO_BACK;

    debconf_get(client, "netcfg/wireless_wep");
    rv = client->value;

    if (empty_str(rv)) {
        unset_wep_key (interface->name);

        if (interface->wepkey != NULL) {
            free(interface->wepkey);
            interface->wepkey = NULL;
        }

        return 0;
    }

    while ((keylen = iw_in_key (rv, buf)) == -1) {
        debconf_subst(client, "netcfg/invalid_wep", "wepkey", rv);
        debconf_input(client, "critical", "netcfg/invalid_wep");
        debconf_go(client);

        debconf_input (client, "high", "netcfg/wireless_wep");
        ret = debconf_go(client);

        if (ret == CMD_GOBACK)
            return GO_BACK;

        debconf_get(client, "netcfg/wireless_wep");
        rv = client->value;
    }

    /* Now rv is safe to store since it parsed fine */
    interface->wepkey = strdup(rv);

    wrq.u.data.pointer = buf;
    wrq.u.data.flags = 0;
    wrq.u.data.length = keylen;

    if ((err = iw_set_ext(skfd, interface->name, SIOCSIWENCODE, &wrq)) < 0) {
        di_warning("setting WEP key on %s failed with code %d", interface->name, err);
        return -1;
    }

    return 0;
}
Esempio n. 3
0
/* Returns non-zero if this interface has an enabled kill switch, otherwise
 * zero.
 */
int check_kill_switch(const char *if_name)
{
    char *temp, *linkbuf;
    const char *killname;
    char killstate;
    size_t len;
    int linklen, killlen;
    int fd = -1;
    int ret = 0;

    /* longest string we need */
    len = strlen(SYSCLASSNET) + strlen(if_name) + strlen("/device/rf_kill") + 1;

    temp = malloc(len);
    snprintf(temp, len, SYSCLASSNET "%s/driver", if_name);
    linkbuf = malloc(1024); /* probably OK ... I hate readlink() */
    linklen = readlink(temp, linkbuf, 1024);
    if (linklen < 0)
        goto out;

    if (strncmp(linkbuf + linklen - 8, "/ipw2100", 8) == 0)
        killname = "rf_kill";
    else if (strncmp(linkbuf + linklen - 8, "/ipw2200", 8) == 0)
        killname = "rf_kill";
    else
        goto out;

    snprintf(temp, len, SYSCLASSNET "%s/device/%s", if_name, killname);
    di_info("Checking RF kill switch: %s", temp);
    fd = open(temp, O_RDONLY);
    if (fd == -1)
        goto out;
    killlen = read(fd, &killstate, 1);
    if (killlen < 0) {
        di_error("Failed to read RF kill state: %s", strerror(errno));
        goto out;
    } else if (killlen == 0) {
        di_warning("RF kill state file empty");
        goto out;
    }

    if (killstate == '2') {
        di_info("RF kill switch enabled");
        ret = 1;
    }

 out:
    free(temp);
    free(linkbuf);

    if (fd != -1)
        close(fd);

    return ret;
}
Esempio n. 4
0
int is_raw_80211(const char *iface)
{
    struct ifreq ifr;
    struct sockaddr sa;

    strncpy(ifr.ifr_name, iface, IFNAMSIZ);

    if (skfd && ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) {
        di_warning("Unable to retrieve interface type.");
        return 0;
    }

    sa = * (struct sockaddr *) &ifr.ifr_hwaddr;
    switch (sa.sa_family) {
    case ARPHRD_IEEE80211:
    case ARPHRD_IEEE80211_PRISM:
    case ARPHRD_IEEE80211_RADIOTAP:
        return 1;

    default:
        return 0;
    }
}
Esempio n. 5
0
/* The main function for writing things to INTERFACES_FILE (aka
 * /etc/network/interfaces).
 *
 * In principle, this function is very simple: just examine the interface
 * we've been passed, and call out to the relevant private helper function. 
 * In practice...
 *
 * Takes the interface struct to write out.  If you pass NULL, the file gets
 * deleted and a helpful comment header gets written.
 *
 * Returns a true/false boolean representing "did everything go OK"; if 0 is
 * returned, the interfaces file will not have been modified, and errno will
 * contain the details.
 */
int netcfg_write_interface(const struct netcfg_interface *interface)
{
	FILE *fd;
	int rv;
	struct stat stat_buf;
	
	if (!interface) {
		di_debug("No interface given; clearing " INTERFACES_FILE);
		rv = unlink(INTERFACES_FILE);
		if (rv < 0 && errno != ENOENT) {
			di_info("Error clearing %s: %s", INTERFACES_FILE, strerror(errno));
			return 0;
		}
	}
	
	fd = file_open(INTERFACES_FILE ".tmp", "w");
	if (!fd) {
		di_warning("Failed to open %s.tmp: %s", INTERFACES_FILE, strerror(errno));
		return 0;
	}

	/* All of this code is to handle the apparently simple task of
	 * copying the existing interfaces file to the tmpfile (if it exists)
	 * so we can add our new stuff to it.  Bloody longwinded way of doing
	 * it, I'm sure you'll agree.
	 */
	rv = stat(INTERFACES_FILE, &stat_buf);
	if (rv < 0 && errno != ENOENT) {
		di_warning("Failed to stat %s: %s", INTERFACES_FILE, strerror(errno));
		unlink(INTERFACES_FILE ".tmp");
		return 0;
	}
	if (rv == 0) {
		char *tmpbuf = malloc(stat_buf.st_size + 1);
		int origfd;
		origfd = open(INTERFACES_FILE, O_RDONLY);
		if (origfd < 0) {
			di_warning("Failed to open %s: %s", INTERFACES_FILE, strerror(errno));
			fclose(fd);
			unlink(INTERFACES_FILE ".tmp");
			free(tmpbuf);
			return 0;
		}
		rv = read(origfd, tmpbuf, stat_buf.st_size);
		if (rv < 0) {
			di_warning("Failed to read %s: %s", INTERFACES_FILE, strerror(errno));
			fclose(fd);
			unlink(INTERFACES_FILE ".tmp");
			free(tmpbuf);
			close(origfd);
			return 0;
		}
		if (rv != stat_buf.st_size) {
			di_warning("Short read on %s", INTERFACES_FILE);
			fclose(fd);
			unlink(INTERFACES_FILE ".tmp");
			free(tmpbuf);
			close(origfd);
			return 0;
		}
		rv = fwrite(tmpbuf, sizeof(char), stat_buf.st_size, fd);
		if (rv != (int)stat_buf.st_size) {
			di_warning("Short write on %s.tmp", INTERFACES_FILE);
			fclose(fd);
			unlink(INTERFACES_FILE ".tmp");
			free(tmpbuf);
			close(origfd);
			return 0;
		}
		free(tmpbuf);
		close(origfd);
	}
		
	
	/* Thank $DEITY all that's out of the way... now we can write a
	 * freaking interfaces file entry */
	rv = 1;

	if (!interface) {
		di_debug("Writing informative header");
		rv = nc_wi_header(fd);
	} else if (interface->loopback == 1) {
		di_debug("Writing loopback interface");
		rv = nc_wi_loopback(interface, fd);
	} else if (interface->dhcp == 1 || interface->slaac == 1) {
		if (interface->dhcp == 1) {
			di_debug("Writing DHCP stanza for %s", interface->name);
			rv = nc_wi_dhcp(interface, fd);
		}
		if (interface->slaac == 1) {
			di_debug("Writing SLAAC stanza for %s", interface->name);
			rv = nc_wi_slaac(interface, fd);
		}
	} else if (interface->address_family == AF_INET) {
		di_debug("Writing static IPv4 stanza for %s", interface->name);
		rv = nc_wi_static_ipv4(interface, fd);
	} else if (interface->address_family == AF_INET6) {
		di_debug("Writing static IPv6 stanza for %s", interface->name);
		rv = nc_wi_static_ipv6(interface, fd);
	}
	if (rv && interface && interface->parentif) {
		di_debug("Writing VLAN: %s", interface->name);
		rv = nc_wi_vlan(interface, fd);
	}
	if (rv && interface && is_wireless_iface(interface->name)) {
		di_debug("Writing wireless options for %s", interface->name);
		rv = nc_wi_wireless_options(interface, fd);
	}

	if (rv) {
		di_debug("Success!");
		rename(INTERFACES_FILE ".tmp", INTERFACES_FILE);
	}

	fclose(fd);
	unlink(INTERFACES_FILE ".tmp");
	return rv;
}
Esempio n. 6
0
int netcfg_wireless_show_essids(struct debconfclient *client, struct netcfg_interface *interface)
{
    wireless_scan_head network_list;
    wireless_config wconf;
    char *buffer;
    int essid_list_len = 1;

    iw_get_basic_config (wfd, interface->name, &wconf);
    interface_up(interface->name);

    if (iw_scan(wfd, interface->name, iw_get_kernel_we_version(),
                &network_list) >= 0 ) {
        wireless_scan *network;

        di_info("Scan of wireless interface %s succeeded.", interface->name);

        /* Determine the actual length of the buffer. */
        for (network = network_list.result; network; network =
                    network->next) {
            if (!exists_in_network_list(network_list, network)) {
                essid_list_len += (strlen(network->b.essid) + 2);
            }
        }
        /* Buffer initialization. */
        buffer = malloc(essid_list_len * sizeof(char));
        if (buffer == NULL) {
            /* Error in memory allocation. */
            di_warning("Unable to allocate memory for network list buffer.");
            return ENTER_MANUALLY;
        }
        strcpy(buffer, "");

        /* Create list of available ESSIDs. */
        for (network = network_list.result; network; network = network->next) {
            if (!exists_in_network_list(network_list, network)) {
                strcat(buffer, network->b.essid);
                strcat(buffer, ", ");
            }
        }

        /* Asking the user. */
        debconf_capb(client, "backup");
        debconf_subst(client, "netcfg/wireless_show_essids", "essid_list", buffer);
        debconf_fset(client, "netcfg/wireless_show_essids", "seen", "false");
        debconf_input(client, "high", "netcfg/wireless_show_essids");

        if (debconf_go(client) == CMD_GOBACK) {
            debconf_fset(client, "netcfg/wireless_show_essids", "seen",
                         "false");
            free_network_list(&network_list.result);
            free(buffer);

            return GO_BACK;
        }

        debconf_get(client, "netcfg/wireless_show_essids");

        /* User wants to enter an ESSID manually. */
        if (strcmp(client->value, "manual") == 0) {
            free_network_list(&network_list.result);
            free(buffer);

            return ENTER_MANUALLY;
        }

        /* User has chosen a network from the list, need to find which one and
         * get its cofiguration. */
        for (network = network_list.result; network; network = network->next) {
            if (strcmp(network->b.essid, client->value) == 0) {
                wconf = network->b;
                interface->essid = strdup(network->b.essid);
                break;
            }
        }

        /* Free the network list. */
        free_network_list(&network_list.result);
        free(buffer);
    }
    else {
        /* Go directly to choosing manually, use the wireless_essid_again
         * question. */
        if (netcfg_wireless_choose_essid_manually(client, interface,
                "netcfg/wireless_essid_again") == GO_BACK) {

            return GO_BACK;
        }

        return 0;
    }

    iw_set_basic_config(wfd, interface->name, &wconf);
    interface_down(interface->name);

    di_info("Network chosen: %s. Proceeding to connect.", interface->essid);

    return 0;
}
int get_hw_addr(const char *iface, struct sockaddr *sa)
{
#if defined(SIOCGIFHWADDR)
    int s;
    struct ifreq ifr;

    if (strlen(iface) >= IFNAMSIZ) {
        di_warning("Interface name '%s' too long for struct ifreq", iface);
        return 0;
    }

    s = socket(AF_INET, SOCK_DGRAM, 0); /* doesn't matter what kind */
    if (s < 0) {
        di_warning("Unable to create socket: %s", strerror(errno));
        return 0;
    }

    strncpy(ifr.ifr_name, iface, IFNAMSIZ);
    if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
        di_warning("Unable to get hardware address of %s: %s",
                   iface, strerror(errno));
        return 0;
    }

    memcpy(sa, &ifr.ifr_hwaddr, sizeof(*sa));
    return 1;
#elif defined(__FreeBSD_kernel__)
    /* Code from iftop. */
    int sysctlparam[6] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
    size_t needed = 0;
    char *buf = NULL;
    struct if_msghdr *msghdr = NULL;
    struct sockaddr_dl *sdl;

    sysctlparam[5] = if_nametoindex(iface);
    if (sysctlparam[5] == 0) {
        di_warning("Unable to get interface index of %s", iface);
        return 0;
    }
    if (sysctl(sysctlparam, 6, NULL, &needed, NULL, 0) < 0) {
        di_warning("Unable to get size of hardware address of %s", iface);
        return 0;
    }
    buf = malloc(needed);
    if (!buf) {
        di_warning("Out of memory");
        return 0;
    }
    if (sysctl(sysctlparam, 6, buf, &needed, NULL, 0) < 0) {
        di_warning("Unable to get hardware address of %s", iface);
        free(buf);
        return 0;
    }
    msghdr = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(msghdr + 1);
    sa->sa_family = ARPHRD_ETHER;
    memcpy(sa->sa_data, LLADDR(sdl), 6);
    free(buf);
    return 1;
#else
    di_warning("Unable to get hardware addresses on this platform");
    return 0;
#endif
}