Send connman mailing list submissions to
        connman@lists.01.org

To subscribe or unsubscribe via the World Wide Web, visit
        https://lists.01.org/mailman/listinfo/connman
or, via email, send a message with subject or body 'help' to
        connman-requ...@lists.01.org

You can reach the person managing the list at
        connman-ow...@lists.01.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of connman digest..."


Today's Topics:

   1. [PATCH 05/27] shared/arp: Add random_ip() (Christian Spielberger)
   2. [PATCH 06/27] inet: Add function connman_inet_is_ifup()
      (Christian Spielberger)
   3. [PATCH 09/27] acd: add struct acd_host (Christian Spielberger)
   4. [PATCH 10/27] acd: add functions start/stop_listening
      (Christian Spielberger)
   5. [PATCH 08/27] doc: Add documentation for
      AddressConflictDetection (Christian Spielberger)


----------------------------------------------------------------------

Message: 1
Date: Wed, 11 Apr 2018 16:00:25 +0200
From: Christian Spielberger <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org, Christian Spielberger
        <christian.spielber...@gmail.com>
Subject: [PATCH 05/27] shared/arp: Add random_ip()
Message-ID:
        <1523455247-5877-6-git-send-email-christian.spielber...@gmail.com>

Following feature ACD also needs a random IPv4 address as fallback. We move
the function ipv4ll_random_ip() from gdhcp/ipv4ll.h to src/shared/random.h.
The gdhcp/ipv4ll.h is now empty and can be removed.
---
 Makefile.am      |  2 +-
 gdhcp/client.c   |  5 ++---
 gdhcp/ipv4ll.h   | 39 ---------------------------------------
 src/shared/arp.c | 18 ++++++++++++++++++
 src/shared/arp.h |  5 +++++
 5 files changed, 26 insertions(+), 43 deletions(-)
 delete mode 100644 gdhcp/ipv4ll.h

diff --git a/Makefile.am b/Makefile.am
index 23c5171..aa58691 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -33,7 +33,7 @@ gdbus_libgdbus_internal_la_SOURCES = gdbus/gdbus.h \
                                gdbus/object.c gdbus/client.c gdbus/polkit.c
 
 gdhcp_sources = gdhcp/gdhcp.h gdhcp/common.h gdhcp/common.c gdhcp/client.c \
-               gdhcp/server.c gdhcp/ipv4ll.h gdhcp/ipv4ll.c gdhcp/unaligned.h
+               gdhcp/server.c gdhcp/unaligned.h
 
 gweb_sources = gweb/gweb.h gweb/gweb.c gweb/gresolv.h gweb/gresolv.c
 
diff --git a/gdhcp/client.c b/gdhcp/client.c
index e36c4e0..9542eec 100644
--- a/gdhcp/client.c
+++ b/gdhcp/client.c
@@ -47,7 +47,6 @@
 #include "../src/shared/arp.h"
 #include "gdhcp.h"
 #include "common.h"
-#include "ipv4ll.h"
 
 #define DISCOVER_TIMEOUT 5
 #define DISCOVER_RETRIES 6
@@ -544,7 +543,7 @@ static gboolean send_probe_packet(gpointer dhcp_data)
        /* if requested_ip is not valid, pick a new address*/
        if (dhcp_client->requested_ip == 0) {
                debug(dhcp_client, "pick a new random address");
-               dhcp_client->requested_ip = ipv4ll_random_ip();
+               dhcp_client->requested_ip = random_ip();
        }
 
        debug(dhcp_client, "sending IPV4LL probe request");
@@ -1343,7 +1342,7 @@ static void ipv4ll_start(GDHCPClient *dhcp_client)
        dhcp_client->retry_times = 0;
        dhcp_client->requested_ip = 0;
 
-       dhcp_client->requested_ip = ipv4ll_random_ip();
+       dhcp_client->requested_ip = random_ip();
 
        /*first wait a random delay to avoid storm of arp request on boot*/
        timeout = random_delay_ms(PROBE_WAIT);
diff --git a/gdhcp/ipv4ll.h b/gdhcp/ipv4ll.h
deleted file mode 100644
index 315ca3d..0000000
--- a/gdhcp/ipv4ll.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *
- *  IPV4 Local Link library with GLib integration
- *
- *  Copyright (C) 2009-2010  Aldebaran Robotics. All rights reserved.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef __G_IPV4LL_H
-#define __G_IPV4LL_H
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* 169.254.0.0 */
-#define LINKLOCAL_ADDR 0xa9fe0000
-
-uint32_t ipv4ll_random_ip(void);
-
-#ifdef __cplusplus
-}
-#endif
-#endif     /* !IPV4LL_H_ */
diff --git a/src/shared/arp.c b/src/shared/arp.c
index f43cbd1..ac1f944 100644
--- a/src/shared/arp.c
+++ b/src/shared/arp.c
@@ -38,6 +38,7 @@
 #include <arpa/inet.h>
 
 #include "src/shared/arp.h"
+#include "src/shared/random.h"
 
 int send_arp_packet(uint8_t* source_eth, uint32_t source_ip,
                    uint32_t target_ip, int ifindex)
@@ -112,6 +113,23 @@ int arp_socket(int ifindex)
        return fd;
 }
 
+/**
+ * Return a random link local IP (in host byte order)
+ */
+uint32_t random_ip(void)
+{
+       unsigned tmp;
+
+       do {
+               uint64_t rand;
+               get_random(&rand);
+               tmp = rand;
+               tmp = tmp & IN_CLASSB_HOST;
+       } while (tmp > (IN_CLASSB_HOST - 0x0200));
+
+       return (LINKLOCAL_ADDR + 0x0100) + tmp;
+}
+
 void get_interface_mac_address(int index, uint8_t *mac_address)
 {
        struct ifreq ifr;
diff --git a/src/shared/arp.h b/src/shared/arp.h
index 1191827..2db946b 100644
--- a/src/shared/arp.h
+++ b/src/shared/arp.h
@@ -35,10 +35,15 @@
 #define RATE_LIMIT_INTERVAL 60
 #define DEFEND_INTERVAL            10
 
+/* 169.254.0.0 */
+#define LINKLOCAL_ADDR 0xa9fe0000
+
 int send_arp_packet(uint8_t* source_eth, uint32_t source_ip,
                    uint32_t target_ip, int ifindex);
 int arp_socket(int ifindex);
 
+uint32_t random_ip(void);
+
 void get_interface_mac_address(int index, uint8_t *mac_address);
 
 #endif
-- 
2.7.4



------------------------------

Message: 2
Date: Wed, 11 Apr 2018 16:00:26 +0200
From: Christian Spielberger <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org, Christian Spielberger
        <christian.spielber...@gmail.com>
Subject: [PATCH 06/27] inet: Add function connman_inet_is_ifup()
Message-ID:
        <1523455247-5877-7-git-send-email-christian.spielber...@gmail.com>

Add function connman_inet_is_ifup() which checks if an interface is up. It will
be used when initializing ACD.
---
 include/inet.h |  1 +
 src/inet.c     | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/include/inet.h b/include/inet.h
index 6482934..9c1918f 100644
--- a/include/inet.h
+++ b/include/inet.h
@@ -38,6 +38,7 @@ char *connman_inet_ifname(int index);
 
 int connman_inet_ifup(int index);
 int connman_inet_ifdown(int index);
+bool connman_inet_is_ifup(int index);
 
 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress);
 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress);
diff --git a/src/inet.c b/src/inet.c
index dcd1ab2..4c2ebb8 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -330,6 +330,40 @@ done:
        return err;
 }
 
+bool connman_inet_is_ifup(int index)
+{
+       int sk;
+       struct ifreq ifr;
+       bool ret = false;
+
+       sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+       if (sk < 0) {
+               connman_warn("Failed to open socket");
+               return false;
+       }
+
+       memset(&ifr, 0, sizeof(ifr));
+       ifr.ifr_ifindex = index;
+
+       if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
+               connman_warn("Failed to get interface name for interface %d", 
index);
+               goto done;
+       }
+
+       if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
+               connman_warn("Failed to get interface flags for index %d", 
index);
+               goto done;
+       }
+
+       if (ifr.ifr_flags & IFF_UP)
+               ret = true;
+
+done:
+       close(sk);
+
+       return ret;
+}
+
 struct in6_ifreq {
        struct in6_addr ifr6_addr;
        __u32 ifr6_prefixlen;
-- 
2.7.4



------------------------------

Message: 3
Date: Wed, 11 Apr 2018 16:00:29 +0200
From: Christian Spielberger <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org, Christian Spielberger
        <christian.spielber...@gmail.com>
Subject: [PATCH 09/27] acd: add struct acd_host
Message-ID:
        <1523455247-5877-10-git-send-email-christian.spielber...@gmail.com>

Adds an enum for the ACD state machine, the ACD struct, a function for
allocation and initialization of the struct.
---
 include/acd.h |  4 ++++
 src/acd.c     | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+)

diff --git a/include/acd.h b/include/acd.h
index c347d77..08f9ec9 100644
--- a/include/acd.h
+++ b/include/acd.h
@@ -23,6 +23,8 @@
 #ifndef __CONNMAN_ACD_H
 #define __CONNMAN_ACD_H
 
+#include <stdint.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -31,6 +33,8 @@ struct _acd_host;
 
 typedef struct _acd_host acd_host;
 
+acd_host *acdhost_new(int ifindex);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/acd.c b/src/acd.c
index 1653d2f..bbc1558 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -17,3 +17,73 @@
  *
  */
 
+#include <connman/acd.h>
+#include <connman/log.h>
+#include <connman/inet.h>
+#include <glib.h>
+#include "src/shared/arp.h"
+
+typedef enum _acd_state {
+       ACD_PROBE,
+       ACD_ANNOUNCE,
+       ACD_MONITOR,
+       ACD_DEFEND,
+} ACDState;
+
+struct _acd_host {
+       ACDState state;
+       int ifindex;
+       char *interface;
+       uint8_t mac_address[6];
+       uint32_t requested_ip; /* host byte order */
+
+       bool listen_on;
+       int listener_sockfd;
+       unsigned int retry_times;
+       unsigned int conflicts;
+       guint timeout;
+       guint listener_watch;
+};
+
+acd_host *acdhost_new(int ifindex)
+{
+       acd_host *acd;
+
+       if (ifindex < 0) {
+               connman_error("Invalid interface index %d", ifindex);
+               return NULL;
+       }
+
+       acd = g_try_new0(acd_host, 1);
+       if (!acd) {
+               connman_error("Could not allocate ACD data structure");
+               return NULL;
+       }
+
+       acd->interface = connman_inet_ifname(ifindex);
+       if (!acd->interface) {
+               connman_error("Interface with index %d is not available", 
ifindex);
+               goto error;
+       }
+
+       if (!connman_inet_is_ifup(ifindex)) {
+               connman_error("Interface with index %d and name %s is down", 
ifindex,
+                               acd->interface);
+               goto error;
+       }
+
+       get_interface_mac_address(ifindex, acd->mac_address);
+
+       acd->listener_sockfd = -1;
+       acd->listen_on = false;
+       acd->ifindex = ifindex;
+       acd->listener_watch = 0;
+       acd->retry_times = 0;
+
+       return acd;
+
+error:
+       g_free(acd->interface);
+       g_free(acd);
+       return NULL;
+}
-- 
2.7.4



------------------------------

Message: 4
Date: Wed, 11 Apr 2018 16:00:30 +0200
From: Christian Spielberger <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org, Christian Spielberger
        <christian.spielber...@gmail.com>
Subject: [PATCH 10/27] acd: add functions start/stop_listening
Message-ID:
        <1523455247-5877-11-git-send-email-christian.spielber...@gmail.com>

Adds functions for starting and stopping of the ARP listening which is essential
for ACD. Adds also the callback function for processing received ARP packets
which does nothing for the moment.
---
 src/acd.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/src/acd.c b/src/acd.c
index bbc1558..7dcad2e 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -22,6 +22,9 @@
 #include <connman/inet.h>
 #include <glib.h>
 #include "src/shared/arp.h"
+#include <errno.h>
+#include <unistd.h>
+#include <stdarg.h>
 
 typedef enum _acd_state {
        ACD_PROBE,
@@ -45,6 +48,25 @@ struct _acd_host {
        guint listener_watch;
 };
 
+static int start_listening(acd_host *acd);
+static void stop_listening(acd_host *acd);
+static gboolean acd_listener_event(GIOChannel *channel, GIOCondition condition,
+                                                       gpointer acd_data);
+static int acd_recv_arp_packet(acd_host *acd);
+
+static void debug(acd_host *acd, const char *format, ...)
+{
+       char str[256];
+       va_list ap;
+
+       va_start(ap, format);
+
+       if (vsnprintf(str, sizeof(str), format, ap) > 0)
+               connman_info("ACD index %d: %s", acd->ifindex, str);
+
+       va_end(ap);
+}
+
 acd_host *acdhost_new(int ifindex)
 {
        acd_host *acd;
@@ -87,3 +109,69 @@ error:
        g_free(acd);
        return NULL;
 }
+
+static int start_listening(acd_host *acd)
+{
+       GIOChannel *listener_channel;
+       int listener_sockfd;
+
+       if (acd->listen_on)
+               return 0;
+
+       debug(acd, "start listening");
+
+       listener_sockfd = arp_socket(acd->ifindex);
+       if (listener_sockfd < 0)
+               return -EIO;
+
+       listener_channel = g_io_channel_unix_new(listener_sockfd);
+       if (!listener_channel) {
+               /* Failed to create listener channel */
+               close(listener_sockfd);
+               return -EIO;
+       }
+
+       acd->listen_on = true;
+       acd->listener_sockfd = listener_sockfd;
+
+       g_io_channel_set_close_on_unref(listener_channel, TRUE);
+       acd->listener_watch =
+                       g_io_add_watch_full(listener_channel, G_PRIORITY_HIGH,
+                               G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
+                                               acd_listener_event, acd,
+                                                               NULL);
+       g_io_channel_unref(listener_channel);
+
+       return 0;
+}
+
+static void stop_listening(acd_host *acd)
+{
+       if (!acd->listen_on)
+               return;
+
+       if (acd->listener_watch > 0)
+               g_source_remove(acd->listener_watch);
+       acd->listen_on = FALSE;
+       acd->listener_sockfd = -1;
+       acd->listener_watch = 0;
+}
+
+static gboolean acd_listener_event(GIOChannel *channel, GIOCondition condition,
+                                                       gpointer acd_data)
+{
+       acd_host *acd = acd_data;
+
+       if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+               acd->listener_watch = 0;
+               return FALSE;
+       }
+
+       if (!acd->listen_on)
+               return FALSE;
+
+       acd_recv_arp_packet(acd);
+
+       return TRUE;
+}
+
-- 
2.7.4



------------------------------

Message: 5
Date: Wed, 11 Apr 2018 16:00:28 +0200
From: Christian Spielberger <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org,       Peter Meerwald-Stadler <pme...@pmeerw.net>
Subject: [PATCH 08/27] doc: Add documentation for
        AddressConflictDetection
Message-ID:
        <1523455247-5877-9-git-send-email-christian.spielber...@gmail.com>

From: Peter Meerwald-Stadler <pme...@pmeerw.net>

Signed-off-by: Peter Meerwald-Stadler <pme...@pmeerw.net>
---
 doc/connman.conf.5.in | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/doc/connman.conf.5.in b/doc/connman.conf.5.in
index 809a0a4..be31902 100644
--- a/doc/connman.conf.5.in
+++ b/doc/connman.conf.5.in
@@ -161,6 +161,16 @@ Default value is true.
 Automatically connect roaming services. This is not recommended unless you know
 you won't have any billing problem.
 Default value is false.
+.TP
+.BI AddressConflictDetection=true\ \fR|\fB\ false
+Enable or disable the implementation of IPv4 address conflict detection
+according to RFC5227. ConnMan will send probe ARP packets to see if an
+IPv4 address is already in use before assigning the address to an interface.
+If an address conflict occurs for a statically configured address, an IPv4LL
+address will be chosen instead (according to RFC3927). If an address conflict
+occurs for an address offered via DHCP, ConnMan send a DHCP DECLINE once and
+for the second conflict resort to finding an IPv4LL address.
+Default value is false.
 .SH "EXAMPLE"
 The following example configuration disables hostname updates and enables
 ethernet tethering.
-- 
2.7.4



------------------------------

Subject: Digest Footer

_______________________________________________
connman mailing list
connman@lists.01.org
https://lists.01.org/mailman/listinfo/connman


------------------------------

End of connman Digest, Vol 30, Issue 5
**************************************

Reply via email to