diff options
author | Tom Gundersen <teg@jklm.no> | 2014-02-23 01:34:05 +0100 |
---|---|---|
committer | Tom Gundersen <teg@jklm.no> | 2014-02-23 01:38:49 +0100 |
commit | ac4f16ab4d74c94e8a9d1608e05c0faf7d3fae76 (patch) | |
tree | 20baf05b1759b57d87fb94446e32a9d6910bfe98 /src/libsystemd-dhcp | |
parent | d8148cc59d0faa44d26fe27f91eb177334b4e08b (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.
Diffstat (limited to 'src/libsystemd-dhcp')
-rw-r--r-- | src/libsystemd-dhcp/dhcp-packet.c | 34 | ||||
-rw-r--r-- | src/libsystemd-dhcp/sd-dhcp-client.c | 4 |
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; |