#include "list.h"
#include "mkdir.h"
#include "fileio.h"
+#include "unaligned.h"
+#include "in-addr-util.h"
#include "dhcp-protocol.h"
#include "dhcp-internal.h"
}
static void lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) {
- be32_t val;
-
assert(option);
assert(ret);
if (len == 4) {
- memcpy(&val, option, 4);
- *ret = be32toh(val);
+ *ret = unaligned_read_be32((be32_t*) option);
if (*ret < min)
*ret = min;
}
static void lease_parse_u16(const uint8_t *option, size_t len, uint16_t *ret, uint16_t min) {
- be16_t val;
-
assert(option);
assert(ret);
if (len == 2) {
- memcpy(&val, option, 2);
- *ret = be16toh(val);
+ *ret = unaligned_read_be16((be16_t*) option);
if (*ret < min)
*ret = min;
return lease_parse_in_addrs_aux(option, len, ret, ret_size, 2);
}
-static int class_prefixlen(uint8_t msb_octet, uint8_t *ret) {
- if (msb_octet < 128)
- /* Class A */
- *ret = 8;
- else if (msb_octet < 192)
- /* Class B */
- *ret = 16;
- else if (msb_octet < 224)
- /* Class C */
- *ret = 24;
- else
- /* Class D or E -- no subnet mask */
- return -ERANGE;
-
- return 0;
-}
-
static int lease_parse_routes(const uint8_t *option, size_t len, struct sd_dhcp_route **routes,
size_t *routes_size, size_t *routes_allocated) {
while (len >= 8) {
struct sd_dhcp_route *route = *routes + *routes_size;
+ int r;
- if (class_prefixlen(*option, &route->dst_prefixlen) < 0) {
+ r = in_addr_default_prefixlen((struct in_addr*) option, &route->dst_prefixlen);
+ if (r < 0) {
log_error("Failed to determine destination prefix length from class based IP, ignoring");
continue;
}
if (r < 0)
return r;
- if (!hostname_is_valid(hostname))
+ if (!hostname_is_valid(hostname) || is_localhost(hostname))
break;
free(lease->hostname);
}
int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) {
- uint32_t address;
+ struct in_addr address;
+ struct in_addr mask;
+ int r;
assert(lease);
- assert(lease->address != INADDR_ANY);
- address = be32toh(lease->address);
+ address.s_addr = lease->address;
/* fall back to the default subnet masks based on address class */
+ r = in_addr_default_subnet_mask(&address, &mask);
+ if (r < 0)
+ return r;
- if ((address >> 31) == 0x0)
- /* class A, leading bits: 0 */
- lease->subnet_mask = htobe32(0xff000000);
- else if ((address >> 30) == 0x2)
- /* class B, leading bits 10 */
- lease->subnet_mask = htobe32(0xffff0000);
- else if ((address >> 29) == 0x6)
- /* class C, leading bits 110 */
- lease->subnet_mask = htobe32(0xffffff00);
- else
- /* class D or E, no default mask. give up */
- return -ERANGE;
+ lease->subnet_mask = mask.s_addr;
return 0;
}