1/* $Id: miniupnpc.h,v 1.79 2025/05/25 21:51:11 nanard Exp $ */
2/* vim: tabstop=4 shiftwidth=4 noexpandtab
3 * Project: miniupnp
4 * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
5 * Author: Thomas Bernard
6 * Copyright (c) 2005-2025 Thomas Bernard
7 * This software is subjects to the conditions detailed
8 * in the LICENCE file provided within this distribution */
9#ifndef MINIUPNPC_H_INCLUDED
10#define MINIUPNPC_H_INCLUDED
11
12/*! \file miniupnpc.h
13 * \brief Main C API for MiniUPnPc
14 *
15 * Contains functions to discover devices and check for device validity
16 * or connectivity.
17 *
18 * \mainpage MiniUPnPc API documentation
19 * MiniUPnPc (MiniUPnP client) is a library implementing a UPnP
20 * Internet Gateway Device (IGD) control point.
21 *
22 * It should be used by applications that need to listen to incoming
23 * traffic from the internet which are running on a LAN where a
24 * UPnP IGD is running on the router (or gateway).
25 *
26 * See more documentation on the website http://miniupnp.free.fr
27 * or https://miniupnp.tuxfamily.org/ or GitHub :
28 * https://github.com/miniupnp/miniupnp/tree/master/miniupnpc
29 */
30#include "miniupnpc_declspec.h"
31#include "igd_desc_parse.h"
32#include "upnpdev.h"
33
34/* error codes : */
35/*! \brief value for success */
36#define UPNPDISCOVER_SUCCESS (0)
37/*! \brief value for unknown error */
38#define UPNPDISCOVER_UNKNOWN_ERROR (-1)
39/*! \brief value for a socket error */
40#define UPNPDISCOVER_SOCKET_ERROR (-101)
41/*! \brief value for a memory allocation error */
42#define UPNPDISCOVER_MEMORY_ERROR (-102)
43
44/*! \brief software version */
45#define MINIUPNPC_VERSION "2.3.3"
46/*! \brief C API version */
47#define MINIUPNPC_API_VERSION 21
48
49/*! \brief any (ie system chosen) port */
50#define UPNP_LOCAL_PORT_ANY 0
51/*! \brief Use as an alias for 1900 for backwards compatibility */
52#define UPNP_LOCAL_PORT_SAME 1
53
54#ifdef __cplusplus
55extern "C" {
56#endif
57
58/* Structures definitions : */
59
60/*!
61 * \brief UPnP method argument
62 */
63struct UPNParg {
64 const char * elt; /*!< \brief UPnP argument name */
65 const char * val; /*!< \brief UPnP argument value */
66};
67
68/*!
69 * \brief execute a UPnP method (SOAP action)
70 *
71 * \todo error reporting should be improved
72 *
73 * \param[in] url Control URL for the service
74 * \param[in] service service to use
75 * \param[in] action action to call
76 * \param[in] args action arguments
77 * \param[out] bufsize the size of the returned buffer
78 * \return NULL in case of error or the raw XML response
79 */
80char *
81simpleUPnPcommand(const char * url, const char * service,
82 const char * action, const struct UPNParg * args,
83 int * bufsize);
84
85/*!
86 * \brief Discover UPnP IGD on the network.
87 *
88 * The discovered devices are returned as a chained list.
89 * It is up to the caller to free the list with freeUPNPDevlist().
90 * If available, device list will be obtained from MiniSSDPd.
91 *
92 * \param[in] delay (in millisecond) maximum time for waiting any device
93 * response
94 * \param[in] multicastif If not NULL, used instead of the default
95 * multicast interface for sending SSDP discover packets
96 * \param[in] minissdpdsock Path to minissdpd socket, default is used if
97 * NULL
98 * \param[in] localport Source port to send SSDP packets.
99 * #UPNP_LOCAL_PORT_SAME for 1900 (same as destination port)
100 * #UPNP_LOCAL_PORT_ANY to let system assign a source port
101 * \param[in] ipv6 0 for IPv4, 1 of IPv6
102 * \param[in] ttl should default to 2 as advised by UDA 1.1
103 * \param[out] error error code when NULL is returned
104 * \return NULL or a linked list
105 */
106MINIUPNP_LIBSPEC struct UPNPDev *
107upnpDiscover(int delay, const char * multicastif,
108 const char * minissdpdsock, int localport,
109 int ipv6, unsigned char ttl,
110 int * error);
111
112/*!
113 * \brief Discover all UPnP devices on the network
114 *
115 * search for "ssdp:all"
116 * \param[in] delay (in millisecond) maximum time for waiting any device
117 * response
118 * \param[in] multicastif If not NULL, used instead of the default
119 * multicast interface for sending SSDP discover packets
120 * \param[in] minissdpdsock Path to minissdpd socket, default is used if
121 * NULL
122 * \param[in] localport Source port to send SSDP packets.
123 * #UPNP_LOCAL_PORT_SAME for 1900 (same as destination port)
124 * #UPNP_LOCAL_PORT_ANY to let system assign a source port
125 * \param[in] ipv6 0 for IPv4, 1 of IPv6
126 * \param[in] ttl should default to 2 as advised by UDA 1.1
127 * \param[out] error error code when NULL is returned
128 * \return NULL or a linked list
129 */
130MINIUPNP_LIBSPEC struct UPNPDev *
131upnpDiscoverAll(int delay, const char * multicastif,
132 const char * minissdpdsock, int localport,
133 int ipv6, unsigned char ttl,
134 int * error);
135
136/*!
137 * \brief Discover one type of UPnP devices
138 *
139 * \param[in] device device type to search
140 * \param[in] delay (in millisecond) maximum time for waiting any device
141 * response
142 * \param[in] multicastif If not NULL, used instead of the default
143 * multicast interface for sending SSDP discover packets
144 * \param[in] minissdpdsock Path to minissdpd socket, default is used if
145 * NULL
146 * \param[in] localport Source port to send SSDP packets.
147 * #UPNP_LOCAL_PORT_SAME for 1900 (same as destination port)
148 * #UPNP_LOCAL_PORT_ANY to let system assign a source port
149 * \param[in] ipv6 0 for IPv4, 1 of IPv6
150 * \param[in] ttl should default to 2 as advised by UDA 1.1
151 * \param[out] error error code when NULL is returned
152 * \return NULL or a linked list
153 */
154MINIUPNP_LIBSPEC struct UPNPDev *
155upnpDiscoverDevice(const char * device, int delay, const char * multicastif,
156 const char * minissdpdsock, int localport,
157 int ipv6, unsigned char ttl,
158 int * error);
159
160/*!
161 * \brief Discover one or several type of UPnP devices
162 *
163 * \param[in] deviceTypes array of device types to search (ending with NULL)
164 * \param[in] delay (in millisecond) maximum time for waiting any device
165 * response
166 * \param[in] multicastif If not NULL, used instead of the default
167 * multicast interface for sending SSDP discover packets
168 * \param[in] minissdpdsock Path to minissdpd socket, default is used if
169 * NULL
170 * \param[in] localport Source port to send SSDP packets.
171 * #UPNP_LOCAL_PORT_SAME for 1900 (same as destination port)
172 * #UPNP_LOCAL_PORT_ANY to let system assign a source port
173 * \param[in] ipv6 0 for IPv4, 1 of IPv6
174 * \param[in] ttl should default to 2 as advised by UDA 1.1
175 * \param[out] error error code when NULL is returned
176 * \param[in] searchalltypes 0 to stop with the first type returning results
177 * \return NULL or a linked list
178 */
179MINIUPNP_LIBSPEC struct UPNPDev *
180upnpDiscoverDevices(const char * const deviceTypes[],
181 int delay, const char * multicastif,
182 const char * minissdpdsock, int localport,
183 int ipv6, unsigned char ttl,
184 int * error,
185 int searchalltypes);
186
187/*!
188 * \brief parse root XML description of a UPnP device
189 *
190 * fill the IGDdatas structure.
191 * \param[in] buffer character buffer containing the XML description
192 * \param[in] bufsize size in bytes of the buffer
193 * \param[out] data IGDdatas structure to fill
194 */
195MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data);
196
197/*!
198 * \brief structure used to get fast access to urls
199 */
200struct UPNPUrls {
201 /*! \brief controlURL of the WANIPConnection */
202 char * controlURL;
203 /*! \brief url of the description of the WANIPConnection */
204 char * ipcondescURL;
205 /*! \brief controlURL of the WANCommonInterfaceConfig */
206 char * controlURL_CIF;
207 /*! \brief controlURL of the WANIPv6FirewallControl */
208 char * controlURL_6FC;
209 /*! \brief url of the root description */
210 char * rootdescURL;
211};
212
213/*! \brief NO IGD found */
214#define UPNP_NO_IGD (0)
215/*! \brief valid and connected IGD */
216#define UPNP_CONNECTED_IGD (1)
217/*! \brief valid and connected IGD but with a reserved address
218 * (non routable) */
219#define UPNP_PRIVATEIP_IGD (2)
220/*! \brief valid but not connected IGD */
221#define UPNP_DISCONNECTED_IGD (3)
222/*! \brief UPnP device not recognized as an IGD */
223#define UPNP_UNKNOWN_DEVICE (4)
224
225/*!
226 * \brief look for a valid and possibly connected IGD in the list
227 *
228 * In any non zero return case, the urls and data structures
229 * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
230 * free allocated memory.
231 * \param[in] devlist A device list obtained with upnpDiscover() /
232 * upnpDiscoverAll() / upnpDiscoverDevice() / upnpDiscoverDevices()
233 * \param[out] urls Urls for the IGD found
234 * \param[out] data datas for the IGD found
235 * \param[out] lanaddr buffer to copy the local address of the host to reach the IGD
236 * \param[in] lanaddrlen size of the lanaddr buffer
237 * \param[out] wanaddr buffer to copy the public address of the IGD
238 * \param[in] wanaddrlen size of the wanaddr buffer
239 * \return #UPNP_NO_IGD / #UPNP_CONNECTED_IGD / #UPNP_PRIVATEIP_IGD /
240 * #UPNP_DISCONNECTED_IGD / #UPNP_UNKNOWN_DEVICE
241 */
242MINIUPNP_LIBSPEC int
243UPNP_GetValidIGD(struct UPNPDev * devlist,
244 struct UPNPUrls * urls,
245 struct IGDdatas * data,
246 char * lanaddr, int lanaddrlen,
247 char * wanaddr, int wanaddrlen);
248
249/*!
250 * \brief Get IGD URLs and data for URL
251 *
252 * Used when skipping the discovery process.
253 * \param[in] rootdescurl Root description URL of the device
254 * \param[out] urls Urls for the IGD found
255 * \param[out] data datas for the IGD found
256 * \param[out] lanaddr buffer to copy the local address of the host to reach the IGD
257 * \param[in] lanaddrlen size of the lanaddr buffer
258 * \return 0 Not ok / 1 OK
259 */
260MINIUPNP_LIBSPEC int
261UPNP_GetIGDFromUrl(const char * rootdescurl,
262 struct UPNPUrls * urls,
263 struct IGDdatas * data,
264 char * lanaddr, int lanaddrlen);
265
266/*!
267 * \brief Prepare the URLs for usage
268 *
269 * build absolute URLs from the root description
270 * \param[out] urls URL structure to initialize
271 * \param[in] data datas for the IGD
272 * \param[in] descURL root description URL for the IGD
273 * \param[in] scope_id if not 0, add the scope to the linklocal IPv6
274 * addresses in URLs
275 */
276MINIUPNP_LIBSPEC void
277GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
278 const char * descURL, unsigned int scope_id);
279
280/*!
281 * \brief free the members of a UPNPUrls struct
282 *
283 * All URLs buffers are freed and zeroed
284 * \param[out] urls URL structure to free
285 */
286MINIUPNP_LIBSPEC void
287FreeUPNPUrls(struct UPNPUrls * urls);
288
289/*!
290 * \brief check the current connection status of an IGD
291 *
292 * it uses UPNP_GetStatusInfo()
293 * \param[in] urls IGD URLs
294 * \param[in] data IGD data
295 * \return 1 Connected / 0 Disconnected
296 */
297MINIUPNP_LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data);
298
299
300#ifdef __cplusplus
301}
302#endif
303
304#endif
305
306