1  /*
2   * UPnP for WPS / internal definitions
3   * Copyright (c) 2000-2003 Intel Corporation
4   * Copyright (c) 2006-2007 Sony Corporation
5   * Copyright (c) 2008-2009 Atheros Communications
6   * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
7   *
8   * See wps_upnp.c for more details on licensing and code history.
9   */
10  
11  #ifndef WPS_UPNP_I_H
12  #define WPS_UPNP_I_H
13  
14  #include "utils/list.h"
15  #include "http.h"
16  
17  #define UPNP_MULTICAST_ADDRESS  "239.255.255.250" /* for UPnP multicasting */
18  #define UPNP_MULTICAST_PORT 1900 /* UDP port to monitor for UPnP */
19  
20  /* min subscribe time per UPnP standard */
21  #define UPNP_SUBSCRIBE_SEC_MIN 1800
22  /* subscribe time we use */
23  #define UPNP_SUBSCRIBE_SEC (UPNP_SUBSCRIBE_SEC_MIN + 1)
24  
25  /* "filenames" used in URLs that we service via our "web server": */
26  #define UPNP_WPS_DEVICE_XML_FILE "wps_device.xml"
27  #define UPNP_WPS_SCPD_XML_FILE   "wps_scpd.xml"
28  #define UPNP_WPS_DEVICE_CONTROL_FILE "wps_control"
29  #define UPNP_WPS_DEVICE_EVENT_FILE "wps_event"
30  
31  #define MULTICAST_MAX_READ 1600 /* max bytes we'll read for UPD request */
32  
33  
34  struct upnp_wps_device_sm;
35  struct wps_registrar;
36  
37  
38  enum advertisement_type_enum {
39  	ADVERTISE_UP = 0,
40  	ADVERTISE_DOWN = 1,
41  	MSEARCH_REPLY = 2
42  };
43  
44  /*
45   * Advertisements are broadcast via UDP NOTIFYs, and are also the essence of
46   * the reply to UDP M-SEARCH requests. This struct handles both cases.
47   *
48   * A state machine is needed because a number of variant forms must be sent in
49   * separate packets and spread out in time to avoid congestion.
50   */
51  struct advertisement_state_machine {
52  	struct dl_list list;
53  	enum advertisement_type_enum type;
54  	int state;
55  	int nerrors;
56  	struct sockaddr_in client; /* for M-SEARCH replies */
57  };
58  
59  
60  /*
61   * An address of a subscriber (who may have multiple addresses). We are
62   * supposed to send (via TCP) updates to each subscriber, trying each address
63   * for a subscriber until we find one that seems to work.
64   */
65  struct subscr_addr {
66  	struct dl_list list;
67  	char *domain_and_port; /* domain and port part of url */
68  	char *path; /* "filepath" part of url (from "mem") */
69  	struct sockaddr_in saddr; /* address for doing connect */
70  	unsigned num_failures;
71  };
72  
73  
74  /*
75   * Subscribers to our events are recorded in this struct. This includes a max
76   * of one outgoing connection (sending an "event message") per subscriber. We
77   * also have to age out subscribers unless they renew.
78   */
79  struct subscription {
80  	struct dl_list list;
81  	struct upnp_wps_device_sm *sm; /* parent */
82  	time_t timeout_time; /* when to age out the subscription */
83  	unsigned next_subscriber_sequence; /* number our messages */
84  	/*
85  	 * This uuid identifies the subscription and is randomly generated by
86  	 * us and given to the subscriber when the subscription is accepted;
87  	 * and is then included with each event sent to the subscriber.
88  	 */
89  	u8 uuid[UUID_LEN];
90  	/* Linked list of address alternatives (rotate through on failure) */
91  	struct dl_list addr_list;
92  	struct dl_list event_queue; /* Queued event messages. */
93  	struct wps_event_ *current_event; /* non-NULL if being sent (not in q)
94  					   */
95  	int last_event_failed; /* Whether delivery of last event failed */
96  
97  	/* Information from SetSelectedRegistrar action */
98  	u8 selected_registrar;
99  	u16 dev_password_id;
100  	u16 config_methods;
101  	u8 authorized_macs[WPS_MAX_AUTHORIZED_MACS][ETH_ALEN];
102  	struct wps_registrar *reg;
103  };
104  
105  
106  struct upnp_wps_device_interface {
107  	struct dl_list list;
108  	struct upnp_wps_device_ctx *ctx; /* callback table */
109  	struct wps_context *wps;
110  	void *priv;
111  
112  	struct dl_list peers; /* active UPnP peer sessions */
113  };
114  
115  /*
116   * Our instance data corresponding to the AP device. Note that there may be
117   * multiple wireless interfaces sharing the same UPnP device instance. Each
118   * such interface is stored in the list of struct upnp_wps_device_interface
119   * instances.
120   *
121   * This is known as an opaque struct declaration to users of the WPS UPnP code.
122   */
123  struct upnp_wps_device_sm {
124  	struct dl_list interfaces; /* struct upnp_wps_device_interface */
125  	char *root_dir;
126  	char *desc_url;
127  	int started; /* nonzero if we are active */
128  	u8 mac_addr[ETH_ALEN]; /* mac addr of network i.f. we use */
129  	char *ip_addr_text; /* IP address of network i.f. we use */
130  	unsigned ip_addr; /* IP address of network i.f. we use (host order) */
131  	struct in_addr netmask;
132  	int multicast_sd; /* send multicast messages over this socket */
133  	int ssdp_sd; /* receive discovery UPD packets on socket */
134  	int ssdp_sd_registered; /* nonzero if we must unregister */
135  	unsigned advertise_count; /* how many advertisements done */
136  	struct advertisement_state_machine advertisement;
137  	struct dl_list msearch_replies;
138  	int web_port; /* our port that others get xml files from */
139  	struct http_server *web_srv;
140  	/* Note: subscriptions are kept in expiry order */
141  	struct dl_list subscriptions;
142  	int event_send_all_queued; /* if we are scheduled to send events soon
143  				    */
144  
145  	char *wlanevent; /* the last WLANEvent data */
146  	enum upnp_wps_wlanevent_type wlanevent_type;
147  	os_time_t last_event_sec;
148  	unsigned int num_events_in_sec;
149  };
150  
151  /* wps_upnp.c */
152  void format_date(struct wpabuf *buf);
153  struct subscription * subscription_start(struct upnp_wps_device_sm *sm,
154  					 const char *callback_urls);
155  struct subscription * subscription_renew(struct upnp_wps_device_sm *sm,
156  					 const u8 uuid[UUID_LEN]);
157  void subscription_destroy(struct subscription *s);
158  struct subscription * subscription_find(struct upnp_wps_device_sm *sm,
159  					const u8 uuid[UUID_LEN]);
160  void subscr_addr_delete(struct subscr_addr *a);
161  int get_netif_info(const char *net_if, unsigned *ip_addr, char **ip_addr_text,
162  		   struct in_addr *netmask, u8 mac[ETH_ALEN]);
163  
164  /* wps_upnp_ssdp.c */
165  void msearchreply_state_machine_stop(struct advertisement_state_machine *a);
166  int advertisement_state_machine_start(struct upnp_wps_device_sm *sm);
167  void advertisement_state_machine_stop(struct upnp_wps_device_sm *sm,
168  				      int send_byebye);
169  void ssdp_listener_stop(struct upnp_wps_device_sm *sm);
170  int ssdp_listener_start(struct upnp_wps_device_sm *sm);
171  int ssdp_listener_open(void);
172  int add_ssdp_network(const char *net_if);
173  int ssdp_open_multicast_sock(u32 ip_addr, const char *forced_ifname);
174  int ssdp_open_multicast(struct upnp_wps_device_sm *sm);
175  
176  /* wps_upnp_web.c */
177  int web_listener_start(struct upnp_wps_device_sm *sm);
178  void web_listener_stop(struct upnp_wps_device_sm *sm);
179  
180  /* wps_upnp_event.c */
181  int wps_upnp_event_add(struct subscription *s, const struct wpabuf *data,
182  		       int probereq);
183  void wps_upnp_event_delete_all(struct subscription *s);
184  void wps_upnp_event_send_all_later(struct upnp_wps_device_sm *sm);
185  void wps_upnp_event_send_stop_all(struct upnp_wps_device_sm *sm);
186  
187  /* wps_upnp_ap.c */
188  int upnp_er_set_selected_registrar(struct wps_registrar *reg,
189  				   struct subscription *s,
190  				   const struct wpabuf *msg);
191  void upnp_er_remove_notification(struct wps_registrar *reg,
192  				 struct subscription *s);
193  
194  #endif /* WPS_UPNP_I_H */
195