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; } }
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; }
/* 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; }
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; } }
/* 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; }
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 }