summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2014-02-23 01:34:05 +0100
committerTom Gundersen <teg@jklm.no>2014-02-23 01:38:49 +0100
commitac4f16ab4d74c94e8a9d1608e05c0faf7d3fae76 (patch)
tree20baf05b1759b57d87fb94446e32a9d6910bfe98
parentd8148cc59d0faa44d26fe27f91eb177334b4e08b (diff)
sd-dhcp: be more detailed about invalid headers
This may be a common problem, so let's make it simpler to debug, at least for now.
-rw-r--r--src/libsystemd-dhcp/dhcp-packet.c34
-rw-r--r--src/libsystemd-dhcp/sd-dhcp-client.c4
2 files changed, 28 insertions, 10 deletions
diff --git a/src/libsystemd-dhcp/dhcp-packet.c b/src/libsystemd-dhcp/dhcp-packet.c
index d606d55a05..4501d27571 100644
--- a/src/libsystemd-dhcp/dhcp-packet.c
+++ b/src/libsystemd-dhcp/dhcp-packet.c
@@ -132,38 +132,58 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, uint8_t op, size_t len) {
assert(op == BOOTREQUEST || op == BOOTREPLY);
- if (len < (DHCP_IP_UDP_SIZE + DHCP_MESSAGE_SIZE))
+ if (len < (DHCP_IP_UDP_SIZE + DHCP_MESSAGE_SIZE)) {
+ log_dhcp_client(client, "ignoring packet: packet too small");
return -EINVAL;
+ }
hdrlen = packet->ip.ihl * 4;
- if (hdrlen < 20 || hdrlen > len || dhcp_checksum(&packet->ip, hdrlen))
+ if (hdrlen < 20 || hdrlen > len) {
+ log_dhcp_client(client, "ignoring packet: header with wrong size");
return -EINVAL;
+ }
- if (hdrlen + be16toh(packet->udp.len) > len)
+ if (dhcp_checksum(&packet->ip, hdrlen)) {
+ log_dhcp_client(client, "ignoring packet: invalid ip checksum");
return -EINVAL;
+ }
+
+ if (hdrlen + be16toh(packet->udp.len) > len) {
+ log_dhcp_client(client, "ignoring packet: packet too small (udp.len=%u)",
+ be16toh(packet->udp.len));
+ return -EINVAL;
+ }
if (packet->udp.check) {
packet->ip.check = packet->udp.len;
packet->ip.ttl = 0;
if (dhcp_checksum(&packet->ip.ttl,
- be16toh(packet->udp.len) + 12))
+ be16toh(packet->udp.len) + 12)) {
+ log_dhcp_client(client, "ignoring packet: invalid udp checksum");
return -EINVAL;
+ }
}
- if (packet->dhcp.op != op)
+ if (packet->dhcp.op != op) {
+ log_dhcp_client(client, "ignoring packet: wrong operation");
return -EINVAL;
+ }
switch (op) {
case BOOTREQUEST:
if (be16toh(packet->udp.source) != DHCP_PORT_CLIENT ||
- be16toh(packet->udp.dest) != DHCP_PORT_SERVER)
+ be16toh(packet->udp.dest) != DHCP_PORT_SERVER) {
+ log_dhcp_client(client, "ignoring packet: wrong ports");
return -EINVAL;
+ }
break;
case BOOTREPLY:
if (be16toh(packet->udp.source) != DHCP_PORT_SERVER ||
- be16toh(packet->udp.dest) != DHCP_PORT_CLIENT)
+ be16toh(packet->udp.dest) != DHCP_PORT_CLIENT) {
+ log_dhcp_client(client, "ignoring packet: wrong ports");
return -EINVAL;
+ }
break;
}
diff --git a/src/libsystemd-dhcp/sd-dhcp-client.c b/src/libsystemd-dhcp/sd-dhcp-client.c
index 3506755304..7f86d92fb5 100644
--- a/src/libsystemd-dhcp/sd-dhcp-client.c
+++ b/src/libsystemd-dhcp/sd-dhcp-client.c
@@ -870,10 +870,8 @@ static int client_receive_message_raw(sd_event_source *s, int fd,
packet = (DHCPPacket *) buf;
r = dhcp_packet_verify_headers(packet, BOOTREPLY, len);
- if (r < 0) {
- log_dhcp_client(client, "ignoring DHCP packet with invalid headers");
+ if (r < 0)
return 0;
- }
len -= DHCP_IP_UDP_SIZE;