Пример #1
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;
}
Пример #2
0
static int get_interfaces(int sock, char *ifname, int *type, std::string *ssid)
{
	int rval;
	struct wireless_info wless_info;
	struct ifreq ifr;
	struct sockaddr_in *sa;
	unsigned char ip[4];
	char a[16];

	/* initialize info */
	bzero((wireless_info *) &wless_info, sizeof(struct wireless_info));

	/* Attempt to get basic wireless information */
	if(iw_get_basic_config(sock, ifname, &(wless_info.b)) < 0)
	{
		/* no wireless extentions.  We need to check for the existence of a wired one */
		strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
		if(ioctl(sock, SIOCGIFFLAGS, &ifr) < 0)
			return(-ENODEV);
		else  	   /* we found a wired network interface */ {
			ssid->assign("Not Applicable");
			*type = IFT_WIRED;
			return (EXEC_SUCCESS);
		}
	}
	/* we found a wireless network interface:
	 * Grab the SSID while I have it in wless_info
	 */
	ssid->assign(wless_info.b.essid, wless_info.b.essid_len);
	*type = IFT_WIRELESS;
	return (EXEC_SUCCESS);
}
Пример #3
0
static void
wireless_applet_set_device (WirelessApplet *applet, gchar *device) {
	g_return_if_fail (device != NULL);

	g_free (applet->device);
	applet->device = g_strdup (device);
	iw_get_basic_config (applet->skfd, applet->device, &applet->cfg);
}
Пример #4
0
int netcfg_wireless_auto_connect(struct debconfclient *client, char *iface,
        wireless_config *wconf, int *couldnt_associate)
{
    int i, success = 0;

    /* Default to any AP */
    wconf->essid[0] = '\0';
    wconf->essid_on = 0;

    iw_set_basic_config (wfd, iface, wconf);

    /* Wait for association.. (MAX_SECS seconds)*/
#ifndef MAX_SECS
#define MAX_SECS 3
#endif

    debconf_capb(client, "backup progresscancel");
    debconf_progress_start(client, 0, MAX_SECS, "netcfg/wifi_progress_title");

    if (debconf_progress_info(client, "netcfg/wifi_progress_info") == 30)
        goto stop;
    netcfg_progress_displayed = 1;

    for (i = 0; i <= MAX_SECS; i++) {
        int progress_ret;

        interface_up(iface);
        sleep (1);
        iw_get_basic_config (wfd, iface, wconf);

        if (!empty_str(wconf->essid)) {
            /* Save for later */
            debconf_set(client, "netcfg/wireless_essid", wconf->essid);
            debconf_progress_set(client, MAX_SECS);
            success = 1;
            break;
        }

        progress_ret = debconf_progress_step(client, 1);
        interface_down(iface);
        if (progress_ret == 30)
            break;
    }

stop:
    debconf_progress_stop(client);
    debconf_capb(client, "backup");
    netcfg_progress_displayed = 0;

    if (success)
        return 0;

    *couldnt_associate = 1;

    return *couldnt_associate;
}
Пример #5
0
static void unset_wep_key (const char *if_name)
{
    wireless_config wconf;

    iw_get_basic_config(wfd, if_name, &wconf);

    wconf.has_key = 1;
    wconf.key[0] = '\0';
    wconf.key_flags = IW_ENCODE_DISABLED | IW_ENCODE_NOKEY;
    wconf.key_size = 0;

    iw_set_basic_config (wfd, if_name, &wconf);
}
Пример #6
0
/* ------------------------------------------------------------------- WirelessInterface_refresh */
static void WirelessInterface_refresh(wiface* self)
{
	iwreq wrq;

	iw_get_basic_config(self->sock, self->ifname, &(self->info.b));
	iw_get_range_info(self->sock, self->ifname, &(self->info.range));

	iw_get_ext(self->sock, self->ifname, SIOCGIWRATE, &wrq);
	memcpy(&(self->info.bitrate), &wrq.u.bitrate, sizeof(iwparam));

	iw_get_ext(self->sock, self->ifname, SIOCGIWAP, &wrq);
	memcpy(&(self->info.ap_addr), &wrq.u.ap_addr, sizeof(sockaddr));

	iw_get_stats(self->sock, self->ifname, &(self->info.stats),
		     &(self->info.range), self->info.has_range);
}
Пример #7
0
void
get_wireless_info (DevInfo *devinfo)
{
	int fd;
	int newqual;
	wireless_info info = {0};

	fd = iw_sockets_open ();

	if (fd < 0)
		return;

	if (iw_get_basic_config (fd, devinfo->name, &info.b) < 0)
		goto out;

	if (info.b.has_essid) {
		if ((!devinfo->essid) || (strcmp (devinfo->essid, info.b.essid) != 0)) {
			devinfo->essid = g_strdup (info.b.essid);
		}
	} else {
		devinfo->essid = NULL;
	}

	if (iw_get_stats (fd, devinfo->name, &info.stats, &info.range, info.has_range) >= 0)
		info.has_stats = 1;

	if (info.has_stats) {
		if ((iw_get_range_info(fd, devinfo->name, &info.range) >= 0) && (info.range.max_qual.qual > 0)) {
			newqual = 0.5f + (100.0f * info.stats.qual.qual) / (1.0f * info.range.max_qual.qual);
		} else {
			newqual = info.stats.qual.qual;
		}

		newqual = CLAMP(newqual, 0, 100);
		if (devinfo->qual != newqual)
			devinfo->qual = newqual;

	} else {
		devinfo->qual = 0;
	}

	goto out;
out:
	if (fd != -1)
		close (fd);
}
Пример #8
0
/* Accepts one parameter and check whether there is a wireless interface having
 * corresponding ESSID */
bool essid(int argc, char **argv)
{
	if (argc != 2) {
		fprintf(stderr, "essid: requires exactly one parameter\n");
		exit(EXIT_FAILURE);
	}

	bool result = 0;
	char *args[2] = { argv[1], (char*) &result };
	int skfd = iw_sockets_open();

	int check_iface(int skfd, char *ifname, char *args[], int count) {
		(void) count;
		wireless_config info;

		iw_get_basic_config(skfd, ifname, &info);
		*args[1] = *args[1] || !strcmp(args[0], info.essid);
		return 0;
	}
Пример #9
0
char *get_wifi(char *buf) {
	char devpath[35], state[5];

	sprintf(devpath, "/sys/class/net/%s/operstate", WIRELESS_D);
	infile = fopen(devpath, "r");

	fscanf(infile, "%s", state); fclose(infile);
	if(strcmp(state, "up") == 0) {
		if(iw_get_basic_config(skfd, WIRELESS_D, &(winfo->b)) > -1) {
			if(iw_get_stats(skfd, WIRELESS_D, &(winfo->stats), &winfo->range, winfo->has_range) >= 0)
				winfo->has_stats = 1;
			if(iw_get_range_info(skfd, WIRELESS_D, &(winfo->range)) >= 0)
				winfo->has_range = 1;
			if(winfo->b.has_essid && winfo->b.essid_on)
				sprintf(buf, WIFI_S, winfo->b.essid, (winfo->stats.qual.qual * 100) / winfo->range.max_qual.qual);
		}
	}
	else
		sprintf(buf, NO_CONN_S);
	return buf;
}
Пример #10
0
int netcfg_wireless_set_essid(struct debconfclient *client, char *iface, char *priority)
{
    wireless_config wconf;
    int choose_ret;

    iw_get_basic_config(wfd, iface, &wconf);

select_essid:
    choose_ret = netcfg_wireless_show_essids(client, iface, priority);

    if (choose_ret == GO_BACK) {
        return GO_BACK;
    }

    if (choose_ret == ENTER_MANUALLY) {
        int manually_ret = netcfg_wireless_choose_essid_manually(client, iface);

        if (manually_ret == GO_BACK) {
            goto select_essid;
        }
    }


    /* Something like:
     * - choose essid
     * - if manual, go to manual (use what is already there)
     *      - if manual = go_back, go back to choose essid
     * - set config
     */

    fprintf(stderr, "%d\n", IW_ESSID_MAX_SIZE);

    fprintf(stderr, "%s\n%d\n%d\n", wconf.essid, wconf.has_essid,
            wconf.essid_on);

    fprintf(stderr, "%s\n", essid);


    return 0;
}
Пример #11
0
C_RESULT vp_com_wf_connect(vp_com_t* vp_com, vp_com_wifi_connection_t* connection, int32_t numAttempts)
{
  C_RESULT res = VP_COM_OK;
#ifdef USE_IWLIB
  int32_t wlsock;
  vp_com_wifi_config_t* config = (vp_com_wifi_config_t*)vp_com->config;
  wireless_config iwconf;

  wlsock = iw_sockets_open();

  res = ( wlsock < 0 ) ? VP_COM_ERROR : VP_COM_OK;
  VP_COM_CHECK( res );

  iw_get_basic_config( wlsock, config->itfName, &iwconf );

  iwconf.has_nwid = 0;
  iwconf.has_freq = 0;
  iwconf.has_key  = 0;

  iwconf.has_mode = 1;
  iwconf.mode = config->infrastructure ? IW_MODE_INFRA : IW_MODE_ADHOC;

  iwconf.has_essid = 1;
  iwconf.essid_on = 1;
  strncpy( &iwconf.essid[0], connection->networkName, IW_ESSID_MAX_SIZE+1 );
  
  res = iw_set_basic_config( wlsock, config->itfName, &iwconf ) < 0 ? C_FAIL : C_OK;

  if( SUCCEED(res) )
    PRINT(" OK!\n");
  else
    PRINT(" FAILED!\n");

  iw_sockets_close(wlsock);

#endif
  return res;
}
Пример #12
0
  /**
  * @brief Fills in basic information like the essid and the maximum signal quality
  */
  bool openDevice()
  {
    if ((wifi_skfd = iw_sockets_open()) < 0)
    {
      ROS_ERROR("socket error");
      return false;
    }

    if (iw_get_basic_config(wifi_skfd, wifi_dev, &(wifi_info->b)) < 0)
    {
      /* If no wireless name : no wireless extensions */
      /* But let's check if the interface exists at all */
      struct ifreq ifr;

      strncpy(ifr.ifr_name, wifi_dev, IFNAMSIZ);
      int ret = ioctl(wifi_skfd, SIOCGIFFLAGS, &ifr);
      if (ret < 0)
      {
        ROS_ERROR("device doesn't exist");
        return false;
      }
      else
      {
        ROS_ERROR("operation not supported");
        return false;
      }
    }

    wifi_sig.essid = wifi_info->b.essid;

    if (iw_get_range_info(wifi_skfd, wifi_dev, &(wifi_info->range)) >= 0)
      wifi_info->has_range = 1;

    wifi_sig.link_quality_max = wifi_info->range.max_qual.qual;

    return true;

  }
Пример #13
0
int netcfg_wireless_set_essid(struct debconfclient *client, struct netcfg_interface *interface)
{
    wireless_config wconf;
    int choose_ret;

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

    choose_ret = netcfg_wireless_show_essids(client, interface);

    if (choose_ret == GO_BACK) {
        return GO_BACK;
    }

    if (choose_ret == ENTER_MANUALLY) {
        if (netcfg_wireless_choose_essid_manually(client, interface,
                "netcfg/wireless_essid") == GO_BACK) {
            goto select_essid;
        }
    }

    return 0;
}
Пример #14
0
/* check stats, modify the state attribute */
static void
wireless_applet_read_device_state (WirelessApplet *applet)
{
	iwrange range;
	iwstats stats;
	gboolean has_range;
	
	/* ewwwww */
	char *enum_args[] = { (char *)applet };

	/* clear the device list */
	g_list_foreach (applet->devices, (GFunc)g_free, NULL);
	g_list_free (applet->devices);
	applet->devices = NULL;

	/* get the config */
	iw_get_basic_config (applet->skfd, applet->device, &applet->cfg);

	iw_enum_devices (applet->skfd,
			 wireless_applet_device_handler,
			 enum_args, 1);

	has_range = iw_get_range_info (applet->skfd, applet->device, &range) < 0 ? FALSE : TRUE;

	if (!iw_get_stats (applet->skfd, applet->device, &stats,
			  &range, has_range)) {
		wireless_applet_update_state (applet,
					      applet->device,
					      stats.qual.qual,
					      stats.qual.level,
					      stats.qual.noise);
	} else {
		wireless_applet_update_state (applet,
					      applet->device,
					      -1, -1, -1);
	}
}
Пример #15
0
int is_wireless_iface (const char* if_name)
{
    wireless_config wc;
    return (iw_get_basic_config (wfd, (char*)if_name, &wc) == 0);
}
Пример #16
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;
}
Пример #17
0
/*
 * Get wireless informations & config from the device driver
 * We will call all the classical wireless ioctl on the driver through
 * the socket to know what is supported and to get the settings...
 */
static int
get_info(int			skfd,
	 char *			ifname,
	 struct wireless_info *	info)
{
  struct iwreq		wrq;

  memset((char *) info, 0, sizeof(struct wireless_info));

  /* Get basic information */
  if(iw_get_basic_config(skfd, ifname, &(info->b)) < 0)
    {
      /* If no wireless name : no wireless extensions */
      /* But let's check if the interface exists at all */
      struct ifreq ifr;

      strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
      if(ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
	return(-ENODEV);
      else
	return(-ENOTSUP);
    }

  /* Get ranges */
  if(iw_get_range_info(skfd, ifname, &(info->range)) >= 0)
    info->has_range = 1;

  /* Get AP address */
  if(iw_get_ext(skfd, ifname, SIOCGIWAP, &wrq) >= 0)
    {
      info->has_ap_addr = 1;
      memcpy(&(info->ap_addr), &(wrq.u.ap_addr), sizeof (sockaddr));
    }

  /* Get bit rate */
  if(iw_get_ext(skfd, ifname, SIOCGIWRATE, &wrq) >= 0)
    {
      info->has_bitrate = 1;
      memcpy(&(info->bitrate), &(wrq.u.bitrate), sizeof(iwparam));
    }

  /* Get Power Management settings */
  wrq.u.power.flags = 0;
  if(iw_get_ext(skfd, ifname, SIOCGIWPOWER, &wrq) >= 0)
    {
      info->has_power = 1;
      memcpy(&(info->power), &(wrq.u.power), sizeof(iwparam));
    }

  /* Get stats */
  if(iw_get_stats(skfd, ifname, &(info->stats),
		  &info->range, info->has_range) >= 0)
    {
      info->has_stats = 1;
    }

#ifndef WE_ESSENTIAL
  /* Get NickName */
  wrq.u.essid.pointer = (caddr_t) info->nickname;
  wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
  wrq.u.essid.flags = 0;
  if(iw_get_ext(skfd, ifname, SIOCGIWNICKN, &wrq) >= 0)
    if(wrq.u.data.length > 1)
      info->has_nickname = 1;

  if((info->has_range) && (info->range.we_version_compiled > 9))
    {
      /* Get Transmit Power */
      if(iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
	{
	  info->has_txpower = 1;
	  memcpy(&(info->txpower), &(wrq.u.txpower), sizeof(iwparam));
	}
    }

  /* Get sensitivity */
  if(iw_get_ext(skfd, ifname, SIOCGIWSENS, &wrq) >= 0)
    {
      info->has_sens = 1;
      memcpy(&(info->sens), &(wrq.u.sens), sizeof(iwparam));
    }

  if((info->has_range) && (info->range.we_version_compiled > 10))
    {
      /* Get retry limit/lifetime */
      if(iw_get_ext(skfd, ifname, SIOCGIWRETRY, &wrq) >= 0)
	{
	  info->has_retry = 1;
	  memcpy(&(info->retry), &(wrq.u.retry), sizeof(iwparam));
	}
    }

  /* Get RTS threshold */
  if(iw_get_ext(skfd, ifname, SIOCGIWRTS, &wrq) >= 0)
    {
      info->has_rts = 1;
      memcpy(&(info->rts), &(wrq.u.rts), sizeof(iwparam));
    }

  /* Get fragmentation threshold */
  if(iw_get_ext(skfd, ifname, SIOCGIWFRAG, &wrq) >= 0)
    {
      info->has_frag = 1;
      memcpy(&(info->frag), &(wrq.u.frag), sizeof(iwparam));
    }
#endif	/* WE_ESSENTIAL */

  return(0);
}
Пример #18
0
int main(int argc, char *argv[])
{
    int num_interfaces = 0;
    enum { BACKUP,
           GET_INTERFACE,
           GET_HOSTNAME_ONLY,
           GET_METHOD,
           GET_DHCP,
           GET_STATIC,
           WCONFIG,
           WCONFIG_ESSID,
           WCONFIG_SECURITY_TYPE,
           WCONFIG_WEP,
           WCONFIG_WPA,
           START_WPA,
           QUIT } state = GET_INTERFACE;

    static struct debconfclient *client;
    static int requested_wireless_tools = 0;
    char **ifaces;
    char *defiface = NULL, *defwireless = NULL;
    response_t res;
    struct netcfg_interface interface;
#ifdef NM
    struct nm_config_info nmconf;
#endif

    /* initialize libd-i */
    di_system_init("netcfg");
    netcfg_interface_init(&interface);

    if (strcmp(basename(argv[0]), "ptom") != 0)
        di_info("Starting netcfg v.%s", NETCFG_VERSION);

    parse_args (argc, argv);
    reap_old_files ();
    open_sockets();

    /* initialize debconf */
    client = debconfclient_new();
    debconf_capb(client, "backup");

    /* Check to see if netcfg should be run at all */
    debconf_get(client, "netcfg/enable");
    if (!strcmp(client->value, "false")) {
        netcfg_get_hostname(client, "netcfg/get_hostname", hostname, 0);
        netcfg_write_common("", hostname, NULL);
        return 0;
    }

    /* always always always default back to autoconfig, unless you've specified
     * disable_autoconfig on the command line. */
    debconf_get(client, "netcfg/disable_autoconfig");

    if (!strcmp(client->value, "true"))
        debconf_set(client, "netcfg/use_autoconfig", "false");
    else
        debconf_set(client, "netcfg/use_autoconfig", "true");

    /* also support disable_dhcp for compatibility */
    debconf_get(client, "netcfg/disable_dhcp");

    if (!strcmp(client->value, "true"))
        debconf_set(client, "netcfg/use_autoconfig", "false");

    for (;;) {
        switch(state) {
        case BACKUP:
            return RETURN_TO_MAIN;
        case GET_INTERFACE:
            /* If we have returned from outside of netcfg and want to
             * reconfigure networking, check to see if wpasupplicant is
             * running, and kill it if it is. If left running when
             * the interfaces are taken up and down, it appears to
             * leave it in an inconsistant state */
            kill_wpa_supplicant();

            /* Choose a default by looking for link */
            if (get_all_ifs(1, &ifaces) > 1) {
                while (*ifaces) {
                    struct netcfg_interface link_interface;

                    if (check_kill_switch(*ifaces)) {
                        debconf_subst(client, "netcfg/kill_switch_enabled", "iface", *ifaces);
                        debconf_input(client, "high", "netcfg/kill_switch_enabled");
                        if (debconf_go(client) == CMD_GOBACK) {
                            state = BACKUP;
                            break;
                        }
                        /* Is it still enabled? */
                        if (check_kill_switch(*ifaces)) {
                            ifaces++;
                            continue;
                        }
                    }

                    interface_up(*ifaces);

                    netcfg_interface_init(&link_interface);
                    link_interface.name = strdup(*ifaces);
                    if (netcfg_detect_link (client, &link_interface) == 1) /* CONNECTED */ {
                        /* CONNECTED */
                        di_info("found link on interface %s, making it the default.", *ifaces);
                        defiface = strdup(*ifaces);
                        free(link_interface.name);
                        break;
                    } else {
#ifdef WIRELESS
                        struct wireless_config wc;
#endif /* WIRELESS */
                        di_info("found no link on interface %s.", *ifaces);
#ifdef WIRELESS
                        if (iw_get_basic_config(wfd, *ifaces, &wc) == 0) {
                            wc.essid[0] = '\0';
                            wc.essid_on = 0;

                            iw_set_basic_config(wfd, *ifaces, &wc);

                            sleep(1);

                            iw_get_basic_config(wfd, *ifaces, &wc);

                            if (!empty_str(wc.essid)) {
                                di_info("%s is associated with %s. Selecting as default", *ifaces, wc.essid);
                                defiface = strdup(*ifaces);
                                interface_down(*ifaces);
                                break;
                            } else {
                                di_info("%s is not associated. Relegating to defwireless", *ifaces);
                                if (defwireless != NULL)
                                    free (defwireless);
                                defwireless = strdup(*ifaces);
                            }
                        }
                        else
                            di_info("%s is not a wireless interface. Continuing.", *ifaces);

                        interface_down(*ifaces);
#endif
                    }

                    free(link_interface.name);
                    interface_down(*ifaces);

                    ifaces++;
                }
            }

            if (state == BACKUP)
                break;

            if (!defiface && defwireless)
                defiface = defwireless;

            if(netcfg_get_interface(client, &(interface.name), &num_interfaces, defiface))
                state = BACKUP;
            else if (! interface.name || ! num_interfaces)
                state = GET_HOSTNAME_ONLY;
            else {
                if (is_wireless_iface (interface.name))
                    state = WCONFIG;
                else
                    state = GET_METHOD;
            }
            break;
        case GET_HOSTNAME_ONLY:
            if(netcfg_get_hostname(client, "netcfg/get_hostname", hostname, 0))
                state = BACKUP;
            else {
                netcfg_write_common("", hostname, NULL);
                state = QUIT;
            }
            break;
        case GET_METHOD:
            if ((res = netcfg_get_method(client)) == GO_BACK)
                state = (num_interfaces == 1) ? BACKUP : GET_INTERFACE;
            else {
                if (netcfg_method == DHCP)
                    state = GET_DHCP;
                else
                    state = GET_STATIC;
            }
            break;

        case GET_DHCP:
            switch (netcfg_activate_dhcp(client, &interface)) {
            case 0:
                state = QUIT;
                break;
            case RETURN_TO_MAIN:
                /*
                 * It doesn't make sense to go back to GET_METHOD because
                 * the user has already been asked whether they want to
                 * try an alternate method.
                 */
                state = (num_interfaces == 1) ? BACKUP : GET_INTERFACE;
                break;
            case CONFIGURE_MANUALLY:
                state = GET_STATIC;
                break;
            default:
                return 1;
            }
            break;

        case GET_STATIC:
            {
                int ret;
                /* Misnomer - this should actually take care of activation */
                if ((ret = netcfg_get_static(client, &interface)) == RETURN_TO_MAIN)
                    state = GET_INTERFACE;
                else if (ret)
                    state = GET_METHOD;
                else
                    state = QUIT;
                break;
            }

        case WCONFIG:
            if (requested_wireless_tools == 0) {
                di_exec_shell_log("apt-install iw wireless-tools");
                requested_wireless_tools = 1;
            }
            state = WCONFIG_ESSID;
            break;

        case WCONFIG_ESSID:
            if (netcfg_wireless_set_essid(client, &interface) == GO_BACK)
                state = BACKUP;
            else {
                init_wpa_supplicant_support(&interface);
                if (interface.wpa_supplicant_status == WPA_UNAVAIL)
                    state = WCONFIG_WEP;
                else
                    state = WCONFIG_SECURITY_TYPE;
            }
            break;

        case WCONFIG_SECURITY_TYPE:
            {
                int ret;
                ret = wireless_security_type(client, interface.name);
                if (ret == GO_BACK)
                    state = WCONFIG_ESSID;
                else if (ret == REPLY_WPA) {
                    state = WCONFIG_WPA;
                    interface.wifi_security = REPLY_WPA;
                }
                else {
                    state = WCONFIG_WEP;
                    interface.wifi_security = REPLY_WEP;
                }
                break;
            }

        case WCONFIG_WEP:
            if (netcfg_wireless_set_wep(client, &interface) == GO_BACK) 
                if (interface.wpa_supplicant_status == WPA_UNAVAIL)
                    state = WCONFIG_ESSID;
                else
                    state = WCONFIG_SECURITY_TYPE;
            else
                state = GET_METHOD;
            break;

        case WCONFIG_WPA:
            if (interface.wpa_supplicant_status == WPA_OK) {
                di_exec_shell_log("apt-install wpasupplicant");
                interface.wpa_supplicant_status = WPA_QUEUED;
            }

            if (netcfg_set_passphrase(client, &interface) == GO_BACK)
                state = WCONFIG_SECURITY_TYPE;
            else
                state = START_WPA;
            break;

        case START_WPA:
            if (wpa_supplicant_start(client, &interface) == GO_BACK)
                state = WCONFIG_ESSID;
            else
                state = GET_METHOD;
            break;

        case QUIT:
#ifdef NM
            if (num_interfaces > 0) {
                nm_get_configuration(&interface, &nmconf);
                nm_write_configuration(nmconf);
            }
#endif

            netcfg_update_entropy();
            return 0;
        }
    }
}
Пример #19
0
int netcfg_wireless_show_essids(struct debconfclient *client, char *iface, char *priority)
{
    wireless_scan_head network_list;
    wireless_config wconf;
    char *buffer;
    int couldnt_associate = 0;
    int essid_list_len = 1;

    iw_get_basic_config (wfd, iface, &wconf);
    network_list.retry = 1;

    if (iw_process_scan(wfd, iface, iw_get_kernel_we_version(),
                &network_list) >= 0 ) {
        wireless_scan *network, *old;

        /* Determine the actual length of the buffer. */
        for (network = network_list.result; network; network = network->next) {
            essid_list_len += strlen(network->b.essid);
        }

        /* Buffer initialization. */
        buffer = malloc(essid_list_len * sizeof(char));
        if (buffer == NULL) {
            /* Error in memory allocation. */
            return -1;
        }
        strcpy(buffer, "");

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

        /* Asking the user. */
        debconf_reset(client, "netcfg/wireless_show_essids");
        debconf_capb(client, "backup");
        strcpy(buffer, "");
        debconf_subst(client, "netcfg/wireless_show_essids", "essid_list", buffer);
        debconf_input(client, priority ? priority : "high", "netcfg/wireless_show_essids");
        int ret = debconf_go(client);

        if (ret == 30) {
            return GO_BACK;
        }

        debconf_get(client, "netcfg/wireless_show_essids");

        /* Question not asked or we're succesfully associated. */
        if (!empty_str(wconf.essid) || empty_str(client->value)) {
            /* TODO Go to automatic... */
            if (netcfg_wireless_auto_connect(client, iface, &wconf,
                        &couldnt_associate) == 0) {
                return 0;
            }
            return couldnt_associate;
        }

        /* User wants to enter an ESSID manually. */
        if (strcmp(client->value, enter_manually) == 0) {
            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;
                essid = strdup(network->b.essid);
                break;
            }
        }

        /* Free the network list. */
        for (network = network_list.result; network; ) {
            old = network;
            network = network->next;
            free(old);
        }
        free(buffer);
    }

    iw_set_basic_config(wfd, iface, &wconf);

    return 0;
}
Пример #20
0
int netproc_scandevice(int sockfd, int iwsockfd, FILE *fp, NETDEVLIST_PTR *netdev_list)
{
	char buffer[512];
	int count = 0;
	int prx_idx, ptx_idx, brx_idx, btx_idx;
	gulong in_packets, out_packets, in_bytes, out_bytes;
	NETDEVLIST_PTR devptr = NULL;

	/* interface information */
	struct ifreq ifr;
	struct ethtool_test edata;
	iwstats iws;
	char *status;
	char *name;
	struct iw_range iwrange;
	int has_iwrange = 0;

	status = fgets (buffer, sizeof(buffer), fp);
	if (!status)
		ERR("netstat: netproc_scnadevice(): Error reading first line from stream!\n");
	status = fgets (buffer, sizeof(buffer), fp);
	if (!status)
		ERR("netstat: netproc_scnadevice(): Error reading second line from stream!\n");
	netproc_parse_stats_header(buffer, &prx_idx, &ptx_idx, &brx_idx, &btx_idx);

	while (fgets(buffer, sizeof(buffer), fp)) {
		/* getting interface name */
		name = buffer;
		while (g_ascii_isspace(name[0])) {
			name++;
		}

		/* reading packet infomation */
		status = netproc_parse_ifname(name);
		netproc_parse_status(status, prx_idx, ptx_idx, &in_packets, &out_packets,
				     brx_idx, btx_idx, &in_bytes, &out_bytes);

		/* check interface hw_type */
		bzero(&ifr, sizeof(ifr));
		strncpy(ifr.ifr_name, name, strlen(name));
  		ifr.ifr_name[strlen(name)+1] = '\0';
		if (ioctl(sockfd, SIOCGIFHWADDR, &ifr)<0)
			continue;

		/* hw_types is not Ethernet and PPP */
		if (ifr.ifr_hwaddr.sa_family!=ARPHRD_ETHER&&ifr.ifr_hwaddr.sa_family!=ARPHRD_PPP)
			continue;

		/* detecting new interface */
		if ((devptr = netproc_netdevlist_find(*netdev_list, name))==NULL) {
			/* check wireless device */
			has_iwrange = (iw_get_range_info(iwsockfd, name, &iwrange)>=0);
			if (!(has_iwrange) || (iwrange.we_version_compiled < 14))
				netproc_netdevlist_add(netdev_list, name, in_bytes, in_packets, out_bytes, out_packets, FALSE);
			else
				netproc_netdevlist_add(netdev_list, name, in_bytes, in_packets, out_bytes, out_packets, TRUE);

			devptr = netproc_netdevlist_find(*netdev_list, name);

			/* MAC Address */
			devptr->info.mac = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
					ifr.ifr_hwaddr.sa_data[0] & 0377,
					ifr.ifr_hwaddr.sa_data[1] & 0377,
					ifr.ifr_hwaddr.sa_data[2] & 0377,
					ifr.ifr_hwaddr.sa_data[3] & 0377,
					ifr.ifr_hwaddr.sa_data[4] & 0377,
					ifr.ifr_hwaddr.sa_data[5] & 0377);
		} else {
			/* Setting device status and update flags */
			if (devptr->info.recv_packets!=in_packets&&devptr->info.trans_packets!=out_packets) {
				if (devptr->info.status!=NETDEV_STAT_BOTHRS)
					devptr->info.updated = TRUE;
			
				devptr->info.status = NETDEV_STAT_BOTHRS;
			} else if (devptr->info.recv_packets!=in_packets) {
				if (devptr->info.status!=NETDEV_STAT_RECVDATA)
					devptr->info.updated = TRUE;

				devptr->info.status = NETDEV_STAT_RECVDATA;
			} else if (devptr->info.trans_packets!=out_packets) {
				if (devptr->info.status!=NETDEV_STAT_SENDDATA)
					devptr->info.updated = TRUE;

				devptr->info.status = NETDEV_STAT_SENDDATA;
			} else {
				if (devptr->info.status!=NETDEV_STAT_NORMAL)
					devptr->info.updated = TRUE;

				devptr->info.status = NETDEV_STAT_NORMAL;
			}

			/* Recording r/t information */
			devptr->info.recv_bytes = in_bytes;
			devptr->info.recv_packets = in_packets;
			devptr->info.trans_bytes = out_bytes;
			devptr->info.trans_packets = out_packets;

			/* give device a life */
			devptr->info.alive = TRUE;
		}

		/* Enable */
		bzero(&ifr, sizeof(ifr));
		strcpy(ifr.ifr_name, devptr->info.ifname);
		ifr.ifr_name[IF_NAMESIZE - 1] = '\0';
		if (ioctl(sockfd, SIOCGIFFLAGS, &ifr)>=0) {
			devptr->info.flags = ifr.ifr_flags;
			if (ifr.ifr_flags & IFF_UP) {
				devptr->info.enable = TRUE;
				devptr->info.updated = TRUE;
			} else {
				devptr->info.enable = FALSE;
				devptr->info.updated = TRUE;
			}

			if (devptr->info.enable) {
				/* Workaround for Atheros Cards */
				if (strncmp(devptr->info.ifname, "ath", 3)==0)
					wireless_refresh(iwsockfd, devptr->info.ifname);
				
				/* plug */
				bzero(&ifr, sizeof(ifr));
				strcpy(ifr.ifr_name, devptr->info.ifname);
				ifr.ifr_name[IF_NAMESIZE - 1] = '\0';

				edata.cmd = 0x0000000a;
				ifr.ifr_data = (caddr_t)&edata;
				if (ioctl(sockfd, SIOCETHTOOL, &ifr)<0) {
					/* using IFF_RUNNING instead due to system doesn't have ethtool or working in non-root */
					if (devptr->info.flags & IFF_RUNNING) {
						if (!devptr->info.plug) {
							devptr->info.plug = TRUE;
							devptr->info.updated = TRUE;
						}
					} else if (devptr->info.plug) {
						devptr->info.plug = FALSE;
						devptr->info.updated = TRUE;
					}
				} else {
					if (edata.data) {
						if (!devptr->info.plug) {
							devptr->info.plug = TRUE;
							devptr->info.updated = TRUE;
						}
					} else if (devptr->info.plug) {
						devptr->info.plug = FALSE;
						devptr->info.updated = TRUE;
					}
				}

				/* get network information */
				if (devptr->info.enable&&devptr->info.plug) {
					if (devptr->info.flags & IFF_RUNNING) {
						/* release old information */
						g_free(devptr->info.ipaddr);
						g_free(devptr->info.bcast);
						g_free(devptr->info.mask);

						/* IP Address */
						bzero(&ifr, sizeof(ifr));
						strcpy(ifr.ifr_name, devptr->info.ifname);
						ifr.ifr_name[IF_NAMESIZE - 1] = '\0';
						if (ioctl(sockfd, SIOCGIFADDR, &ifr)<0)
							devptr->info.ipaddr = g_strdup("0.0.0.0");
						else
							devptr->info.ipaddr = g_strdup(inet_ntoa(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr));

						/* Point-to-Porint Address */
						if (devptr->info.flags & IFF_POINTOPOINT) {
							bzero(&ifr, sizeof(ifr));
							strcpy(ifr.ifr_name, devptr->info.ifname);
							ifr.ifr_name[IF_NAMESIZE - 1] = '\0';
							if (ioctl(sockfd, SIOCGIFDSTADDR, &ifr)<0)
								devptr->info.dest = NULL;
							else
								devptr->info.dest = g_strdup(inet_ntoa(((struct sockaddr_in*)&ifr.ifr_dstaddr)->sin_addr));
						}

						/* Broadcast */
						if (devptr->info.flags & IFF_BROADCAST) {
							bzero(&ifr, sizeof(ifr));
							strcpy(ifr.ifr_name, devptr->info.ifname);
							ifr.ifr_name[IF_NAMESIZE - 1] = '\0';
							if (ioctl(sockfd, SIOCGIFBRDADDR, &ifr)<0)
								devptr->info.bcast = NULL;
							else
								devptr->info.bcast = g_strdup(inet_ntoa(((struct sockaddr_in*)&ifr.ifr_broadaddr)->sin_addr));
						}

						/* Netmask */
						bzero(&ifr, sizeof(ifr));
						strcpy(ifr.ifr_name, devptr->info.ifname);
						ifr.ifr_name[IF_NAMESIZE - 1] = '\0';
						if (ioctl(sockfd, SIOCGIFNETMASK, &ifr)<0)
							devptr->info.mask = NULL;
						else
							devptr->info.mask = g_strdup(inet_ntoa(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr));

						/* Wireless Information */
						if (devptr->info.wireless) {
							struct wireless_config wconfig;

							/* get wireless config */
							if (iw_get_basic_config(iwsockfd, devptr->info.ifname, &wconfig)>=0) {
								/* Protocol */
								devptr->info.protocol = g_strdup(wconfig.name);
								/* ESSID */
								devptr->info.essid = g_strdup(wconfig.essid);

								/* Signal Quality */
								iw_get_stats(iwsockfd, devptr->info.ifname, &iws, &iwrange, has_iwrange);
								devptr->info.quality = rint((log (iws.qual.qual) / log (92)) * 100.0);
							}
						}

						/* check problem connection */
						if (strcmp(devptr->info.ipaddr, "0.0.0.0")==0) {
							devptr->info.status = NETDEV_STAT_PROBLEM;
							/* has connection problem  */
							if (devptr->info.connected) {
								devptr->info.connected = FALSE;
								devptr->info.updated = TRUE;
							}
						} else if (!devptr->info.connected) {
								devptr->info.status = NETDEV_STAT_NORMAL;
								devptr->info.connected = TRUE;
								devptr->info.updated = TRUE;
						}
					} else {
						/* has connection problem  */
						devptr->info.status = NETDEV_STAT_PROBLEM;
						if (devptr->info.connected) {
							devptr->info.connected = FALSE;
							devptr->info.updated = TRUE;
						}
					}
				}
			}
		}

		devptr = NULL;
		count++;
	}

	rewind(fp);
	fflush(fp);

	return count;
}
Пример #21
0
int netcfg_wireless_choose_essid_manually(struct debconfclient *client, char *iface)
{
    /* Priority here should be high, since user had already chosen to
     * enter an ESSID, he wants to see this question. */

    int ret, couldnt_associate = 0;
    wireless_config wconf;
    char* tf = NULL, *user_essid = NULL, *ptr = wconf.essid;

    iw_get_basic_config (wfd, iface, &wconf);

    debconf_reset(client, "netcfg/wireless_essid");
    debconf_reset(client, "netcfg/wireless_essid_again");

    debconf_subst(client, "netcfg/wireless_essid", "iface", iface);
    debconf_subst(client, "netcfg/wireless_essid_again", "iface", iface);
    debconf_subst(client, "netcfg/wireless_adhoc_managed", "iface", iface);

    debconf_input(client, "low", "netcfg/wireless_adhoc_managed");

    if (debconf_go(client) == 30)
        return GO_BACK;

    debconf_get(client, "netcfg/wireless_adhoc_managed");

    if (!strcmp(client->value, "Ad-hoc network (Peer to peer)"))
        mode = ADHOC;

    wconf.has_mode = 1;
    wconf.mode = mode;

    debconf_input(client, "high", "netcfg/wireless_essid");

    if (debconf_go(client) == 30)
        return GO_BACK;

    debconf_get(client, "netcfg/wireless_essid");
    tf = strdup(client->value);

automatic:
    /* User doesn't care or we're successfully associated. */
    if (!empty_str(wconf.essid) || empty_str(client->value)) {
        if (netcfg_wireless_auto_connect(client, iface, &wconf,
                &couldnt_associate) == 0) {
            return 0;
        }
    }

    /* Yes, wants to set an essid by himself. */

    if (strlen(tf) <= IW_ESSID_MAX_SIZE) /* looks ok, let's use it */
        user_essid = tf;

    while (!user_essid || empty_str(user_essid) ||
           strlen(user_essid) > IW_ESSID_MAX_SIZE) {
        /* Misnomer of a check. Basically, if we went through autodetection,
         * we want to enter this loop, but we want to suppress anything that
         * relied on the checking of tf/user_essid (i.e. "", in most cases.) */
        if (!couldnt_associate) {
            debconf_subst(client, "netcfg/invalid_essid", "essid", user_essid);
            debconf_input(client, "high", "netcfg/invalid_essid");
            debconf_go(client);
        }

        if (couldnt_associate)
            ret = debconf_input(client, "critical", "netcfg/wireless_essid_again");
        else
            ret = debconf_input(client, "low", "netcfg/wireless_essid");

        /* we asked the question once, why can't we ask it again? */
        if (ret == 30)
            /* maybe netcfg/wireless_essid was preseeded; if so, give up */
            break;

        if (debconf_go(client) == 30) /* well, we did, but he wants to go back */
            return GO_BACK;

        if (couldnt_associate)
            debconf_get(client, "netcfg/wireless_essid_again");
        else
            debconf_get(client, "netcfg/wireless_essid");

        if (empty_str(client->value)) {
            if (couldnt_associate)
                /* we've already tried the empty string here, so give up */
                break;
            else
                goto automatic;
        }

        /* But now we'd not like to suppress any MORE errors */
        couldnt_associate = 0;

        free(user_essid);
        user_essid = strdup(client->value);
    }

    essid = user_essid;

    memset(ptr, 0, IW_ESSID_MAX_SIZE + 1);
    snprintf(wconf.essid, IW_ESSID_MAX_SIZE + 1, "%s", essid);
    wconf.has_essid = 1;
    wconf.essid_on = 1;

    iw_set_basic_config(wfd, iface, &wconf);

    return 0;
}
Пример #22
0
void CWextHW::readSignalQuality() {
	if ( (m_wextFd == -1) ) {
		return;
	}
	struct iw_range range;
	memset(&range,0,sizeof(struct iw_range));
	int hasRange = 0;
	iwstats stats;
	memset(&stats,0,sizeof(iwstats));
	WextRawScan res;
	/* workaround */
	struct wireless_config wifiConfig;
	memset(&wifiConfig,0,sizeof(struct wireless_config));
	/* Get basic information */ 
	if(iw_get_basic_config(m_wextFd, m_ifname.toAscii().constData(), &wifiConfig) < 0) {
		/* If no wireless name : no wireless extensions */ 
		/* But let's check if the interface exists at all */ 
		struct ifreq ifr;
		memset(&ifr,0,sizeof(struct ifreq)); 
	
		strncpy(ifr.ifr_name, m_ifname.toAscii().data(), IFNAMSIZ); 
		if(ioctl(m_wextFd, SIOCGIFFLAGS, &ifr) < 0) 
			qWarning() << tr("(Wireless Extension) No device present");
		else
			qWarning() << tr("(Wireless Extension) device not supported");
		return;
	}
	qDebug() << "Fetched basic config.";

	//We encode frequency in mhz;
	//kernel encodes as double; (hopefully always in hz)
	//But better test this:
	res.freq = -1;
	if (wifiConfig.has_freq) {
		if ( ( (wifiConfig.freq/1e9) < 10.0 ) && ( (wifiConfig.freq/1e9) > 0.0 ) ) {
			res.freq = (int) (wifiConfig.freq/1e6);
		}
	}
	
	struct iwreq wrq;
	memset(&wrq,0,sizeof(struct iwreq));
	
	/* Get AP address */
	if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWAP, &wrq) >= 0) {
		//Add mac address of current ap;
		res.bssid = libnutcommon::MacAddress((ether_addr*)wrq.u.ap_addr.sa_data);
		qDebug() << "Got AP: " << res.bssid.toString();
	}
	
	/* Get ssid */
	quint8 * buffer = new quint8[IW_ESSID_MAX_SIZE];
	memset(buffer, '\0', IW_ESSID_MAX_SIZE);
	wrq.u.essid.pointer = (void *)buffer;
	wrq.u.essid.length = IW_ESSID_MAX_SIZE;
	if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWESSID, &wrq) >= 0) {
		if (wrq.u.essid.length > IW_ESSID_MAX_SIZE)
			wrq.u.essid.length = IW_ESSID_MAX_SIZE;
		if (wrq.u.essid.flags) {
			/* Does it have an ESSID index ? */
			if ( wrq.u.essid.pointer && wrq.u.essid.length ) {
				if ( (wrq.u.essid.flags & IW_ENCODE_INDEX) > 1) {
					res.ssid = QString("%1 [%2]").arg(QString::fromAscii((char*) wrq.u.essid.pointer, wrq.u.essid.length), QString::number(wrq.u.essid.flags & IW_ENCODE_INDEX));
				}
				else {
					res.ssid = QString::fromAscii((char*) wrq.u.essid.pointer, wrq.u.essid.length);
				}
			}
			else {
				res.ssid = "N/A";
			}
		}
		qDebug() << "Got ssid: " << res.ssid;
	}
	delete[] buffer;
	
	/* Get bit rate */
	if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWRATE, &wrq) >= 0) {
		res.bitrates.append((qint32) wrq.u.bitrate.value);
		qDebug() << "Got bit rate: " << res.bitrates[0];
	}
	
	/* Get Power Management settings */
	wrq.u.power.flags = 0;
	if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWPOWER, &wrq) >= 0) {
		qDebug() << "Got power";
	}
	/* workaround */
	
	
	/* Get range stuff */
	qDebug() << QString("Getting range stuff for %1").arg(m_ifname.toAscii().data());
	if (iw_get_range_info(m_wextFd, m_ifname.toAscii().data(), &range) >= 0) {
		hasRange = 1;
		qDebug() << "Success readWirelessInfo getrange" << strerror(errno);
	}
	else { //This is VERY strange: we always get the "operation not permitted" error, although iw_get_range() worked
		qDebug() << QString("Error \"hasRange == 0\" (%1)").arg(strerror(errno));
	}
	res.hasRange = hasRange;
	if (errno == EAGAIN) {
		m_sqTimeOutCount++;
		qDebug() << QString("Getting range stuff failed (%1)").arg(strerror(errno));
		if ( (m_sqTimeOutCount > 10) && m_sqPollrate < 1000) {
			setSignalQualityPollRate(10000);
		}
		else if (m_sqTimeOutCount > 10) { //Fast polling disabled, but still EAGAIN errors
			//Seems the kernel does not care about our calls
			killTimer(m_sqTimerId);
			m_sqTimerId = -1;
		}
		return;
	}
	
	qDebug() << "Got range stuff";
	

	//Set supported Frequencies if the list is not empty;
	if (m_supportedFrequencies.isEmpty() && hasRange) {
		qDebug() << range.num_frequency;
		qDebug() << "Printing Frequency information";
		quint32 m;
		quint16 e;
		quint32 freqinmhz;
		for (int i=0; i < range.num_channels; i++) {
			m = (quint32) range.freq[i].m;
			e = (quint16) range.freq[i].e;
			freqinmhz = m;
			for (int j=0; j < 9-e-3; j++) {
				freqinmhz = freqinmhz/10;
			}
			if (!m_supportedFrequencies.contains(freqinmhz)) { //Only add frequency that are not in our list
				m_supportedFrequencies.append(freqinmhz);
			}
			qDebug() << m << e << freqinmhz << frequencyToChannel(freqinmhz);
		}
		qDebug() << "Done printing";
	}
	else {
		qDebug() << "m_supportedFrequencies not set";
	}
	
	if (hasRange) {
		res.maxquality.level = (quint8) range.max_qual.level;
		res.maxquality.qual = (quint8) range.max_qual.qual;
		res.maxquality.noise = (quint8) range.max_qual.noise;
		res.maxquality.updated = (quint8) range.max_qual.updated;
		qDebug() << "RANGE: " << res.maxquality.level  << res.maxquality.qual << res.maxquality.noise << res.maxquality.updated;
	}
	else {
		res.maxquality.level = 0;
		res.maxquality.qual = 0;
		res.maxquality.noise = 0;
		res.maxquality.updated = 0;
		qDebug() << "Range information are not available";
	}
	if ( (hasRange) && (range.we_version_compiled > 11) ) {
		struct iwreq wrq;
		memset(&wrq,0,sizeof(struct iwreq));
		wrq.u.data.pointer = (caddr_t) &stats;
		wrq.u.data.length = sizeof(struct iw_statistics);
		wrq.u.data.flags = 1; // Clear updated flag
		strncpy(wrq.ifr_name, m_ifname.toAscii().data(), IFNAMSIZ);
		
		qDebug() << "Getting wireless stats";
		if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWSTATS, &wrq) < 0) {
			qWarning() << tr("Error occured while fetching wireless info: ") << strerror(errno);
		}
		else { //Stats fetched
			qDebug() << "Stats fetched";
			res.quality.level = (quint8) stats.qual.level;
			res.quality.qual = (quint8) stats.qual.qual;
			res.quality.noise = (quint8) stats.qual.noise;
			res.quality.updated = (quint8) stats.qual.updated;
			qDebug() << "STATS: " << res.quality.level << res.quality.qual << res.quality.noise << res.quality.updated;
			m_sq = convertValues(res);
			qDebug() << "Emittig m_signalQualityUpdated()";
			if (m_sqPollrate < 1000) {
				setSignalQualityPollRate(10000);
				emit message(tr("Auto-resetting timer to 10 seconds"));
			}
			emit signalQualityUpdated(m_sq);
		}
	}
	else if (range.we_version_compiled <= 11) {
		emit message(tr("Cannot fetch wireless information as your wireless extension is too old"));
		emit message(tr("Think about updating your kernel (it's way too old)"));
	}
	else {
		qDebug() << "Error while trying to fetch wireless information" << strerror(errno);
		qDebug() << "Wireless Extension socket file descriptor was: " << m_wextFd;
	}
}
Пример #23
0
int netcfg_wireless_set_essid (struct debconfclient * client, char *iface, char* priority)
{
    int ret, couldnt_associate = 0;
    wireless_config wconf;
    char* tf = NULL, *user_essid = NULL, *ptr = wconf.essid;
    
    iw_get_basic_config (wfd, iface, &wconf);
    
    debconf_subst(client, "netcfg/wireless_essid", "iface", iface);
    debconf_subst(client, "netcfg/wireless_essid_again", "iface", iface);
    debconf_subst(client, "netcfg/wireless_adhoc_managed", "iface", iface);
    
    debconf_input(client, priority ? priority : "low", "netcfg/wireless_adhoc_managed");
    
    if (debconf_go(client) == 30)
        return GO_BACK;
    
    debconf_get(client, "netcfg/wireless_adhoc_managed");
    
    if (!strcmp(client->value, "Ad-hoc network (Peer to peer)"))
        mode = ADHOC;
    
    wconf.has_mode = 1;
    wconf.mode = mode;
    
    debconf_input(client, priority ? priority : "low", "netcfg/wireless_essid");
    
    if (debconf_go(client) == 30)
        return GO_BACK;
    
    debconf_get(client, "netcfg/wireless_essid");
    tf = strdup(client->value);
    
automatic:
    /* question not asked or user doesn't care or we're successfully associated */
    if (!empty_str(wconf.essid) || empty_str(client->value)) 
    {
        int i, success = 0;
        
        /* Default to any AP */
        wconf.essid[0] = '\0';
        wconf.essid_on = 0;
        
        iw_set_basic_config (wfd, iface, &wconf);
        
        /* Wait for association.. (MAX_SECS seconds)*/
#define MAX_SECS 3
        
        debconf_capb(client, "backup progresscancel");
        debconf_progress_start(client, 0, MAX_SECS, "netcfg/wifi_progress_title");
        if (debconf_progress_info(client, "netcfg/wifi_progress_info") == 30)
            goto stop;
        netcfg_progress_displayed = 1;
        
        for (i = 0; i <= MAX_SECS; i++) {
            int progress_ret;
            
            interface_up(iface);
            sleep (1);
            iw_get_basic_config (wfd, iface, &wconf);
            
            if (!empty_str(wconf.essid)) {
                /* Save for later */
                debconf_set(client, "netcfg/wireless_essid", wconf.essid);
                debconf_progress_set(client, MAX_SECS);
                success = 1;
                break;
            }
            
            progress_ret = debconf_progress_step(client, 1);
            interface_down(iface);
            if (progress_ret == 30)
                break;
        }
        
    stop:
        debconf_progress_stop(client);
        debconf_capb(client, "backup");
        netcfg_progress_displayed = 0;
        
        if (success)
            return 0;
        
        couldnt_associate = 1;
    }
    /* yes, wants to set an essid by himself */
    
    if (strlen(tf) <= IW_ESSID_MAX_SIZE) /* looks ok, let's use it */
        user_essid = tf;
    
    while (!user_essid || empty_str(user_essid) ||
           strlen(user_essid) > IW_ESSID_MAX_SIZE) {
        /* Misnomer of a check. Basically, if we went through autodetection,
         * we want to enter this loop, but we want to suppress anything that
         * relied on the checking of tf/user_essid (i.e. "", in most cases.) */
        if (!couldnt_associate) {
            debconf_subst(client, "netcfg/invalid_essid", "essid", user_essid);
            debconf_input(client, "high", "netcfg/invalid_essid");
            debconf_go(client);
        }
        
        if (couldnt_associate)
            ret = debconf_input(client, "critical", "netcfg/wireless_essid_again");
        else
            ret = debconf_input(client, "low", "netcfg/wireless_essid");
        
        /* we asked the question once, why can't we ask it again? */
        assert (ret != 30);
        
        if (debconf_go(client) == 30) /* well, we did, but he wants to go back */
            return GO_BACK;
        
        if (couldnt_associate)
            debconf_get(client, "netcfg/wireless_essid_again");
        else
            debconf_get(client, "netcfg/wireless_essid");
        
        if (empty_str(client->value)) {
            if (couldnt_associate)
                /* we've already tried the empty string here, so give up */
                break;
            else
                goto automatic;
        }
        
        /* But now we'd not like to suppress any MORE errors */
        couldnt_associate = 0;
        
        free(user_essid);
        user_essid = strdup(client->value);
    }
    
    essid = user_essid;
    
    memset(ptr, 0, IW_ESSID_MAX_SIZE + 1);
    snprintf(wconf.essid, IW_ESSID_MAX_SIZE + 1, "%s", essid);
    wconf.has_essid = 1;
    wconf.essid_on = 1;
    
    iw_set_basic_config (wfd, iface, &wconf);
    
    return 0;
}
Пример #24
0
static int get_wireless_info(const char *interface, wireless_info_t *info) {
        memset(info, 0, sizeof(wireless_info_t));

#ifdef LINUX
        int skfd = iw_sockets_open();
        if (skfd < 0) {
                perror("iw_sockets_open");
                return 0;
        }

        wireless_config wcfg;
        if (iw_get_basic_config(skfd, interface, &wcfg) < 0) {
            close(skfd);
            return 0;
        }

        if (wcfg.has_essid && wcfg.essid_on) {
                info->flags |= WIRELESS_INFO_FLAG_HAS_ESSID;
                strncpy(&info->essid[0], wcfg.essid, IW_ESSID_MAX_SIZE);
                info->essid[IW_ESSID_MAX_SIZE] = '\0';
        }

        /* If the function iw_get_stats does not return proper stats, the
           wifi is considered as down.
           Since ad-hoc network does not have theses stats, we need to return
           here for this mode. */
        if (wcfg.mode == 1) {
                close(skfd);
                return 1;
        }

        /* Wireless quality is a relative value in a driver-specific range.
           Signal and noise level can be either relative or absolute values
           in dBm. Furthermore, noise and quality can be expressed directly
           in dBm or in RCPI (802.11k), which we convert to dBm. When those
           values are expressed directly in dBm, they range from -192 to 63,
           and since the values are packed into 8 bits, we need to perform
           8-bit arithmetic on them. Assume absolute values if everything
           else fails (driver bug). */

        iwrange range;
        if (iw_get_range_info(skfd, interface, &range) < 0) {
                close(skfd);
                return 0;
        }

        iwstats stats;
        if (iw_get_stats(skfd, interface, &stats, &range, 1) < 0) {
                close(skfd);
                return 0;
        }

        if (stats.qual.level != 0 || (stats.qual.updated & (IW_QUAL_DBM | IW_QUAL_RCPI))) {
                if (!(stats.qual.updated & IW_QUAL_QUAL_INVALID)) {
                        info->quality = stats.qual.qual;
                        info->quality_max = range.max_qual.qual;
                        info->quality_average = range.avg_qual.qual;
                        info->flags |= WIRELESS_INFO_FLAG_HAS_QUALITY;
                }

                if (stats.qual.updated & IW_QUAL_RCPI) {
                        if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
                                info->signal_level = stats.qual.level / 2.0 - 110 + 0.5;
                                info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
                        }
                        if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
                                info->noise_level = stats.qual.noise / 2.0 - 110 + 0.5;
                                info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
                        }
                }
                else {
                        if ((stats.qual.updated & IW_QUAL_DBM) || stats.qual.level > range.max_qual.level) {
                                if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
                                        info->signal_level = stats.qual.level;
                                        if (info->signal_level > 63)
                                                info->signal_level -= 256;
                                        info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
                                }
                                if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
                                        info->noise_level = stats.qual.noise;
                                        if (info->noise_level > 63)
                                                info->noise_level -= 256;
                                        info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
                                }
                        }
                        else {
                                if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
                                        info->signal_level = stats.qual.level;
                                        info->signal_level_max = range.max_qual.level;
                                        info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
                                }
                                if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
                                        info->noise_level = stats.qual.noise;
                                        info->noise_level_max = range.max_qual.noise;
                                        info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
                                }
                        }
                }
        }
        else {
                if (!(stats.qual.updated & IW_QUAL_QUAL_INVALID)) {
                        info->quality = stats.qual.qual;
                        info->flags |= WIRELESS_INFO_FLAG_HAS_QUALITY;
                }
                if (!(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
                        info->quality = stats.qual.level;
                        info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
                }
                if (!(stats.qual.updated & IW_QUAL_NOISE_INVALID)) {
                        info->quality = stats.qual.noise;
                        info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
                }
        }

        struct iwreq wrq;
        if (iw_get_ext(skfd, interface, SIOCGIWRATE, &wrq) >= 0)
                info->bitrate = wrq.u.bitrate.value;

        close(skfd);
        return 1;
#endif
#if defined(__FreeBSD__) || defined(__DragonFly__)
        int s, len, inwid;
        uint8_t buf[24 * 1024], *cp;
        struct ieee80211req na;
        char network_id[IEEE80211_NWID_LEN + 1];

        if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
                return (0);

        memset(&na, 0, sizeof(na));
        strlcpy(na.i_name, interface, sizeof(na.i_name));
        na.i_type = IEEE80211_IOC_SSID;
        na.i_data = &info->essid[0];
        na.i_len = IEEE80211_NWID_LEN + 1;
        if ((inwid = ioctl(s, SIOCG80211, (caddr_t)&na)) == -1) {
                close(s);
                return (0);
        }
        if (inwid == 0) {
                if (na.i_len <= IEEE80211_NWID_LEN)
                        len = na.i_len + 1;
                else
                        len = IEEE80211_NWID_LEN + 1;
                info->essid[len -1] = '\0';
        } else {
                close(s);
                return (0);
        }
        info->flags |= WIRELESS_INFO_FLAG_HAS_ESSID;

        memset(&na, 0, sizeof(na));
        strlcpy(na.i_name, interface, sizeof(na.i_name));
        na.i_type = IEEE80211_IOC_SCAN_RESULTS;
        na.i_data = buf;
        na.i_len = sizeof(buf);

        if (ioctl(s, SIOCG80211, (caddr_t)&na) == -1) {
                printf("fail\n");
                close(s);
                return (0);
        }

        close(s);
        len = na.i_len;
        cp = buf;
        struct ieee80211req_scan_result *sr;
        uint8_t *vp;
        sr = (struct ieee80211req_scan_result *)cp;
        vp = (u_int8_t *)(sr + 1);
        strlcpy(network_id, (const char *)vp, sr->isr_ssid_len + 1);
        if (!strcmp(network_id, &info->essid[0])) {
                info->signal_level = sr->isr_rssi;
                info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
                info->noise_level = sr->isr_noise;
                info->flags |= WIRELESS_INFO_FLAG_HAS_NOISE;
                info->quality = sr->isr_intval;
                info->flags |= WIRELESS_INFO_FLAG_HAS_QUALITY;
        }

        return 1;
#endif
#ifdef __OpenBSD__
	struct ifreq ifr;
	struct ieee80211_bssid bssid;
	struct ieee80211_nwid nwid;
	struct ieee80211_nodereq nr;

	struct ether_addr ea;

        int s, len, ibssid, inwid;
	u_int8_t zero_bssid[IEEE80211_ADDR_LEN];

	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
		return (0);

        memset(&ifr, 0, sizeof(ifr));
        ifr.ifr_data = (caddr_t)&nwid;
	(void)strlcpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name));
        inwid = ioctl(s, SIOCG80211NWID, (caddr_t)&ifr);

	memset(&bssid, 0, sizeof(bssid));
	strlcpy(bssid.i_name, interface, sizeof(bssid.i_name));
	ibssid = ioctl(s, SIOCG80211BSSID, &bssid);

	if (ibssid != 0 || inwid != 0) {
		close(s);
		return 0;
	}

	/* NWID */
	{
		if (nwid.i_len <= IEEE80211_NWID_LEN)
			len = nwid.i_len + 1;
		else
			len = IEEE80211_NWID_LEN + 1;

		strncpy(&info->essid[0], nwid.i_nwid, len);
		info->essid[IW_ESSID_MAX_SIZE] = '\0';
		info->flags |= WIRELESS_INFO_FLAG_HAS_ESSID;
	}

	/* Signal strength */
	{
		memset(&zero_bssid, 0, sizeof(zero_bssid));
		if (ibssid == 0 && memcmp(bssid.i_bssid, zero_bssid, IEEE80211_ADDR_LEN) != 0) {
			memcpy(&ea.ether_addr_octet, bssid.i_bssid, sizeof(ea.ether_addr_octet));

			bzero(&nr, sizeof(nr));
			bcopy(bssid.i_bssid, &nr.nr_macaddr, sizeof(nr.nr_macaddr));
			strlcpy(nr.nr_ifname, interface, sizeof(nr.nr_ifname));

			if (ioctl(s, SIOCG80211NODE, &nr) == 0 && nr.nr_rssi) {
				if (nr.nr_max_rssi)
					info->signal_level_max = IEEE80211_NODEREQ_RSSI(&nr);
				else
					info->signal_level = nr.nr_rssi;

		                info->flags |= WIRELESS_INFO_FLAG_HAS_SIGNAL;
			}
		}
	}

	close(s);
	return 1;
#endif
	return 0;
}
Пример #25
0
//noise levels, returned by this functions, are invalid, don't use them
void CWextHW::readScanResults() {
	if (m_wextFd == -1) {
		return;
	}
	//Kill Timer:
	if (m_scTimerId != -1) {
		killTimer(m_scPollrate);
		m_scTimerId = -1;
	}
	else { //This is not a timer call; this should not happen
		qWarning() << tr("Warning, no timer present while trying to get scan results");
		return;
	}
	struct iwreq wrq;
	memset(&wrq,0,sizeof(struct iwreq));
	unsigned char * buffer = NULL;		/* Results */
	int buflen = IW_SCAN_MAX_DATA; /* Min for compat WE<17 */
	struct iw_range range;
	memset(&range,0,sizeof(struct iw_range));
	int has_range;
	QList<WextRawScan> res = QList<WextRawScan>();
	WextRawScan singleres;
	singleres.bssid = libnutcommon::MacAddress();
	singleres.group = GCI_UNDEFINED;
	singleres.pairwise = PCI_UNDEFINED;
	singleres.protocols = PROTO_UNDEFINED;
	singleres.keyManagement = KM_UNDEFINED;
	
	/* workaround */
	struct wireless_config wifiConfig;
	memset(&wifiConfig,0,sizeof(struct wireless_config));

	/* Get basic information */ 
	if(iw_get_basic_config(m_wextFd, m_ifname.toAscii().constData(), &wifiConfig) < 0) {
		/* If no wireless name : no wireless extensions */ 
		/* But let's check if the interface exists at all */ 
		struct ifreq ifr;
		memset(&ifr,0,sizeof(struct ifreq)); 
	
		strncpy(ifr.ifr_name, m_ifname.toAscii().data(), IFNAMSIZ); 
		if(ioctl(m_wextFd, SIOCGIFFLAGS, &ifr) < 0) 
			qWarning() << tr("(Wireless Extension) No device present");
		else
			qWarning() << tr("(Wireless Extension) Device not supported");
		return;
	}
	qDebug() << "Fetched basic config.";
	
	/* Get AP address */
	if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWAP, &wrq) >= 0) {
		qDebug() << "Got AP";
	}
	
	/* Get bit rate */
	if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWRATE, &wrq) >= 0) {
		qDebug() << "Got bit rate";
	}
	
	/* Get Power Management settings */
	wrq.u.power.flags = 0;
	if(iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWPOWER, &wrq) >= 0) {
		qDebug() << "Got power";
	}
	/* workaround */

	/* Get range stuff */
	/* Get range stuff */
	qDebug() << QString("Getting range stuff for %1").arg(m_ifname.toAscii().data());
	if (iw_get_range_info(m_wextFd, m_ifname.toAscii().data(), &range) >= 0) {
		has_range = 1;
		qDebug() << "Success readWirelessInfo getrange" << strerror(errno);
	}
	else { //This is VERY strange: we always get the "operation not permitted" error, although iw_get_range() worked
		qDebug() << QString("Error \"hasRange == 0\" (%1)").arg(strerror(errno));
	}
	singleres.hasRange = has_range;

	//If we get a timeout for more than 5 times, stop polling.
	if (errno == EAGAIN) {
		qDebug() << "Scan results not available yet";
		m_scTimeOutCount++;
		if (m_scTimeOutCount == 5) {
			return;
		}
		m_scTimerId = startTimer(m_scPollrate);
		return;
	}
	
	qDebug() << "Got range stuff";

	if (has_range) {
		singleres.maxquality.level = (quint8) range.max_qual.level;
		singleres.maxquality.qual = (quint8) range.max_qual.qual;
		singleres.maxquality.noise = (quint8) range.max_qual.noise;
		singleres.maxquality.updated = (quint8) range.max_qual.updated;
		qDebug() << "RANGE (scanresults): " << singleres.maxquality.level  << singleres.maxquality.qual << singleres.maxquality.noise << singleres.maxquality.updated;
	}
	else {
		singleres.maxquality.level = 0;
		singleres.maxquality.qual = 0;
		singleres.maxquality.noise = 0;
		singleres.maxquality.updated = 0;
		qWarning() << tr("Range information are not available");
	}

	unsigned char * newbuf;
	for (int i=0; i <= 16; i++) { //realloc (don't do this forever)
		//Allocate newbuffer 
		newbuf = (uchar*) realloc(buffer, buflen);
		if(newbuf == NULL) {
			if (buffer) {
				free(buffer);
				buffer = NULL;
			}
			qDebug() << "Allocating buffer for Wext failed";
			return;
		}
		buffer = newbuf;
		
		//Set Request variables:
		wrq.u.data.pointer = buffer;
		wrq.u.data.flags = 0;
		wrq.u.data.length = buflen;
		
		//Get the data:
		if (iw_get_ext(m_wextFd, m_ifname.toAscii().data(), SIOCGIWSCAN, &wrq) < 0) {
			//Buffer is too small
			if((errno == E2BIG) && (range.we_version_compiled > 16)) {
				
				//check if driver gives any hints about scan length:
				if (wrq.u.data.length > buflen) {
					buflen = wrq.u.data.length;
				}
				else { //If not, double the length
					buflen *= 2;
				}
				//Start from the beginning:
				qDebug() << "Buffer was too small";
				continue;
			}
			//No range error occured or kernel has wireless extension < 16
			if (errno == EAGAIN) {
				qDebug() << "Scan results not available yet";
				m_scTimerId = startTimer(m_scPollrate);
				return;
			}
			
			//Bad error occured
			if (buffer) {
				free(buffer);
				buffer = NULL;
			}
			qWarning() << tr("(%1) Failed to read scan data : %2").arg(m_ifname, QString(strerror(errno)));
		}
		else { //Results are there
			break;
		}
	}

	//Now read the data:
	if (wrq.u.data.length) {

		struct iw_event iwe;
		memset(&iwe,0,sizeof(struct iw_event));
		struct stream_descr stream;
		memset(&stream,0,sizeof(struct stream_descr));
		int ret;
		
		//Init event stream
// 		char buffer2[128];
		libnutcommon::MacAddress tmpMac;
		iw_init_event_stream(&stream, (char *) buffer, wrq.u.data.length);
		do {
			/* Extract an event and parse it*/
			memset(&iwe,0,sizeof(struct iw_event)); //valgrind complains about it?
			ret = iw_extract_event_stream(&stream, &iwe, range.we_version_compiled);
			if(ret > 0) {
				//Now parse our scan event:
				switch(iwe.cmd) {
					case SIOCGIWAP:
						//ap_addr has type socketaddr
						//Workaround for macaddress
// 						iw_saether_ntop(&(iwe.u.ap_addr), buffer2);
// 						tmpMac = libnutcommon::MacAddress(QString::fromAscii(buffer2,128));
						tmpMac = libnutcommon::MacAddress( (ether_addr*) iwe.u.ap_addr.sa_data);
						if (singleres.bssid.zero()) { //First bssid
							singleres.bssid = tmpMac;
							qDebug() << "Start parsing one network" << singleres.bssid.toString();
						}
						// if our last bssid is different from the actual one, then we have to append it to our scanlist
						if ( (singleres.bssid != tmpMac) )  {
							res.append(singleres);
							qDebug() << "End parsing one network" << singleres.bssid.toString();
							//reset singleres
							singleres.ssid = QString();
							singleres.bssid.clear();
							singleres.quality = WextRawSignal();
							singleres.freq = -1;
							singleres.group = GCI_UNDEFINED;
							singleres.pairwise = PCI_UNDEFINED;
							singleres.keyManagement = KM_UNDEFINED;
							singleres.protocols = PROTO_UNDEFINED;
							singleres.opmode = OPM_AUTO;
							singleres.bssid = tmpMac;
							qDebug() << "Start parsing one network" << singleres.bssid.toString();
						}
						qDebug() << "BSSID" << singleres.bssid.toString();
						break;
					case IWEVQUAL: //Quality event:
						qDebug() << "Quality" << singleres.bssid.toString();
						singleres.quality.qual = (quint8) iwe.u.qual.qual;
						singleres.quality.level = (quint8) iwe.u.qual.level;
						singleres.quality.noise = (quint8) iwe.u.qual.noise;
						singleres.quality.updated = (quint8) iwe.u.qual.updated;
						qDebug() << "STATS (scanresults): " << singleres.quality.level << singleres.quality.qual << singleres.quality.noise << singleres.quality.updated;
						break;
					case SIOCGIWFREQ:
						qDebug() << "Frequency" << singleres.bssid.toString();
						{
							double freq;
							freq = iw_freq2float(&(iwe.u.freq)); //Hopefully in hz
							if ( ( (freq/1e9) < 10.0 ) && ( (freq/1e9) > 0.0 ) ) {
								singleres.freq = (int) (freq/1e6);
								qDebug() << "Channel for" << singleres.ssid << "is " << freq << singleres.freq;
							}
							else {
								singleres.freq = -1;
							}
						}
						break;
					
					case SIOCGIWMODE:
						qDebug() << "Mode:" << singleres.bssid.toString();
						if(iwe.u.mode >= IW_NUM_OPER_MODE) {
							iwe.u.mode = IW_NUM_OPER_MODE;
						}
						singleres.opmode = (OPMODE) iwe.u.mode;
						break;
					case SIOCGIWESSID:
						qDebug() << "ESSID:" << singleres.bssid.toString();
						if (iwe.u.essid.flags) {
							/* Does it have an ESSID index ? */
							if ( iwe.u.essid.pointer && iwe.u.essid.length ) {
								if ( (iwe.u.essid.flags & IW_ENCODE_INDEX) > 1) {
									singleres.ssid = QString("%1 [%2]").arg(QString::fromAscii((char*) iwe.u.essid.pointer,iwe.u.essid.length), QString::number(iwe.u.essid.flags & IW_ENCODE_INDEX));
								}
								else {
									singleres.ssid = QString("%1").arg(QString::fromAscii((char*) iwe.u.essid.pointer,iwe.u.essid.length));
								}
							}
							else {
								singleres.ssid = QString("N/A");
							}
						}
						else { //Hidden essid or broken driver
							singleres.ssid = QString();
						}
						break;

					case SIOCGIWENCODE: //Get encrytion stuff: (just the key)
						qDebug() << "Encode" << singleres.bssid.toString();
						if (! iwe.u.data.pointer) {
							iwe.u.data.flags |= IW_ENCODE_NOKEY;
						}
						if(iwe.u.data.flags & IW_ENCODE_DISABLED) { //Encryption is disabled
							singleres.keyManagement = KM_NONE;
							qDebug() << "PARING ENCODE-Information: NO KEY";
						}
						else {
							//Extract key information: (See iwlib.c line 1500)
							
							//keyflags: iwe.u.data.flags
							//keysize = iwe.u.data.length
							//
							//Do we have a key
							if (iwe.u.data.flags & IW_ENCODE_NOKEY) { //no key
								if (iwe.u.data.length <= 0) {
									//Encryption is on, but group is unknown
									singleres.keyManagement = KM_NONE;
									qDebug() << "PARSING ENCODE-INFORMATION: WEP KEY";
								}
							} //else: we have a, key but check type later
						}
						break;

					case SIOCGIWRATE:
						singleres.bitrates.append((qint32) iwe.u.bitrate.value);
						qDebug() << "Adding Bitrate: " << (qint32) iwe.u.bitrate.value;
						break;
					
					case IWEVGENIE: //group/pairwsie ciphers etc.
						//buffer = iwe.u.data.pointer
						//bufflen = iwe.u.data.length
						qDebug() << "IE_START" << singleres.bssid.toString();
						{
							int offset = 0;
							/* Loop on each IE, each IE is minimum 2 bytes */
							while(offset <= (iwe.u.data.length - 2)) {
								/* Check IE type */
								if (0xdd == ((uchar *) iwe.u.data.pointer)[offset] || (0x30 == ((uchar *) iwe.u.data.pointer)[offset]) ) { // WPA1/2
									parseWextIeWpa(((uchar *) iwe.u.data.pointer) + offset, iwe.u.data.length, &singleres);

								qDebug() << "Parsed IE-Information of " << singleres.ssid << singleres.bssid.toString();
								qDebug() << toString(singleres.group) << toString(singleres.pairwise) << toString(singleres.keyManagement);
								}
								/* Skip over this IE to the next one in the list. */
								offset += buffer[offset+1] + 2;
							}
						}
						qDebug() << "IE_END" << singleres.bssid.toString();
						break;

					default: //Ignore all other event types. Maybe we need them later?
						break;
				}
			}
			else { //Append last scan:
				if (!singleres.bssid.zero()) {
					res.append(singleres);
					qDebug() << "End parsing one network" << singleres.bssid.toString();
				}
			}
	
		} while(ret > 0);

		//Delete buffer
		if (buffer) {
			free(buffer);
			buffer = NULL;
		}
		//We have the data, now construct complete ScanResult
		setScanResults(res);
	}
	else {
		qWarning() << tr("No Scanresults available");
		setScanResults(QList<WextRawScan>());
	}
	if (buffer) {
		free(buffer);
		buffer = NULL;
	}
}
Пример #26
0
int netcfg_wireless_choose_essid_manually(struct debconfclient *client,
        struct netcfg_interface *interface, char *question)
{
    wireless_config wconf;

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

    debconf_subst(client, question, "iface", interface->name);
    debconf_subst(client, "netcfg/wireless_adhoc_managed", "iface", interface->name);

    if (debconf_go(client) == CMD_GOBACK) {
        debconf_fset(client, question, "seen", "false");
        return GO_BACK;
    }

    debconf_get(client, "netcfg/wireless_adhoc_managed");

    if (!strcmp(client->value, "Ad-hoc network (Peer to peer)")) {
        interface->mode = ADHOC;
    }

    wconf.has_mode = 1;
    wconf.mode = interface->mode;

get_essid:
    debconf_input(client, "high", question);

    if (debconf_go(client) == CMD_GOBACK) {
        return GO_BACK;
    }

    debconf_get(client, question);

    if (client->value && strlen(client->value) > IW_ESSID_MAX_SIZE) {
        char max_len_string[5];
        sprintf(max_len_string, "%d", IW_ESSID_MAX_SIZE);
        debconf_capb(client, "");
        debconf_subst(client, "netcfg/invalid_essid", "essid", client->value);
        debconf_subst(client, "netcfg/invalid_essid", "max_essid_len",
                      max_len_string);
        debconf_input(client, "critical", "netcfg/invalid_essid");
        debconf_go(client);

        debconf_fset(client, question, "seen", "false");
        debconf_capb(client, "backup");
        goto get_essid;
    }

    interface->essid = strdup(client->value);

    memset(wconf.essid, 0, IW_ESSID_MAX_SIZE + 1);
    snprintf(wconf.essid, IW_ESSID_MAX_SIZE + 1, "%s", interface->essid);
    wconf.has_essid = 1;
    wconf.essid_on = 1;

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

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

    return 0;
}
Пример #27
0
int main(int argc, const char **argv) {
	/* Check uid */
	if (getuid() != 0) {
		fprintf(stderr,"Swifer must be run as root.\n");
		return 1;
	}
	/* Check config file for interface and dhcp */
	FILE *cfg;
	if ( (cfg=fopen(config,"r")) ) {
		char *line = calloc(MAX_LINE+1,sizeof(char));
		char *val = calloc(MAX_LINE+1,sizeof(char));
		while (fgets(line,MAX_LINE,cfg) != NULL) {
			if (line[0] == '#') continue;
			if (sscanf(line,"INTERFACE = %s",val))
				strncpy(ifname,val,IFNAMSIZ);
			else if (sscanf(line,"DHCP = %s",val))
				strncpy(dhcp,val,DHCPLEN);
			else if (sscanf(line,"PRE_UP = %s",val))
				hook_preup = strdup(val);
			else if (sscanf(line,"POST_UP = %s",val))
				hook_postup = strdup(val);
			else if (strncmp(line,"[NETWORKS]",10)==0)
				break;
		}
		free(line); free(val); fclose(cfg);
	}
	/* Get basic wifi info */
	we_ver = iw_get_kernel_we_version();
	skfd = iw_sockets_open();
	iw_get_basic_config(skfd,ifname,&cur);
	/* Bring up interface (eg "ip link set IFACE up") */
	struct ifreq req;
	int err;
	strncpy(req.ifr_name,ifname,IFNAMSIZ);
	if ( (err=ioctl(skfd,SIOCGIFFLAGS,&req)) ){
		int loop = 0;
		while ( (err=ioctl(skfd,SIOCGIFFLAGS,&req)) ) {
			usleep(100000);
			if (loop++ > 50) break;
		}
		if (err) {
			close(skfd);
			return 2;
		}
	}
	req.ifr_flags |= IFF_UP;
	if (ioctl(skfd,SIOCSIFFLAGS,&req)) {
		close(skfd); return 3;
	}
	/* Processes command line arguments */
	int i;
	for (i = 1; i < argc; i++) {
		if (strncmp(argv[i],"ad",2)==0) mode |= MODE_ADD;
		else if (strncmp(argv[i],"au",2)==0) mode |= MODE_AUTO;
		else if (strncmp(argv[i],"hi",2)==0) mode |= MODE_HIDDEN;
		else if (strncmp(argv[i],"an",2)==0) mode |= (MODE_ANY | MODE_AUTO);
		else if (strncmp(argv[i],"re",2)==0) mode |= (MODE_RECONNECT | MODE_AUTO);
		else if (strncmp(argv[i],"ve",2)==0) mode |= MODE_VERBOSE;
		else if (strncmp(argv[i],"wa",2)==0) mode |= MODE_WAIT;
		else if (strncmp(argv[i],"de",2)==0) {
			if (argc > i+1) remove_network(argv[i+1]);
		}
		else fprintf(stderr,"[%s] Ignoring unknown parameter: %s\n",
			argv[0],argv[i]);
	}
	if ( (mode & MODE_VERBOSE) && (mode & MODE_AUTO) ) mode &= ~MODE_VERBOSE;
	/* Scan and select network */
	iw_scan(skfd,ifname,we_ver,&context);
	wireless_scan *ws;
	if (mode & MODE_AUTO) {
		if (mode && MODE_WAIT) {
			int loops;
			/* keep trying for up to 5 minutes */
			for (loops = 0; loops < 30 && !(ws=get_best()); ++loops)
				sleep(TIMEOUT);
		}
		else ws = get_best();
	}
	else ws = show_menu();
	const char *arg[4];
	if (ws) { /* Stop any current processes then connect to "ws" */
		arg[0] = killall; arg[1] = dhcp; arg[2] = NULL;
		if (fork()==0) {
			fclose(stdout); fclose(stderr);
			execvp(arg[0],(char * const *) arg);
		}
		arg[1] = wpa_sup;
		if (fork()==0) {
			fclose(stdout); fclose(stderr);
			execvp(arg[0],(char * const *) arg);
		}
		sleep(1);
		if ( (mode & MODE_ADD) && is_known(ws) ) mode &= ~MODE_ADD;
		if (ws->b.key_flags == 2048) mode |= MODE_SECURE;
		mode_t pre = umask(S_IWGRP|S_IWOTH|S_IRGRP|S_IROTH);
		ws_connect(ws);
		umask(pre);
	}
	else if ( !(mode & MODE_RECONNECT) ) {
		fprintf(stderr,"[swifer] no suitable networks found.\n");
		return 5;
	}
	/* Keep alive to reconnect? */
	iw_sockets_close(skfd);
	if (mode & MODE_RECONNECT) {
		if (fork() == 0) {
			setsid();
			int level = THRESHOLD + 1, ret;
			char scanline[256];
			snprintf(scanline,255,"%%*[^\n]\n%%*[^\n]\n%s: %%*d %%d.",ifname);
			FILE *procw;
			while (level > THRESHOLD) {
				sleep(TIMEOUT);
				procw = fopen(PROC_NET_WIRELESS,"r");
				ret = fscanf(procw,scanline,&level);
				fclose(procw);
				if (ret != 1) level = 0;
			}
			arg[0] = argv[0]; arg[1] = re; arg[2] = an; arg[3] = NULL;
			if ( !(mode & MODE_ANY)) arg[2] = NULL;
			execvp(arg[0],(char * const *) arg);
		}
	}
	if (hook_preup) free(hook_preup);
	if (hook_postup) free(hook_postup);
	return 0;
}