diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-10-14 12:15:09 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-10-14 12:15:09 +0200 |
commit | 9ea79b459edef51e3ccc1ddde07c7b1399bed601 (patch) | |
tree | a688c4d5e81f1a7da2f384af3b9681400f2eb6a1 /src/libsystemd-network/sd-ipv4ll.c | |
parent | ade37eb98c2fedefd0c1645d0cd083c171dba194 (diff) | |
parent | ce6c77ebf12f80c807ad7589a1fb565fabc6a543 (diff) |
Merge pull request #1530 from teg/network-fixes-2
networkd/libsystemd-network: collection of trivial patches v2
Diffstat (limited to 'src/libsystemd-network/sd-ipv4ll.c')
-rw-r--r-- | src/libsystemd-network/sd-ipv4ll.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c index dd427ddd78..57bd337a9a 100644 --- a/src/libsystemd-network/sd-ipv4ll.c +++ b/src/libsystemd-network/sd-ipv4ll.c @@ -25,6 +25,7 @@ #include <arpa/inet.h> #include "event-util.h" +#include "in-addr-util.h" #include "list.h" #include "random-util.h" #include "refcnt.h" @@ -232,6 +233,39 @@ bool sd_ipv4ll_is_running(sd_ipv4ll *ll) { return sd_ipv4acd_is_running(ll->acd); } +static bool ipv4ll_address_is_valid(const struct in_addr *address) { + uint32_t addr; + + assert(address); + + if (!in_addr_is_link_local(AF_INET, (const union in_addr_union *) address)) + return false; + + addr = be32toh(address->s_addr); + + if ((addr & 0x0000FF00) == 0x0000 || + (addr & 0x0000FF00) == 0xFF00) + return false; + + return true; +} + +int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address) { + int r; + + assert_return(ll, -EINVAL); + assert_return(address, -EINVAL); + assert_return(ipv4ll_address_is_valid(address), -EINVAL); + + r = sd_ipv4acd_set_address(ll->acd, address); + if (r < 0) + return r; + + ll->address = address->s_addr; + + return 0; +} + static int ipv4ll_pick_address(sd_ipv4ll *ll) { struct in_addr in_addr; be32_t addr; @@ -247,18 +281,15 @@ static int ipv4ll_pick_address(sd_ipv4ll *ll) { return r; addr = htonl((random & 0x0000FFFF) | IPV4LL_NETWORK); } while (addr == ll->address || - (ntohl(addr) & IPV4LL_NETMASK) != IPV4LL_NETWORK || (ntohl(addr) & 0x0000FF00) == 0x0000 || (ntohl(addr) & 0x0000FF00) == 0xFF00); in_addr.s_addr = addr; - r = sd_ipv4acd_set_address(ll->acd, &in_addr); + r = sd_ipv4ll_set_address(ll, &in_addr); if (r < 0) return r; - ll->address = addr; - return 0; } |