Exemplo n.º 1
0
/**
 * event_retry - Called when we had a failure delivering event msg
 * @e: Event
 * @do_next_address: skip address e.g. on connect fail
 */
static void event_retry(struct wps_event_ *e, int do_next_address)
{
	struct subscription *s = e->s;
	struct upnp_wps_device_sm *sm = s->sm;

	wpa_printf(MSG_DEBUG, "WPS UPnP: Retry event %p for subscription %p",
		   e, s);
	event_clean(e);
	/* will set: s->current_event = NULL; */

	if (do_next_address) {
		e->retry++;
		wpa_printf(MSG_DEBUG, "WPS UPnP: Try address %d", e->retry);
	}
	if (e->retry >= dl_list_len(&s->addr_list)) {
		wpa_printf(MSG_DEBUG, "WPS UPnP: Giving up on sending event "
			   "for %s", e->addr->domain_and_port);
		event_delete(e);
		s->last_event_failed = 1;
		if (!dl_list_empty(&s->event_queue))
			event_send_all_later(s->sm);
		return;
	}
	dl_list_add(&s->event_queue, &e->list);
	event_send_all_later(sm);
}
Exemplo n.º 2
0
static void
acs_survey_chan_interference_factor(struct hostapd_iface *iface,
				    struct hostapd_channel_data *chan)
{
	struct freq_survey *survey;
	unsigned int i = 0;
	long double int_factor = 0;

	if (dl_list_empty(&chan->survey_list))
		return;

	if (chan->flag & HOSTAPD_CHAN_DISABLED)
		return;

	chan->interference_factor = 0;

	dl_list_for_each(survey, &chan->survey_list, struct freq_survey, list)
	{
		int_factor = acs_survey_interference_factor(survey,
							    iface->lowest_nf);
		chan->interference_factor += int_factor;
		wpa_printf(MSG_DEBUG, "ACS: %d: min_nf=%d interference_factor=%Lg nf=%d time=%lu busy=%lu rx=%lu",
			   ++i, chan->min_nf, int_factor,
			   survey->nf, (unsigned long) survey->channel_time,
			   (unsigned long) survey->channel_time_busy,
			   (unsigned long) survey->channel_time_rx);
	}

	chan->interference_factor = chan->interference_factor /
		dl_list_len(&chan->survey_list);
}
Exemplo n.º 3
0
/**
 * event_add - Add a new event to a queue
 * @s: Subscription
 * @data: Event data (is copied; caller retains ownership)
 * @probereq: Whether this is a Probe Request event
 * Returns: 0 on success, -1 on error, 1 on max event queue limit reached
 */
int event_add(struct subscription *s, const struct wpabuf *data, int probereq)
{
	struct wps_event_ *e;
	unsigned int len;

	len = dl_list_len(&s->event_queue);
	if (len >= MAX_EVENTS_QUEUED) {
		wpa_printf(MSG_DEBUG, "WPS UPnP: Too many events queued for "
			   "subscriber %p", s);
		if (probereq)
			return 1;

		/* Drop oldest entry to allow EAP event to be stored. */
		e = event_dequeue(s);
		if (!e)
			return 1;
		event_delete(e);
	}

	if (s->last_event_failed && probereq && len > 0) {
		/*
		 * Avoid queuing frames for subscribers that may have left
		 * without unsubscribing.
		 */
		wpa_printf(MSG_DEBUG, "WPS UPnP: Do not queue more Probe "
			   "Request frames for subscription %p since last "
			   "delivery failed", s);
		return -1;
	}

	e = os_zalloc(sizeof(*e));
	if (e == NULL)
		return -1;
	dl_list_init(&e->list);
	e->s = s;
	e->data = wpabuf_dup(data);
	if (e->data == NULL) {
		os_free(e);
		return -1;
	}
	e->subscriber_sequence = s->next_subscriber_sequence++;
	if (s->next_subscriber_sequence == 0)
		s->next_subscriber_sequence++;
	wpa_printf(MSG_DEBUG, "WPS UPnP: Queue event %p for subscriber %p "
		   "(queue len %u)", e, s, len + 1);
	dl_list_add_tail(&s->event_queue, &e->list);
	event_send_all_later(s->sm);
	return 0;
}
Exemplo n.º 4
0
static struct tls_netconn *net_alloc_socket(struct tls_netconn *conn)
{
    int sock=-1, i=0, j=0;
    u32 cpu_sr;
	struct tls_netconn * conn_t = NULL;

    for (i = 0; i < TLS_MAX_NETCONN_NUM; i++)
    {
        if(p_net_conn[i] == NULL)
		{
			sock = i;
			break;
		}
    }

	if (i == TLS_MAX_NETCONN_NUM){
		return NULL;
	}

    if(conn != NULL)
    {
        j = dl_list_len(&conn->list);
        if(j>=4)
        {
            sock = -1;
        }
    }
	if(sock < 0)
		return NULL;
	cpu_sr = tls_os_set_critical();
	conn_t = tls_mem_alloc(sizeof(struct tls_netconn));
	tls_os_release_critical(cpu_sr);
	if (NULL != conn_t) {
    	p_net_conn[sock] = conn_t;
    	memset(conn_t, 0, sizeof(struct tls_netconn));
    	conn_t->used = true;
    	conn_t->state = NETCONN_STATE_NONE;
    	conn_t->skt_num = sock + 1;//TLS_MAX_NETCONN_NUM + 
    	dl_list_init(&conn_t->list);
    	if (sys_sem_new(&conn_t->op_completed, 0) != ERR_OK) {
			net_free_socket(conn_t);
    	}
	}
	TLS_DBGPRT_INFO("net_alloc_socket conn ptr = 0x%x\n", conn_t);
	return conn_t;
	
//    return NULL;
}
Exemplo n.º 5
0
/**
 * subscription_start - Remember a UPnP control point to send events to.
 * @sm: WPS UPnP state machine from upnp_wps_device_init()
 * @callback_urls: Callback URLs
 * Returns: %NULL on error, or pointer to new subscription structure.
 */
struct subscription * subscription_start(struct upnp_wps_device_sm *sm,
					 const char *callback_urls)
{
	struct subscription *s;
	time_t now = time(NULL);
	time_t expire = now + UPNP_SUBSCRIBE_SEC;

	/* Get rid of expired subscriptions so we have room */
	subscription_list_age(sm, now);

	/* If too many subscriptions, remove oldest */
	if (dl_list_len(&sm->subscriptions) >= MAX_SUBSCRIPTIONS) {
		s = dl_list_first(&sm->subscriptions, struct subscription,
				  list);
		wpa_printf(MSG_INFO, "WPS UPnP: Too many subscriptions, "
			   "trashing oldest");
		dl_list_del(&s->list);
		subscription_destroy(s);
	}
Exemplo n.º 6
0
static enum http_reply_code
web_process_get_device_info(struct upnp_wps_device_sm *sm,
			    struct wpabuf **reply, const char **replyname)
{
	static const char *name = "NewDeviceInfo";
	struct wps_config cfg;
	struct upnp_wps_device_interface *iface;
	struct upnp_wps_peer *peer;

	iface = dl_list_first(&sm->interfaces,
			      struct upnp_wps_device_interface, list);

	wpa_printf(MSG_DEBUG, "WPS UPnP: GetDeviceInfo");

	if (!iface || iface->ctx->ap_pin == NULL)
		return HTTP_INTERNAL_SERVER_ERROR;

	peer = os_zalloc(sizeof(*peer));
	if (!peer)
		return HTTP_INTERNAL_SERVER_ERROR;

	/*
	 * Request for DeviceInfo, i.e., M1 TLVs. This is a start of WPS
	 * registration over UPnP with the AP acting as an Enrollee. It should
	 * be noted that this is frequently used just to get the device data,
	 * i.e., there may not be any intent to actually complete the
	 * registration.
	 */

	os_memset(&cfg, 0, sizeof(cfg));
	cfg.wps = iface->wps;
	cfg.pin = (u8 *) iface->ctx->ap_pin;
	cfg.pin_len = os_strlen(iface->ctx->ap_pin);
	peer->wps = wps_init(&cfg);
	if (peer->wps) {
		enum wsc_op_code op_code;
		*reply = wps_get_msg(peer->wps, &op_code);
		if (*reply == NULL) {
			wps_deinit(peer->wps);
			peer->wps = NULL;
		}
	} else
		*reply = NULL;
	if (*reply == NULL) {
		wpa_printf(MSG_INFO, "WPS UPnP: Failed to get DeviceInfo");
		os_free(peer);
		return HTTP_INTERNAL_SERVER_ERROR;
	}

	if (dl_list_len(&iface->peers) > 3) {
		struct upnp_wps_peer *old;

		old = dl_list_first(&iface->peers, struct upnp_wps_peer, list);
		if (old) {
			wpa_printf(MSG_DEBUG, "WPS UPnP: Drop oldest active session");
			wps_upnp_peer_del(old);
		}
	}
	dl_list_add_tail(&iface->peers, &peer->list);
	/* TODO: Could schedule a timeout to free the entry */

	*replyname = name;
	return HTTP_OK;
}
Exemplo n.º 7
0
/** 
 * @brief WPS worker thread
 * 
 * @param arg
 * 
 * @return 
 */
void *wps_pbc_work(void *arg)
{
    struct wbr_context *wctx ;
    struct wbr_wpa_pbc *pvap ;
    int pid ;

    char *cmdargs[] = {  "/sbin/wpatalk" ,
                            NULL , 
                            "configthem" ,
                            NULL } ;

    wbr_printf(MSG_DEBUG,"%s: Starting WPS worker ...\n",__func__);

    wctx = (struct wbr_context *) arg;

    /* Wait on condition */ 
    pthread_mutex_lock(&wctx->wps_pbc_mutex) ;
    pthread_cond_wait(&wctx->wps_pbc_cond ,&wctx->wps_pbc_mutex);
    pthread_mutex_unlock(&wctx->wps_pbc_mutex) ;

    while(1)
    {
        pvap = NULL ;

        pthread_mutex_lock(&wctx->wps_pbc_mutex) ;
        if(dl_list_len( &wctx->wps_pbc_head ))
        {
            pvap = dl_list_entry(wctx->wps_pbc_head.next, 
                                struct wbr_wpa_pbc, list) ;
            dl_list_del(&pvap->list) ; 
            pthread_mutex_unlock(&wctx->wps_pbc_mutex) ;

            cmdargs[1] = pvap->name ;

            pid = 0 ;
            pid = fork();
            if(pid == 0)
            {
                /* Child process.
                 * Execute '/sbin/wpatalk <vap> configthem'.
                 */
                wbr_printf(MSG_DEBUG,"%s: Execute wpatalk for %s\n",
                                        __func__,pvap->name);
                execve("/sbin/wpatalk" , cmdargs , NULL) ;
            }
            else
            {
                int stat ;
                int sleepcount ;
                int sleepdur ; /* sleep duration in sec */

                /* wait on child process */
                sleepdur = 5 ; 
                sleepcount = (130) / sleepdur;
                while(sleepcount)
                {
                    sleep(sleepdur);
                    stat = waitpid(pid, &stat, WNOHANG);
                    if ( stat == pid )
                        break ;

                    sleepcount--;
                }

                if(sleepcount == 0)
                {
                    /* Child did not terminate during wait period.
                     * Send signal to terminate child. 
                     */
                    kill(pid , SIGTERM) ;
                    waitpid(pid, &stat, WUNTRACED);
                }

                free(pvap) ;
            }

        } // end if(dl_list_len( &wctx->wps_pbc_head ))
        else
        {
Exemplo n.º 8
0
/* subscr_addr_add_url -- add address(es) for one url to subscription */
static void subscr_addr_add_url(struct subscription *s, const char *url,
				size_t url_len)
{
	int alloc_len;
	char *scratch_mem = NULL;
	char *mem;
	char *domain_and_port;
	char *delim;
	char *path;
	char *domain;
	int port = 80;  /* port to send to (default is port 80) */
	struct addrinfo hints;
	struct addrinfo *result = NULL;
	struct addrinfo *rp;
	int rerr;

	/* url MUST begin with http: */
	if (url_len < 7 || os_strncasecmp(url, "http://", 7))
		goto fail;
	url += 7;
	url_len -= 7;

	/* allocate memory for the extra stuff we need */
	alloc_len = 2 * (url_len + 1);
	scratch_mem = os_zalloc(alloc_len);
	if (scratch_mem == NULL)
		goto fail;
	mem = scratch_mem;
	os_strncpy(mem, url, url_len);
	wpa_printf(MSG_DEBUG, "WPS UPnP: Adding URL '%s'", mem);
	domain_and_port = mem;
	mem += 1 + os_strlen(mem);
	delim = os_strchr(domain_and_port, '/');
	if (delim) {
		*delim++ = 0;   /* null terminate domain and port */
		path = delim;
	} else {
		path = domain_and_port + os_strlen(domain_and_port);
	}
	domain = mem;
	strcpy(domain, domain_and_port);
	delim = os_strchr(domain, ':');
	if (delim) {
		*delim++ = 0;   /* null terminate domain */
		if (isdigit(*delim))
			port = atol(delim);
	}

	/*
	 * getaddrinfo does the right thing with dotted decimal notations, or
	 * will resolve domain names. Resolving domain names will unfortunately
	 * hang the entire program until it is resolved or it times out
	 * internal to getaddrinfo; fortunately we think that the use of actual
	 * domain names (vs. dotted decimal notations) should be uncommon.
	 */
	os_memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_INET;      /* IPv4 */
	hints.ai_socktype = SOCK_STREAM;
#if NO_DOMAIN_NAME_RESOLUTION
	/* Suppress domain name resolutions that would halt
	 * the program for periods of time
	 */
	hints.ai_flags = AI_NUMERICHOST;
#else
	/* Allow domain name resolution. */
	hints.ai_flags = 0;
#endif
	hints.ai_protocol = 0;          /* Any protocol? */
	rerr = getaddrinfo(domain, NULL /* fill in port ourselves */,
			   &hints, &result);
	if (rerr) {
		wpa_printf(MSG_INFO, "WPS UPnP: Resolve error %d (%s) on: %s",
			   rerr, gai_strerror(rerr), domain);
		goto fail;
	}
	for (rp = result; rp; rp = rp->ai_next) {
		struct subscr_addr *a;

		/* Limit no. of address to avoid denial of service attack */
		if (dl_list_len(&s->addr_list) >= MAX_ADDR_PER_SUBSCRIPTION) {
			wpa_printf(MSG_INFO, "WPS UPnP: subscr_addr_add_url: "
				   "Ignoring excessive addresses");
			break;
		}

		a = os_zalloc(sizeof(*a) + alloc_len);
		if (a == NULL)
			continue;
		mem = (void *) (a + 1);
		a->domain_and_port = mem;
		strcpy(mem, domain_and_port);
		mem += 1 + strlen(mem);
		a->path = mem;
		if (path[0] != '/')
			*mem++ = '/';
		strcpy(mem, path);
		mem += 1 + os_strlen(mem);
		os_memcpy(&a->saddr, rp->ai_addr, sizeof(a->saddr));
		a->saddr.sin_port = htons(port);

		dl_list_add(&s->addr_list, &a->list);
	}

fail:
	if (result)
		freeaddrinfo(result);
	os_free(scratch_mem);
}
Exemplo n.º 9
0
u8 * hostapd_eid_fils_indic(struct hostapd_data *hapd, u8 *eid, int hessid)
{
	u8 *pos = eid;
#ifdef CONFIG_FILS
	u8 *len;
	u16 fils_info = 0;
	size_t realms;
	struct fils_realm *realm;

	if (!(hapd->conf->wpa & WPA_PROTO_RSN) ||
	    !wpa_key_mgmt_fils(hapd->conf->wpa_key_mgmt))
		return pos;

	realms = dl_list_len(&hapd->conf->fils_realms);
	if (realms > 7)
		realms = 7; /* 3 bit count field limits this to max 7 */

	*pos++ = WLAN_EID_FILS_INDICATION;
	len = pos++;
	/* TODO: B0..B2: Number of Public Key Identifiers */
	if (hapd->conf->erp_domain) {
		/* B3..B5: Number of Realm Identifiers */
		fils_info |= realms << 3;
	}
	/* TODO: B6: FILS IP Address Configuration */
	if (hapd->conf->fils_cache_id_set)
		fils_info |= BIT(7);
	if (hessid && !is_zero_ether_addr(hapd->conf->hessid))
		fils_info |= BIT(8); /* HESSID Included */
	/* FILS Shared Key Authentication without PFS Supported */
	fils_info |= BIT(9);
	if (hapd->conf->fils_dh_group) {
		/* FILS Shared Key Authentication with PFS Supported */
		fils_info |= BIT(10);
	}
	/* TODO: B11: FILS Public Key Authentication Supported */
	/* B12..B15: Reserved */
	WPA_PUT_LE16(pos, fils_info);
	pos += 2;
	if (hapd->conf->fils_cache_id_set) {
		os_memcpy(pos, hapd->conf->fils_cache_id, FILS_CACHE_ID_LEN);
		pos += FILS_CACHE_ID_LEN;
	}
	if (hessid && !is_zero_ether_addr(hapd->conf->hessid)) {
		os_memcpy(pos, hapd->conf->hessid, ETH_ALEN);
		pos += ETH_ALEN;
	}

	dl_list_for_each(realm, &hapd->conf->fils_realms, struct fils_realm,
			 list) {
		if (realms == 0)
			break;
		realms--;
		os_memcpy(pos, realm->hash, 2);
		pos += 2;
	}
	*len = pos - len - 1;
#endif /* CONFIG_FILS */

	return pos;
}
Exemplo n.º 10
0
/* subscr_addr_add_url -- add address(es) for one url to subscription */
static void subscr_addr_add_url(struct subscription *s, const char *url,
				size_t url_len)
{
	int alloc_len;
	char *scratch_mem = NULL;
	char *mem;
	char *host;
	char *delim;
	char *path;
	int port = 80;  /* port to send to (default is port 80) */
	struct addrinfo hints;
	struct addrinfo *result = NULL;
	struct addrinfo *rp;
	int rerr;
	size_t host_len, path_len;

	/* url MUST begin with http: */
	if (url_len < 7 || os_strncasecmp(url, "http://", 7))
		goto fail;
	url += 7;
	url_len -= 7;

	/* Make a copy of the string to allow modification during parsing */
	scratch_mem = dup_binstr(url, url_len);
	if (scratch_mem == NULL)
		goto fail;
	wpa_printf(MSG_DEBUG, "WPS UPnP: Adding URL '%s'", scratch_mem);
	host = scratch_mem;
	path = os_strchr(host, '/');
	if (path)
		*path++ = '\0'; /* null terminate host */

	/* Process and remove optional port component */
	delim = os_strchr(host, ':');
	if (delim) {
		*delim = '\0'; /* null terminate host name for now */
		if (isdigit(delim[1]))
			port = atol(delim + 1);
	}

	/*
	 * getaddrinfo does the right thing with dotted decimal notations, or
	 * will resolve domain names. Resolving domain names will unfortunately
	 * hang the entire program until it is resolved or it times out
	 * internal to getaddrinfo; fortunately we think that the use of actual
	 * domain names (vs. dotted decimal notations) should be uncommon.
	 */
	os_memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_INET;      /* IPv4 */
	hints.ai_socktype = SOCK_STREAM;
#if NO_DOMAIN_NAME_RESOLUTION
	/* Suppress domain name resolutions that would halt
	 * the program for periods of time
	 */
	hints.ai_flags = AI_NUMERICHOST;
#else
	/* Allow domain name resolution. */
	hints.ai_flags = 0;
#endif
	hints.ai_protocol = 0;          /* Any protocol? */
	rerr = getaddrinfo(host, NULL /* fill in port ourselves */,
			   &hints, &result);
	if (rerr) {
		wpa_printf(MSG_INFO, "WPS UPnP: Resolve error %d (%s) on: %s",
			   rerr, gai_strerror(rerr), host);
		goto fail;
	}

	if (delim)
		*delim = ':'; /* Restore port */

	host_len = os_strlen(host);
	path_len = path ? os_strlen(path) : 0;
	alloc_len = host_len + 1 + 1 + path_len + 1;

	for (rp = result; rp; rp = rp->ai_next) {
		struct subscr_addr *a;

		/* Limit no. of address to avoid denial of service attack */
		if (dl_list_len(&s->addr_list) >= MAX_ADDR_PER_SUBSCRIPTION) {
			wpa_printf(MSG_INFO, "WPS UPnP: subscr_addr_add_url: "
				   "Ignoring excessive addresses");
			break;
		}

		a = os_zalloc(sizeof(*a) + alloc_len);
		if (a == NULL)
			break;
		mem = (char *) (a + 1);
		a->domain_and_port = mem;
		os_memcpy(mem, host, host_len);
		mem += host_len + 1;
		a->path = mem;
		if (path == NULL || path[0] != '/')
			*mem++ = '/';
		if (path)
			os_memcpy(mem, path, path_len);
		os_memcpy(&a->saddr, rp->ai_addr, sizeof(a->saddr));
		a->saddr.sin_port = htons(port);

		dl_list_add(&s->addr_list, &a->list);
	}

fail:
	if (result)
		freeaddrinfo(result);
	os_free(scratch_mem);
}