static int eloop_sock_table_add_sock(struct eloop_sock_table *table, int sock, eloop_sock_handler handler, void *eloop_data, void *user_data) { struct eloop_sock *tmp; int new_max_sock; if (sock > eloop.max_sock) new_max_sock = sock; else new_max_sock = eloop.max_sock; if (table == NULL) return -1; #ifdef CONFIG_ELOOP_POLL if (new_max_sock >= eloop.max_pollfd_map) { struct pollfd **nmap; nmap = os_realloc_array(eloop.pollfds_map, new_max_sock + 50, sizeof(struct pollfd *)); if (nmap == NULL) return -1; eloop.max_pollfd_map = new_max_sock + 50; eloop.pollfds_map = nmap; } if (eloop.count + 1 > eloop.max_poll_fds) { struct pollfd *n; int nmax = eloop.count + 1 + 50; n = os_realloc_array(eloop.pollfds, nmax, sizeof(struct pollfd)); if (n == NULL) return -1; eloop.max_poll_fds = nmax; eloop.pollfds = n; } #endif /* CONFIG_ELOOP_POLL */ eloop_trace_sock_remove_ref(table); tmp = os_realloc_array(table->table, table->count + 1, sizeof(struct eloop_sock)); if (tmp == NULL) return -1; tmp[table->count].sock = sock; tmp[table->count].eloop_data = eloop_data; tmp[table->count].user_data = user_data; tmp[table->count].handler = handler; wpa_trace_record(&tmp[table->count]); table->count++; table->table = tmp; eloop.max_sock = new_max_sock; eloop.count++; table->changed = 1; eloop_trace_sock_add_ref(table); return 0; }
static int eloop_sock_table_add_sock(struct eloop_sock_table *table, int sock, eloop_sock_handler handler, void *eloop_data, void *user_data) { struct eloop_sock *tmp; int new_max_sock; if (sock > eloop.max_sock) new_max_sock = sock; else new_max_sock = eloop.max_sock; if (table == NULL) return -1; if (new_max_sock >= eloop.max_pollfd_map) { struct pollfd **nmap; nmap = os_realloc_array(eloop.pollfds_map, new_max_sock + 50, sizeof(struct pollfd *)); if (nmap == NULL) return -1; eloop.max_pollfd_map = new_max_sock + 50; eloop.pollfds_map = nmap; } if (eloop.count + 1 > eloop.max_poll_fds) { struct pollfd *n; int nmax = eloop.count + 1 + 50; n = os_realloc_array(eloop.pollfds, nmax, sizeof(struct pollfd)); if (n == NULL) return -1; eloop.max_poll_fds = nmax; eloop.pollfds = n; } tmp = os_realloc_array(table->table, table->count + 1, sizeof(struct eloop_sock)); if (tmp == NULL) return -1; tmp[table->count].sock = sock; tmp[table->count].eloop_data = eloop_data; tmp[table->count].user_data = user_data; tmp[table->count].handler = handler; table->count++; table->table = tmp; eloop.max_sock = new_max_sock; eloop.count++; table->changed = 1; return 0; }
static int * bgscan_learn_get_supp_freqs(struct wpa_supplicant *wpa_s) { struct hostapd_hw_modes *modes; int i, j, *freqs = NULL, *n; size_t count = 0; modes = wpa_s->hw.modes; if (modes == NULL) return NULL; for (i = 0; i < wpa_s->hw.num_modes; i++) { for (j = 0; j < modes[i].num_channels; j++) { if (modes[i].channels[j].flag & HOSTAPD_CHAN_DISABLED) continue; /* some hw modes (e.g. 11b & 11g) contain same freqs */ if (in_array(freqs, modes[i].channels[j].freq)) continue; n = os_realloc_array(freqs, count + 2, sizeof(int)); if (n == NULL) continue; freqs = n; freqs[count] = modes[i].channels[j].freq; count++; freqs[count] = 0; } } return freqs; }
static int * bgscan_learn_get_probe_freq(struct bgscan_learn_data *data, int *freqs, size_t count) { int idx, *n; if (data->supp_freqs == NULL) return freqs; idx = data->probe_idx; do { if (!in_array(freqs, data->supp_freqs[idx])) { wpa_printf(MSG_DEBUG, "bgscan learn: Probe new freq " "%u", data->supp_freqs[idx]); data->probe_idx = idx + 1; if (data->supp_freqs[data->probe_idx] == 0) data->probe_idx = 0; n = os_realloc_array(freqs, count + 2, sizeof(int)); if (n == NULL) return freqs; freqs = n; freqs[count] = data->supp_freqs[idx]; count++; freqs[count] = 0; break; } idx++; if (data->supp_freqs[idx] == 0) idx = 0; } while (idx != data->probe_idx); return freqs; }
struct p2p_group * p2p_group_init(struct p2p_data *p2p, struct p2p_group_config *config) { struct p2p_group *group, **groups; group = os_zalloc(sizeof(*group)); if (group == NULL) return NULL; groups = os_realloc_array(p2p->groups, p2p->num_groups + 1, sizeof(struct p2p_group *)); if (groups == NULL) { os_free(group); return NULL; } groups[p2p->num_groups++] = group; p2p->groups = groups; group->p2p = p2p; group->cfg = config; group->group_formation = 1; group->beacon_update = 1; p2p_group_update_ies(group); group->cfg->idle_update(group->cfg->cb_ctx, 1); return group; }
int eloop_register_event(void *event, size_t event_size, eloop_event_handler handler, void *eloop_data, void *user_data) { struct eloop_event *tmp; HANDLE h = event; if (event_size != sizeof(HANDLE) || h == INVALID_HANDLE_VALUE) return -1; if (eloop_prepare_handles()) return -1; tmp = os_realloc_array(eloop.events, eloop.event_count + 1, sizeof(struct eloop_event)); if (tmp == NULL) return -1; tmp[eloop.event_count].eloop_data = eloop_data; tmp[eloop.event_count].user_data = user_data; tmp[eloop.event_count].handler = handler; tmp[eloop.event_count].event = h; eloop.event_count++; eloop.events = tmp; return 0; }
/** * radius_client_register - Register a RADIUS client RX handler * @radius: RADIUS client context from radius_client_init() * @msg_type: RADIUS client type (RADIUS_AUTH or RADIUS_ACCT) * @handler: Handler for received RADIUS messages * @data: Context pointer for handler callbacks * Returns: 0 on success, -1 on failure * * This function is used to register a handler for processing received RADIUS * authentication and accounting messages. The handler() callback function will * be called whenever a RADIUS message is received from the active server. * * There can be multiple registered RADIUS message handlers. The handlers will * be called in order until one of them indicates that it has processed or * queued the message. */ int radius_client_register(struct radius_client_data *radius, RadiusType msg_type, RadiusRxResult (*handler)(struct radius_msg *msg, struct radius_msg *req, const u8 *shared_secret, size_t shared_secret_len, void *data), void *data) { struct radius_rx_handler **handlers, *newh; size_t *num; if (msg_type == RADIUS_ACCT) { handlers = &radius->acct_handlers; num = &radius->num_acct_handlers; } else { handlers = &radius->auth_handlers; num = &radius->num_auth_handlers; } newh = os_realloc_array(*handlers, *num + 1, sizeof(struct radius_rx_handler)); if (newh == NULL) return -1; newh[*num].handler = handler; newh[*num].data = data; (*num)++; *handlers = newh; return 0; }
static void add_alt_name_othername(struct http_ctx *ctx, struct http_cert *cert, OTHERNAME *o) { char txt[100]; int res; struct http_othername *on; ASN1_TYPE *val; on = os_realloc_array(cert->othername, cert->num_othername + 1, sizeof(struct http_othername)); if (on == NULL) return; cert->othername = on; on = &on[cert->num_othername]; os_memset(on, 0, sizeof(*on)); res = OBJ_obj2txt(txt, sizeof(txt), o->type_id, 1); if (res < 0 || res >= (int) sizeof(txt)) return; on->oid = os_strdup(txt); if (on->oid == NULL) return; val = o->value; on->data = val->value.octet_string->data; on->len = val->value.octet_string->length; cert->num_othername++; }
static void sme_sa_query_timer(void *eloop_ctx, void *timeout_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; unsigned int timeout, sec, usec; u8 *trans_id, *nbuf; if (wpa_s->sme.sa_query_count > 0 && sme_check_sa_query_timeout(wpa_s)) return; nbuf = os_realloc_array(wpa_s->sme.sa_query_trans_id, wpa_s->sme.sa_query_count + 1, WLAN_SA_QUERY_TR_ID_LEN); if (nbuf == NULL) return; if (wpa_s->sme.sa_query_count == 0) { /* Starting a new SA Query procedure */ os_get_time(&wpa_s->sme.sa_query_start); } trans_id = nbuf + wpa_s->sme.sa_query_count * WLAN_SA_QUERY_TR_ID_LEN; wpa_s->sme.sa_query_trans_id = nbuf; wpa_s->sme.sa_query_count++; os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN); timeout = sa_query_retry_timeout; sec = ((timeout / 1000) * 1024) / 1000; usec = (timeout % 1000) * 1024; eloop_register_timeout(sec, usec, sme_sa_query_timer, wpa_s, NULL); wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association SA Query attempt %d", wpa_s->sme.sa_query_count); sme_send_sa_query_req(wpa_s, trans_id); }
static void wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res, struct ieee80211req_scan_result *sr) { struct wpa_scan_res *result, **tmp; size_t extra_len; u8 *pos; extra_len = 2 + sr->isr_ssid_len; extra_len += 2 + sr->isr_nrates; extra_len += 3; /* ERP IE */ extra_len += sr->isr_ie_len; result = os_zalloc(sizeof(*result) + extra_len); if (result == NULL) return; os_memcpy(result->bssid, sr->isr_bssid, ETH_ALEN); result->freq = sr->isr_freq; result->beacon_int = sr->isr_intval; result->caps = sr->isr_capinfo; result->qual = sr->isr_rssi; result->noise = sr->isr_noise; pos = (u8 *)(result + 1); *pos++ = WLAN_EID_SSID; *pos++ = sr->isr_ssid_len; os_memcpy(pos, sr + 1, sr->isr_ssid_len); pos += sr->isr_ssid_len; /* * Deal all rates as supported rate. * Because net80211 doesn't report extended supported rate or not. */ *pos++ = WLAN_EID_SUPP_RATES; *pos++ = sr->isr_nrates; os_memcpy(pos, sr->isr_rates, sr->isr_nrates); pos += sr->isr_nrates; *pos++ = WLAN_EID_ERP_INFO; *pos++ = 1; *pos++ = sr->isr_erp; os_memcpy(pos, (u8 *)(sr + 1) + sr->isr_ssid_len, sr->isr_ie_len); pos += sr->isr_ie_len; result->ie_len = pos - (u8 *)(result + 1); tmp = os_realloc_array(res->res, res->num + 1, sizeof(struct wpa_scan_res *)); if (tmp == NULL) { os_free(result); return; } tmp[res->num++] = result; res->res = tmp; }
static dbus_bool_t _wpa_dbus_dict_entry_get_binarray( DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry) { struct wpa_dbus_dict_entry tmpentry; size_t buflen = 0; int i; if (dbus_message_iter_get_element_type(iter) != DBUS_TYPE_BYTE) return FALSE; entry->array_type = WPAS_DBUS_TYPE_BINARRAY; entry->array_len = 0; entry->binarray_value = NULL; while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_ARRAY) { DBusMessageIter iter_array; if (entry->array_len == buflen) { struct wpabuf **newbuf; buflen += BIN_ARRAY_CHUNK_SIZE; newbuf = os_realloc_array(entry->binarray_value, buflen, BIN_ARRAY_ITEM_SIZE); if (!newbuf) goto cleanup; entry->binarray_value = newbuf; } dbus_message_iter_recurse(iter, &iter_array); if (_wpa_dbus_dict_entry_get_byte_array(&iter_array, &tmpentry) == FALSE) goto cleanup; entry->binarray_value[entry->array_len] = wpabuf_alloc_ext_data((u8 *) tmpentry.bytearray_value, tmpentry.array_len); if (entry->binarray_value[entry->array_len] == NULL) { wpa_dbus_dict_entry_clear(&tmpentry); goto cleanup; } entry->array_len++; dbus_message_iter_next(iter); } return TRUE; cleanup: for (i = 0; i < (int) entry->array_len; i++) wpabuf_free(entry->binarray_value[i]); os_free(entry->binarray_value); entry->array_len = 0; entry->binarray_value = NULL; return FALSE; }
/** * Decrease the usage counter for given ifname. * Returns * -1 on error or if iface was not found * 0 if iface was found and is still present * 1 if iface was removed from global list */ static int hapd_put_dynamic_iface(const char *parent, const char *ifname, struct hostapd_data *hapd) { size_t i; struct hostapd_dynamic_iface *j = NULL, **tmp; struct hapd_interfaces *hapd_glob = hapd->iface->interfaces; if (!parent) parent = ""; for (i = 0; i < hapd_glob->count_dynamic; i++) { j = hapd_glob->dynamic_iface[i]; if (os_strncmp(j->iface, ifname, sizeof(j->iface)) == 0 && os_strncmp(j->parent, parent, sizeof(j->parent)) == 0) break; } if (i == hapd_glob->count_dynamic) { /* * Interface not in global list. This can happen if alloc in * _get_ failed. */ return -1; } if (j->usage > 0) { j->usage--; return 0; } os_free(j); for (; i < hapd_glob->count_dynamic - 1; i++) hapd_glob->dynamic_iface[i] = hapd_glob->dynamic_iface[i + 1]; hapd_glob->dynamic_iface[hapd_glob->count_dynamic - 1] = NULL; hapd_glob->count_dynamic--; if (hapd_glob->count_dynamic == 0) { os_free(hapd_glob->dynamic_iface); hapd_glob->dynamic_iface = NULL; return 1; } tmp = os_realloc_array(hapd_glob->dynamic_iface, hapd_glob->count_dynamic, sizeof(*hapd_glob->dynamic_iface)); if (!tmp) { wpa_printf(MSG_ERROR, "VLAN: Failed to release memory in %s", __func__); return -1; } hapd_glob->dynamic_iface = tmp; return 1; }
static dbus_bool_t _wpa_dbus_dict_entry_get_byte_array( DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry) { dbus_uint32_t count = 0; dbus_bool_t success = FALSE; char *buffer, *nbuffer; entry->bytearray_value = NULL; entry->array_type = DBUS_TYPE_BYTE; buffer = os_calloc(BYTE_ARRAY_CHUNK_SIZE, BYTE_ARRAY_ITEM_SIZE); if (!buffer) return FALSE; entry->bytearray_value = buffer; entry->array_len = 0; while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_BYTE) { char byte; if ((count % BYTE_ARRAY_CHUNK_SIZE) == 0 && count != 0) { nbuffer = os_realloc_array( buffer, count + BYTE_ARRAY_CHUNK_SIZE, BYTE_ARRAY_ITEM_SIZE); if (nbuffer == NULL) { os_free(buffer); wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_" "entry_get_byte_array out of " "memory trying to retrieve the " "string array"); goto done; } buffer = nbuffer; } entry->bytearray_value = buffer; dbus_message_iter_get_basic(iter, &byte); entry->bytearray_value[count] = byte; entry->array_len = ++count; dbus_message_iter_next(iter); } /* Zero-length arrays are valid. */ if (entry->array_len == 0) { os_free(entry->bytearray_value); entry->bytearray_value = NULL; } success = TRUE; done: return success; }
static int eloop_prepare_handles(void) { HANDLE *n; if (eloop.num_handles > eloop.reader_count + eloop.event_count + 8) return 0; n = os_realloc_array(eloop.handles, eloop.num_handles * 2, sizeof(eloop.handles[0])); if (n == NULL) return -1; eloop.handles = n; eloop.num_handles *= 2; return 0; }
static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx) { struct hostapd_data *hapd = eloop_ctx; struct sta_info *sta = timeout_ctx; unsigned int timeout, sec, usec; u8 *trans_id, *nbuf; wpa_printf(MSG_DEBUG, "%s: SA Query timer for STA " MACSTR " (count=%d)", hapd->conf->iface, MAC2STR(sta->addr), sta->sa_query_count); if (sta->sa_query_count > 0 && ap_check_sa_query_timeout(hapd, sta)) return; nbuf = os_realloc_array(sta->sa_query_trans_id, sta->sa_query_count + 1, WLAN_SA_QUERY_TR_ID_LEN); if (nbuf == NULL) return; if (sta->sa_query_count == 0) { /* Starting a new SA Query procedure */ os_get_reltime(&sta->sa_query_start); } trans_id = nbuf + sta->sa_query_count * WLAN_SA_QUERY_TR_ID_LEN; sta->sa_query_trans_id = nbuf; sta->sa_query_count++; if (os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN) < 0) { /* * We don't really care which ID is used here, so simply * hardcode this if the mostly theoretical os_get_random() * failure happens. */ trans_id[0] = 0x12; trans_id[1] = 0x34; } timeout = hapd->conf->assoc_sa_query_retry_timeout; sec = ((timeout / 1000) * 1024) / 1000; usec = (timeout % 1000) * 1024; eloop_register_timeout(sec, usec, ap_sa_query_timer, hapd, sta); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "association SA Query attempt %d", sta->sa_query_count); ieee802_11_send_sa_query_req(hapd, sta->addr, trans_id); }
static void bgscan_learn_add_neighbor(struct bgscan_learn_bss *bss, const u8 *bssid) { u8 *n; if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) return; if (bssid_in_array(bss->neigh, bss->num_neigh, bssid)) return; n = os_realloc_array(bss->neigh, bss->num_neigh + 1, ETH_ALEN); if (n == NULL) return; os_memcpy(n + bss->num_neigh * ETH_ALEN, bssid, ETH_ALEN); bss->neigh = n; bss->num_neigh++; }
static void int_array_concat(int **res, const int *a) { int reslen, alen, i; int *n; reslen = int_array_len(*res); alen = int_array_len(a); n = os_realloc_array(*res, reslen + alen + 1, sizeof(int)); if (n == NULL) { os_free(*res); *res = NULL; return; } for (i = 0; i <= alen; i++) n[reslen + i] = a[i]; *res = n; }
/** * Increase the usage counter for given parent/ifname combination. * If create is set, then this iface is added to the global list. * Returns * -1 on error * 0 if iface is not in list * 1 if iface is in list (was there or has been added) */ static int hapd_get_dynamic_iface(const char *parent, const char *ifname, int create, struct hostapd_data *hapd) { size_t i; struct hostapd_dynamic_iface *j = NULL, **tmp; struct hapd_interfaces *hapd_global = hapd->iface->interfaces; if (!parent) parent = ""; for (i = 0; i < hapd_global->count_dynamic; i++) { j = hapd_global->dynamic_iface[i]; if (os_strncmp(j->iface, ifname, sizeof(j->iface)) == 0 && os_strncmp(j->parent, parent, sizeof(j->parent)) == 0) break; } if (i < hapd_global->count_dynamic) { j->usage++; return 1; } /* new entry required */ if (!create) return 0; j = os_zalloc(sizeof(*j)); if (!j) return -1; os_strlcpy(j->iface, ifname, sizeof(j->iface)); os_strlcpy(j->parent, parent, sizeof(j->parent)); tmp = os_realloc_array(hapd_global->dynamic_iface, i + 1, sizeof(*hapd_global->dynamic_iface)); if (!tmp) { wpa_printf(MSG_ERROR, "VLAN: Failed to allocate memory in %s", __func__); return -1; } hapd_global->count_dynamic++; hapd_global->dynamic_iface = tmp; hapd_global->dynamic_iface[i] = j; return 1; }
static void add_alt_name_dns(struct http_ctx *ctx, struct http_cert *cert, ASN1_STRING *name) { char *buf; char **n; buf = NULL; if (ASN1_STRING_to_UTF8((unsigned char **) &buf, name) < 0) return; n = os_realloc_array(cert->dnsname, cert->num_dnsname + 1, sizeof(char *)); if (n == NULL) return; cert->dnsname = n; n[cert->num_dnsname] = buf; cert->num_dnsname++; }
int eloop_register_signal(int sig, eloop_signal_handler handler, void *user_data) { struct eloop_signal *tmp; tmp = os_realloc_array(eloop.signals, eloop.signal_count + 1, sizeof(struct eloop_signal)); if (tmp == NULL) return -1; tmp[eloop.signal_count].sig = sig; tmp[eloop.signal_count].user_data = user_data; tmp[eloop.signal_count].handler = handler; tmp[eloop.signal_count].signaled = 0; eloop.signal_count++; eloop.signals = tmp; signal(sig, eloop_handle_signal); return 0; }
int eloop_register_read_sock(int sock, eloop_sock_handler handler, void *eloop_data, void *user_data) { WSAEVENT event; struct eloop_sock *tmp; if (eloop_prepare_handles()) return -1; event = WSACreateEvent(); if (event == WSA_INVALID_EVENT) { printf("WSACreateEvent() failed: %d\n", WSAGetLastError()); return -1; } if (WSAEventSelect(sock, event, FD_READ)) { printf("WSAEventSelect() failed: %d\n", WSAGetLastError()); WSACloseEvent(event); return -1; } tmp = os_realloc_array(eloop.readers, eloop.reader_count + 1, sizeof(struct eloop_sock)); if (tmp == NULL) { WSAEventSelect(sock, event, 0); WSACloseEvent(event); return -1; } tmp[eloop.reader_count].sock = sock; tmp[eloop.reader_count].eloop_data = eloop_data; tmp[eloop.reader_count].user_data = user_data; tmp[eloop.reader_count].handler = handler; tmp[eloop.reader_count].event = event; eloop.reader_count++; eloop.readers = tmp; if (sock > eloop.max_sock) eloop.max_sock = sock; eloop.reader_table_changed = 1; return 0; }
static int radius_msg_add_attr_to_array(struct radius_msg *msg, struct radius_attr_hdr *attr) { if (msg->attr_used >= msg->attr_size) { size_t *nattr_pos; int nlen = msg->attr_size * 2; nattr_pos = os_realloc_array(msg->attr_pos, nlen, sizeof(*msg->attr_pos)); if (nattr_pos == NULL) return -1; msg->attr_pos = nattr_pos; msg->attr_size = nlen; } msg->attr_pos[msg->attr_used++] = (unsigned char *) attr - wpabuf_head_u8(msg->buf); return 0; }
static int * bgscan_learn_get_freqs(struct bgscan_learn_data *data, size_t *count) { struct bgscan_learn_bss *bss; int *freqs = NULL, *n; *count = 0; dl_list_for_each(bss, &data->bss, struct bgscan_learn_bss, list) { if (in_array(freqs, bss->freq)) continue; n = os_realloc_array(freqs, *count + 2, sizeof(int)); if (n == NULL) return freqs; freqs = n; freqs[*count] = bss->freq; (*count)++; freqs[*count] = 0; } return freqs; }
int hostapd_register_probereq_cb(struct hostapd_data *hapd, int (*cb)(void *ctx, const u8 *sa, const u8 *da, const u8 *bssid, const u8 *ie, size_t ie_len, int ssi_signal), void *ctx) { struct hostapd_probereq_cb *n; n = os_realloc_array(hapd->probereq_cb, hapd->num_probereq_cb + 1, sizeof(struct hostapd_probereq_cb)); if (n == NULL) return -1; hapd->probereq_cb = n; n = &hapd->probereq_cb[hapd->num_probereq_cb]; hapd->num_probereq_cb++; n->cb = cb; n->ctx = ctx; return 0; }
static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx) { struct hostapd_data *hapd = eloop_ctx; struct sta_info *sta = timeout_ctx; unsigned int timeout, sec, usec; u8 *trans_id, *nbuf; if (sta->sa_query_count > 0 && ap_check_sa_query_timeout(hapd, sta)) return; nbuf = os_realloc_array(sta->sa_query_trans_id, sta->sa_query_count + 1, WLAN_SA_QUERY_TR_ID_LEN); if (nbuf == NULL) return; if (sta->sa_query_count == 0) { /* Starting a new SA Query procedure */ os_get_time(&sta->sa_query_start); } trans_id = nbuf + sta->sa_query_count * WLAN_SA_QUERY_TR_ID_LEN; sta->sa_query_trans_id = nbuf; sta->sa_query_count++; os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN); timeout = hapd->conf->assoc_sa_query_retry_timeout; sec = ((timeout / 1000) * 1024) / 1000; usec = (timeout % 1000) * 1024; eloop_register_timeout(sec, usec, ap_sa_query_timer, hapd, sta); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "association SA Query attempt %d", sta->sa_query_count); ieee802_11_send_sa_query_req(hapd, sta->addr, trans_id); }
int main(int argc, char *argv[]) { int c, i; struct wpa_interface *ifaces, *iface; int iface_count, exitcode = -1; struct wpa_params params; struct wpa_global *global; if (os_program_init()) return -1; os_memset(¶ms, 0, sizeof(params)); params.wpa_debug_level = MSG_INFO; iface = ifaces = os_zalloc(sizeof(struct wpa_interface)); if (ifaces == NULL) return -1; iface_count = 1; wpa_supplicant_fd_workaround(1); for (;;) { c = getopt(argc, argv, "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW"); if (c < 0) break; switch (c) { case 'b': iface->bridge_ifname = optarg; break; case 'B': params.daemonize++; break; case 'c': iface->confname = optarg; break; case 'C': iface->ctrl_interface = optarg; break; case 'D': iface->driver = optarg; break; case 'd': #ifdef CONFIG_NO_STDOUT_DEBUG printf("Debugging disabled with " "CONFIG_NO_STDOUT_DEBUG=y build time " "option.\n"); goto out; #else /* CONFIG_NO_STDOUT_DEBUG */ params.wpa_debug_level--; break; #endif /* CONFIG_NO_STDOUT_DEBUG */ case 'e': params.entropy_file = optarg; break; #ifdef CONFIG_DEBUG_FILE case 'f': params.wpa_debug_file_path = optarg; break; #endif /* CONFIG_DEBUG_FILE */ case 'g': params.ctrl_interface = optarg; break; case 'G': params.ctrl_interface_group = optarg; break; case 'h': usage(); exitcode = 0; goto out; case 'i': iface->ifname = optarg; break; case 'I': iface->confanother = optarg; break; case 'K': params.wpa_debug_show_keys++; break; case 'L': license(); exitcode = 0; goto out; #ifdef CONFIG_P2P case 'm': params.conf_p2p_dev = optarg; break; #endif /* CONFIG_P2P */ case 'o': params.override_driver = optarg; break; case 'O': params.override_ctrl_interface = optarg; break; case 'p': iface->driver_param = optarg; break; case 'P': os_free(params.pid_file); params.pid_file = os_rel2abs_path(optarg); break; case 'q': params.wpa_debug_level++; break; #ifdef CONFIG_DEBUG_SYSLOG case 's': params.wpa_debug_syslog++; break; #endif /* CONFIG_DEBUG_SYSLOG */ #ifdef CONFIG_DEBUG_LINUX_TRACING case 'T': params.wpa_debug_tracing++; break; #endif /* CONFIG_DEBUG_LINUX_TRACING */ case 't': params.wpa_debug_timestamp++; break; #ifdef CONFIG_CTRL_IFACE_DBUS_NEW case 'u': params.dbus_ctrl_interface = 1; break; #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ case 'v': printf("%s\n", wpa_supplicant_version); exitcode = 0; goto out; case 'W': params.wait_for_monitor++; break; #ifdef CONFIG_MATCH_IFACE case 'M': params.match_iface_count++; iface = os_realloc_array(params.match_ifaces, params.match_iface_count, sizeof(struct wpa_interface)); if (!iface) goto out; params.match_ifaces = iface; iface = ¶ms.match_ifaces[params.match_iface_count - 1]; os_memset(iface, 0, sizeof(*iface)); break; #endif /* CONFIG_MATCH_IFACE */ case 'N': iface_count++; iface = os_realloc_array(ifaces, iface_count, sizeof(struct wpa_interface)); if (iface == NULL) goto out; ifaces = iface; iface = &ifaces[iface_count - 1]; os_memset(iface, 0, sizeof(*iface)); break; default: usage(); exitcode = 0; goto out; } } exitcode = 0; global = wpa_supplicant_init(¶ms); if (global == NULL) { wpa_printf(MSG_ERROR, "Failed to initialize wpa_supplicant"); exitcode = -1; goto out; } else { wpa_printf(MSG_INFO, "Successfully initialized " "wpa_supplicant"); } if (fst_global_init()) { wpa_printf(MSG_ERROR, "Failed to initialize FST"); exitcode = -1; goto out; } #if defined(CONFIG_FST) && defined(CONFIG_CTRL_IFACE) if (!fst_global_add_ctrl(fst_ctrl_cli)) wpa_printf(MSG_WARNING, "Failed to add CLI FST ctrl"); #endif for (i = 0; exitcode == 0 && i < iface_count; i++) { struct wpa_supplicant *wpa_s; if ((ifaces[i].confname == NULL && ifaces[i].ctrl_interface == NULL) || ifaces[i].ifname == NULL) { if (iface_count == 1 && (params.ctrl_interface || #ifdef CONFIG_MATCH_IFACE params.match_iface_count || #endif /* CONFIG_MATCH_IFACE */ params.dbus_ctrl_interface)) break; usage(); exitcode = -1; break; } wpa_s = wpa_supplicant_add_iface(global, &ifaces[i], NULL); if (wpa_s == NULL) { exitcode = -1; break; } } #ifdef CONFIG_MATCH_IFACE if (exitcode == 0) exitcode = wpa_supplicant_init_match(global); #endif /* CONFIG_MATCH_IFACE */ if (exitcode == 0) exitcode = wpa_supplicant_run(global); wpa_supplicant_deinit(global); fst_global_deinit(); out: wpa_supplicant_fd_workaround(0); os_free(ifaces); #ifdef CONFIG_MATCH_IFACE os_free(params.match_ifaces); #endif /* CONFIG_MATCH_IFACE */ os_free(params.pid_file); os_program_deinit(); return exitcode; }
int main(int argc, char *argv[]) { struct hapd_interfaces interfaces; int ret = 1; size_t i, j; int c, debug = 0; const char *log_file = NULL; const char *entropy_file = NULL; char **bss_config = NULL, **tmp_bss; size_t num_bss_configs = 0; #ifdef CONFIG_DEBUG_LINUX_TRACING int enable_trace_dbg = 0; #endif /* CONFIG_DEBUG_LINUX_TRACING */ if (os_program_init()) return -1; os_memset(&interfaces, 0, sizeof(interfaces)); interfaces.reload_config = hostapd_reload_config; interfaces.config_read_cb = hostapd_config_read; interfaces.for_each_interface = hostapd_for_each_interface; interfaces.ctrl_iface_init = hostapd_ctrl_iface_init; interfaces.ctrl_iface_deinit = hostapd_ctrl_iface_deinit; interfaces.driver_init = hostapd_driver_init; interfaces.global_iface_path = NULL; interfaces.global_iface_name = NULL; interfaces.global_ctrl_sock = -1; wpa_supplicant_event = hostapd_wpa_event; for (;;) { c = getopt(argc, argv, "b:Bde:f:hKP:Ttu:g:G:v::"); if (c < 0) break; switch (c) { case 'h': usage(); break; case 'd': debug++; if (wpa_debug_level > 0) wpa_debug_level--; break; case 'B': daemonize++; break; case 'e': entropy_file = optarg; break; case 'f': log_file = optarg; break; case 'K': wpa_debug_show_keys++; break; case 'P': os_free(pid_file); pid_file = os_rel2abs_path(optarg); break; case 't': wpa_debug_timestamp++; break; #ifdef CONFIG_DEBUG_LINUX_TRACING case 'T': enable_trace_dbg = 1; break; #endif /* CONFIG_DEBUG_LINUX_TRACING */ case 'v': if (optarg) exit(!has_feature(optarg)); show_version(); exit(1); break; case 'g': if (hostapd_get_global_ctrl_iface(&interfaces, optarg)) return -1; break; case 'G': if (hostapd_get_ctrl_iface_group(&interfaces, optarg)) return -1; break; case 'b': tmp_bss = os_realloc_array(bss_config, num_bss_configs + 1, sizeof(char *)); if (tmp_bss == NULL) goto out; bss_config = tmp_bss; bss_config[num_bss_configs++] = optarg; break; #ifdef CONFIG_WPS case 'u': return gen_uuid(optarg); #endif /* CONFIG_WPS */ default: usage(); break; } } if (optind == argc && interfaces.global_iface_path == NULL && num_bss_configs == 0) usage(); wpa_msg_register_ifname_cb(hostapd_msg_ifname_cb); if (log_file) wpa_debug_open_file(log_file); #ifdef CONFIG_DEBUG_LINUX_TRACING if (enable_trace_dbg) { int tret = wpa_debug_open_linux_tracing(); if (tret) { wpa_printf(MSG_ERROR, "Failed to enable trace logging"); return -1; } } #endif /* CONFIG_DEBUG_LINUX_TRACING */ interfaces.count = argc - optind; if (interfaces.count || num_bss_configs) { interfaces.iface = os_calloc(interfaces.count + num_bss_configs, sizeof(struct hostapd_iface *)); if (interfaces.iface == NULL) { wpa_printf(MSG_ERROR, "malloc failed"); return -1; } } if (hostapd_global_init(&interfaces, entropy_file)) { wpa_printf(MSG_ERROR, "Failed to initilize global context"); return -1; } /* Allocate and parse configuration for full interface files */ for (i = 0; i < interfaces.count; i++) { interfaces.iface[i] = hostapd_interface_init(&interfaces, argv[optind + i], debug); if (!interfaces.iface[i]) { wpa_printf(MSG_ERROR, "Failed to initialize interface"); goto out; } } /* Allocate and parse configuration for per-BSS files */ for (i = 0; i < num_bss_configs; i++) { struct hostapd_iface *iface; char *fname; wpa_printf(MSG_INFO, "BSS config: %s", bss_config[i]); fname = os_strchr(bss_config[i], ':'); if (fname == NULL) { wpa_printf(MSG_ERROR, "Invalid BSS config identifier '%s'", bss_config[i]); goto out; } *fname++ = '\0'; iface = hostapd_interface_init_bss(&interfaces, bss_config[i], fname, debug); if (iface == NULL) goto out; for (j = 0; j < interfaces.count; j++) { if (interfaces.iface[j] == iface) break; } if (j == interfaces.count) { struct hostapd_iface **tmp; tmp = os_realloc_array(interfaces.iface, interfaces.count + 1, sizeof(struct hostapd_iface *)); if (tmp == NULL) { hostapd_interface_deinit_free(iface); goto out; } interfaces.iface = tmp; interfaces.iface[interfaces.count++] = iface; } } /* * Enable configured interfaces. Depending on channel configuration, * this may complete full initialization before returning or use a * callback mechanism to complete setup in case of operations like HT * co-ex scans, ACS, or DFS are needed to determine channel parameters. * In such case, the interface will be enabled from eloop context within * hostapd_global_run(). */ interfaces.terminate_on_error = interfaces.count; for (i = 0; i < interfaces.count; i++) { if (hostapd_driver_init(interfaces.iface[i]) || hostapd_setup_interface(interfaces.iface[i])) goto out; } hostapd_global_ctrl_iface_init(&interfaces); if (hostapd_global_run(&interfaces, daemonize, pid_file)) { wpa_printf(MSG_ERROR, "Failed to start eloop"); goto out; } ret = 0; out: hostapd_global_ctrl_iface_deinit(&interfaces); /* Deinitialize all interfaces */ for (i = 0; i < interfaces.count; i++) { if (!interfaces.iface[i]) continue; interfaces.iface[i]->driver_ap_teardown = !!(interfaces.iface[i]->drv_flags & WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); hostapd_interface_deinit_free(interfaces.iface[i]); } os_free(interfaces.iface); hostapd_global_deinit(pid_file); os_free(pid_file); if (log_file) wpa_debug_close_file(); wpa_debug_close_linux_tracing(); os_free(bss_config); os_program_deinit(); return ret; }
/** * eap_peer_select_phase2_methods - Select phase 2 EAP method * @config: Pointer to the network configuration * @prefix: 'phase2' configuration prefix, e.g., "auth=" * @types: Buffer for returning allocated list of allowed EAP methods * @num_types: Buffer for returning number of allocated EAP methods * Returns: 0 on success, -1 on failure * * This function is used to parse EAP method list and select allowed methods * for Phase2 authentication. */ int eap_peer_select_phase2_methods(struct eap_peer_config *config, const char *prefix, struct eap_method_type **types, size_t *num_types) { char *start, *pos, *buf; struct eap_method_type *methods = NULL, *_methods; u8 method; size_t num_methods = 0, prefix_len; if (config == NULL || config->phase2 == NULL) goto get_defaults; start = buf = os_strdup(config->phase2); if (buf == NULL) return -1; prefix_len = os_strlen(prefix); while (start && *start != '\0') { int vendor; pos = os_strstr(start, prefix); if (pos == NULL) break; if (start != pos && *(pos - 1) != ' ') { start = pos + prefix_len; continue; } start = pos + prefix_len; pos = os_strchr(start, ' '); if (pos) *pos++ = '\0'; method = eap_get_phase2_type(start, &vendor); if (vendor == EAP_VENDOR_IETF && method == EAP_TYPE_NONE) { wpa_printf(MSG_ERROR, "TLS: Unsupported Phase2 EAP " "method '%s'", start); } else { num_methods++; _methods = os_realloc_array(methods, num_methods, sizeof(*methods)); if (_methods == NULL) { os_free(methods); os_free(buf); return -1; } methods = _methods; methods[num_methods - 1].vendor = vendor; methods[num_methods - 1].method = method; } start = pos; } os_free(buf); get_defaults: if (methods == NULL) methods = eap_get_phase2_types(config, &num_methods); if (methods == NULL) { wpa_printf(MSG_ERROR, "TLS: No Phase2 EAP methods available"); return -1; } wpa_hexdump(MSG_DEBUG, "TLS: Phase2 EAP types", (u8 *) methods, num_methods * sizeof(struct eap_method_type)); *types = methods; *num_types = num_methods; return 0; }
static dbus_bool_t _wpa_dbus_dict_entry_get_string_array( DBusMessageIter *iter, int array_type, struct wpa_dbus_dict_entry *entry) { dbus_uint32_t count = 0; dbus_bool_t success = FALSE; char **buffer, **nbuffer; entry->strarray_value = NULL; entry->array_type = DBUS_TYPE_STRING; buffer = os_calloc(STR_ARRAY_CHUNK_SIZE, STR_ARRAY_ITEM_SIZE); if (buffer == NULL) return FALSE; entry->strarray_value = buffer; entry->array_len = 0; while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) { const char *value; char *str; if ((count % STR_ARRAY_CHUNK_SIZE) == 0 && count != 0) { nbuffer = os_realloc_array( buffer, count + STR_ARRAY_CHUNK_SIZE, STR_ARRAY_ITEM_SIZE); if (nbuffer == NULL) { os_free(buffer); wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_" "entry_get_string_array out of " "memory trying to retrieve the " "string array"); goto done; } buffer = nbuffer; } entry->strarray_value = buffer; dbus_message_iter_get_basic(iter, &value); str = os_strdup(value); if (str == NULL) { wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_entry_get_" "string_array out of memory trying to " "duplicate the string array"); goto done; } entry->strarray_value[count] = str; entry->array_len = ++count; dbus_message_iter_next(iter); } /* Zero-length arrays are valid. */ if (entry->array_len == 0) { os_free(entry->strarray_value); entry->strarray_value = NULL; } success = TRUE; done: return success; }
static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, const u8 *osu_ssid, u8 osu_ssid_len, const u8 *pos, size_t len) { struct osu_provider *prov; const u8 *end = pos + len; u16 len2; const u8 *pos2; u8 uri_len, osu_method_len, osu_nai_len; wpa_hexdump(MSG_DEBUG, "HS 2.0: Parsing OSU Provider", pos, len); prov = os_realloc_array(wpa_s->osu_prov, wpa_s->osu_prov_count + 1, sizeof(*prov)); if (prov == NULL) return; wpa_s->osu_prov = prov; prov = &prov[wpa_s->osu_prov_count]; os_memset(prov, 0, sizeof(*prov)); os_memcpy(prov->bssid, bss->bssid, ETH_ALEN); os_memcpy(prov->osu_ssid, osu_ssid, osu_ssid_len); prov->osu_ssid_len = osu_ssid_len; /* OSU Friendly Name Length */ if (end - pos < 2) { wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU " "Friendly Name Length"); return; } len2 = WPA_GET_LE16(pos); pos += 2; if (len2 > end - pos) { wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU " "Friendly Name Duples"); return; } pos2 = pos; pos += len2; /* OSU Friendly Name Duples */ while (pos - pos2 >= 4 && prov->friendly_name_count < OSU_MAX_ITEMS) { struct osu_lang_string *f; if (1 + pos2[0] > pos - pos2 || pos2[0] < 3) { wpa_printf(MSG_DEBUG, "Invalid OSU Friendly Name"); break; } f = &prov->friendly_name[prov->friendly_name_count++]; os_memcpy(f->lang, pos2 + 1, 3); os_memcpy(f->text, pos2 + 1 + 3, pos2[0] - 3); pos2 += 1 + pos2[0]; } /* OSU Server URI */ if (end - pos < 1) { wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU Server URI length"); return; } uri_len = *pos++; if (uri_len > end - pos) { wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU Server " "URI"); return; } os_memcpy(prov->server_uri, pos, uri_len); pos += uri_len; /* OSU Method list */ if (end - pos < 1) { wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU Method " "list length"); return; } osu_method_len = pos[0]; if (osu_method_len > end - pos - 1) { wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU Method " "list"); return; } pos2 = pos + 1; pos += 1 + osu_method_len; while (pos2 < pos) { if (*pos2 < 32) prov->osu_methods |= BIT(*pos2); pos2++; } /* Icons Available Length */ if (end - pos < 2) { wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for Icons " "Available Length"); return; } len2 = WPA_GET_LE16(pos); pos += 2; if (len2 > end - pos) { wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for Icons " "Available"); return; } pos2 = pos; pos += len2; /* Icons Available */ while (pos2 < pos) { struct osu_icon *icon = &prov->icon[prov->icon_count]; u8 flen; if (2 + 2 + 3 + 1 + 1 > pos - pos2) { wpa_printf(MSG_DEBUG, "HS 2.0: Invalid Icon Metadata"); break; } icon->width = WPA_GET_LE16(pos2); pos2 += 2; icon->height = WPA_GET_LE16(pos2); pos2 += 2; os_memcpy(icon->lang, pos2, 3); pos2 += 3; flen = *pos2++; if (flen > pos - pos2) { wpa_printf(MSG_DEBUG, "HS 2.0: Not room for Icon Type"); break; } os_memcpy(icon->icon_type, pos2, flen); pos2 += flen; if (pos - pos2 < 1) { wpa_printf(MSG_DEBUG, "HS 2.0: Not room for Icon " "Filename length"); break; } flen = *pos2++; if (flen > pos - pos2) { wpa_printf(MSG_DEBUG, "HS 2.0: Not room for Icon " "Filename"); break; } os_memcpy(icon->filename, pos2, flen); pos2 += flen; prov->icon_count++; } /* OSU_NAI */ if (end - pos < 1) { wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU_NAI"); return; } osu_nai_len = *pos++; if (osu_nai_len > end - pos) { wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU_NAI"); return; } os_memcpy(prov->osu_nai, pos, osu_nai_len); pos += osu_nai_len; /* OSU Service Description Length */ if (end - pos < 2) { wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU " "Service Description Length"); return; } len2 = WPA_GET_LE16(pos); pos += 2; if (len2 > end - pos) { wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU " "Service Description Duples"); return; } pos2 = pos; pos += len2; /* OSU Service Description Duples */ while (pos - pos2 >= 4 && prov->serv_desc_count < OSU_MAX_ITEMS) { struct osu_lang_string *f; u8 descr_len; descr_len = *pos2++; if (descr_len > pos - pos2 || descr_len < 3) { wpa_printf(MSG_DEBUG, "Invalid OSU Service " "Description"); break; } f = &prov->serv_desc[prov->serv_desc_count++]; os_memcpy(f->lang, pos2, 3); os_memcpy(f->text, pos2 + 3, descr_len - 3); pos2 += descr_len; } wpa_printf(MSG_DEBUG, "HS 2.0: Added OSU Provider through " MACSTR, MAC2STR(bss->bssid)); wpa_s->osu_prov_count++; }