Beispiel #1
0
static void test_public_api_setters(sd_event *e) {
        struct in_addr address = {};
        unsigned seed = 0;
        sd_ipv4ll *ll;
        struct ether_addr mac_addr = {
                .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};

        if (verbose)
                printf("* %s\n", __FUNCTION__);

        assert_se(sd_ipv4ll_new(&ll) == 0);
        assert_se(ll);

        assert_se(sd_ipv4ll_attach_event(NULL, NULL, 0) == -EINVAL);
        assert_se(sd_ipv4ll_attach_event(ll, e, 0) == 0);
        assert_se(sd_ipv4ll_attach_event(ll, e, 0) == -EBUSY);

        assert_se(sd_ipv4ll_set_callback(NULL, NULL, NULL) == -EINVAL);
        assert_se(sd_ipv4ll_set_callback(ll, NULL, NULL) == 0);

        assert_se(sd_ipv4ll_set_address(ll, &address) == -EINVAL);
        address.s_addr |= htobe32(169U << 24 | 254U << 16);
        assert_se(sd_ipv4ll_set_address(ll, &address) == -EINVAL);
        address.s_addr |= htobe32(0x00FF);
        assert_se(sd_ipv4ll_set_address(ll, &address) == -EINVAL);
        address.s_addr |= htobe32(0xF000);
        assert_se(sd_ipv4ll_set_address(ll, &address) == 0);
        address.s_addr |= htobe32(0x0F00);
        assert_se(sd_ipv4ll_set_address(ll, &address) == -EINVAL);

        assert_se(sd_ipv4ll_set_address_seed(NULL, seed) == -EINVAL);
        assert_se(sd_ipv4ll_set_address_seed(ll, seed) == 0);

        assert_se(sd_ipv4ll_set_mac(NULL, NULL) == -EINVAL);
        assert_se(sd_ipv4ll_set_mac(ll, NULL) == -EINVAL);
        assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);

        assert_se(sd_ipv4ll_set_index(NULL, -1) == -EINVAL);
        assert_se(sd_ipv4ll_set_index(ll, -1) == -EINVAL);
        assert_se(sd_ipv4ll_set_index(ll, -99) == -EINVAL);
        assert_se(sd_ipv4ll_set_index(ll, 1) == 0);
        assert_se(sd_ipv4ll_set_index(ll, 99) == 0);

        assert_se(sd_ipv4ll_ref(ll) == ll);
        assert_se(sd_ipv4ll_unref(ll) == NULL);

        /* Cleanup */
        assert_se(sd_ipv4ll_unref(ll) == NULL);
}
Beispiel #2
0
static int client_run(int ifindex, const char *seed_str, const struct ether_addr *ha, sd_event *e) {
        sd_ipv4ll *ll;

        assert_se(sd_ipv4ll_new(&ll) >= 0);
        assert_se(sd_ipv4ll_attach_event(ll, e, 0) >= 0);

        assert_se(sd_ipv4ll_set_index(ll, ifindex) >= 0);
        assert_se(sd_ipv4ll_set_mac(ll, ha) >= 0);
        assert_se(sd_ipv4ll_set_callback(ll, ll_handler, NULL) >= 0);

        if (seed_str) {
                unsigned seed;

                assert_se(safe_atou(seed_str, &seed) >= 0);

                assert_se(sd_ipv4ll_set_address_seed(ll, seed) >= 0);
        }

        log_info("starting IPv4LL client");

        assert_se(sd_ipv4ll_start(ll) >= 0);

        assert_se(sd_event_loop(e) >= 0);

        assert_se(!sd_ipv4ll_unref(ll));

        return EXIT_SUCCESS;
}
Beispiel #3
0
int ipv4ll_configure(Link *link) {
        uint8_t seed[8];
        int r;

        assert(link);
        assert(link->network);
        assert(link->network->link_local & ADDRESS_FAMILY_IPV4);

        if (!link->ipv4ll) {
                r = sd_ipv4ll_new(&link->ipv4ll);
                if (r < 0)
                        return r;
        }

        if (link->udev_device) {
                r = net_get_unique_predictable_data(link->udev_device, seed);
                if (r >= 0) {
                        assert_cc(sizeof(unsigned) <= 8);

                        r = sd_ipv4ll_set_address_seed(link->ipv4ll, *(unsigned *)seed);
                        if (r < 0)
                                return r;
                }
        }

        r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
        if (r < 0)
                return r;

        r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
        if (r < 0)
                return r;

        r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
        if (r < 0)
                return r;

        r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
        if (r < 0)
                return r;

        return 0;
}
Beispiel #4
0
int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr) {
        int r;

        assert_return(ll, -EINVAL);

        if (!ll->random_data) {
                uint64_t seed;

                /* If no random data is set, generate some from the MAC */
                seed = siphash24(&addr->ether_addr_octet, ETH_ALEN, HASH_KEY.bytes);

                assert_cc(sizeof(unsigned) <= 8);

                r = sd_ipv4ll_set_address_seed(ll, (unsigned) htole64(seed));
                if (r < 0)
                        return r;
        }

        return sd_ipv4acd_set_mac(ll->acd, addr);
}
Beispiel #5
0
int ipv4ll_configure(Link *link) {
        uint8_t seed[8];
        int r;

        assert(link);
        assert(link->network);
        assert(link->network->ipv4ll);

        r = sd_ipv4ll_new(&link->ipv4ll);
        if (r < 0)
                return r;

        if (link->udev_device) {
                r = net_get_unique_predictable_data(link->udev_device, seed);
                if (r >= 0) {
                        r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
                        if (r < 0)
                                return r;
                }
        }

        r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
        if (r < 0)
                return r;

        r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
        if (r < 0)
                return r;

        r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
        if (r < 0)
                return r;

        r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
        if (r < 0)
                return r;

        return 0;
}
Beispiel #6
0
int ipv4ll_configure(Link *link) {
        uint64_t seed;
        int r;

        assert(link);
        assert(link->network);
        assert(link->network->link_local & ADDRESS_FAMILY_IPV4);

        if (!link->ipv4ll) {
                r = sd_ipv4ll_new(&link->ipv4ll);
                if (r < 0)
                        return r;
        }

        if (link->sd_device &&
            net_get_unique_predictable_data(link->sd_device, &seed) >= 0) {
                r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
                if (r < 0)
                        return r;
        }

        r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
        if (r < 0)
                return r;

        r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
        if (r < 0)
                return r;

        r = sd_ipv4ll_set_ifindex(link->ipv4ll, link->ifindex);
        if (r < 0)
                return r;

        r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
        if (r < 0)
                return r;

        return 0;
}
Beispiel #7
0
int sd_ipv4ll_start (sd_ipv4ll *ll) {
    int r;

    assert_return(ll, -EINVAL);
    assert_return(ll->event, -EINVAL);
    assert_return(ll->index > 0, -EINVAL);
    assert_return(IN_SET(ll->state, IPV4LL_STATE_INIT,
                         IPV4LL_STATE_STOPPED), -EBUSY);

    ll->state = IPV4LL_STATE_INIT;

    r = arp_network_bind_raw_socket(ll->index, &ll->link);

    if (r < 0)
        goto out;

    ll->fd = r;
    ll->conflict = 0;
    ll->defend_window = 0;
    ll->claimed_address = 0;

    if (!ll->random_data) {
        uint8_t seed[8];

        /* Fallback to mac */
        siphash24(seed, &ll->mac_addr.ether_addr_octet,
                  ETH_ALEN, HASH_KEY.bytes);

        r = sd_ipv4ll_set_address_seed(ll, seed);
        if (r < 0)
            goto out;
    }

    if (ll->address == 0) {
        r = ipv4ll_pick_address(ll, &ll->address);
        if (r < 0)
            goto out;
    }

    ipv4ll_set_state (ll, IPV4LL_STATE_INIT, 1);

    r = sd_event_add_io(ll->event, &ll->receive_message, ll->fd,
                        EPOLLIN, ipv4ll_receive_message, ll);
    if (r < 0)
        goto out;

    r = sd_event_source_set_priority(ll->receive_message, ll->event_priority);
    if (r < 0)
        goto out;

    r = sd_event_source_set_description(ll->receive_message, "ipv4ll-receive-message");
    if (r < 0)
        goto out;

    r = sd_event_add_time(ll->event,
                          &ll->timer,
                          clock_boottime_or_monotonic(),
                          now(clock_boottime_or_monotonic()), 0,
                          ipv4ll_timer, ll);

    if (r < 0)
        goto out;

    r = sd_event_source_set_priority(ll->timer, ll->event_priority);
    if (r < 0)
        goto out;

    r = sd_event_source_set_description(ll->timer, "ipv4ll-timer");
out:
    if (r < 0)
        ipv4ll_stop(ll, IPV4LL_EVENT_STOP);

    return 0;
}