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

📄 wps_upnp.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * UPnP WPS Device * Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2006-2007 Sony Corporation * Copyright (c) 2008-2009 Atheros Communications * Copyright (c) 2009, Jouni Malinen <j@w1.fi> * * See below for more details on licensing and code history. *//* * This has been greatly stripped down from the original file * (upnp_wps_device.c) by Ted Merrill, Atheros Communications * in order to eliminate use of the bulky libupnp library etc. * * History: * upnp_wps_device.c is/was a shim layer between wps_opt_upnp.c and * the libupnp library. * The layering (by Sony) was well done; only a very minor modification * to API of upnp_wps_device.c was required. * libupnp was found to be undesirable because: * -- It consumed too much code and data space * -- It uses multiple threads, making debugging more difficult *      and possibly reducing reliability. * -- It uses static variables and only supports one instance. * The shim and libupnp are here replaced by special code written * specifically for the needs of hostapd. * Various shortcuts can and are taken to keep the code size small. * Generally, execution time is not as crucial. * * BUGS: * -- UPnP requires that we be able to resolve domain names. * While uncommon, if we have to do it then it will stall the entire * hostapd program, which is bad. * This is because we use the standard linux getaddrinfo() function * which is syncronous. * An asyncronous solution would be to use the free "ares" library. * -- Does not have a robust output buffering scheme.  Uses a single * fixed size output buffer per TCP/HTTP connection, with possible (although * unlikely) possibility of overflow and likely excessive use of RAM. * A better solution would be to write the HTTP output as a buffered stream, * using chunking: (handle header specially, then) generate data with * a printf-like function into a buffer, catching buffer full condition, * then send it out surrounded by http chunking. * -- There is some code that could be separated out into the common * library to be shared with wpa_supplicant. * -- Needs renaming with module prefix to avoid polluting the debugger * namespace and causing possible collisions with other static fncs * and structure declarations when using the debugger. * -- Just what should be in the first event message sent after subscription * for the WLANEvent field? If i pass it empty, Vista replies with OK * but apparently barfs on the message. * -- The http error code generation is pretty bogus, hopefully noone cares. * * Author: Ted Merrill, Atheros Communications, based upon earlier work * as explained above and below. * * Copyright: * Copyright 2008 Atheros Communications. * * The original header (of upnp_wps_device.c) reads: * *  Copyright (c) 2006-2007 Sony Corporation. All Rights Reserved. * *  File Name: upnp_wps_device.c *  Description: EAP-WPS UPnP device source * *   Redistribution and use in source and binary forms, with or without *   modification, are permitted provided that the following conditions *   are met: * *     * Redistributions of source code must retain the above copyright *       notice, this list of conditions and the following disclaimer. *     * Redistributions in binary form must reproduce the above copyright *       notice, this list of conditions and the following disclaimer in *       the documentation and/or other materials provided with the *       distribution. *     * Neither the name of Sony Corporation nor the names of its *       contributors may be used to endorse or promote products derived *       from this software without specific prior written permission. * *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Portions from Intel libupnp files, e.g. genlib/net/http/httpreadwrite.c * typical header: * * Copyright (c) 2000-2003 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither name of Intel Corporation nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*//* * Overview of WPS over UPnP: * * UPnP is a protocol that allows devices to discover each other and control * each other. In UPnP terminology, a device is either a "device" (a server * that provides information about itself and allows itself to be controlled) * or a "control point" (a client that controls "devices") or possibly both. * This file implements a UPnP "device". * * For us, we use mostly basic UPnP discovery, but the control part of interest * is WPS carried via UPnP messages. There is quite a bit of basic UPnP * discovery to do before we can get to WPS, however. * * UPnP discovery begins with "devices" send out multicast UDP packets to a * certain fixed multicast IP address and port, and "control points" sending * out other such UDP packets. * * The packets sent by devices are NOTIFY packets (not to be confused with TCP * NOTIFY packets that are used later) and those sent by control points are * M-SEARCH packets. These packets contain a simple HTTP style header. The * packets are sent redundantly to get around packet loss. Devices respond to * M-SEARCH packets with HTTP-like UDP packets containing HTTP/1.1 200 OK * messages, which give similar information as the UDP NOTIFY packets. * * The above UDP packets advertise the (arbitrary) TCP ports that the * respective parties will listen to. The control point can then do a HTTP * SUBSCRIBE (something like an HTTP PUT) after which the device can do a * separate HTTP NOTIFY (also like an HTTP PUT) to do event messaging. * * The control point will also do HTTP GET of the "device file" listed in the * original UDP information from the device (see UPNP_WPS_DEVICE_XML_FILE * data), and based on this will do additional GETs... HTTP POSTs are done to * cause an action. * * Beyond some basic information in HTTP headers, additional information is in * the HTTP bodies, in a format set by the SOAP and XML standards, a markup * language related to HTML used for web pages. This language is intended to * provide the ultimate in self-documentation by providing a universal * namespace based on pseudo-URLs called URIs. Note that although a URI looks * like a URL (a web address), they are never accessed as such but are used * only as identifiers. * * The POST of a GetDeviceInfo gets information similar to what might be * obtained from a probe request or response on Wi-Fi. WPS messages M1-M8 * are passed via a POST of a PutMessage; the M1-M8 WPS messages are converted * to a bin64 ascii representation for encapsulation. When proxying messages, * WLANEvent and PutWLANResponse are used. * * This of course glosses over a lot of details. */#include "includes.h"#include <assert.h>#include <net/if.h>#include <netdb.h>#include <sys/ioctl.h>#include "common.h"#include "uuid.h"#include "base64.h"#include "wps.h"#include "wps_i.h"#include "wps_upnp.h"#include "wps_upnp_i.h"/* * UPnP allows a client ("control point") to send a server like us ("device") * a domain name for registration, and we are supposed to resolve it. This is * bad because, using the standard Linux library, we will stall the entire * hostapd waiting for resolution. * * The "correct" solution would be to use an event driven library for domain * name resolution such as "ares". However, this would increase code size * further. Since it is unlikely that we'll actually see such domain names, we * can just refuse to accept them. */#define NO_DOMAIN_NAME_RESOLUTION 1  /* 1 to allow only dotted ip addresses *//* * UPnP does not scale well. If we were in a room with thousands of control * points then potentially we could be expected to handle subscriptions for * each of them, which would exhaust our memory. So we must set a limit. In * practice we are unlikely to see more than one or two. */#define MAX_SUBSCRIPTIONS 4    /* how many subscribing clients we handle */#define MAX_ADDR_PER_SUBSCRIPTION 8/* Write the current date/time per RFC */void format_date(struct wpabuf *buf){	const char *weekday_str = "Sun\0Mon\0Tue\0Wed\0Thu\0Fri\0Sat";	const char *month_str = "Jan\0Feb\0Mar\0Apr\0May\0Jun\0"		"Jul\0Aug\0Sep\0Oct\0Nov\0Dec";	struct tm *date;	time_t t;	t = time(NULL);	date = gmtime(&t);	wpabuf_printf(buf, "%s, %02d %s %d %02d:%02d:%02d GMT",		      &weekday_str[date->tm_wday * 4], date->tm_mday,		      &month_str[date->tm_mon * 4], date->tm_year + 1900,		      date->tm_hour, date->tm_min, date->tm_sec);}/*************************************************************************** * UUIDs (unique identifiers) * * These are supposed to be unique in all the world. * Sometimes permanent ones are used, sometimes temporary ones * based on random numbers... there are different rules for valid content * of different types. * Each uuid is 16 bytes long. **************************************************************************//* uuid_make -- construct a random UUID * The UPnP documents don't seem to offer any guidelines as to which method to * use for constructing UUIDs for subscriptions. Presumably any method from * rfc4122 is good enough; I've chosen random number method. */static void uuid_make(u8 uuid[UUID_LEN]){	os_get_random(uuid, UUID_LEN);	/* Replace certain bits as specified in rfc4122 or X.667 */	uuid[6] &= 0x0f; uuid[6] |= (4 << 4);   /* version 4 == random gen */	uuid[8] &= 0x3f; uuid[8] |= 0x80;}/* * Subscriber address handling. * Since a subscriber may have an arbitrary number of addresses, we have to * add a bunch of code to handle them. * * Addresses are passed in text, and MAY be domain names instead of the (usual * and expected) dotted IP addresses. Resolving domain names consumes a lot of * resources. Worse, we are currently using the standard Linux getaddrinfo() * which will block the entire program until complete or timeout! The proper * solution would be to use the "ares" library or similar with more state * machine steps etc. or just disable domain name resolution by setting * NO_DOMAIN_NAME_RESOLUTION to 1 at top of this file. *//* subscr_addr_delete -- delete single unlinked subscriber address * (be sure to unlink first if need be) */static void subscr_addr_delete(struct subscr_addr *a){	/*	 * Note: do NOT free domain_and_port or path because they point to	 * memory within the allocation of "a".	 */	os_free(a);}/* subscr_addr_unlink -- unlink subscriber address from linked list */static void subscr_addr_unlink(struct subscription *s, struct subscr_addr *a){	struct subscr_addr **listp = &s->addr_list;	s->n_addr--;	a->next->prev = a->prev;	a->prev->next = a->next;	if (*listp == a) {		if (a == a->next) {			/* last in queue */			*listp = NULL;			assert(s->n_addr == 0);		} else {			*listp = a->next;		}	}}/* subscr_addr_free_all -- unlink and delete list of subscriber addresses. */static void subscr_addr_free_all(struct subscription *s){	struct subscr_addr **listp = &s->addr_list;	struct subscr_addr *a;	while ((a = *listp) != NULL) {		subscr_addr_unlink(s, a);		subscr_addr_delete(a);	}}/* subscr_addr_link -- add subscriber address to list of addresses */static void subscr_addr_link(struct subscription *s, struct subscr_addr *a){	struct subscr_addr **listp = &s->addr_list;	s->n_addr++;	if (*listp == NULL) {		*listp = a->next = a->prev = a;	} else {		a->next = *listp;		a->prev = (*listp)->prev;		a->prev->next = a;		a->next->prev = a;	}}/* subscr_addr_add_url -- add address(es) for one url to subscription */static void subscr_addr_add_url(struct subscription *s, const char *url){	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;	struct subscr_addr *a = NULL;	/* url MUST begin with http: */	if (os_strncasecmp(url, "http://", 7))		goto fail;	url += 7;	/* allocate memory for the extra stuff we need */	alloc_len = (2 * (os_strlen(url) + 1));	scratch_mem = os_zalloc(alloc_len);	if (scratch_mem == NULL)		goto fail;	mem = scratch_mem;	strcpy(mem, url);	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);	}

⌨️ 快捷键说明

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