예제 #1
0
static void test_invalid_buffer_length(void)
{
        DHCPMessage message;

        assert_se(dhcp_option_parse(&message, 0, NULL, NULL) == -EINVAL);
        assert_se(dhcp_option_parse(&message, sizeof(DHCPMessage), NULL, NULL)
               == -EINVAL);
}
예제 #2
0
static void test_options(struct option_desc *desc)
{
        uint8_t *options = NULL;
        uint8_t *file = NULL;
        uint8_t *sname = NULL;
        int optlen = 0;
        int filelen = 0;
        int snamelen = 0;
        int buflen = 0;
        _cleanup_free_ DHCPMessage *message;
        int res;

        if (desc) {
                file = &desc->file[0];
                filelen = desc->filelen;
                if (!filelen)
                        desc->filepos = -1;

                sname = &desc->sname[0];
                snamelen = desc->snamelen;
                if (!snamelen)
                        desc->snamepos = -1;

                options = &desc->options[0];
                optlen = desc->len;
                desc->pos = 0;
        }
        message = create_message(options, optlen, file, filelen,
                        sname, snamelen);

        buflen = sizeof(DHCPMessage) + 4 + optlen;

        if (!desc) {
                assert_se((res = dhcp_option_parse(message, buflen,
                                                test_options_cb,
                                                NULL)) == -ENOMSG);
        } else if (desc->success) {
                assert_se((res = dhcp_option_parse(message, buflen,
                                                test_options_cb,
                                                desc)) >= 0);
                assert_se(desc->pos == -1 && desc->filepos == -1 &&
                                desc->snamepos == -1);
        } else
                assert_se((res = dhcp_option_parse(message, buflen,
                                                test_options_cb,
                                                desc)) < 0);

        if (verbose)
                printf("DHCP type %s\n", dhcp_type(res));
}
예제 #3
0
static int test_addr_acq_recv_discover(size_t size, DHCPMessage *discover) {
        uint16_t udp_check = 0;
        uint8_t *msg_bytes = (uint8_t *)discover;
        int res;

        res = dhcp_option_parse(discover, size, check_options, NULL, NULL);
        assert_se(res == DHCP_DISCOVER);

        assert_se(msg_bytes[size - 1] == SD_DHCP_OPTION_END);

        xid = discover->xid;

        if (verbose)
                printf("  recv DHCP Discover 0x%08x\n", be32toh(xid));

        memcpy(&test_addr_acq_offer[26], &udp_check, sizeof(udp_check));
        memcpy(&test_addr_acq_offer[32], &xid, sizeof(xid));
        memcpy(&test_addr_acq_offer[56], &mac_addr, ETHER_ADDR_LEN);

        callback_recv = test_addr_acq_recv_request;

        res = write(test_fd[1], test_addr_acq_offer,
                    sizeof(test_addr_acq_offer));
        assert_se(res == sizeof(test_addr_acq_offer));

        if (verbose)
                printf("  sent DHCP Offer\n");

        return 0;
}
예제 #4
0
static int test_addr_acq_recv_request(size_t size, DHCPMessage *request) {
        uint16_t udp_check = 0;
        uint8_t *msg_bytes = (uint8_t *)request;
        int res;

        res = dhcp_option_parse(request, size, check_options, NULL, NULL);
        assert_se(res == DHCP_REQUEST);
        assert_se(xid == request->xid);

        assert_se(msg_bytes[size - 1] == SD_DHCP_OPTION_END);

        if (verbose)
                printf("  recv DHCP Request  0x%08x\n", be32toh(xid));

        memcpy(&test_addr_acq_ack[26], &udp_check, sizeof(udp_check));
        memcpy(&test_addr_acq_ack[32], &xid, sizeof(xid));
        memcpy(&test_addr_acq_ack[56], &mac_addr, ETHER_ADDR_LEN);

        callback_recv = NULL;

        res = write(test_fd[1], test_addr_acq_ack,
                    sizeof(test_addr_acq_ack));
        assert_se(res == sizeof(test_addr_acq_ack));

        if (verbose)
                printf("  send DHCP Ack\n");

        return 0;
};
예제 #5
0
static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
                             size_t len) {
        _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
        int r;

        r = dhcp_lease_new(&lease);
        if (r < 0)
                return r;

        r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease);
        if (r == DHCP_NAK) {
                log_dhcp_client(client, "NAK");
                return DHCP_EVENT_NO_LEASE;
        }

        if (r != DHCP_ACK) {
                log_dhcp_client(client, "receieved message was not an ACK, ignoring");
                return -ENOMSG;
        }

        lease->next_server = ack->siaddr;

        lease->address = ack->yiaddr;

        if (lease->address == INADDR_ANY ||
            lease->server_address == INADDR_ANY ||
            lease->lifetime == 0) {
                log_dhcp_client(client, "receieved lease lacks address, server "
                                "address or lease lifetime, ignoring");
                return -ENOMSG;
        }

        if (lease->subnet_mask == INADDR_ANY) {
                r = dhcp_lease_set_default_subnet_mask(lease);
                if (r < 0) {
                        log_dhcp_client(client, "receieved lease lacks subnet "
                                        "mask, and a fallback one can not be "
                                        "generated, ignoring");
                        return -ENOMSG;
                }
        }

        r = DHCP_EVENT_IP_ACQUIRE;
        if (client->lease) {
                if (client->lease->address != lease->address ||
                    client->lease->subnet_mask != lease->subnet_mask ||
                    client->lease->router != lease->router) {
                        r = DHCP_EVENT_IP_CHANGE;
                }

                client->lease = sd_dhcp_lease_unref(client->lease);
        }

        client->lease = lease;
        lease = NULL;

        log_dhcp_client(client, "ACK");

        return r;
}
예제 #6
0
static int test_discover_message_verify(size_t size, struct DHCPMessage *dhcp) {
        int res;

        res = dhcp_option_parse(dhcp, size, check_options, NULL, NULL);
        assert_se(res == DHCP_DISCOVER);

        if (verbose)
                printf("  recv DHCP Discover 0x%08x\n", be32toh(dhcp->xid));

        return 0;
}
예제 #7
0
static void test_cookie(void)
{
        _cleanup_free_ DHCPMessage *message;
        size_t len = sizeof(DHCPMessage) + 4;
        uint8_t *opt;

        message = malloc0(len);

        opt = (uint8_t *)(message + 1);
        opt[0] = 0xff;

        assert_se(dhcp_option_parse(message, len, NULL, NULL) == -EINVAL);

        opt[0] = 99;
        opt[1] = 130;
        opt[2] = 83;
        opt[3] = 99;

        assert_se(dhcp_option_parse(message, len, NULL, NULL) == -ENOMSG);
}
예제 #8
0
static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
                               size_t len) {
        _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
        int r;

        r = dhcp_lease_new(&lease);
        if (r < 0)
                return r;

        r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease);
        if (r != DHCP_OFFER) {
                log_dhcp_client(client, "receieved message was not an OFFER, ignoring");
                return -ENOMSG;
        }

        lease->next_server = offer->siaddr;

        lease->address = offer->yiaddr;

        if (lease->address == INADDR_ANY ||
            lease->server_address == INADDR_ANY ||
            lease->lifetime == 0) {
                log_dhcp_client(client, "receieved lease lacks address, server "
                                "address or lease lifetime, ignoring");
                return -ENOMSG;
        }

        if (lease->subnet_mask == INADDR_ANY) {
                r = dhcp_lease_set_default_subnet_mask(lease);
                if (r < 0) {
                        log_dhcp_client(client, "receieved lease lacks subnet "
                                        "mask, and a fallback one can not be "
                                        "generated, ignoring");
                        return -ENOMSG;
                }
        }

        sd_dhcp_lease_unref(client->lease);
        client->lease = lease;
        lease = NULL;

        log_dhcp_client(client, "OFFER");

        return 0;
}
예제 #9
0
static void test_message_init(void)
{
        _cleanup_free_ DHCPMessage *message = NULL;
        size_t optlen = 4, optoffset;
        size_t len = sizeof(DHCPMessage) + optlen;
        uint8_t *magic;

        message = malloc0(len);

        assert_se(dhcp_message_init(message, BOOTREQUEST, 0x12345678,
                  DHCP_DISCOVER, optlen, &optoffset) >= 0);

        assert_se(message->xid == htobe32(0x12345678));
        assert_se(message->op == BOOTREQUEST);

        magic = (uint8_t*)&message->magic;

        assert_se(magic[0] == 99);
        assert_se(magic[1] == 130);
        assert_se(magic[2] == 83);
        assert_se(magic[3] == 99);

        assert_se(dhcp_option_parse(message, len, NULL, NULL) >= 0);
}