]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add common ctrl_iface files
authorJanusz Dziedzic <janusz.dziedzic@tieto.com>
Fri, 4 Mar 2016 09:20:20 +0000 (10:20 +0100)
committerJouni Malinen <j@w1.fi>
Sat, 5 Mar 2016 15:15:05 +0000 (17:15 +0200)
This is preparation for sharing a single implementation for ctrl_iface
functionality in wpa_supplicant and hostapd.

Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
src/common/ctrl_iface_common.c [new file with mode: 0644]
src/common/ctrl_iface_common.h [new file with mode: 0644]

diff --git a/src/common/ctrl_iface_common.c b/src/common/ctrl_iface_common.c
new file mode 100644 (file)
index 0000000..d08b4a5
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Common hostapd/wpa_supplicant ctrl iface code.
+ * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2015, Qualcomm Atheros, Inc.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "utils/includes.h"
+#include <netdb.h>
+#include <sys/un.h>
+
+#include "utils/common.h"
+#include "ctrl_iface_common.h"
+
+static int sockaddr_compare(struct sockaddr_storage *a, socklen_t a_len,
+                           struct sockaddr_storage *b, socklen_t b_len)
+{
+       struct sockaddr_in *in_a, *in_b;
+       struct sockaddr_in6 *in6_a, *in6_b;
+       struct sockaddr_un *u_a, *u_b;
+
+       if (a->ss_family != b->ss_family)
+               return 1;
+
+       switch (a->ss_family) {
+       case AF_INET:
+               in_a = (struct sockaddr_in *) a;
+               in_b = (struct sockaddr_in *) b;
+
+               if (in_a->sin_port != in_b->sin_port)
+                       return 1;
+               if (in_a->sin_addr.s_addr != in_b->sin_addr.s_addr)
+                       return 1;
+               break;
+       case AF_INET6:
+               in6_a = (struct sockaddr_in6 *) a;
+               in6_b = (struct sockaddr_in6 *) b;
+
+               if (in6_a->sin6_port != in6_b->sin6_port)
+                       return 1;
+               if (os_memcmp(&in6_a->sin6_addr, &in6_b->sin6_addr,
+                             sizeof(in6_a->sin6_addr)) != 0)
+                       return 1;
+               break;
+       case AF_UNIX:
+               u_a = (struct sockaddr_un *) a;
+               u_b = (struct sockaddr_un *) b;
+
+               if (a_len != b_len ||
+                   os_memcmp(u_a->sun_path, u_b->sun_path,
+                             a_len - offsetof(struct sockaddr_un, sun_path))
+                   != 0)
+                       return 1;
+               break;
+       default:
+               return 1;
+       }
+
+       return 0;
+}
+
+
+void sockaddr_print(int level, const char *msg, struct sockaddr_storage *sock,
+                   socklen_t socklen)
+{
+       char host[NI_MAXHOST] = { 0 };
+       char service[NI_MAXSERV] = { 0 };
+       char addr_txt[200];
+
+       switch (sock->ss_family) {
+       case AF_INET:
+       case AF_INET6:
+               getnameinfo((struct sockaddr *) sock, socklen,
+                           host, sizeof(host),
+                           service, sizeof(service),
+                           NI_NUMERICHOST);
+
+               wpa_printf(level, "%s %s:%s", msg, host, service);
+               break;
+       case AF_UNIX:
+               printf_encode(addr_txt, sizeof(addr_txt),
+                             (u8 *) ((struct sockaddr_un *) sock)->sun_path,
+                             socklen - offsetof(struct sockaddr_un, sun_path));
+               wpa_printf(level, "%s %s", msg, addr_txt);
+               break;
+       default:
+               wpa_printf(level, "%s", msg);
+               break;
+       }
+}
+
+
+int ctrl_iface_attach(struct dl_list *ctrl_dst, struct sockaddr_un *from,
+                     socklen_t fromlen)
+{
+       struct wpa_ctrl_dst *dst;
+
+       dst = os_zalloc(sizeof(*dst));
+       if (dst == NULL)
+               return -1;
+       os_memcpy(&dst->addr, from, fromlen);
+       dst->addrlen = fromlen;
+       dst->debug_level = MSG_INFO;
+       dl_list_add(ctrl_dst, &dst->list);
+
+       sockaddr_print(MSG_DEBUG, "CTRL_IFACE monitor attached",
+                      (struct sockaddr_storage *) from, fromlen);
+       return 0;
+}
+
+
+int ctrl_iface_detach(struct dl_list *ctrl_dst, struct sockaddr_un *from,
+                     socklen_t fromlen)
+{
+       struct wpa_ctrl_dst *dst;
+
+       dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
+               if (!sockaddr_compare((struct sockaddr_storage *) from,
+                                     fromlen,
+                                     (struct sockaddr_storage *) &dst->addr,
+                                     dst->addrlen)) {
+                       sockaddr_print(MSG_DEBUG, "CTRL_IFACE monitor detached",
+                                      (struct sockaddr_storage *) from,
+                                      fromlen);
+                       dl_list_del(&dst->list);
+                       os_free(dst);
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
+
+int ctrl_iface_level(struct dl_list *ctrl_dst, struct sockaddr_un *from,
+                    socklen_t fromlen, const char *level)
+{
+       struct wpa_ctrl_dst *dst;
+
+       wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
+
+       dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
+               if (!sockaddr_compare((struct sockaddr_storage *) from,
+                                     fromlen,
+                                     (struct sockaddr_storage *) &dst->addr,
+                                     dst->addrlen)) {
+                       sockaddr_print(MSG_DEBUG,
+                                      "CTRL_IFACE changed monitor level",
+                                      (struct sockaddr_storage *) from,
+                                      fromlen);
+                       dst->debug_level = atoi(level);
+                       return 0;
+               }
+       }
+
+       return -1;
+}
diff --git a/src/common/ctrl_iface_common.h b/src/common/ctrl_iface_common.h
new file mode 100644 (file)
index 0000000..6844093
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Common hostapd/wpa_supplicant ctrl iface code.
+ * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2015, Qualcomm Atheros, Inc.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+#ifndef CONTROL_IFACE_COMMON_H
+#define CONTROL_IFACE_COMMON_H
+
+#include "utils/list.h"
+
+/**
+ * struct wpa_ctrl_dst - Data structure of control interface monitors
+ *
+ * This structure is used to store information about registered control
+ * interface monitors into struct wpa_supplicant.
+ */
+struct wpa_ctrl_dst {
+       struct dl_list list;
+       struct sockaddr_un addr;
+       socklen_t addrlen;
+       int debug_level;
+       int errors;
+};
+
+void sockaddr_print(int level, const char *msg, struct sockaddr_storage *sock,
+                   socklen_t socklen);
+
+int ctrl_iface_attach(struct dl_list *ctrl_dst, struct sockaddr_un *from,
+                      socklen_t fromlen);
+int ctrl_iface_detach(struct dl_list *ctrl_dst, struct sockaddr_un *from,
+                     socklen_t fromlen);
+int ctrl_iface_level(struct dl_list *ctrl_dst, struct sockaddr_un *from,
+                    socklen_t fromlen, const char *level);
+
+#endif /* CONTROL_IFACE_COMMON_H */