⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wps_upnp.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	domain = mem;	strcpy(domain, domain_and_port);	delim = 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) {		/* Limit no. of address to avoid denial of service attack */		if (s->n_addr >= 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;		a->s = s;		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 + strlen(mem);		os_memcpy(&a->saddr, rp->ai_addr, sizeof(a->saddr));		a->saddr.sin_port = htons(port);		subscr_addr_link(s, a);		a = NULL;       /* don't free it below */	}fail:	if (result)		freeaddrinfo(result);	os_free(scratch_mem);	os_free(a);}/* subscr_addr_list_create -- create list from urls in string. *      Each url is enclosed by angle brackets. */static void subscr_addr_list_create(struct subscription *s,				    const char *url_list){	char *end;	for (;;) {		while (*url_list == ' ' || *url_list == '\t')			url_list++;		if (*url_list != '<')			break;		url_list++;		end = os_strchr(url_list, '>');		if (end == NULL)			break;		*end++ = 0;		subscr_addr_add_url(s, url_list);		url_list = end;	}}int send_wpabuf(int fd, struct wpabuf *buf){	wpa_printf(MSG_DEBUG, "WPS UPnP: Send %lu byte message",		   (unsigned long) wpabuf_len(buf));	errno = 0;	if (write(fd, wpabuf_head(buf), wpabuf_len(buf)) !=	    (int) wpabuf_len(buf)) {		wpa_printf(MSG_ERROR, "WPS UPnP: Failed to send buffer: "			   "errno=%d (%s)",			   errno, strerror(errno));		return -1;	}	return 0;}static void wpabuf_put_property(struct wpabuf *buf, const char *name,				const char *value){	wpabuf_put_str(buf, "<e:property>");	wpabuf_printf(buf, "<%s>", name);	if (value)		wpabuf_put_str(buf, value);	wpabuf_printf(buf, "</%s>", name);	wpabuf_put_str(buf, "</e:property>\n");}/** * upnp_wps_device_send_event - Queue event messages for subscribers * @sm: WPS UPnP state machine from upnp_wps_device_init() * * This function queues the last WLANEvent to be sent for all currently * subscribed UPnP control points. sm->wlanevent must have been set with the * encoded data before calling this function. */static void upnp_wps_device_send_event(struct upnp_wps_device_sm *sm){	/* Enqueue event message for all subscribers */	struct wpabuf *buf; /* holds event message */	int buf_size = 0;	struct subscription *s;	/* Actually, utf-8 is the default, but it doesn't hurt to specify it */	const char *format_head =		"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"		"<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\">\n";	const char *format_tail = "</e:propertyset>\n";	if (sm->subscriptions == NULL) {		/* optimize */		return;	}	/* Determine buffer size needed first */	buf_size += os_strlen(format_head);	buf_size += 50 + 2 * os_strlen("WLANEvent");	if (sm->wlanevent)		buf_size += os_strlen(sm->wlanevent);	buf_size += os_strlen(format_tail);	buf = wpabuf_alloc(buf_size);	if (buf == NULL)		return;	wpabuf_put_str(buf, format_head);	wpabuf_put_property(buf, "WLANEvent", sm->wlanevent);	wpabuf_put_str(buf, format_tail);	wpa_printf(MSG_MSGDUMP, "WPS UPnP: WLANEvent message:\n%s",		   (char *) wpabuf_head(buf));	s = sm->subscriptions;	do {		if (event_add(s, buf)) {			struct subscription *s_old = s;			wpa_printf(MSG_INFO, "WPS UPnP: Dropping "				   "subscriber due to event backlog");			s = s_old->next;			subscription_unlink(s_old);			subscription_destroy(s_old);		} else {			s = s->next;		}	} while (s != sm->subscriptions);	wpabuf_free(buf);}/* * Event subscription (subscriber machines register with us to receive event * messages). * This is the result of an incoming HTTP over TCP SUBSCRIBE request. *//* subscription_unlink -- remove from the active list */void subscription_unlink(struct subscription *s){	struct upnp_wps_device_sm *sm = s->sm;	if (s->next == s) {		/* only one? */		sm->subscriptions = NULL;	} else  {		if (sm->subscriptions == s)			sm->subscriptions = s->next;		s->next->prev = s->prev;		s->prev->next = s->next;	}	sm->n_subscriptions--;}/* subscription_link_to_end -- link to end of active list * (should have high expiry time!) */static void subscription_link_to_end(struct subscription *s){	struct upnp_wps_device_sm *sm = s->sm;	if (sm->subscriptions) {		s->next = sm->subscriptions;		s->prev = s->next->prev;		s->prev->next = s;		s->next->prev = s;	} else {		sm->subscriptions = s->next = s->prev = s;	}	sm->n_subscriptions++;}/* subscription_destroy -- destroy an unlinked subscription * Be sure to unlink first if necessary. */void subscription_destroy(struct subscription *s){	wpa_printf(MSG_DEBUG, "WPS UPnP: Destroy subscription %p", s);	if (s->addr_list)		subscr_addr_free_all(s);	event_delete_all(s);	os_free(s);}/* subscription_list_age -- remove expired subscriptions */static void subscription_list_age(struct upnp_wps_device_sm *sm, time_t now){	struct subscription *s;	while ((s = sm->subscriptions) != NULL && s->timeout_time < now) {		wpa_printf(MSG_DEBUG, "WPS UPnP: Removing aged subscription");		subscription_unlink(s);		subscription_destroy(s);	}}/* subscription_find -- return existing subscription matching uuid, if any * returns NULL if not found */struct subscription * subscription_find(struct upnp_wps_device_sm *sm,					const u8 uuid[UUID_LEN]){	struct subscription *s0 = sm->subscriptions;	struct subscription *s = s0;	if (s0 == NULL)		return NULL;	do {		if (os_memcmp(s->uuid, uuid, UUID_LEN) == 0)			return s; /* Found match */		s = s->next;	} while (s != s0);	return NULL;}/* subscription_first_event -- send format/queue event that is automatically * sent on a new subscription. */static int subscription_first_event(struct subscription *s){	/*	 * Actually, utf-8 is the default, but it doesn't hurt to specify it.	 *	 * APStatus is apparently a bit set,	 * 0x1 = configuration change (but is always set?)	 * 0x10 = ap is locked	 *	 * Per UPnP spec, we send out the last value of each variable, even	 * for WLANEvent, whatever it was.	 */	char *wlan_event;	struct wpabuf *buf;	int ap_status = 1;      /* TODO: add 0x10 if access point is locked */	const char *head =		"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"		"<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\">\n";	const char *tail = "</e:propertyset>\n";	char txt[10];	wlan_event = s->sm->wlanevent;	if (wlan_event == NULL || *wlan_event == '\0') {		wpa_printf(MSG_DEBUG, "WPS UPnP: WLANEvent not known for "			   "initial event message");		wlan_event = "";	}	buf = wpabuf_alloc(500 + os_strlen(wlan_event));	if (buf == NULL)		return 1;	wpabuf_put_str(buf, head);	wpabuf_put_property(buf, "STAStatus", "1");	os_snprintf(txt, sizeof(txt), "%d", ap_status);	wpabuf_put_property(buf, "APStatus", txt);	if (*wlan_event)		wpabuf_put_property(buf, "WLANEvent", wlan_event);	wpabuf_put_str(buf, tail);	if (event_add(s, buf)) {		wpabuf_free(buf);		return 1;	}	wpabuf_free(buf);	return 0;}/** * subscription_start - Rremember a UPnP control point to send events to. * @sm: WPS UPnP state machine from upnp_wps_device_init() * @callback_urls: malloc' mem given to the subscription * Returns: %NULL on error, or pointer to new subscription structure. */struct subscription * subscription_start(struct upnp_wps_device_sm *sm,					 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 (sm->n_subscriptions >= MAX_SUBSCRIPTIONS) {		s = sm->subscriptions;		wpa_printf(MSG_INFO, "WPS UPnP: Too many subscriptions, "			   "trashing oldest");		subscription_unlink(s);		subscription_destroy(s);	}	s = os_zalloc(sizeof(*s));	if (s == NULL)		return NULL;	s->sm = sm;	s->timeout_time = expire;	uuid_make(s->uuid);	subscr_addr_list_create(s, callback_urls);	/* Add to end of list, since it has the highest expiration time */	subscription_link_to_end(s);	/* Queue up immediate event message (our last event)	 * as required by UPnP spec.	 */	if (subscription_first_event(s)) {		wpa_printf(MSG_INFO, "WPS UPnP: Dropping subscriber due to "			   "event backlog");		subscription_unlink(s);		subscription_destroy(s);		return NULL;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -