1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright (C) 2013 Intel Corporation. All rights reserved.
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
27 #include "dhcp-internal.h"
29 int dhcp_option_append(uint8_t options[], size_t size, size_t *offset,
30 uint8_t code, size_t optlen, const void *optval) {
38 if (size - *offset < 1)
41 options[*offset] = code;
46 if (size - *offset < optlen + 2)
51 options[*offset] = code;
52 options[*offset + 1] = optlen;
53 memcpy(&options[*offset + 2], optval, optlen);
55 *offset += optlen + 2;
63 static int parse_options(const uint8_t *buf, size_t buflen, uint8_t *overload,
64 uint8_t *message_type, dhcp_option_cb_t cb,
67 const uint8_t *code = buf;
80 case DHCP_OPTION_MESSAGE_TYPE:
90 *message_type = *(len + 1);
96 case DHCP_OPTION_OVERLOAD:
106 *overload = *(len + 1);
118 if (buflen < (size_t)*len + 2)
123 cb(*code, *len, len + 1, user_data);
137 int dhcp_option_parse(DHCPMessage *message, size_t len,
138 dhcp_option_cb_t cb, void *user_data)
140 uint8_t overload = 0;
141 uint8_t message_type = 0;
147 if (len < sizeof(DHCPMessage))
150 len -= sizeof(DHCPMessage);
152 res = parse_options(message->options, len, &overload, &message_type,
157 if (overload & DHCP_OVERLOAD_FILE) {
158 res = parse_options(message->file, sizeof(message->file),
159 NULL, &message_type, cb, user_data);
164 if (overload & DHCP_OVERLOAD_SNAME) {
165 res = parse_options(message->sname, sizeof(message->sname),
166 NULL, &message_type, cb, user_data);