1189251Ssam/* 2189251Ssam * UPnP for WPS / internal definitions 3189251Ssam * Copyright (c) 2000-2003 Intel Corporation 4189251Ssam * Copyright (c) 2006-2007 Sony Corporation 5189251Ssam * Copyright (c) 2008-2009 Atheros Communications 6189251Ssam * Copyright (c) 2009, Jouni Malinen <j@w1.fi> 7189251Ssam * 8189251Ssam * See wps_upnp.c for more details on licensing and code history. 9189251Ssam */ 10189251Ssam 11189251Ssam#ifndef WPS_UPNP_I_H 12189251Ssam#define WPS_UPNP_I_H 13189251Ssam 14214734Srpaulo#include "utils/list.h" 15214734Srpaulo#include "http.h" 16214734Srpaulo 17189251Ssam#define UPNP_MULTICAST_ADDRESS "239.255.255.250" /* for UPnP multicasting */ 18189251Ssam#define UPNP_MULTICAST_PORT 1900 /* UDP port to monitor for UPnP */ 19189251Ssam 20189251Ssam/* min subscribe time per UPnP standard */ 21189251Ssam#define UPNP_SUBSCRIBE_SEC_MIN 1800 22189251Ssam/* subscribe time we use */ 23189251Ssam#define UPNP_SUBSCRIBE_SEC (UPNP_SUBSCRIBE_SEC_MIN + 1) 24189251Ssam 25189251Ssam/* "filenames" used in URLs that we service via our "web server": */ 26189251Ssam#define UPNP_WPS_DEVICE_XML_FILE "wps_device.xml" 27189251Ssam#define UPNP_WPS_SCPD_XML_FILE "wps_scpd.xml" 28189251Ssam#define UPNP_WPS_DEVICE_CONTROL_FILE "wps_control" 29189251Ssam#define UPNP_WPS_DEVICE_EVENT_FILE "wps_event" 30189251Ssam 31214734Srpaulo#define MULTICAST_MAX_READ 1600 /* max bytes we'll read for UPD request */ 32189251Ssam 33214734Srpaulo 34189251Ssamstruct upnp_wps_device_sm; 35214734Srpaulostruct wps_registrar; 36189251Ssam 37189251Ssam 38189251Ssamenum advertisement_type_enum { 39189251Ssam ADVERTISE_UP = 0, 40189251Ssam ADVERTISE_DOWN = 1, 41189251Ssam MSEARCH_REPLY = 2 42189251Ssam}; 43189251Ssam 44189251Ssam/* 45189251Ssam * Advertisements are broadcast via UDP NOTIFYs, and are also the essence of 46189251Ssam * the reply to UDP M-SEARCH requests. This struct handles both cases. 47189251Ssam * 48189251Ssam * A state machine is needed because a number of variant forms must be sent in 49189251Ssam * separate packets and spread out in time to avoid congestion. 50189251Ssam */ 51189251Ssamstruct advertisement_state_machine { 52214734Srpaulo struct dl_list list; 53189251Ssam enum advertisement_type_enum type; 54189251Ssam int state; 55189251Ssam int nerrors; 56189251Ssam struct sockaddr_in client; /* for M-SEARCH replies */ 57189251Ssam}; 58189251Ssam 59189251Ssam 60189251Ssam/* 61189251Ssam * An address of a subscriber (who may have multiple addresses). We are 62189251Ssam * supposed to send (via TCP) updates to each subscriber, trying each address 63189251Ssam * for a subscriber until we find one that seems to work. 64189251Ssam */ 65189251Ssamstruct subscr_addr { 66214734Srpaulo struct dl_list list; 67189251Ssam char *domain_and_port; /* domain and port part of url */ 68189251Ssam char *path; /* "filepath" part of url (from "mem") */ 69189251Ssam struct sockaddr_in saddr; /* address for doing connect */ 70252726Srpaulo unsigned num_failures; 71189251Ssam}; 72189251Ssam 73189251Ssam 74189251Ssam/* 75189251Ssam * Subscribers to our events are recorded in this struct. This includes a max 76189251Ssam * of one outgoing connection (sending an "event message") per subscriber. We 77189251Ssam * also have to age out subscribers unless they renew. 78189251Ssam */ 79189251Ssamstruct subscription { 80214734Srpaulo struct dl_list list; 81189251Ssam struct upnp_wps_device_sm *sm; /* parent */ 82189251Ssam time_t timeout_time; /* when to age out the subscription */ 83189251Ssam unsigned next_subscriber_sequence; /* number our messages */ 84189251Ssam /* 85189251Ssam * This uuid identifies the subscription and is randomly generated by 86189251Ssam * us and given to the subscriber when the subscription is accepted; 87189251Ssam * and is then included with each event sent to the subscriber. 88189251Ssam */ 89189251Ssam u8 uuid[UUID_LEN]; 90189251Ssam /* Linked list of address alternatives (rotate through on failure) */ 91214734Srpaulo struct dl_list addr_list; 92214734Srpaulo struct dl_list event_queue; /* Queued event messages. */ 93189251Ssam struct wps_event_ *current_event; /* non-NULL if being sent (not in q) 94189251Ssam */ 95252726Srpaulo int last_event_failed; /* Whether delivery of last event failed */ 96214734Srpaulo 97214734Srpaulo /* Information from SetSelectedRegistrar action */ 98214734Srpaulo u8 selected_registrar; 99214734Srpaulo u16 dev_password_id; 100214734Srpaulo u16 config_methods; 101252726Srpaulo u8 authorized_macs[WPS_MAX_AUTHORIZED_MACS][ETH_ALEN]; 102214734Srpaulo struct wps_registrar *reg; 103189251Ssam}; 104189251Ssam 105189251Ssam 106252726Srpaulostruct upnp_wps_device_interface { 107252726Srpaulo struct dl_list list; 108252726Srpaulo struct upnp_wps_device_ctx *ctx; /* callback table */ 109252726Srpaulo struct wps_context *wps; 110252726Srpaulo void *priv; 111252726Srpaulo 112252726Srpaulo /* FIX: maintain separate structures for each UPnP peer */ 113252726Srpaulo struct upnp_wps_peer peer; 114252726Srpaulo}; 115252726Srpaulo 116189251Ssam/* 117252726Srpaulo * Our instance data corresponding to the AP device. Note that there may be 118252726Srpaulo * multiple wireless interfaces sharing the same UPnP device instance. Each 119252726Srpaulo * such interface is stored in the list of struct upnp_wps_device_interface 120252726Srpaulo * instances. 121189251Ssam * 122189251Ssam * This is known as an opaque struct declaration to users of the WPS UPnP code. 123189251Ssam */ 124189251Ssamstruct upnp_wps_device_sm { 125252726Srpaulo struct dl_list interfaces; /* struct upnp_wps_device_interface */ 126189251Ssam char *root_dir; 127189251Ssam char *desc_url; 128189251Ssam int started; /* nonzero if we are active */ 129189251Ssam u8 mac_addr[ETH_ALEN]; /* mac addr of network i.f. we use */ 130189251Ssam char *ip_addr_text; /* IP address of network i.f. we use */ 131189251Ssam unsigned ip_addr; /* IP address of network i.f. we use (host order) */ 132189251Ssam int multicast_sd; /* send multicast messages over this socket */ 133189251Ssam int ssdp_sd; /* receive discovery UPD packets on socket */ 134189251Ssam int ssdp_sd_registered; /* nonzero if we must unregister */ 135189251Ssam unsigned advertise_count; /* how many advertisements done */ 136189251Ssam struct advertisement_state_machine advertisement; 137214734Srpaulo struct dl_list msearch_replies; 138189251Ssam int web_port; /* our port that others get xml files from */ 139214734Srpaulo struct http_server *web_srv; 140189251Ssam /* Note: subscriptions are kept in expiry order */ 141214734Srpaulo struct dl_list subscriptions; 142189251Ssam int event_send_all_queued; /* if we are scheduled to send events soon 143189251Ssam */ 144189251Ssam 145189251Ssam char *wlanevent; /* the last WLANEvent data */ 146252726Srpaulo enum upnp_wps_wlanevent_type wlanevent_type; 147252726Srpaulo os_time_t last_event_sec; 148252726Srpaulo unsigned int num_events_in_sec; 149189251Ssam}; 150189251Ssam 151189251Ssam/* wps_upnp.c */ 152189251Ssamvoid format_date(struct wpabuf *buf); 153189251Ssamstruct subscription * subscription_start(struct upnp_wps_device_sm *sm, 154209158Srpaulo const char *callback_urls); 155189251Ssamstruct subscription * subscription_renew(struct upnp_wps_device_sm *sm, 156189251Ssam const u8 uuid[UUID_LEN]); 157189251Ssamvoid subscription_destroy(struct subscription *s); 158189251Ssamstruct subscription * subscription_find(struct upnp_wps_device_sm *sm, 159189251Ssam const u8 uuid[UUID_LEN]); 160252726Srpaulovoid subscr_addr_delete(struct subscr_addr *a); 161214734Srpauloint get_netif_info(const char *net_if, unsigned *ip_addr, char **ip_addr_text, 162214734Srpaulo u8 mac[ETH_ALEN]); 163189251Ssam 164189251Ssam/* wps_upnp_ssdp.c */ 165189251Ssamvoid msearchreply_state_machine_stop(struct advertisement_state_machine *a); 166189251Ssamint advertisement_state_machine_start(struct upnp_wps_device_sm *sm); 167209158Srpaulovoid advertisement_state_machine_stop(struct upnp_wps_device_sm *sm, 168209158Srpaulo int send_byebye); 169189251Ssamvoid ssdp_listener_stop(struct upnp_wps_device_sm *sm); 170189251Ssamint ssdp_listener_start(struct upnp_wps_device_sm *sm); 171214734Srpauloint ssdp_listener_open(void); 172214734Srpauloint add_ssdp_network(const char *net_if); 173281806Srpauloint ssdp_open_multicast_sock(u32 ip_addr, const char *forced_ifname); 174189251Ssamint ssdp_open_multicast(struct upnp_wps_device_sm *sm); 175189251Ssam 176189251Ssam/* wps_upnp_web.c */ 177189251Ssamint web_listener_start(struct upnp_wps_device_sm *sm); 178189251Ssamvoid web_listener_stop(struct upnp_wps_device_sm *sm); 179189251Ssam 180189251Ssam/* wps_upnp_event.c */ 181252726Srpauloint event_add(struct subscription *s, const struct wpabuf *data, int probereq); 182189251Ssamvoid event_delete_all(struct subscription *s); 183189251Ssamvoid event_send_all_later(struct upnp_wps_device_sm *sm); 184189251Ssamvoid event_send_stop_all(struct upnp_wps_device_sm *sm); 185189251Ssam 186214734Srpaulo/* wps_upnp_ap.c */ 187214734Srpauloint upnp_er_set_selected_registrar(struct wps_registrar *reg, 188214734Srpaulo struct subscription *s, 189214734Srpaulo const struct wpabuf *msg); 190252726Srpaulovoid upnp_er_remove_notification(struct wps_registrar *reg, 191252726Srpaulo struct subscription *s); 192214734Srpaulo 193189251Ssam#endif /* WPS_UPNP_I_H */ 194