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 v3 23/27] network: Add function for delayed dhcp start (Christian Spielberger) 2. [PATCH v3 06/27] inet: Add function connman_inet_is_ifup() (Christian Spielberger) 3. [PATCH v3 17/27] acd: Add callback registration (Christian Spielberger) 4. [PATCH v3 03/27] shared: Add low-level ARP functions (Christian Spielberger) ---------------------------------------------------------------------- Message: 1 Date: Tue, 15 May 2018 12:35: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 v3 23/27] network: Add function for delayed dhcp start Message-ID: <1526380534-23540-24-git-send-email-christian.spielber...@gmail.com> In case of an address conflict for a DHCP lease we have to send a DHCP DECLINE and then try DHCP process a second time after a delay of 10 seconds. If second DHCP lease also has a conflict the fallback is IPv4LL. --- include/network.h | 2 ++ src/network.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/include/network.h b/include/network.h index ee5d2f6..8f87d7c 100644 --- a/include/network.h +++ b/include/network.h @@ -102,6 +102,8 @@ void connman_network_set_error(struct connman_network *network, int connman_network_set_connected(struct connman_network *network, bool connected); bool connman_network_get_connected(struct connman_network *network); +void connman_network_set_connected_dhcp_later(struct connman_network *network, + uint32_t sec); bool connman_network_get_associating(struct connman_network *network); diff --git a/src/network.c b/src/network.c index ddcad65..af23c65 100644 --- a/src/network.c +++ b/src/network.c @@ -71,6 +71,7 @@ struct connman_network { int router_solicit_refresh_count; struct acd_host *acd_host; guint ipv4ll_timeout; + guint dhcp_timeout; struct connman_network_driver *driver; void *driver_data; @@ -493,6 +494,14 @@ err: return err; } +static void remove_dhcp_timeout(struct connman_network *network) +{ + if (network->dhcp_timeout > 0) { + g_source_remove(network->dhcp_timeout); + network->dhcp_timeout = 0; + } +} + static int set_connected_dhcp(struct connman_network *network) { struct connman_service *service; @@ -500,6 +509,7 @@ static int set_connected_dhcp(struct connman_network *network) int err; DBG("network %p", network); + remove_dhcp_timeout(network); service = connman_service_lookup_from_network(network); ipconfig_ipv4 = __connman_service_get_ip4config(service); @@ -515,6 +525,44 @@ static int set_connected_dhcp(struct connman_network *network) return 0; } +static gboolean set_connected_dhcp_timout(gpointer data) +{ + struct connman_network *network = data; + struct connman_service *service; + struct connman_ipconfig *ipconfig; + enum connman_ipconfig_method method; + + network->dhcp_timeout = 0; + + service = connman_service_lookup_from_network(network); + if (!service) + return FALSE; + + ipconfig = __connman_service_get_ip4config(service); + if (!ipconfig) + return FALSE; + + /* Method is still DHCP? */ + method = __connman_ipconfig_get_method(ipconfig); + if (method == CONNMAN_IPCONFIG_METHOD_DHCP) + set_connected_dhcp(network); + + return FALSE; +} + +void connman_network_set_connected_dhcp_later(struct connman_network *network, + uint32_t sec) +{ + remove_dhcp_timeout(network); + + network->dhcp_timeout = + g_timeout_add_seconds_full(G_PRIORITY_HIGH, + sec, + set_connected_dhcp_timout, + network, + NULL); +} + static int manual_ipv6_set(struct connman_network *network, struct connman_ipconfig *ipconfig_ipv6) { @@ -916,6 +964,7 @@ static void set_disconnected(struct connman_network *network) __connman_service_notify_ipv4_configuration(service); /* fall through */ case CONNMAN_IPCONFIG_METHOD_DHCP: + remove_dhcp_timeout(network); __connman_dhcp_stop(ipconfig_ipv4); break; } @@ -1205,6 +1254,8 @@ struct connman_network *connman_network_create(const char *identifier, network_list = g_slist_prepend(network_list, network); + network->dhcp_timeout = 0; + DBG("network %p identifier %s type %s", network, identifier, type2string(type)); return network; @@ -1796,6 +1847,7 @@ int __connman_network_clear_ipconfig(struct connman_network *network, __connman_ipconfig_address_remove(ipconfig); break; case CONNMAN_IPCONFIG_METHOD_DHCP: + remove_dhcp_timeout(network); __connman_dhcp_stop(ipconfig_ipv4); break; } -- 2.7.4 ------------------------------ Message: 2 Date: Tue, 15 May 2018 12:35:13 +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 v3 06/27] inet: Add function connman_inet_is_ifup() Message-ID: <1526380534-23540-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 7ed493b..0992ed4 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: Tue, 15 May 2018 12:35:24 +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 v3 17/27] acd: Add callback registration Message-ID: <1526380534-23540-18-git-send-email-christian.spielber...@gmail.com> Adds function acd_host_register_event for registration of higher level address conflict callback functions. --- include/acd.h | 12 ++++++++++++ src/acd.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/include/acd.h b/include/acd.h index ce7bc9f..34e2539 100644 --- a/include/acd.h +++ b/include/acd.h @@ -41,6 +41,18 @@ void acd_host_stop(struct acd_host *acd); typedef void (*acd_host_cb_t) (struct acd_host *acd, gpointer user_data); +enum acd_host_event { + ACD_HOST_EVENT_IPV4_AVAILABLE, + ACD_HOST_EVENT_IPV4_LOST, + ACD_HOST_EVENT_IPV4_CONFLICT, + ACD_HOST_EVENT_IPV4_MAXCONFLICT, +}; + +void acd_host_register_event(struct acd_host *acd, + enum acd_host_event event, + acd_host_cb_t func, + gpointer user_data); + #ifdef __cplusplus } #endif diff --git a/src/acd.c b/src/acd.c index 6f2a7ab..7f945c7 100644 --- a/src/acd.c +++ b/src/acd.c @@ -464,3 +464,32 @@ static gboolean acd_defend_timeout(gpointer acd_data) return FALSE; } + +void acd_host_register_event(struct acd_host *acd, + enum acd_host_event event, + acd_host_cb_t func, + gpointer user_data) +{ + switch (event) { + case ACD_HOST_EVENT_IPV4_AVAILABLE: + acd->ipv4_available_cb = func; + acd->ipv4_available_data = user_data; + break; + case ACD_HOST_EVENT_IPV4_LOST: + acd->ipv4_lost_cb = func; + acd->ipv4_lost_data = user_data; + break; + case ACD_HOST_EVENT_IPV4_CONFLICT: + acd->ipv4_conflict_cb = func; + acd->ipv4_conflict_data = user_data; + break; + case ACD_HOST_EVENT_IPV4_MAXCONFLICT: + acd->ipv4_max_conflicts_cb = func; + acd->ipv4_max_conflicts_data = user_data; + break; + default: + connman_warn("%s unknown event %d.", __FUNCTION__, event); + break; + } +} + -- 2.7.4 ------------------------------ Message: 4 Date: Tue, 15 May 2018 12:35:10 +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 v3 03/27] shared: Add low-level ARP functions Message-ID: <1526380534-23540-4-git-send-email-christian.spielber...@gmail.com> We took the local functions for sending ARP packets in gdhcp and put them into new source files src/shared/arp.[h|c]. This will be helpful for ACD (Address Conflict Detection). --- Makefile.am | 7 ++-- gdhcp/client.c | 7 ++-- gdhcp/ipv4ll.c | 72 ------------------------------------- gdhcp/ipv4ll.h | 17 +-------- src/shared/arp.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/shared/arp.h | 42 ++++++++++++++++++++++ 6 files changed, 159 insertions(+), 94 deletions(-) create mode 100644 src/shared/arp.c create mode 100644 src/shared/arp.h diff --git a/Makefile.am b/Makefile.am index dcd803b..e994ab9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -54,7 +54,8 @@ backtrace_sources = src/backtrace.c endif shared_sources = src/shared/util.h src/shared/util.c \ - src/shared/netlink.h src/shared/netlink.c + src/shared/netlink.h src/shared/netlink.c \ + src/shared/arp.h src/shared/arp.c if DATAFILES @@ -356,11 +357,11 @@ tools_wpad_test_LDADD = @GLIB_LIBS@ -lresolv tools_stats_tool_LDADD = @GLIB_LIBS@ tools_dhcp_test_SOURCES = $(backtrace_sources) src/log.c \ - src/util.c $(gdhcp_sources) tools/dhcp-test.c + src/util.c $(gdhcp_sources) tools/dhcp-test.c src/shared/arp.c tools_dhcp_test_LDADD = @GLIB_LIBS@ -ldl tools_dhcp_server_test_SOURCES = $(backtrace_sources) src/log.c src/util.c \ - $(gdhcp_sources) tools/dhcp-server-test.c + $(gdhcp_sources) tools/dhcp-server-test.c src/shared/arp.c tools_dhcp_server_test_LDADD = @GLIB_LIBS@ -ldl tools_dbus_test_SOURCES = tools/dbus-test.c diff --git a/gdhcp/client.c b/gdhcp/client.c index 5f42e39..ac29814 100644 --- a/gdhcp/client.c +++ b/gdhcp/client.c @@ -44,6 +44,7 @@ #include <glib.h> #include "../src/connman.h" +#include "../src/shared/arp.h" #include "gdhcp.h" #include "common.h" #include "ipv4ll.h" @@ -552,7 +553,7 @@ static gboolean send_probe_packet(gpointer dhcp_data) dhcp_client->state = IPV4LL_PROBE; switch_listening_mode(dhcp_client, L_ARP); } - ipv4ll_send_arp_packet(dhcp_client->mac_address, 0, + arp_send_packet(dhcp_client->mac_address, 0, dhcp_client->requested_ip, dhcp_client->ifindex); if (dhcp_client->retry_times < PROBE_NUM) { @@ -581,7 +582,7 @@ static gboolean send_announce_packet(gpointer dhcp_data) debug(dhcp_client, "sending IPV4LL announce request"); - ipv4ll_send_arp_packet(dhcp_client->mac_address, + arp_send_packet(dhcp_client->mac_address, dhcp_client->requested_ip, dhcp_client->requested_ip, dhcp_client->ifindex); @@ -1568,7 +1569,7 @@ static int switch_listening_mode(GDHCPClient *dhcp_client, dhcp_client->interface, AF_INET); } else if (listen_mode == L_ARP) - listener_sockfd = ipv4ll_arp_socket(dhcp_client->ifindex); + listener_sockfd = arp_socket(dhcp_client->ifindex); else return -EIO; diff --git a/gdhcp/ipv4ll.c b/gdhcp/ipv4ll.c index 2ee58f7..be96f75 100644 --- a/gdhcp/ipv4ll.c +++ b/gdhcp/ipv4ll.c @@ -54,75 +54,3 @@ uint32_t ipv4ll_random_ip(void) return ((LINKLOCAL_ADDR + 0x0100) + tmp); } -int ipv4ll_send_arp_packet(uint8_t* source_eth, uint32_t source_ip, - uint32_t target_ip, int ifindex) -{ - struct sockaddr_ll dest; - struct ether_arp p; - uint32_t ip_source; - uint32_t ip_target; - int fd, n; - - fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (fd < 0) - return -errno; - - memset(&dest, 0, sizeof(dest)); - memset(&p, 0, sizeof(p)); - - dest.sll_family = AF_PACKET; - dest.sll_protocol = htons(ETH_P_ARP); - dest.sll_ifindex = ifindex; - dest.sll_halen = ETH_ALEN; - memset(dest.sll_addr, 0xFF, ETH_ALEN); - if (bind(fd, (struct sockaddr *)&dest, sizeof(dest)) < 0) { - int err = errno; - close(fd); - return -err; - } - - ip_source = htonl(source_ip); - ip_target = htonl(target_ip); - p.arp_hrd = htons(ARPHRD_ETHER); - p.arp_pro = htons(ETHERTYPE_IP); - p.arp_hln = ETH_ALEN; - p.arp_pln = 4; - p.arp_op = htons(ARPOP_REQUEST); - - memcpy(&p.arp_sha, source_eth, ETH_ALEN); - memcpy(&p.arp_spa, &ip_source, sizeof(p.arp_spa)); - memcpy(&p.arp_tpa, &ip_target, sizeof(p.arp_tpa)); - - n = sendto(fd, &p, sizeof(p), 0, - (struct sockaddr*) &dest, sizeof(dest)); - if (n < 0) - n = -errno; - - close(fd); - - return n; -} - -int ipv4ll_arp_socket(int ifindex) -{ - int fd; - struct sockaddr_ll sock; - - fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (fd < 0) - return fd; - - memset(&sock, 0, sizeof(sock)); - - sock.sll_family = AF_PACKET; - sock.sll_protocol = htons(ETH_P_ARP); - sock.sll_ifindex = ifindex; - - if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) != 0) { - int err = errno; - close(fd); - return -err; - } - - return fd; -} diff --git a/gdhcp/ipv4ll.h b/gdhcp/ipv4ll.h index bf8c363..315ca3d 100644 --- a/gdhcp/ipv4ll.h +++ b/gdhcp/ipv4ll.h @@ -22,7 +22,7 @@ #ifndef __G_IPV4LL_H #define __G_IPV4LL_H -#include <glib.h> +#include <stdint.h> #ifdef __cplusplus extern "C" { @@ -31,22 +31,7 @@ extern "C" { /* 169.254.0.0 */ #define LINKLOCAL_ADDR 0xa9fe0000 -/* See RFC 3927 */ -#define PROBE_WAIT 1 -#define PROBE_NUM 3 -#define PROBE_MIN 1 -#define PROBE_MAX 2 -#define ANNOUNCE_WAIT 2 -#define ANNOUNCE_NUM 2 -#define ANNOUNCE_INTERVAL 2 -#define MAX_CONFLICTS 10 -#define RATE_LIMIT_INTERVAL 60 -#define DEFEND_INTERVAL 10 - uint32_t ipv4ll_random_ip(void); -int ipv4ll_send_arp_packet(uint8_t* source_eth, uint32_t source_ip, - uint32_t target_ip, int ifindex); -int ipv4ll_arp_socket(int ifindex); #ifdef __cplusplus } diff --git a/src/shared/arp.c b/src/shared/arp.c new file mode 100644 index 0000000..02b5003 --- /dev/null +++ b/src/shared/arp.c @@ -0,0 +1,108 @@ +/* + * + * Connection Manager + * + * based on IPv4 Local Link library with GLib integration, + * Copyright (C) 2009-2010 Aldebaran Robotics. All rights reserved. + * + * Copyright (C) 2018 Commend International. 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. + * + */ +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> + +#include <sys/time.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <netpacket/packet.h> +#include <net/ethernet.h> +#include <netinet/if_ether.h> +#include <net/if_arp.h> + +#include <arpa/inet.h> + +#include "src/shared/arp.h" + +int arp_send_packet(uint8_t* source_eth, uint32_t source_ip, + uint32_t target_ip, int ifindex) +{ + struct sockaddr_ll dest; + struct ether_arp p; + uint32_t ip_source; + uint32_t ip_target; + int fd, n; + + fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (fd < 0) + return -errno; + + memset(&dest, 0, sizeof(dest)); + memset(&p, 0, sizeof(p)); + + dest.sll_family = AF_PACKET; + dest.sll_protocol = htons(ETH_P_ARP); + dest.sll_ifindex = ifindex; + dest.sll_halen = ETH_ALEN; + memset(dest.sll_addr, 0xFF, ETH_ALEN); + if (bind(fd, (struct sockaddr *)&dest, sizeof(dest)) < 0) { + int err = errno; + close(fd); + return -err; + } + + ip_source = htonl(source_ip); + ip_target = htonl(target_ip); + p.arp_hrd = htons(ARPHRD_ETHER); + p.arp_pro = htons(ETHERTYPE_IP); + p.arp_hln = ETH_ALEN; + p.arp_pln = 4; + p.arp_op = htons(ARPOP_REQUEST); + + memcpy(&p.arp_sha, source_eth, ETH_ALEN); + memcpy(&p.arp_spa, &ip_source, sizeof(p.arp_spa)); + memcpy(&p.arp_tpa, &ip_target, sizeof(p.arp_tpa)); + + n = sendto(fd, &p, sizeof(p), 0, + (struct sockaddr*) &dest, sizeof(dest)); + if (n < 0) + n = -errno; + + close(fd); + + return n; +} + +int arp_socket(int ifindex) +{ + int fd; + struct sockaddr_ll sock; + + fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (fd < 0) + return fd; + + memset(&sock, 0, sizeof(sock)); + + sock.sll_family = AF_PACKET; + sock.sll_protocol = htons(ETH_P_ARP); + sock.sll_ifindex = ifindex; + + if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) != 0) { + int err = errno; + close(fd); + return -err; + } + + return fd; +} diff --git a/src/shared/arp.h b/src/shared/arp.h new file mode 100644 index 0000000..e0d26e7 --- /dev/null +++ b/src/shared/arp.h @@ -0,0 +1,42 @@ +/* + * + * Connection Manager + * + * based on IPv4 Local Link library with GLib integration, + * Copyright (C) 2009-2010 Aldebaran Robotics. All rights reserved. + * + * Copyright (C) 2018 Commend International. 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. + * + */ + +#ifndef SHARED_ARP_H +#define SHARED_ARP_H + +#include <stdint.h> + +/* IPv4 Link-Local (RFC 3927), IPv4 Address Conflict Detection (RFC 5227) */ +#define PROBE_WAIT 1 +#define PROBE_NUM 3 +#define PROBE_MIN 1 +#define PROBE_MAX 2 +#define ANNOUNCE_WAIT 2 +#define ANNOUNCE_NUM 2 +#define ANNOUNCE_INTERVAL 2 +#define MAX_CONFLICTS 10 +#define RATE_LIMIT_INTERVAL 60 +#define DEFEND_INTERVAL 10 + +int arp_send_packet(uint8_t* source_eth, uint32_t source_ip, + uint32_t target_ip, int ifindex); +int arp_socket(int ifindex); + +#endif -- 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 31, Issue 11 ***************************************