LCOV - code coverage report
Current view: top level - src/common - ctrl_iface_common.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1475438200 Lines: 43 47 91.5 %
Date: 2016-10-02 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Common hostapd/wpa_supplicant ctrl iface code.
       3             :  * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
       4             :  * Copyright (c) 2015, Qualcomm Atheros, Inc.
       5             :  *
       6             :  * This software may be distributed under the terms of the BSD license.
       7             :  * See README for more details.
       8             :  */
       9             : 
      10             : #include "utils/includes.h"
      11             : #include <netdb.h>
      12             : #include <sys/un.h>
      13             : 
      14             : #include "utils/common.h"
      15             : #include "ctrl_iface_common.h"
      16             : 
      17       15243 : static int sockaddr_compare(struct sockaddr_storage *a, socklen_t a_len,
      18             :                             struct sockaddr_storage *b, socklen_t b_len)
      19             : {
      20       15243 :         if (a->ss_family != b->ss_family)
      21           0 :                 return 1;
      22             : 
      23       15243 :         switch (a->ss_family) {
      24             : #ifdef CONFIG_CTRL_IFACE_UDP
      25             :         case AF_INET:
      26             :         {
      27             :                 struct sockaddr_in *in_a, *in_b;
      28             : 
      29             :                 in_a = (struct sockaddr_in *) a;
      30             :                 in_b = (struct sockaddr_in *) b;
      31             : 
      32             :                 if (in_a->sin_port != in_b->sin_port)
      33             :                         return 1;
      34             :                 if (in_a->sin_addr.s_addr != in_b->sin_addr.s_addr)
      35             :                         return 1;
      36             :                 break;
      37             :         }
      38             :         case AF_INET6:
      39             :         {
      40             :                 struct sockaddr_in6 *in6_a, *in6_b;
      41             : 
      42             :                 in6_a = (struct sockaddr_in6 *) a;
      43             :                 in6_b = (struct sockaddr_in6 *) b;
      44             : 
      45             :                 if (in6_a->sin6_port != in6_b->sin6_port)
      46             :                         return 1;
      47             :                 if (os_memcmp(&in6_a->sin6_addr, &in6_b->sin6_addr,
      48             :                               sizeof(in6_a->sin6_addr)) != 0)
      49             :                         return 1;
      50             :                 break;
      51             :         }
      52             : #endif /* CONFIG_CTRL_IFACE_UDP */
      53             : #ifdef CONFIG_CTRL_IFACE_UNIX
      54             :         case AF_UNIX:
      55             :         {
      56             :                 struct sockaddr_un *u_a, *u_b;
      57             : 
      58       15243 :                 u_a = (struct sockaddr_un *) a;
      59       15243 :                 u_b = (struct sockaddr_un *) b;
      60             : 
      61       30478 :                 if (a_len != b_len ||
      62       15235 :                     os_memcmp(u_a->sun_path, u_b->sun_path,
      63             :                               a_len - offsetof(struct sockaddr_un, sun_path))
      64             :                     != 0)
      65         639 :                         return 1;
      66       14604 :                 break;
      67             :         }
      68             : #endif /* CONFIG_CTRL_IFACE_UNIX */
      69             :         default:
      70           0 :                 return 1;
      71             :         }
      72             : 
      73       14604 :         return 0;
      74             : }
      75             : 
      76             : 
      77      270924 : void sockaddr_print(int level, const char *msg, struct sockaddr_storage *sock,
      78             :                     socklen_t socklen)
      79             : {
      80      270924 :         switch (sock->ss_family) {
      81             : #ifdef CONFIG_CTRL_IFACE_UDP
      82             :         case AF_INET:
      83             :         case AF_INET6:
      84             :         {
      85             :                 char host[NI_MAXHOST] = { 0 };
      86             :                 char service[NI_MAXSERV] = { 0 };
      87             : 
      88             :                 getnameinfo((struct sockaddr *) sock, socklen,
      89             :                             host, sizeof(host),
      90             :                             service, sizeof(service),
      91             :                             NI_NUMERICHOST);
      92             : 
      93             :                 wpa_printf(level, "%s %s:%s", msg, host, service);
      94             :                 break;
      95             :         }
      96             : #endif /* CONFIG_CTRL_IFACE_UDP */
      97             : #ifdef CONFIG_CTRL_IFACE_UNIX
      98             :         case AF_UNIX:
      99             :         {
     100             :                 char addr_txt[200];
     101             : 
     102      541848 :                 printf_encode(addr_txt, sizeof(addr_txt),
     103      270924 :                               (u8 *) ((struct sockaddr_un *) sock)->sun_path,
     104             :                               socklen - offsetof(struct sockaddr_un, sun_path));
     105      270924 :                 wpa_printf(level, "%s %s", msg, addr_txt);
     106      270924 :                 break;
     107             :         }
     108             : #endif /* CONFIG_CTRL_IFACE_UNIX */
     109             :         default:
     110           0 :                 wpa_printf(level, "%s", msg);
     111           0 :                 break;
     112             :         }
     113      270924 : }
     114             : 
     115             : 
     116       14759 : int ctrl_iface_attach(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
     117             :                       socklen_t fromlen)
     118             : {
     119             :         struct wpa_ctrl_dst *dst;
     120             : 
     121       14759 :         dst = os_zalloc(sizeof(*dst));
     122       14759 :         if (dst == NULL)
     123           8 :                 return -1;
     124       14751 :         os_memcpy(&dst->addr, from, fromlen);
     125       14751 :         dst->addrlen = fromlen;
     126       14751 :         dst->debug_level = MSG_INFO;
     127       14751 :         dl_list_add(ctrl_dst, &dst->list);
     128             : 
     129       14751 :         sockaddr_print(MSG_DEBUG, "CTRL_IFACE monitor attached", from, fromlen);
     130       14751 :         return 0;
     131             : }
     132             : 
     133             : 
     134       14614 : int ctrl_iface_detach(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
     135             :                       socklen_t fromlen)
     136             : {
     137             :         struct wpa_ctrl_dst *dst;
     138             : 
     139       15251 :         dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
     140       15239 :                 if (!sockaddr_compare(from, fromlen,
     141             :                                       &dst->addr, dst->addrlen)) {
     142       14602 :                         sockaddr_print(MSG_DEBUG, "CTRL_IFACE monitor detached",
     143             :                                        from, fromlen);
     144       14602 :                         dl_list_del(&dst->list);
     145       14602 :                         os_free(dst);
     146       14602 :                         return 0;
     147             :                 }
     148             :         }
     149             : 
     150          12 :         return -1;
     151             : }
     152             : 
     153             : 
     154           4 : int ctrl_iface_level(struct dl_list *ctrl_dst, struct sockaddr_storage *from,
     155             :                      socklen_t fromlen, const char *level)
     156             : {
     157             :         struct wpa_ctrl_dst *dst;
     158             : 
     159           4 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
     160             : 
     161           6 :         dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
     162           4 :                 if (!sockaddr_compare(from, fromlen,
     163             :                                       &dst->addr, dst->addrlen)) {
     164           2 :                         sockaddr_print(MSG_DEBUG,
     165             :                                        "CTRL_IFACE changed monitor level",
     166             :                                        from, fromlen);
     167           2 :                         dst->debug_level = atoi(level);
     168           2 :                         return 0;
     169             :                 }
     170             :         }
     171             : 
     172           2 :         return -1;
     173             : }

Generated by: LCOV version 1.10