コード例 #1
0
static int client_message_init(sd_dhcp_client *client, DHCPMessage *message,
                               uint8_t type, uint16_t secs, uint8_t **opt,
                               size_t *optlen) {
        int r;

        assert(secs);

        r = dhcp_message_init(message, BOOTREQUEST, client->xid, type, opt,
                              optlen);
        if (r < 0)
                return r;

        /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
           refuse to issue an DHCP lease if 'secs' is set to zero */
        message->secs = htobe16(secs);

        memcpy(&message->chaddr, &client->mac_addr, ETH_ALEN);

        if (client->state == DHCP_STATE_RENEWING ||
            client->state == DHCP_STATE_REBINDING)
                message->ciaddr = client->lease->address;

        /* Some DHCP servers will refuse to issue an DHCP lease if the Client
           Identifier option is not set */
        r = dhcp_option_append(opt, optlen, DHCP_OPTION_CLIENT_IDENTIFIER,
                               ETH_ALEN, &client->mac_addr);
        if (r < 0)
                return r;

        if (type == DHCP_DISCOVER || type == DHCP_REQUEST) {
                be16_t max_size;

                r = dhcp_option_append(opt, optlen,
                                       DHCP_OPTION_PARAMETER_REQUEST_LIST,
                                       client->req_opts_size,
                                       client->req_opts);
                if (r < 0)
                        return r;

                /* Some DHCP servers will send bigger DHCP packets than the
                   defined default size unless the Maximum Messge Size option
                   is explicitely set */
                max_size = htobe16(DHCP_IP_UDP_SIZE + DHCP_MESSAGE_SIZE +
                                   DHCP_MIN_OPTIONS_SIZE);
                r = dhcp_option_append(opt, optlen,
                                       DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
                                       2, &max_size);
                if (r < 0)
                        return r;
        }

        return 0;
}
コード例 #2
0
ファイル: test-dhcp-option.c プロジェクト: alan030189/systemd
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);
}
コード例 #3
0
ファイル: sd-dhcp-client.c プロジェクト: kyoiora/systemd
static int client_message_init(sd_dhcp_client *client, DHCPMessage *message,
                               uint8_t type, uint8_t **opt, size_t *optlen) {
        be16_t max_size;
        int r;

        assert(client);
        assert(client->secs);
        assert(message);
        assert(opt);
        assert(optlen);
        assert(type == DHCP_DISCOVER || type == DHCP_REQUEST);

        r = dhcp_message_init(message, BOOTREQUEST, client->xid, type, opt,
                              optlen);
        if (r < 0)
                return r;

        /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
           refuse to issue an DHCP lease if 'secs' is set to zero */
        message->secs = htobe16(client->secs);

        /* RFC2132 section 4.1.1:
           The client MUST include its hardware address in the ’chaddr’ field, if
           necessary for delivery of DHCP reply messages.
         */
        memcpy(&message->chaddr, &client->client_id.mac_addr, ETH_ALEN);

        /* Some DHCP servers will refuse to issue an DHCP lease if the Client
           Identifier option is not set */
        r = dhcp_option_append(opt, optlen, DHCP_OPTION_CLIENT_IDENTIFIER,
                               sizeof(client->client_id), &client->client_id);
        if (r < 0)
                return r;


        /* RFC2131 section 3.5:
           in its initial DHCPDISCOVER or DHCPREQUEST message, a
           client may provide the server with a list of specific
           parameters the client is interested in. If the client
           includes a list of parameters in a DHCPDISCOVER message,
           it MUST include that list in any subsequent DHCPREQUEST
           messages.
         */
        r = dhcp_option_append(opt, optlen,
                               DHCP_OPTION_PARAMETER_REQUEST_LIST,
                               client->req_opts_size,
                               client->req_opts);
        if (r < 0)
                return r;

        /* RFC2131 section 3.5:
           The client SHOULD include the ’maximum DHCP message size’ option to
           let the server know how large the server may make its DHCP messages.

           Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
           than the defined default size unless the Maximum Messge Size option
           is explicitely set
         */
        max_size = htobe16(DHCP_IP_UDP_SIZE + DHCP_MESSAGE_SIZE +
                           DHCP_MIN_OPTIONS_SIZE);
        r = dhcp_option_append(opt, optlen,
                               DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
                               2, &max_size);
        if (r < 0)
                return r;

        return 0;
}
コード例 #4
0
ファイル: sd-dhcp-client.c プロジェクト: c4milo/systemd
static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
                               uint8_t type, size_t *_optlen, size_t *_optoffset) {
        _cleanup_free_ DHCPPacket *packet;
        size_t optlen, optoffset, size;
        be16_t max_size;
        int r;

        assert(client);
        assert(client->secs);
        assert(ret);
        assert(_optlen);
        assert(_optoffset);
        assert(type == DHCP_DISCOVER || type == DHCP_REQUEST);

        optlen = DHCP_MIN_OPTIONS_SIZE;
        size = sizeof(DHCPPacket) + optlen;

        packet = malloc0(size);
        if (!packet)
                return -ENOMEM;

        r = dhcp_message_init(&packet->dhcp, BOOTREQUEST, client->xid, type,
                              optlen, &optoffset);
        if (r < 0)
                return r;

        /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
           refuse to issue an DHCP lease if 'secs' is set to zero */
        packet->dhcp.secs = htobe16(client->secs);

        /* RFC2132 section 4.1
           A client that cannot receive unicast IP datagrams until its protocol
           software has been configured with an IP address SHOULD set the
           BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
           DHCPREQUEST messages that client sends.  The BROADCAST bit will
           provide a hint to the DHCP server and BOOTP relay agent to broadcast
           any messages to the client on the client's subnet. */
        if (client->broadcast)
                packet->dhcp.flags = htobe16(0x8000);

        /* RFC2132 section 4.1.1:
           The client MUST include its hardware address in the ’chaddr’ field, if
           necessary for delivery of DHCP reply messages.
         */
        memcpy(&packet->dhcp.chaddr, &client->client_id.mac_addr, ETH_ALEN);

        /* Some DHCP servers will refuse to issue an DHCP lease if the Client
           Identifier option is not set */
        r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
                               DHCP_OPTION_CLIENT_IDENTIFIER,
                               sizeof(client->client_id), &client->client_id);
        if (r < 0)
                return r;


        /* RFC2131 section 3.5:
           in its initial DHCPDISCOVER or DHCPREQUEST message, a
           client may provide the server with a list of specific
           parameters the client is interested in. If the client
           includes a list of parameters in a DHCPDISCOVER message,
           it MUST include that list in any subsequent DHCPREQUEST
           messages.
         */
        r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
                               DHCP_OPTION_PARAMETER_REQUEST_LIST,
                               client->req_opts_size, client->req_opts);
        if (r < 0)
                return r;

        /* RFC2131 section 3.5:
           The client SHOULD include the ’maximum DHCP message size’ option to
           let the server know how large the server may make its DHCP messages.

           Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
           than the defined default size unless the Maximum Messge Size option
           is explicitely set
         */
        max_size = htobe16(size);
        r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
                               DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
                               2, &max_size);
        if (r < 0)
                return r;

        *_optlen = optlen;
        *_optoffset = optoffset;
        *ret = packet;
        packet = NULL;

        return 0;
}