assert(op == BOOTREQUEST || op == BOOTREPLY);
- *opt = (uint8_t *)(message + 1);
-
- if (*optlen < 4)
- return -ENOBUFS;
- *optlen -= 4;
-
message->op = op;
message->htype = ARPHRD_ETHER;
message->hlen = ETHER_ADDR_LEN;
message->xid = htobe32(xid);
+ message->magic = htobe32(DHCP_MAGIC_COOKIE);
- (*opt)[0] = 0x63;
- (*opt)[1] = 0x82;
- (*opt)[2] = 0x53;
- (*opt)[3] = 0x63;
-
- *opt += 4;
+ *opt = (uint8_t *)(message + 1);
err = dhcp_option_append(opt, optlen, DHCP_OPTION_MESSAGE_TYPE, 1,
&type);
/* IP */
- if (len < DHCP_IP_SIZE) {
- log_dhcp_client(client, "ignoring packet: packet (%zu bytes) "
- " smaller than IP header (%u bytes)", len,
- DHCP_IP_SIZE);
+ if (packet->ip.version != IPVERSION) {
+ log_dhcp_client(client, "ignoring packet: not IPv4");
return -EINVAL;
}
return -EINVAL;
}
- if (dhcp_packet_checksum(&packet->ip, hdrlen)) {
- log_dhcp_client(client, "ignoring packet: invalid IP checksum");
- return -EINVAL;
- }
-
/* UDP */
- if (len < DHCP_IP_UDP_SIZE) {
- log_dhcp_client(client, "ignoring packet: packet (%zu bytes) "
- " smaller than IP+UDP header (%u bytes)", len,
- DHCP_IP_UDP_SIZE);
+ if (packet->ip.protocol != IPPROTO_UDP) {
+ log_dhcp_client(client, "ignoring packet: not UDP");
return -EINVAL;
}
return -EINVAL;
}
+ if (be16toh(packet->udp.dest) != DHCP_PORT_CLIENT) {
+ log_dhcp_client(client, "ignoring packet: to port %u, which "
+ "is not the DHCP client port (%u)",
+ be16toh(packet->udp.dest), DHCP_PORT_CLIENT);
+ return -EINVAL;
+ }
+
+ /* checksums - computing these is relatively expensive, so only do it
+ if all the other checks have passed
+ */
+
+ if (dhcp_packet_checksum(&packet->ip, hdrlen)) {
+ log_dhcp_client(client, "ignoring packet: invalid IP checksum");
+ return -EINVAL;
+ }
+
if (checksum && packet->udp.check) {
packet->ip.check = packet->udp.len;
packet->ip.ttl = 0;
}
}
- if (be16toh(packet->udp.dest) != DHCP_PORT_CLIENT) {
- log_dhcp_client(client, "ignoring packet: to port %u, which "
- "is not the DHCP client port (%u)",
- be16toh(packet->udp.dest), DHCP_PORT_CLIENT);
- return -EINVAL;
- }
-
return 0;
}