From 4c6e53f60110acdffece47baaa7568010de40823 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 25 Aug 2010 15:54:35 +0000 Subject: [PATCH] * IPv4 must always set the net_buffer::interface_address on incoming buffers; it didn't do that for broadcasts - this is still not a full solution as it won't work for link layer broadcasts, but this should fix most DHCP problems. * IPv4 multicast doesn't do that yet. * Only send ICMP errors if it hasn't been a link layer broadcast. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38356 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/network/protocols/ipv4/ipv4.cpp | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp b/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp index 18e127585a..7aaa57cefc 100644 --- a/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp +++ b/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp @@ -1579,7 +1579,8 @@ ipv4_receive_data(net_buffer* buffer) return B_BAD_DATA; // lower layers notion of broadcast or multicast have no relevance to us - // TODO: they actually have when deciding whether to send an ICMP error + // other than deciding whether to send an ICMP error + bool wasMulticast = (buffer->flags & (MSG_BCAST | MSG_MCAST)) != 0; buffer->flags &= ~(MSG_BCAST | MSG_MCAST); sockaddr_in destination; @@ -1587,27 +1588,41 @@ ipv4_receive_data(net_buffer* buffer) if (header.destination == INADDR_BROADCAST) { buffer->flags |= MSG_BCAST; + + // Find first interface with a matching family + // TODO: support for ethernet broadcasts! + // TODO: we might need to send it to all interfaces if it's an ethernet + // broadcast as well! + sDatalinkModule->is_local_link_address(sDomain, true, + buffer->destination, &buffer->interface_address); } else if (IN_MULTICAST(ntohl(header.destination))) { buffer->flags |= MSG_MCAST; + // TODO: must set buffer->interface_address! } else { uint32 matchedAddressType = 0; // test if the packet is really for us if (!sDatalinkModule->is_local_address(sDomain, (sockaddr*)&destination, - &buffer->interface_address, &matchedAddressType) - && !sDatalinkModule->is_local_link_address(sDomain, true, - buffer->destination, &buffer->interface_address)) { - TRACE(" ipv4_receive_data(): packet was not for us %x -> %x", - ntohl(header.source), ntohl(header.destination)); + &buffer->interface_address, &matchedAddressType)) { + sDatalinkModule->is_local_link_address(sDomain, true, + buffer->destination, &buffer->interface_address); + } else { + // copy over special address types (MSG_BCAST or MSG_MCAST): + buffer->flags |= matchedAddressType; + } + } + if (buffer->interface_address == NULL) { + TRACE(" ipv4_receive_data(): packet was not for us %x -> %x", + ntohl(header.source), ntohl(header.destination)); + + if (!wasMulticast) { // Send ICMP error: Host unreachable sDomain->module->error_reply(NULL, buffer, B_NET_ERROR_UNREACH_HOST, NULL); - return B_ERROR; } - // copy over special address types (MSG_BCAST or MSG_MCAST): - buffer->flags |= matchedAddressType; + return B_ERROR; } // set net_buffer's source/destination address