[haiku-commits] r37916 - haiku/trunk/src/add-ons/kernel/network/datalink_protocols/arp

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 5 Aug 2010 09:56:23 +0200 (CEST)

Author: axeld
Date: 2010-08-05 09:56:23 +0200 (Thu, 05 Aug 2010)
New Revision: 37916
Changeset: http://dev.haiku-os.org/changeset/37916

Modified:
   haiku/trunk/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp
Log:
* We need to call arp_remove_local_entry() from arp_change_address() even if the
  old address is NULL for anything but SIOCAIFADDR. Hopefully, this fixes the
  problem Rene is seeing.
* Make sure that arp_entry::protocol is not NULL before using it. This is
  necessary because of the possibility to manually set ARP entries.
* Further improved debug output.
* Minor cleanup.


Modified: haiku/trunk/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp       
2010-08-05 03:16:18 UTC (rev 37915)
+++ haiku/trunk/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp       
2010-08-05 07:56:23 UTC (rev 37916)
@@ -127,6 +127,35 @@
 static bool sIgnoreReplies;
 
 
+#ifdef TRACE_ARP
+
+
+const char*
+mac_to_string(uint8* address)
+{
+       static char buffer[20];
+       snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
+               address[0], address[1], address[2], address[3], address[4], 
address[5]);
+       return buffer;
+}
+
+
+const char*
+inet_to_string(in_addr_t address)
+{
+       static char buffer[20];
+
+       unsigned int hostAddress = ntohl(address);
+       snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d",
+               hostAddress >> 24, (hostAddress >> 16) & 0xff,
+               (hostAddress >> 8) & 0xff, hostAddress & 0xff);
+       return buffer;
+}
+
+
+#endif // TRACE_ARP
+
+
 static net_buffer*
 get_request_buffer(arp_entry* entry)
 {
@@ -165,6 +194,33 @@
 }
 
 
+static void
+ipv4_to_ether_multicast(sockaddr_dl *destination, const sockaddr_in *source)
+{
+       // RFC 1112 - Host extensions for IP multicasting
+       //
+       //   ``An IP host group address is mapped to an Ethernet multicast
+       //   address by placing the low-order 23-bits of the IP address into
+       //   the low-order 23 bits of the Ethernet multicast address
+       //   01-00-5E-00-00-00 (hex).''
+
+       destination->sdl_len = sizeof(sockaddr_dl);
+       destination->sdl_family = AF_LINK;
+       destination->sdl_index = 0;
+       destination->sdl_type = IFT_ETHER;
+       destination->sdl_e_type = ETHER_TYPE_IP;
+       destination->sdl_nlen = destination->sdl_slen = 0;
+       destination->sdl_alen = ETHER_ADDRESS_LENGTH;
+
+       memcpy(LLADDR(destination) + 2, &source->sin_addr, sizeof(in_addr));
+       uint32 *data = (uint32 *)LLADDR(destination);
+       data[0] = (data[0] & htonl(0x7f)) | htonl(0x01005e00);
+}
+
+
+// #pragma mark -
+
+
 /*static*/ int
 arp_entry::Compare(void *_entry, const void *_key)
 {
@@ -316,33 +372,6 @@
 //     #pragma mark -
 
 
-static void
-ipv4_to_ether_multicast(sockaddr_dl *destination, const sockaddr_in *source)
-{
-       // RFC 1112 - Host extensions for IP multicasting
-       //
-       //   ``An IP host group address is mapped to an Ethernet multicast
-       //   address by placing the low-order 23-bits of the IP address into
-       //   the low-order 23 bits of the Ethernet multicast address
-       //   01-00-5E-00-00-00 (hex).''
-
-       destination->sdl_len = sizeof(sockaddr_dl);
-       destination->sdl_family = AF_LINK;
-       destination->sdl_index = 0;
-       destination->sdl_type = IFT_ETHER;
-       destination->sdl_e_type = ETHER_TYPE_IP;
-       destination->sdl_nlen = destination->sdl_slen = 0;
-       destination->sdl_alen = ETHER_ADDRESS_LENGTH;
-
-       memcpy(LLADDR(destination) + 2, &source->sin_addr, sizeof(in_addr));
-       uint32 *data = (uint32 *)LLADDR(destination);
-       data[0] = (data[0] & htonl(0x7f)) | htonl(0x01005e00);
-}
-
-
-//     #pragma mark -
-
-
 /*!    Updates the entry determined by \a protocolAddress with the specified
        \a hardwareAddress.
        If such an entry does not exist yet, a new entry is added. If you try
@@ -379,6 +408,7 @@
 
                entry->hardware_address = *hardwareAddress;
                entry->timestamp = system_time();
+               entry->protocol = NULL;
        } else {
                entry = arp_entry::Add(protocolAddress, hardwareAddress, flags);
                if (entry == NULL)
@@ -393,7 +423,7 @@
                sStackModule->set_timer(&entry->timer, ARP_STALE_TIMEOUT);
        }
 
-       if (entry->flags & ARP_FLAG_REJECT)
+       if ((entry->flags & ARP_FLAG_REJECT) != 0)
                entry->MarkFailed();
        else
                entry->MarkValid();
@@ -409,10 +439,16 @@
 arp_remove_local_entry(arp_protocol* protocol, const sockaddr* local,
        bool updateLocalAddress)
 {
-       in_addr_t inetAddress = ((sockaddr_in*)local)->sin_addr.s_addr;
+       in_addr_t inetAddress;
 
-       TRACE(("%s(): address %x\n", __FUNCTION__, inetAddress));
+       if (local == NULL) {
+               // interface has not yet been set
+               inetAddress = INADDR_ANY;
+       } else
+               inetAddress = ((sockaddr_in*)local)->sin_addr.s_addr;
 
+       TRACE(("%s(): address %s\n", __FUNCTION__, 
inet_to_string(inetAddress)));
+
        MutexLocker locker(sCacheLock);
 
        arp_entry* entry = arp_entry::Lookup(inetAddress);
@@ -462,17 +498,17 @@
 arp_set_local_entry(arp_protocol* protocol, const sockaddr* local)
 {
        MutexLocker locker(sCacheLock);
-       
+
        net_interface* interface = protocol->interface;
        in_addr_t inetAddress;
-       
+
        if (local == NULL) {
                // interface has not yet been set
                inetAddress = INADDR_ANY;
        } else
                inetAddress = ((sockaddr_in*)local)->sin_addr.s_addr;
 
-       TRACE(("%s(): address %x\n", __FUNCTION__, inetAddress));
+       TRACE(("%s(): address %s\n", __FUNCTION__, 
inet_to_string(inetAddress)));
 
        if (protocol->local_address == 0)
                protocol->local_address = inetAddress;
@@ -545,7 +581,7 @@
        // check if this request is for us
 
        arp_entry *entry = arp_entry::Lookup(header.protocol_target);
-       if (entry == NULL
+       if (entry == NULL || entry->protocol == NULL
                || (entry->flags & (ARP_FLAG_LOCAL | ARP_FLAG_PUBLISH)) == 0) {
                // We're not the one to answer this request
                // TODO: instead of letting the other's request time-out, can 
we reply
@@ -603,21 +639,11 @@
        uint16 opcode = ntohs(header.opcode);
 
 #ifdef TRACE_ARP
-       dprintf("  hw sender: %02x:%02x:%02x:%02x:%02x:%02x\n",
-               header.hardware_sender[0], header.hardware_sender[1],
-               header.hardware_sender[2], header.hardware_sender[3],
-               header.hardware_sender[4], header.hardware_sender[5]);
-       unsigned int addr = ntohl(header.protocol_sender);
-       dprintf("  proto sender: %d.%d.%d.%d\n", addr >> 24, (addr >> 16) & 
0xff,
-               (addr >> 8) & 0xff, addr & 0xff);
-       dprintf("  hw target: %02x:%02x:%02x:%02x:%02x:%02x\n",
-               header.hardware_target[0], header.hardware_target[1],
-               header.hardware_target[2], header.hardware_target[3],
-               header.hardware_target[4], header.hardware_target[5]);
-       addr = ntohl(header.protocol_target);
-       dprintf("  proto target: %d.%d.%d.%d\n", addr >> 24, (addr >> 16) & 
0xff,
-               (addr >> 8) & 0xff, addr & 0xff);
-#endif
+       dprintf("  hw sender: %s\n", mac_to_string(header.hardware_sender));
+       dprintf("  proto sender: %s\n", inet_to_string(header.protocol_sender));
+       dprintf("  hw target: %s\n", mac_to_string(header.hardware_target));;
+       dprintf("  proto target: %s\n", inet_to_string(header.protocol_target));
+#endif // TRACE_ARP
 
        if (ntohs(header.protocol_type) != ETHER_TYPE_IP
                || ntohs(header.hardware_type) != ARP_HARDWARE_TYPE_ETHER)
@@ -698,7 +724,8 @@
 
                default:
                {
-                       if (entry->timer_state > ARP_STATE_LAST_REQUEST)
+                       if (entry->timer_state > ARP_STATE_LAST_REQUEST
+                               || entry->protocol == NULL)
                                break;
 
                        TRACE(("  send request for ARP entry %p!\n", entry));
@@ -946,7 +973,7 @@
 }
 
 
-//     #pragma mark -
+//     #pragma mark - net_datalink_protocol
 
 
 status_t
@@ -1023,7 +1050,7 @@
 
                        if ((entry->flags & ARP_FLAG_REJECT) != 0)
                                return EHOSTUNREACH;
-                       
+
                        if ((entry->flags & ARP_FLAG_VALID) == 0) {
                                // entry is still being resolved.
                                TRACE(("ARP Queuing packet %p, entry still 
being resolved.\n",
@@ -1086,16 +1113,17 @@
                        // Those are the options we handle
                        if ((protocol->interface->flags & IFF_UP) != 0) {
                                // Update ARP entry for the local address
-                       
+
                                if (newAddress != NULL && newAddress->sa_family 
== AF_INET) {
                                        status_t status = 
arp_set_local_entry(protocol, newAddress);
                                        if (status != B_OK)
                                                return status;
                                }
 
-                               if (oldAddress != NULL && oldAddress->sa_family 
== AF_INET)
+                               if (option != SIOCAIFADDR
+                                       && (oldAddress == NULL || 
oldAddress->sa_family == AF_INET))
                                        arp_remove_local_entry(protocol, 
oldAddress, true);
-                       }                       
+                       }
                        break;
 
                default:


Other related posts:

  • » [haiku-commits] r37916 - haiku/trunk/src/add-ons/kernel/network/datalink_protocols/arp - axeld