chiark / gitweb /
build: Add initial build support
[elogind.git] / src / libsystemd-dhcp / dhcp-client.c
1 /***
2   This file is part of systemd.
3
4   Copyright (C) 2013 Intel Corporation. All rights reserved.
5
6   systemd is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as published by
8   the Free Software Foundation; either version 2.1 of the License, or
9   (at your option) any later version.
10
11   systemd is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <stdio.h>
24
25 #include "util.h"
26 #include "list.h"
27
28 #include "dhcp-protocol.h"
29 #include "sd-dhcp-client.h"
30
31 struct sd_dhcp_client {
32         DHCPState state;
33         int index;
34         uint8_t *req_opts;
35         size_t req_opts_size;
36         uint32_t last_addr;
37 };
38
39 static const uint8_t default_req_opts[] = {
40         DHCP_OPTION_SUBNET_MASK,
41         DHCP_OPTION_ROUTER,
42         DHCP_OPTION_HOST_NAME,
43         DHCP_OPTION_DOMAIN_NAME,
44         DHCP_OPTION_DOMAIN_NAME_SERVER,
45         DHCP_OPTION_NTP_SERVER,
46 };
47
48 int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option)
49 {
50         size_t i;
51
52         assert_return(client, -EINVAL);
53         assert_return (client->state == DHCP_STATE_INIT, -EBUSY);
54
55         switch(option) {
56         case DHCP_OPTION_PAD:
57         case DHCP_OPTION_OVERLOAD:
58         case DHCP_OPTION_MESSAGE_TYPE:
59         case DHCP_OPTION_PARAMETER_REQUEST_LIST:
60         case DHCP_OPTION_END:
61                 return -EINVAL;
62
63         default:
64                 break;
65         }
66
67         for (i = 0; i < client->req_opts_size; i++)
68                 if (client->req_opts[i] == option)
69                         return -EEXIST;
70
71         if (!GREEDY_REALLOC(client->req_opts, client->req_opts_size,
72                             client->req_opts_size + 1))
73                 return -ENOMEM;
74
75         client->req_opts[client->req_opts_size - 1] = option;
76
77         return 0;
78 }
79
80 int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
81                                        const struct in_addr *last_addr)
82 {
83         assert_return(client, -EINVAL);
84         assert_return(client->state == DHCP_STATE_INIT, -EBUSY);
85
86         if (last_addr)
87                 client->last_addr = last_addr->s_addr;
88         else
89                 client->last_addr = INADDR_ANY;
90
91         return 0;
92 }
93
94 int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index)
95 {
96         assert_return(client, -EINVAL);
97         assert_return(client->state == DHCP_STATE_INIT, -EBUSY);
98         assert_return(interface_index >= -1, -EINVAL);
99
100         client->index = interface_index;
101
102         return 0;
103 }
104
105 sd_dhcp_client *sd_dhcp_client_new(void)
106 {
107         sd_dhcp_client *client;
108
109         client = new0(sd_dhcp_client, 1);
110         if (!client)
111                 return NULL;
112
113         client->state = DHCP_STATE_INIT;
114         client->index = -1;
115
116         client->req_opts_size = ELEMENTSOF(default_req_opts);
117
118         client->req_opts = memdup(default_req_opts, client->req_opts_size);
119         if (!client->req_opts) {
120                 free(client);
121                 return NULL;
122         }
123
124         return client;
125 }