[haiku-commits] r37794 - in haiku/trunk: build/jam headers/posix/net headers/posix/sys headers/private/net src/add-ons/kernel/network/datalink_protocols ...

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 28 Jul 2010 19:38:24 +0200 (CEST)

Author: axeld
Date: 2010-07-28 19:38:23 +0200 (Wed, 28 Jul 2010)
New Revision: 37794
Changeset: http://dev.haiku-os.org/changeset/37794

Added:
   haiku/trunk/src/add-ons/kernel/network/stack/device_interfaces.cpp
   haiku/trunk/src/add-ons/kernel/network/stack/device_interfaces.h
Removed:
   haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv4_datagram/
Modified:
   haiku/trunk/build/jam/HaikuImage
   haiku/trunk/headers/posix/net/if.h
   haiku/trunk/headers/posix/sys/sockio.h
   haiku/trunk/headers/private/net/net_buffer.h
   haiku/trunk/headers/private/net/net_datalink.h
   haiku/trunk/headers/private/net/net_datalink_protocol.h
   haiku/trunk/src/add-ons/kernel/network/datalink_protocols/Jamfile
   haiku/trunk/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp
   
haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ethernet_frame/ethernet_frame.cpp
   
haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp
   
haiku/trunk/src/add-ons/kernel/network/datalink_protocols/loopback_frame/loopback_frame.cpp
   haiku/trunk/src/add-ons/kernel/network/protocols/icmp/icmp.cpp
   haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp
   haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/ipv4_address.cpp
   haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/multicast.cpp
   haiku/trunk/src/add-ons/kernel/network/protocols/ipv6/ipv6_address.cpp
   haiku/trunk/src/add-ons/kernel/network/protocols/l2cap/l2cap_address.cpp
   haiku/trunk/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
   haiku/trunk/src/add-ons/kernel/network/protocols/tcp/tcp.cpp
   haiku/trunk/src/add-ons/kernel/network/protocols/udp/udp.cpp
   haiku/trunk/src/add-ons/kernel/network/protocols/unix/UnixAddress.cpp
   haiku/trunk/src/add-ons/kernel/network/stack/Jamfile
   haiku/trunk/src/add-ons/kernel/network/stack/datalink.cpp
   haiku/trunk/src/add-ons/kernel/network/stack/domains.cpp
   haiku/trunk/src/add-ons/kernel/network/stack/domains.h
   haiku/trunk/src/add-ons/kernel/network/stack/interfaces.cpp
   haiku/trunk/src/add-ons/kernel/network/stack/interfaces.h
   haiku/trunk/src/add-ons/kernel/network/stack/link.cpp
   haiku/trunk/src/add-ons/kernel/network/stack/net_buffer.cpp
   haiku/trunk/src/add-ons/kernel/network/stack/routes.cpp
   haiku/trunk/src/add-ons/kernel/network/stack/routes.h
   haiku/trunk/src/add-ons/kernel/network/stack/stack.cpp
   haiku/trunk/src/add-ons/kernel/network/stack/stack_private.h
   haiku/trunk/src/bin/debug/strace/ioctl.cpp
   haiku/trunk/src/bin/network/ifconfig/ifconfig.cpp
   haiku/trunk/src/bin/network/setwep/setwep.c
   haiku/trunk/src/bin/network/tcpdump/libpcap/pcap-haiku.cpp
   haiku/trunk/src/servers/net/DHCPClient.cpp
   haiku/trunk/src/servers/net/NetServer.cpp
   haiku/trunk/src/system/kernel/fs/vfs_net_boot.cpp
Log:
* Reworked the complete stack to allow more than one address per network
  interface - this caused quite a number of changes.
* Network interfaces, and its addresses are now reference counted (not yet
  complete, though, InterfaceAddresses need to hold references to their
  interface as well).
* There are two known regressions of this commit that I will fix later:
  - you cannot remove interfaces anymore
  - IPv4 multicast was broken anyway, but now it's disabled, too.
* Moved a device_interfaces.cpp|h out of interfaces.cpp.
* The datalink layer chain is now instantiated per domain per interface,
  not just per interface anymore.
* When a buffer reaches the network layer, it has no known interface yet, ie.
  the ipv4|6|whatever modules need to set this manually.
* Added more debug output, and some new debugger commands, the control option
  is now printed in clear text.
* Added hash_address() function to the address modules. Added "const" to
  set_to_defaults() where needed.
* Fixed net_buffer's restore header functions offset use as reported by Atis.
* Improved buffer dump output, use the domain module to print the address if
  available.
* Moved net_buffer::type into the union, as it's not needed by the upper layers
  anymore.
* Moved IPv6 specific code from {add|remove}_default_route() to where it
  belongs, but disabled it for the time being.
* Completely discarded useless ipv4_datagram module.
* Added ping6 to the build.


Modified: haiku/trunk/build/jam/HaikuImage
===================================================================
--- haiku/trunk/build/jam/HaikuImage    2010-07-28 17:09:12 UTC (rev 37793)
+++ haiku/trunk/build/jam/HaikuImage    2010-07-28 17:38:23 UTC (rev 37794)
@@ -46,8 +46,8 @@
        mkfifo mkfs mkindex mktemp modifiers mount mount_nfs mountvolume mv
        netcat netstat nl nohup notify nproc
        od open
-       passwd paste patch pathchk pc ping play playfile playsound playwav pr 
prio
-       printenv printf profile ps ptx pwd
+       passwd paste patch pathchk pc ping ping6 play playfile playsound playwav
+       pr prio printenv printf profile ps ptx pwd
        query quit
        rc readlink ReadOnlyBootPrompt reindex release renice rlog rm rmattr
        rmindex rmdir roster route
@@ -105,10 +105,10 @@
 ;
 
 SYSTEM_NETWORK_DEVICES = ethernet loopback ;
-SYSTEM_NETWORK_DATALINK_PROTOCOLS = ethernet_frame <module>arp loopback_frame
-       ipv4_datagram ;
+SYSTEM_NETWORK_DATALINK_PROTOCOLS = ethernet_frame <module>arp loopback_frame ;
+       #ipv6_datagram ;
 #SYSTEM_NETWORK_PPP = ipcp modem pap pppoe ;
-SYSTEM_NETWORK_PROTOCOLS = ipv4 tcp udp icmp unix ;
+SYSTEM_NETWORK_PROTOCOLS = ipv4 tcp udp icmp unix ; # icmp6 ipv6 ;
 
 SYSTEM_ADD_ONS_ACCELERANTS = $(X86_ONLY)radeon.accelerant
        $(X86_ONLY)nvidia.accelerant $(X86_ONLY)matrox.accelerant

Modified: haiku/trunk/headers/posix/net/if.h
===================================================================
--- haiku/trunk/headers/posix/net/if.h  2010-07-28 17:09:12 UTC (rev 37793)
+++ haiku/trunk/headers/posix/net/if.h  2010-07-28 17:38:23 UTC (rev 37794)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  */
 #ifndef _NET_IF_H
@@ -16,12 +16,6 @@
 
 #define IFNAMSIZ IF_NAMESIZE
 
-struct ifreq_parameter {
-       char            base_name[IF_NAMESIZE];
-       char            device[128];
-       uint8_t         sub_type;
-};
-
 struct ifreq_stream_stats {
        uint32_t        packets;
        uint32_t        errors;
@@ -43,7 +37,6 @@
                struct sockaddr ifr_dstaddr;
                struct sockaddr ifr_broadaddr;
                struct sockaddr ifr_mask;
-               struct ifreq_parameter ifr_parameter;
                struct ifreq_stats ifr_stats;
                struct route_entry ifr_route;
                int             ifr_flags;
@@ -56,6 +49,14 @@
        };
 };
 
+/* used with SIOCAIFADDR */
+struct ifaliasreq {
+       char            ifra_name[IF_NAMESIZE];
+       struct sockaddr_storage ifra_addr;
+       struct sockaddr_storage ifra_broadaddr;
+       struct sockaddr_storage ifra_mask;
+};
+
 /* interface flags */
 #define IFF_UP                         0x0001
 #define IFF_BROADCAST          0x0002  /* valid broadcast address */

Modified: haiku/trunk/headers/posix/sys/sockio.h
===================================================================
--- haiku/trunk/headers/posix/sys/sockio.h      2010-07-28 17:09:12 UTC (rev 
37793)
+++ haiku/trunk/headers/posix/sys/sockio.h      2010-07-28 17:38:23 UTC (rev 
37794)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2007, Haiku Inc. All Rights Reserved.
+ * Copyright 2002-2010, Haiku Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  */
 #ifndef _SYS_SOCKIO_H
@@ -38,7 +38,6 @@
 #define SIOCGETRT                      8928    /* get route information for 
destination */
 
 #define SIOCGIFSTATS           8929    /* get interface stats */
-#define SIOCGIFPARAM           8930    /* get interface parameter */
 #define SIOCGIFTYPE                    8931    /* get interface type */
 
 #define SIOCSPACKETCAP         8932    /* Start capturing packets on an 
interface */

Modified: haiku/trunk/headers/private/net/net_buffer.h
===================================================================
--- haiku/trunk/headers/private/net/net_buffer.h        2010-07-28 17:09:12 UTC 
(rev 37793)
+++ haiku/trunk/headers/private/net/net_buffer.h        2010-07-28 17:38:23 UTC 
(rev 37794)
@@ -18,14 +18,9 @@
 typedef struct net_buffer {
        struct list_link                link;
 
-       // TODO: we should think about moving the address fields into the buffer
-       // data itself via associated data or something like this. Or this
-       // structure as a whole, too...
-
        struct sockaddr*                source;
        struct sockaddr*                destination;
-       struct net_interface*   interface;
-       int32                                   type;
+       struct net_interface_address*   interface_address;
        union {
                struct {
                        uint16                  start;
@@ -33,6 +28,7 @@
                }                                       fragment;
                uint32                          sequence;
                uint32                          offset;
+               int32                           type;
        };
        uint32                                  flags;
        uint32                                  size;

Modified: haiku/trunk/headers/private/net/net_datalink.h
===================================================================
--- haiku/trunk/headers/private/net/net_datalink.h      2010-07-28 17:09:12 UTC 
(rev 37793)
+++ haiku/trunk/headers/private/net/net_datalink.h      2010-07-28 17:38:23 UTC 
(rev 37794)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  */
 #ifndef NET_DATALINK_H
@@ -18,84 +18,98 @@
 
 typedef struct net_datalink_protocol net_datalink_protocol;
 
+
 typedef struct net_domain {
-       const char                      *name;
+       const char*                     name;
        int                                     family;
-       struct list                     interfaces;
 
-       struct net_protocol_module_info *module;
-       struct net_address_module_info *address_module;
+       struct net_protocol_module_info* module;
+       struct net_address_module_info* address_module;
 } net_domain;
 
-struct net_interface {
-       struct list_link        link;
-       struct net_domain       *domain;
-       struct net_device       *device;
-       struct net_datalink_protocol *first_protocol;
-       struct net_datalink_protocol_module_info *first_info;
+typedef struct net_interface_address {
+       struct net_domain*      domain;
+       struct net_interface* interface;
+       struct sockaddr*        local;
+       struct sockaddr*        destination;
+       struct sockaddr*        mask;
+} net_interface_address;
 
+typedef struct net_interface {
+       struct net_device*      device;
+
        char                            name[IF_NAMESIZE];
-       struct sockaddr         *address;
-       struct sockaddr         *destination;
-       struct sockaddr         *mask;
        uint32                          index;
        uint32                          flags;
        uint8                           type;
        uint32                          mtu;
        uint32                          metric;
-};
+} net_interface;
 
-struct net_route {
-       struct sockaddr         *destination;
-       struct sockaddr         *mask;
-       struct sockaddr         *gateway;
+typedef struct net_route {
+       struct sockaddr*        destination;
+       struct sockaddr*        mask;
+       struct sockaddr*        gateway;
        uint32                          flags;
        uint32                          mtu;
-       struct net_interface *interface;
-};
+       struct net_interface_address* interface_address;
+} net_route;
 
-struct net_route_info {
+typedef struct net_route_info {
        struct list_link        link;
-       struct net_route        *route;
+       struct net_route*       route;
        struct sockaddr         address;
-};
+} net_route_info;
 
+
 struct net_datalink_module_info {
        module_info info;
 
-       status_t (*control)(struct net_domain *domain, int32 option, void 
*value,
-                                       size_t *_length);
-       status_t (*send_data)(struct net_route *route, struct net_buffer 
*buffer);
-       status_t (*send_datagram)(struct net_protocol *protocol,
-                                       struct net_domain *domain, struct 
net_buffer *buffer);
+       status_t                (*control)(net_domain* domain, int32 option, 
void* value,
+                                               size_t* _length);
+       status_t                (*send_data)(net_route* route, net_buffer* 
buffer);
+       status_t                (*send_datagram)(struct net_protocol* protocol,
+                                               net_domain* domain, net_buffer* 
buffer);
 
-       bool (*is_local_address)(struct net_domain *domain,
-                                       const struct sockaddr *address, 
net_interface **_interface,
-                                       uint32 *_matchedType);
-       bool (*is_local_link_address)(struct net_domain *domain, bool 
unconfigured,
-                                       const struct sockaddr *address, 
net_interface **_interface);
+       bool                    (*is_local_address)(net_domain* domain,
+                                               const struct sockaddr* address,
+                                               net_interface_address** 
_interfaceAddress,
+                                               uint32* _matchedType);
+       bool                    (*is_local_link_address)(net_domain* domain,
+                                               bool unconfigured, const struct 
sockaddr* address,
+                                               net_interface_address** 
_interfaceAddress);
 
-       net_interface *(*get_interface)(struct net_domain *domain, uint32 
index);
-       net_interface *(*get_interface_with_address)(struct net_domain *domain,
-                                       const struct sockaddr *address);
+       net_interface*  (*get_interface)(net_domain* domain, uint32 index);
+       net_interface*  (*get_interface_with_address)(
+                                               const struct sockaddr* address);
+       void                    (*put_interface)(net_interface* interface);
 
+       net_interface_address* (*get_interface_address)(
+                                               const struct sockaddr* address);
+       bool                    (*get_next_interface_address)(net_interface* 
interface,
+                                               net_interface_address** 
_address);
+       void                    (*put_interface_address)(net_interface_address* 
address);
+
+       status_t                (*join_multicast)(net_interface* interface,
+                                               net_domain* domain, const 
struct sockaddr* address);
+       status_t                (*leave_multicast)(net_interface* interface,
+                                               net_domain* domain, const 
struct sockaddr* address);
+
        // routes
-       status_t (*add_route)(struct net_domain *domain,
-                                       const struct net_route *route);
-       status_t (*remove_route)(struct net_domain *domain,
-                                       const struct net_route *route);
-       struct net_route *(*get_route)(struct net_domain *domain,
-                                       const struct sockaddr *address);
-       status_t (*get_buffer_route)(struct net_domain *domain,
-                                       struct net_buffer *buffer, struct 
net_route **_route);
-       void (*put_route)(struct net_domain *domain, struct net_route *route);
+       status_t                (*add_route)(net_domain* domain, const 
net_route* route);
+       status_t                (*remove_route)(net_domain* domain, const 
net_route* route);
+       net_route*              (*get_route)(net_domain* domain,
+                                               const struct sockaddr* address);
+       status_t                (*get_buffer_route)(net_domain* domain,
+                                               struct net_buffer* buffer, 
net_route** _route);
+       void                    (*put_route)(net_domain* domain, net_route* 
route);
 
-       status_t (*register_route_info)(struct net_domain *domain,
-                                       struct net_route_info *info);
-       status_t (*unregister_route_info)(struct net_domain *domain,
-                                       struct net_route_info *info);
-       status_t (*update_route_info)(struct net_domain *domain,
-                                       struct net_route_info *info);
+       status_t                (*register_route_info)(net_domain* domain,
+                                               net_route_info* info);
+       status_t                (*unregister_route_info)(net_domain* domain,
+                                               net_route_info* info);
+       status_t                (*update_route_info)(net_domain* domain,
+                                               net_route_info* info);
 };
 
 #define NET_ADDRESS_MODULE_FLAG_BROADCAST_ADDRESS              0x01
@@ -104,47 +118,58 @@
        module_info info;
        uint32 flags;
 
-       status_t (*copy_address)(const sockaddr *from, sockaddr **to,
-                                       bool replaceWithZeros, const sockaddr 
*mask);
+       status_t                (*copy_address)(const struct sockaddr* from,
+                                               struct sockaddr** to, bool 
replaceWithZeros,
+                                               const struct sockaddr* mask);
 
-       status_t (*mask_address)(const sockaddr *address, const sockaddr *mask,
-                                       sockaddr *result);
+       status_t                (*mask_address)(const struct sockaddr* address,
+                                               const struct sockaddr* mask, 
struct sockaddr* result);
 
-       bool (*equal_addresses)(const sockaddr *a, const sockaddr *b);
-       bool (*equal_ports)(const sockaddr *a, const sockaddr *b);
-       bool (*equal_addresses_and_ports)(const sockaddr *a, const sockaddr *b);
-       bool (*equal_masked_addresses)(const sockaddr *a, const sockaddr *b,
-                                       const sockaddr *mask);
-       bool (*is_empty_address)(const sockaddr *address, bool checkPort);
-       bool (*is_same_family)(const sockaddr *address);
+       bool                    (*equal_addresses)(const struct sockaddr* a,
+                                               const struct sockaddr* b);
+       bool                    (*equal_ports)(const struct sockaddr* a,
+                                               const struct sockaddr* b);
+       bool                    (*equal_addresses_and_ports)(const struct 
sockaddr* a,
+                                               const struct sockaddr* b);
+       bool                    (*equal_masked_addresses)(const struct 
sockaddr* a,
+                                               const struct sockaddr* b, const 
struct sockaddr* mask);
+       bool                    (*is_empty_address)(const struct sockaddr* 
address,
+                                               bool checkPort);
+       bool                    (*is_same_family)(const struct sockaddr* 
address);
 
-       int32 (*first_mask_bit)(const sockaddr *mask);
+       int32                   (*first_mask_bit)(const struct sockaddr* mask);
 
-       bool (*check_mask)(const sockaddr *address);
+       bool                    (*check_mask)(const struct sockaddr* address);
 
-       status_t (*print_address)(const sockaddr *address, char **buffer,
-                                       bool printPort);
-       status_t (*print_address_buffer)(const sockaddr *address, char *buffer,
-                                       size_t bufferSize, bool printPort);
+       status_t                (*print_address)(const struct sockaddr* address,
+                                               char** buffer, bool printPort);
+       status_t                (*print_address_buffer)(const struct sockaddr* 
address,
+                                               char* buffer, size_t 
bufferSize, bool printPort);
 
-       uint16 (*get_port)(const sockaddr *address);
-       status_t (*set_port)(sockaddr *address, uint16 port);
+       uint16                  (*get_port)(const struct sockaddr* address);
+       status_t                (*set_port)(struct sockaddr* address, uint16 
port);
 
-       status_t (*set_to)(sockaddr *address, const sockaddr *from);
-       status_t (*set_to_empty_address)(sockaddr *address);
-       status_t (*set_to_defaults)(sockaddr *defaultMask,
-                                       sockaddr *defaultBroadcast, sockaddr 
*address,
-                                       sockaddr *netmask);
+       status_t                (*set_to)(struct sockaddr* address,
+                                               const struct sockaddr* from);
+       status_t                (*set_to_empty_address)(struct sockaddr* 
address);
+       status_t                (*set_to_defaults)(struct sockaddr* defaultMask,
+                                               struct sockaddr* 
defaultBroadcast,
+                                               const struct sockaddr* address,
+                                               const struct sockaddr* netmask);
 
-       status_t (*update_to)(sockaddr *address, const sockaddr *from);
+       status_t                (*update_to)(struct sockaddr* address,
+                                               const struct sockaddr* from);
 
-       uint32 (*hash_address_pair)(const sockaddr *ourAddress,
-                                       const sockaddr *peerAddress);
+       uint32                  (*hash_address)(const struct sockaddr* address,
+                                               bool includePort);
+       uint32                  (*hash_address_pair)(const struct sockaddr* 
ourAddress,
+                                               const struct sockaddr* 
peerAddress);
 
-       status_t (*checksum_address)(struct Checksum *checksum,
-                                       const sockaddr *address);
+       status_t                (*checksum_address)(struct Checksum* checksum,
+                                               const struct sockaddr* address);
 
-       void (*get_loopback_address)(sockaddr *result);
+       void                    (*get_loopback_address)(struct sockaddr* 
result);
 };
 
+
 #endif // NET_DATALINK_H

Modified: haiku/trunk/headers/private/net/net_datalink_protocol.h
===================================================================
--- haiku/trunk/headers/private/net/net_datalink_protocol.h     2010-07-28 
17:09:12 UTC (rev 37793)
+++ haiku/trunk/headers/private/net/net_datalink_protocol.h     2010-07-28 
17:38:23 UTC (rev 37794)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  */
 #ifndef NET_DATALINK_PROTOCOL_H
@@ -10,31 +10,37 @@
 
 
 typedef struct net_datalink_protocol {
-       struct net_datalink_protocol                            *next;
-       struct net_datalink_protocol_module_info        *module;
-       struct net_interface                                            
*interface;
+       struct net_datalink_protocol*                           next;
+       struct net_datalink_protocol_module_info*       module;
+       struct net_interface*                                           
interface;
+       struct net_domain*                                                      
domain;
 } net_datalink_protocol;
 
 struct net_datalink_protocol_module_info {
        module_info info;
 
-       status_t        (*init_protocol)(struct net_interface *interface,
-                                       net_datalink_protocol **_protocol);
-       status_t        (*uninit_protocol)(net_datalink_protocol *self);
+       status_t        (*init_protocol)(net_interface* interface, net_domain* 
domain,
+                                       net_datalink_protocol** _protocol);
+       status_t        (*uninit_protocol)(net_datalink_protocol* self);
 
-       status_t        (*send_data)(net_datalink_protocol *self,
-                                       net_buffer *buffer);
+       status_t        (*send_data)(net_datalink_protocol* self, net_buffer* 
buffer);
 
-       status_t        (*interface_up)(net_datalink_protocol *self);
-       void            (*interface_down)(net_datalink_protocol *self);
+       status_t        (*interface_up)(net_datalink_protocol* self);
+       void            (*interface_down)(net_datalink_protocol* self);
 
-       status_t        (*control)(net_datalink_protocol *self,
-                                       int32 op, void *argument, size_t 
length);
+       status_t        (*change_address)(net_datalink_protocol* self,
+                                       net_interface_address* address, int32 
option,
+                                       const struct sockaddr* oldAddress,
+                                       const struct sockaddr* newAddress);
 
-       status_t        (*join_multicast)(net_datalink_protocol *self,
-                                       const sockaddr *address);
-       status_t        (*leave_multicast)(net_datalink_protocol *self,
-                                       const sockaddr *address);
+       status_t        (*control)(net_datalink_protocol* self, int32 option,
+                                       void* argument, size_t length);
+
+       status_t        (*join_multicast)(net_datalink_protocol* self,
+                                       const struct sockaddr* address);
+       status_t        (*leave_multicast)(net_datalink_protocol* self,
+                                       const struct sockaddr* address);
 };
 
+
 #endif // NET_DATALINK_PROTOCOL_H

Modified: haiku/trunk/src/add-ons/kernel/network/datalink_protocols/Jamfile
===================================================================
--- haiku/trunk/src/add-ons/kernel/network/datalink_protocols/Jamfile   
2010-07-28 17:09:12 UTC (rev 37793)
+++ haiku/trunk/src/add-ons/kernel/network/datalink_protocols/Jamfile   
2010-07-28 17:38:23 UTC (rev 37794)
@@ -1,7 +1,6 @@
 SubDir HAIKU_TOP src add-ons kernel network datalink_protocols ;
 
-SubInclude HAIKU_TOP src add-ons kernel network datalink_protocols arp ;
-SubInclude HAIKU_TOP src add-ons kernel network datalink_protocols 
ethernet_frame ;
-SubInclude HAIKU_TOP src add-ons kernel network datalink_protocols 
ipv4_datagram ;
-SubInclude HAIKU_TOP src add-ons kernel network datalink_protocols 
ipv6_datagram ;
-SubInclude HAIKU_TOP src add-ons kernel network datalink_protocols 
loopback_frame ;
+HaikuSubInclude arp ;
+HaikuSubInclude ethernet_frame ;
+HaikuSubInclude ipv6_datagram ;
+HaikuSubInclude loopback_frame ;

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-07-28 17:09:12 UTC (rev 37793)
+++ haiku/trunk/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp       
2010-07-28 17:38:23 UTC (rev 37794)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -7,6 +7,7 @@
  *             Hugo Santos, hugosantos@xxxxxxxxx
  */
 
+
 //! Ethernet Address Resolution Protocol, see RFC 826.
 
 
@@ -110,6 +111,7 @@
 
 struct arp_protocol : net_datalink_protocol {
        sockaddr_dl     hardware_address;
+       in_addr_t       local_address;
 };
 
 
@@ -117,9 +119,10 @@
 
 static void arp_timer(struct net_timer *timer, void *data);
 
-net_buffer_module_info *gBufferModule;
-static net_stack_module_info *sStackModule;
-static hash_table *sCache;
+net_buffer_module_info* gBufferModule;
+static net_stack_module_info* sStackModule;
+static net_datalink_module_info* sDatalinkModule;
+static hash_table* sCache;
 static mutex sCacheLock;
 static bool sIgnoreReplies;
 
@@ -283,7 +286,7 @@
 arp_entry::MarkValid()
 {
        TRACE(("ARP entry %p Marked as VALID, have %li packets queued.\n", this,
-               queue.Size()));
+               queue.Count()));
 
        flags = (flags & ~ARP_FLAG_REJECT) | ARP_FLAG_VALID;
 
@@ -316,9 +319,6 @@
 static void
 ipv4_to_ether_multicast(sockaddr_dl *destination, const sockaddr_in *source)
 {
-       // TODO: this is ethernet specific, and doesn't belong here
-       //      (should be moved to the ethernet_frame module)
-
        // RFC 1112 - Host extensions for IP multicasting
        //
        //   ``An IP host group address is mapped to an Ethernet multicast
@@ -352,7 +352,7 @@
        This function does not lock the cache - you have to do it yourself
        before calling it.
 */
-status_t
+static status_t
 arp_update_entry(in_addr_t protocolAddress, sockaddr_dl *hardwareAddress,
        uint32 flags, arp_entry **_entry = NULL)
 {
@@ -405,23 +405,74 @@
 }
 
 
-/*!    Creates a permanent local entry for the interface belonging to this 
protocol.
-       You need to hold the cache lock when calling this function.
+static void
+arp_remove_local_entry(arp_protocol* protocol, const sockaddr* local,
+       bool updateLocalAddress)
+{
+       in_addr_t inetAddress = ((sockaddr_in*)local)->sin_addr.s_addr;
+
+       MutexLocker locker(sCacheLock);
+
+       arp_entry* entry = arp_entry::Lookup(inetAddress);
+       if (entry != NULL) {
+               hash_remove(sCache, entry);
+               entry->flags |= ARP_FLAG_REMOVED;
+       }
+
+       if (updateLocalAddress && protocol->local_address == inetAddress) {
+               // find new local sender address
+               protocol->local_address = 0;
+
+               net_interface_address* address = NULL;
+               while 
(sDatalinkModule->get_next_interface_address(protocol->interface,
+                               &address)) {
+                       if (address->local == NULL || address->local->sa_family 
!= AF_INET)
+                               continue;
+
+                       protocol->local_address
+                               = 
((sockaddr_in*)address->local)->sin_addr.s_addr;
+               }
+       }
+
+       locker.Unlock();
+       delete entry;
+}
+
+
+/*!    Removes all entries belonging to the local interface of the \a procotol
+       given.
 */
+static void
+arp_remove_local(arp_protocol* protocol)
+{
+       net_interface_address* address = NULL;
+       while (sDatalinkModule->get_next_interface_address(protocol->interface,
+                       &address)) {
+               if (address->local == NULL || address->local->sa_family != 
AF_INET)
+                       continue;
+
+               arp_remove_local_entry(protocol, address->local, false);
+       }
+}
+
+
 static status_t
-arp_update_local(arp_protocol *protocol)
+arp_set_local_entry(arp_protocol* protocol, const sockaddr* local)
 {
-       ASSERT_LOCKED_MUTEX(&sCacheLock);
-
-       net_interface *interface = protocol->interface;
+       MutexLocker locker(sCacheLock);
+       
+       net_interface* interface = protocol->interface;
        in_addr_t inetAddress;
-
-       if (interface->address == NULL) {
+       
+       if (local == NULL) {
                // interface has not yet been set
                inetAddress = INADDR_ANY;
        } else
-               inetAddress = ((sockaddr_in 
*)interface->address)->sin_addr.s_addr;
+               inetAddress = ((sockaddr_in*)local)->sin_addr.s_addr;
 
+       if (protocol->local_address == 0)
+               protocol->local_address = inetAddress;
+
        sockaddr_dl address;
        address.sdl_len = sizeof(sockaddr_dl);
        address.sdl_family = AF_LINK;
@@ -435,7 +486,7 @@
        memcpy(&protocol->hardware_address, &address, sizeof(sockaddr_dl));
                // cache the address in our protocol
 
-       arp_entry *entry;
+       arp_entry* entry;
        status_t status = arp_update_entry(inetAddress, &address,
                ARP_FLAG_LOCAL | ARP_FLAG_PERMANENT, &entry);
        if (status == B_OK)
@@ -445,7 +496,38 @@
 }
 
 
+/*!    Creates permanent local entries for all addresses of the interface 
belonging
+       to this protocol.
+       Returns an error if no entry could be added.
+*/
 static status_t
+arp_update_local(arp_protocol* protocol)
+{
+       protocol->local_address = 0;
+               // TODO: test if this actually works - maybe we should use
+               // INADDR_BROADCAST instead
+
+       ssize_t count = 0;
+
+       net_interface_address* address = NULL;
+       while (sDatalinkModule->get_next_interface_address(protocol->interface,
+                       &address)) {
+               if (address->local == NULL || address->local->sa_family != 
AF_INET)
+                       continue;
+
+               if (arp_set_local_entry(protocol, address->local) == B_OK) {
+                       count++;
+               }
+       }
+
+       if (count == 0)
+               return arp_set_local_entry(protocol, NULL);
+
+       return B_OK;
+}
+
+
+static status_t
 handle_arp_request(net_buffer *buffer, arp_header &header)
 {
        MutexLocker locker(sCacheLock);
@@ -518,15 +600,19 @@
 
 #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]);
-       dprintf("  proto sender: %ld.%ld.%ld.%ld\n", header.protocol_sender >> 
24, (header.protocol_sender >> 16) & 0xff,
-               (header.protocol_sender >> 8) & 0xff, header.protocol_sender & 
0xff);
+               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]);
-       dprintf("  proto target: %ld.%ld.%ld.%ld\n", header.protocol_target >> 
24, (header.protocol_target >> 16) & 0xff,
-               (header.protocol_target >> 8) & 0xff, header.protocol_target & 
0xff);
+               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
 
        if (ntohs(header.protocol_type) != ETHER_TYPE_IP
@@ -588,21 +674,23 @@
 
                case ARP_STATE_REMOVE_FAILED:
                case ARP_STATE_STALE:
+               {
                        // the entry has aged so much that we're going to 
remove it
                        TRACE(("  remove ARP entry %p!\n", entry));
 
-                       mutex_lock(&sCacheLock);
+                       MutexLocker locker(sCacheLock);
                        if ((entry->flags & ARP_FLAG_REMOVED) != 0) {
-                               // The entry has already been removed, and is 
about to be deleted
-                               mutex_unlock(&sCacheLock);
+                               // The entry has already been removed, and is 
about to be
+                               // deleted
                                break;
                        }
 
                        hash_remove(sCache, entry);
-                       mutex_unlock(&sCacheLock);
+                       locker.Unlock();
 
                        delete entry;
                        break;
+               }
 
                default:
                {
@@ -649,8 +737,7 @@
        You need to have the sCacheLock held when calling this function.
 */
 static status_t
-arp_start_resolve(net_datalink_protocol *protocol, in_addr_t address,
-       arp_entry **_entry)
+arp_start_resolve(arp_protocol* protocol, in_addr_t address, arp_entry** 
_entry)
 {
        ASSERT_LOCKED_MUTEX(&sCacheLock);
 
@@ -686,16 +773,8 @@
        header.opcode = htons(ARP_OPCODE_REQUEST);
 
        memcpy(header.hardware_sender, device->address.data, 
ETHER_ADDRESS_LENGTH);
-       if (protocol->interface->address != NULL) {
-               header.protocol_sender
-                       = ((sockaddr_in 
*)protocol->interface->address)->sin_addr.s_addr;
-       } else {
-               header.protocol_sender = 0;
-                       // TODO: test if this actually works - maybe we should 
use
-                       // INADDR_BROADCAST instead
-       }
-
        memset(header.hardware_target, 0, ETHER_ADDRESS_LENGTH);
+       header.protocol_sender = protocol->local_address;
        header.protocol_target = address;
 
        // prepare source and target addresses
@@ -867,21 +946,25 @@
 
 
 status_t
-arp_init_protocol(struct net_interface *interface,
-       net_datalink_protocol **_protocol)
+arp_init_protocol(net_interface* interface, net_domain* domain,
+       net_datalink_protocol** _protocol)
 {
        // We currently only support a single family and type!
-       if (interface->domain->family != AF_INET
-               || interface->device->type != IFT_ETHER)
+       if (interface->device->type != IFT_ETHER
+               || domain->family != AF_INET)
                return B_BAD_TYPE;
 
        status_t status = 
sStackModule->register_device_handler(interface->device,
                ETHER_FRAME_TYPE | ETHER_TYPE_ARP, &arp_receive, NULL);
+       if (status != B_OK)
+               return status;
 
-       if (status < B_OK)
+       status = sStackModule->register_domain_device_handler(
+               interface->device, ETHER_FRAME_TYPE | ETHER_TYPE_IP, domain);
+       if (status != B_OK)
                return status;
 
-       arp_protocol *protocol = new (std::nothrow) arp_protocol;
+       arp_protocol* protocol = new(std::nothrow) arp_protocol;
        if (protocol == NULL)
                return B_NO_MEMORY;
 
@@ -896,6 +979,8 @@
 {
        sStackModule->unregister_device_handler(protocol->interface->device,
                ETHER_FRAME_TYPE | ETHER_TYPE_ARP);
+       sStackModule->unregister_device_handler(protocol->interface->device,
+               ETHER_FRAME_TYPE | ETHER_TYPE_IP);
 
        delete protocol;
        return B_OK;
@@ -914,7 +999,7 @@
                memcpy(buffer->source, &protocol->hardware_address,
                        protocol->hardware_address.sdl_len);
 
-               if (buffer->flags & MSG_MCAST) {
+               if ((buffer->flags & MSG_MCAST) != 0) {
                        sockaddr_dl multicastDestination;
                        ipv4_to_ether_multicast(&multicastDestination,
                                (sockaddr_in *)buffer->destination);
@@ -926,14 +1011,16 @@
                                ((struct sockaddr_in 
*)buffer->destination)->sin_addr.s_addr);
                        if (entry == NULL) {
                                status_t status = arp_start_resolve(protocol,
-                                       ((struct sockaddr_in 
*)buffer->destination)->sin_addr.s_addr, &entry);
-                               if (status < B_OK)
+                                       ((struct 
sockaddr_in*)buffer->destination)->sin_addr.s_addr,
+                                       &entry);
+                               if (status != B_OK)
                                        return status;
                        }
 
-                       if (entry->flags & ARP_FLAG_REJECT)
+                       if ((entry->flags & ARP_FLAG_REJECT) != 0)
                                return EHOSTUNREACH;
-                       else if (!(entry->flags & ARP_FLAG_VALID)) {
+                       
+                       if ((entry->flags & ARP_FLAG_VALID) == 0) {
                                // entry is still being resolved.
                                TRACE(("ARP Queuing packet %p, entry still 
being resolved.\n",
                                        buffer));
@@ -951,20 +1038,17 @@
 
 
 status_t
-arp_up(net_datalink_protocol *_protocol)
+arp_up(net_datalink_protocol* _protocol)
 {
-       arp_protocol *protocol = (arp_protocol *)_protocol;
+       arp_protocol* protocol = (arp_protocol*)_protocol;
        status_t status = protocol->next->module->interface_up(protocol->next);
-       if (status < B_OK)
+       if (status != B_OK)
                return status;
 
        // cache this device's address for later use
 
-       mutex_lock(&sCacheLock);
        status = arp_update_local(protocol);
-       mutex_unlock(&sCacheLock);
-
-       if (status < B_OK) {
+       if (status != B_OK) {
                protocol->next->module->interface_down(protocol->next);
                return status;
        }
@@ -976,70 +1060,55 @@
 void
 arp_down(net_datalink_protocol *protocol)
 {
-       // remove local ARP entry from the cache
+       // remove local ARP entries from the cache
+       arp_remove_local((arp_protocol*)protocol);
 
-       if (protocol->interface->address != NULL) {
-               MutexLocker locker(sCacheLock);
-
-               arp_entry *entry = arp_entry::Lookup(
-                       ((sockaddr_in 
*)protocol->interface->address)->sin_addr.s_addr);
-               if (entry != NULL) {
-                       hash_remove(sCache, entry);
-                       entry->flags |= ARP_FLAG_REMOVED;
-                       locker.Unlock();
-
-                       delete entry;
-               }
-       }
-
        protocol->next->module->interface_down(protocol->next);
 }
 
 
 status_t
-arp_control(net_datalink_protocol *_protocol, int32 op, void *argument,
-       size_t length)
+arp_change_address(net_datalink_protocol* _protocol,
+       net_interface_address* address, int32 option,
+       const struct sockaddr* oldAddress, const struct sockaddr* newAddress)
 {
-       arp_protocol *protocol = (arp_protocol *)_protocol;
+       arp_protocol* protocol = (arp_protocol*)_protocol;
 
-       if (op == SIOCSIFADDR && (protocol->interface->flags & IFF_UP) != 0) {
-               // The interface may get a new address, so we need to update our
-               // local entries.
-               in_addr_t oldAddress = 0;
-               if (protocol->interface->address != NULL) {
-                       oldAddress
-                               = ((sockaddr_in 
*)protocol->interface->address)->sin_addr.s_addr;
-               }
+       switch (option) {
+               case SIOCSIFADDR:
+               case SIOCAIFADDR:
+               case SIOCDIFADDR:
+                       // 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;
+                               }
 
-               status_t status = 
protocol->next->module->control(protocol->next,
-                       SIOCSIFADDR, argument, length);
-               if (status < B_OK)
-                       return status;
+                               if (oldAddress != NULL && oldAddress->sa_family 
== AF_INET)
+                                       arp_remove_local_entry(protocol, 
oldAddress, true);
+                       }                       
+                       break;
 
-               MutexLocker locker(sCacheLock);
+               default:
+                       break;
+       }
 
-               arp_update_local(protocol);
+       return protocol->next->module->change_address(protocol->next, address,
+               option, oldAddress, newAddress);
+}
 
-               if (oldAddress == ((sockaddr_in *)
-                               protocol->interface->address)->sin_addr.s_addr)
-                       return B_OK;
 
-               // remove previous address from cache
-
-               arp_entry *entry = arp_entry::Lookup(oldAddress);
-               if (entry != NULL) {
-                       hash_remove(sCache, entry);
-                       entry->flags |= ARP_FLAG_REMOVED;
-                       locker.Unlock();
-
-                       delete entry;
-               }
-
-               return B_OK;
-       }
-
-       return protocol->next->module->control(protocol->next,
-               op, argument, length);
+status_t
+arp_control(net_datalink_protocol *_protocol, int32 op, void *argument,
+       size_t length)
+{
+       arp_protocol* protocol = (arp_protocol*)_protocol;
+       return protocol->next->module->control(protocol->next, op, argument,
+               length);
 }
 
 
@@ -1097,6 +1166,7 @@
        arp_send_data,
        arp_up,
        arp_down,
+       arp_change_address,
        arp_control,
        arp_join_multicast,
        arp_leave_multicast,
@@ -1104,12 +1174,13 @@
 
 
 module_dependency module_dependencies[] = {
-       {NET_STACK_MODULE_NAME, (module_info **)&sStackModule},
-       {NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule},
+       {NET_STACK_MODULE_NAME, (module_info**)&sStackModule},
+       {NET_DATALINK_MODULE_NAME, (module_info**)&sDatalinkModule},
+       {NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule},
        {}
 };
 
-module_info *modules[] = {
-       (module_info *)&sARPModule,
+module_info* modules[] = {
+       (module_info*)&sARPModule,
        NULL
 };

Modified: 
haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ethernet_frame/ethernet_frame.cpp
===================================================================
--- 
haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ethernet_frame/ethernet_frame.cpp
 2010-07-28 17:09:12 UTC (rev 37793)
+++ 
haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ethernet_frame/ethernet_frame.cpp
 2010-07-28 17:38:23 UTC (rev 37794)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -30,23 +30,23 @@
 
 static const uint8 kBroadcastAddress[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
-struct net_buffer_module_info *gBufferModule;
+struct net_buffer_module_info* gBufferModule;
 
 
 int32
-ethernet_deframe(net_device *device, net_buffer *buffer)
+ethernet_deframe(net_device* device, net_buffer* buffer)
 {
        //dprintf("asked to deframe buffer for device %s\n", device->name);

[... truncated: 6933 lines follow ...]

Other related posts: