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 */ 70189251Ssam}; 71189251Ssam 72189251Ssam 73189251Ssam/* 74189251Ssam * Subscribers to our events are recorded in this struct. This includes a max 75189251Ssam * of one outgoing connection (sending an "event message") per subscriber. We 76189251Ssam * also have to age out subscribers unless they renew. 77189251Ssam */ 78189251Ssamstruct subscription { 79214734Srpaulo struct dl_list list; 80189251Ssam struct upnp_wps_device_sm *sm; /* parent */ 81189251Ssam time_t timeout_time; /* when to age out the subscription */ 82189251Ssam unsigned next_subscriber_sequence; /* number our messages */ 83189251Ssam /* 84189251Ssam * This uuid identifies the subscription and is randomly generated by 85189251Ssam * us and given to the subscriber when the subscription is accepted; 86189251Ssam * and is then included with each event sent to the subscriber. 87189251Ssam */ 88189251Ssam u8 uuid[UUID_LEN]; 89189251Ssam /* Linked list of address alternatives (rotate through on failure) */ 90214734Srpaulo struct dl_list addr_list; 91214734Srpaulo struct dl_list event_queue; /* Queued event messages. */ 92189251Ssam struct wps_event_ *current_event; /* non-NULL if being sent (not in q) 93189251Ssam */ 94214734Srpaulo 95214734Srpaulo /* Information from SetSelectedRegistrar action */ 96214734Srpaulo u8 selected_registrar; 97214734Srpaulo u16 dev_password_id; 98214734Srpaulo u16 config_methods; 99214734Srpaulo struct wps_registrar *reg; 100189251Ssam}; 101189251Ssam 102189251Ssam 103189251Ssam/* 104189251Ssam * Our instance data corresponding to one WiFi network interface 105189251Ssam * (multiple might share the same wired network interface!). 106189251Ssam * 107189251Ssam * This is known as an opaque struct declaration to users of the WPS UPnP code. 108189251Ssam */ 109189251Ssamstruct upnp_wps_device_sm { 110189251Ssam struct upnp_wps_device_ctx *ctx; /* callback table */ 111189251Ssam struct wps_context *wps; 112189251Ssam void *priv; 113189251Ssam char *root_dir; 114189251Ssam char *desc_url; 115189251Ssam int started; /* nonzero if we are active */ 116189251Ssam u8 mac_addr[ETH_ALEN]; /* mac addr of network i.f. we use */ 117189251Ssam char *ip_addr_text; /* IP address of network i.f. we use */ 118189251Ssam unsigned ip_addr; /* IP address of network i.f. we use (host order) */ 119189251Ssam int multicast_sd; /* send multicast messages over this socket */ 120189251Ssam int ssdp_sd; /* receive discovery UPD packets on socket */ 121189251Ssam int ssdp_sd_registered; /* nonzero if we must unregister */ 122189251Ssam unsigned advertise_count; /* how many advertisements done */ 123189251Ssam struct advertisement_state_machine advertisement; 124214734Srpaulo struct dl_list msearch_replies; 125189251Ssam int web_port; /* our port that others get xml files from */ 126214734Srpaulo struct http_server *web_srv; 127189251Ssam /* Note: subscriptions are kept in expiry order */ 128214734Srpaulo struct dl_list subscriptions; 129189251Ssam int event_send_all_queued; /* if we are scheduled to send events soon 130189251Ssam */ 131189251Ssam 132189251Ssam char *wlanevent; /* the last WLANEvent data */ 133189251Ssam 134189251Ssam /* FIX: maintain separate structures for each UPnP peer */ 135189251Ssam struct upnp_wps_peer peer; 136189251Ssam}; 137189251Ssam 138189251Ssam/* wps_upnp.c */ 139189251Ssamvoid format_date(struct wpabuf *buf); 140189251Ssamstruct subscription * subscription_start(struct upnp_wps_device_sm *sm, 141209158Srpaulo const char *callback_urls); 142189251Ssamstruct subscription * subscription_renew(struct upnp_wps_device_sm *sm, 143189251Ssam const u8 uuid[UUID_LEN]); 144189251Ssamvoid subscription_destroy(struct subscription *s); 145189251Ssamstruct subscription * subscription_find(struct upnp_wps_device_sm *sm, 146189251Ssam const u8 uuid[UUID_LEN]); 147189251Ssamint send_wpabuf(int fd, struct wpabuf *buf); 148214734Srpauloint get_netif_info(const char *net_if, unsigned *ip_addr, char **ip_addr_text, 149214734Srpaulo u8 mac[ETH_ALEN]); 150189251Ssam 151189251Ssam/* wps_upnp_ssdp.c */ 152189251Ssamvoid msearchreply_state_machine_stop(struct advertisement_state_machine *a); 153189251Ssamint advertisement_state_machine_start(struct upnp_wps_device_sm *sm); 154209158Srpaulovoid advertisement_state_machine_stop(struct upnp_wps_device_sm *sm, 155209158Srpaulo int send_byebye); 156189251Ssamvoid ssdp_listener_stop(struct upnp_wps_device_sm *sm); 157189251Ssamint ssdp_listener_start(struct upnp_wps_device_sm *sm); 158214734Srpauloint ssdp_listener_open(void); 159214734Srpauloint add_ssdp_network(const char *net_if); 160214734Srpauloint ssdp_open_multicast_sock(u32 ip_addr); 161189251Ssamint ssdp_open_multicast(struct upnp_wps_device_sm *sm); 162189251Ssam 163189251Ssam/* wps_upnp_web.c */ 164189251Ssamint web_listener_start(struct upnp_wps_device_sm *sm); 165189251Ssamvoid web_listener_stop(struct upnp_wps_device_sm *sm); 166189251Ssam 167189251Ssam/* wps_upnp_event.c */ 168189251Ssamint event_add(struct subscription *s, const struct wpabuf *data); 169189251Ssamvoid event_delete_all(struct subscription *s); 170189251Ssamvoid event_send_all_later(struct upnp_wps_device_sm *sm); 171189251Ssamvoid event_send_stop_all(struct upnp_wps_device_sm *sm); 172189251Ssam 173214734Srpaulo/* wps_upnp_ap.c */ 174214734Srpauloint upnp_er_set_selected_registrar(struct wps_registrar *reg, 175214734Srpaulo struct subscription *s, 176214734Srpaulo const struct wpabuf *msg); 177214734Srpaulovoid upnp_er_remove_notification(struct subscription *s); 178214734Srpaulo 179189251Ssam#endif /* WPS_UPNP_I_H */ 180