[haiku-commits] r38356 - haiku/trunk/src/add-ons/kernel/network/protocols/ipv4

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 25 Aug 2010 17:54:35 +0200 (CEST)

Author: axeld
Date: 2010-08-25 17:54:35 +0200 (Wed, 25 Aug 2010)
New Revision: 38356
Changeset: http://dev.haiku-os.org/changeset/38356

Modified:
   haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp
Log:
* 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.


Modified: haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp      
2010-08-25 15:51:43 UTC (rev 38355)
+++ haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp      
2010-08-25 15:54:35 UTC (rev 38356)
@@ -1579,7 +1579,8 @@
                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 @@
 
        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


Other related posts: