summaryrefslogtreecommitdiff
path: root/thirdparty/miniupnpc/listdevices.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/miniupnpc/listdevices.c')
-rw-r--r--thirdparty/miniupnpc/listdevices.c197
1 files changed, 197 insertions, 0 deletions
diff --git a/thirdparty/miniupnpc/listdevices.c b/thirdparty/miniupnpc/listdevices.c
new file mode 100644
index 0000000000..bd9ba57efc
--- /dev/null
+++ b/thirdparty/miniupnpc/listdevices.c
@@ -0,0 +1,197 @@
+/* $Id: listdevices.c,v 1.6 2015/07/23 20:40:08 nanard Exp $ */
+/* Project : miniupnp
+ * Author : Thomas Bernard
+ * Copyright (c) 2013-2015 Thomas Bernard
+ * This software is subject to the conditions detailed in the
+ * LICENCE file provided in this distribution. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef _WIN32
+#include <winsock2.h>
+#endif /* _WIN32 */
+#include "miniupnpc.h"
+
+struct upnp_dev_list {
+ struct upnp_dev_list * next;
+ char * descURL;
+ struct UPNPDev * * array;
+ size_t count;
+ size_t allocated_count;
+};
+
+#define ADD_DEVICE_COUNT_STEP 16
+
+void add_device(struct upnp_dev_list * * list_head, struct UPNPDev * dev)
+{
+ struct upnp_dev_list * elt;
+ size_t i;
+
+ if(dev == NULL)
+ return;
+ for(elt = *list_head; elt != NULL; elt = elt->next) {
+ if(strcmp(elt->descURL, dev->descURL) == 0) {
+ for(i = 0; i < elt->count; i++) {
+ if (strcmp(elt->array[i]->st, dev->st) == 0 && strcmp(elt->array[i]->usn, dev->usn) == 0) {
+ return; /* already found */
+ }
+ }
+ if(elt->count >= elt->allocated_count) {
+ struct UPNPDev * * tmp;
+ elt->allocated_count += ADD_DEVICE_COUNT_STEP;
+ tmp = realloc(elt->array, elt->allocated_count * sizeof(struct UPNPDev *));
+ if(tmp == NULL) {
+ fprintf(stderr, "Failed to realloc(%p, %lu)\n", elt->array, (unsigned long)(elt->allocated_count * sizeof(struct UPNPDev *)));
+ return;
+ }
+ elt->array = tmp;
+ }
+ elt->array[elt->count++] = dev;
+ return;
+ }
+ }
+ elt = malloc(sizeof(struct upnp_dev_list));
+ if(elt == NULL) {
+ fprintf(stderr, "Failed to malloc(%lu)\n", (unsigned long)sizeof(struct upnp_dev_list));
+ return;
+ }
+ elt->next = *list_head;
+ elt->descURL = strdup(dev->descURL);
+ if(elt->descURL == NULL) {
+ fprintf(stderr, "Failed to strdup(%s)\n", dev->descURL);
+ free(elt);
+ return;
+ }
+ elt->allocated_count = ADD_DEVICE_COUNT_STEP;
+ elt->array = malloc(ADD_DEVICE_COUNT_STEP * sizeof(struct UPNPDev *));
+ if(elt->array == NULL) {
+ fprintf(stderr, "Failed to malloc(%lu)\n", (unsigned long)(ADD_DEVICE_COUNT_STEP * sizeof(struct UPNPDev *)));
+ free(elt->descURL);
+ free(elt);
+ return;
+ }
+ elt->array[0] = dev;
+ elt->count = 1;
+ *list_head = elt;
+}
+
+void free_device(struct upnp_dev_list * elt)
+{
+ free(elt->descURL);
+ free(elt->array);
+ free(elt);
+}
+
+int main(int argc, char * * argv)
+{
+ const char * searched_device = NULL;
+ const char * * searched_devices = NULL;
+ const char * multicastif = 0;
+ const char * minissdpdpath = 0;
+ int ipv6 = 0;
+ unsigned char ttl = 2;
+ int error = 0;
+ struct UPNPDev * devlist = 0;
+ struct UPNPDev * dev;
+ struct upnp_dev_list * sorted_list = NULL;
+ struct upnp_dev_list * dev_array;
+ int i;
+
+#ifdef _WIN32
+ WSADATA wsaData;
+ int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
+ if(nResult != NO_ERROR)
+ {
+ fprintf(stderr, "WSAStartup() failed.\n");
+ return -1;
+ }
+#endif
+
+ for(i = 1; i < argc; i++) {
+ if(strcmp(argv[i], "-6") == 0)
+ ipv6 = 1;
+ else if(strcmp(argv[i], "-d") == 0) {
+ if(++i >= argc) {
+ fprintf(stderr, "%s option needs one argument\n", "-d");
+ return 1;
+ }
+ searched_device = argv[i];
+ } else if(strcmp(argv[i], "-t") == 0) {
+ if(++i >= argc) {
+ fprintf(stderr, "%s option needs one argument\n", "-t");
+ return 1;
+ }
+ ttl = (unsigned char)atoi(argv[i]);
+ } else if(strcmp(argv[i], "-l") == 0) {
+ if(++i >= argc) {
+ fprintf(stderr, "-l option needs at least one argument\n");
+ return 1;
+ }
+ searched_devices = (const char * *)(argv + i);
+ break;
+ } else if(strcmp(argv[i], "-m") == 0) {
+ if(++i >= argc) {
+ fprintf(stderr, "-m option needs one argument\n");
+ return 1;
+ }
+ multicastif = argv[i];
+ } else {
+ printf("usage : %s [options] [-l <device1> <device2> ...]\n", argv[0]);
+ printf("options :\n");
+ printf(" -6 : use IPv6\n");
+ printf(" -m address/ifname : network interface to use for multicast\n");
+ printf(" -d <device string> : search only for this type of device\n");
+ printf(" -l <device1> <device2> ... : search only for theses types of device\n");
+ printf(" -t ttl : set multicast TTL. Default value is 2.\n");
+ printf(" -h : this help\n");
+ return 1;
+ }
+ }
+
+ if(searched_device) {
+ printf("searching UPnP device type %s\n", searched_device);
+ devlist = upnpDiscoverDevice(searched_device,
+ 2000, multicastif, minissdpdpath,
+ 0/*localport*/, ipv6, ttl, &error);
+ } else if(searched_devices) {
+ printf("searching UPnP device types :\n");
+ for(i = 0; searched_devices[i]; i++)
+ printf("\t%s\n", searched_devices[i]);
+ devlist = upnpDiscoverDevices(searched_devices,
+ 2000, multicastif, minissdpdpath,
+ 0/*localport*/, ipv6, ttl, &error, 1);
+ } else {
+ printf("searching all UPnP devices\n");
+ devlist = upnpDiscoverAll(2000, multicastif, minissdpdpath,
+ 0/*localport*/, ipv6, ttl, &error);
+ }
+ if(devlist) {
+ for(dev = devlist, i = 1; dev != NULL; dev = dev->pNext, i++) {
+ printf("%3d: %-48s\n", i, dev->st);
+ printf(" %s\n", dev->descURL);
+ printf(" %s\n", dev->usn);
+ add_device(&sorted_list, dev);
+ }
+ putchar('\n');
+ for (dev_array = sorted_list; dev_array != NULL ; dev_array = dev_array->next) {
+ printf("%s :\n", dev_array->descURL);
+ for(i = 0; (unsigned)i < dev_array->count; i++) {
+ printf("%2d: %s\n", i+1, dev_array->array[i]->st);
+ printf(" %s\n", dev_array->array[i]->usn);
+ }
+ putchar('\n');
+ }
+ freeUPNPDevlist(devlist);
+ while(sorted_list != NULL) {
+ dev_array = sorted_list;
+ sorted_list = sorted_list->next;
+ free_device(dev_array);
+ }
+ } else {
+ printf("no device found.\n");
+ }
+
+ return 0;
+}
+