Author: axeld Date: 2010-07-28 19:09:12 +0200 (Wed, 28 Jul 2010) New Revision: 37793 Changeset: http://dev.haiku-os.org/changeset/37793 Added: haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ndp.h Modified: 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/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/ipv4_datagram/ipv4_datagram.cpp haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/Jamfile 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/icmp6/Jamfile haiku/trunk/src/add-ons/kernel/network/protocols/icmp6/icmp6.cpp haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/ipv4_address.cpp haiku/trunk/src/add-ons/kernel/network/protocols/ipv6/ipv6.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/tcp.cpp haiku/trunk/src/add-ons/kernel/network/protocols/unix/UnixAddress.cpp haiku/trunk/src/add-ons/kernel/network/stack/datalink.cpp Log: * Applied next work in progress patch by Atis that takes into account most of my comments so far. Thanks! Modified: haiku/trunk/headers/private/net/net_datalink.h =================================================================== --- haiku/trunk/headers/private/net/net_datalink.h 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/headers/private/net/net_datalink.h 2010-07-28 17:09:12 UTC (rev 37793) @@ -98,9 +98,11 @@ struct net_route_info *info); }; +#define NET_ADDRESS_MODULE_FLAG_BROADCAST_ADDRESS 0x01 + struct net_address_module_info { module_info info; - bool has_broadcast_address; + uint32 flags; status_t (*copy_address)(const sockaddr *from, sockaddr **to, bool replaceWithZeros, const sockaddr *mask); Modified: haiku/trunk/headers/private/net/net_datalink_protocol.h =================================================================== --- haiku/trunk/headers/private/net/net_datalink_protocol.h 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/headers/private/net/net_datalink_protocol.h 2010-07-28 17:09:12 UTC (rev 37793) @@ -24,7 +24,6 @@ status_t (*send_data)(net_datalink_protocol *self, net_buffer *buffer); - status_t (*receive_data)(net_buffer *buffer); status_t (*interface_up)(net_datalink_protocol *self); void (*interface_down)(net_datalink_protocol *self); 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 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp 2010-07-28 17:09:12 UTC (rev 37793) @@ -1095,7 +1095,6 @@ arp_init_protocol, arp_uninit_protocol, arp_send_data, - NULL, // receive_data arp_up, arp_down, arp_control, 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 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ethernet_frame/ethernet_frame.cpp 2010-07-28 17:09:12 UTC (rev 37793) @@ -210,7 +210,6 @@ ethernet_frame_init, ethernet_frame_uninit, ethernet_frame_send_data, - NULL, // receive_data ethernet_frame_up, ethernet_frame_down, ethernet_frame_control, Modified: haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv4_datagram/ipv4_datagram.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv4_datagram/ipv4_datagram.cpp 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv4_datagram/ipv4_datagram.cpp 2010-07-28 17:09:12 UTC (rev 37793) @@ -127,6 +127,7 @@ return B_ERROR; } + net_datalink_protocol_module_info gIPv4DataLinkModule = { { "network/datalink_protocols/ipv4_datagram/v1", @@ -136,7 +137,6 @@ ipv4_datalink_init, ipv4_datalink_uninit, ipv4_datalink_send_data, - NULL, // receive_data ipv4_datalink_up, ipv4_datalink_down, ipv4_datalink_control, Modified: haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/Jamfile =================================================================== --- haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/Jamfile 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/Jamfile 2010-07-28 17:09:12 UTC (rev 37793) @@ -12,6 +12,7 @@ UsePrivateKernelHeaders ; UsePrivateHeaders kernel net ; +UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network protocols ] : true ; KernelAddon ipv6_datagram : ipv6_datagram.cpp Modified: haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp 2010-07-28 17:09:12 UTC (rev 37793) @@ -31,8 +31,9 @@ #include <new> -#include "../../protocols/ipv6/jenkins.h" // TODO: move this file -#include "../../protocols/ipv6/ipv6_address.h" +#include <ipv6/jenkins.h> +#include <ipv6/ipv6_address.h> +#include "ndp.h" #define TRACE_NDP @@ -83,7 +84,19 @@ uint8 link_address[ETHER_ADDRESS_LENGTH]; } _PACKED; +struct router_advertisement_header { + uint8 icmp6_type; + uint8 icmp6_code; + uint16 icmp6_checksum; + uint8 hop_limit; + uint8 flags; + uint16 router_lifetime; + uint32 reachable_time; + uint32 retransmit_timer; + uint8 options[]; +} _PACKED; + struct ndp_entry { ndp_entry* next; in6_addr protocol_address; @@ -532,8 +545,10 @@ static status_t -handle_neighbor_solicitation(net_buffer* buffer) +ndp_receive_solicitation(net_buffer* buffer, bool* reuseBuffer) { + *reuseBuffer = false; + NetBufferHeaderReader<neighbor_discovery_header> bufferHeader(buffer); if (bufferHeader.Status() < B_OK) return bufferHeader.Status(); @@ -594,22 +609,19 @@ buffer->flags = 0; // make sure this won't be a broadcast message - // TODO: there is not need to clone, could reuse old buffer - net_buffer* clone = gBufferModule->clone(buffer, true); - if (clone == NULL) - return B_NO_MEMORY; - if (sIPv6Protocol == NULL) return B_ERROR; + *reuseBuffer = true; + // send the ICMPv6 packet out TRACE(("Sending Neighbor Advertisement\n")); - return sIPv6Module->send_data(sIPv6Protocol, clone); + return sIPv6Module->send_data(sIPv6Protocol, buffer); } static void -handle_neighbor_advertisement(net_buffer* buffer) +ndp_receive_advertisement(net_buffer* buffer) { // TODO: also process unsolicited advertisments? if ((buffer->flags & MSG_MCAST) != 0) @@ -642,6 +654,53 @@ static void +ndp_receive_router_advertisement(net_buffer* buffer) +{ + NetBufferHeaderReader<router_advertisement_header> bufferHeader(buffer); + if (bufferHeader.Status() < B_OK) + return; + + // TODO: check for validity + + // TODO: parse the options +} + + +static status_t +ndp_receive_data(net_buffer* buffer) +{ + dprintf("ndp_receive_data\n"); + + NetBufferHeaderReader<icmp6_hdr> icmp6Header(buffer); + if (icmp6Header.Status() < B_OK) + return icmp6Header.Status(); + + bool reuseBuffer = false; + + switch (icmp6Header->icmp6_type) { + case ND_NEIGHBOR_SOLICIT: + TRACE((" received Neighbor Solicitation\n")); + ndp_receive_solicitation(buffer, &reuseBuffer); + break; + + case ND_NEIGHBOR_ADVERT: + TRACE((" received Neighbor Advertisement\n")); + ndp_receive_advertisement(buffer); + break; + + case ND_ROUTER_ADVERT: + TRACE((" received Router Advertisement\n")); + ndp_receive_router_advertisement(buffer); + break; + } + + if (reuseBuffer == false) + gBufferModule->free(buffer); + return B_OK; +} + + +static void ndp_timer(struct net_timer* timer, void* data) { ndp_entry* entry = (ndp_entry*)data; @@ -898,30 +957,6 @@ static status_t -ipv6_datalink_receive_data(net_buffer* buffer) -{ - NetBufferHeaderReader<icmp6_hdr> bufferHeader(buffer); - if (bufferHeader.Status() < B_OK) - return bufferHeader.Status(); - - switch (bufferHeader->icmp6_type) { - case ND_NEIGHBOR_SOLICIT: - TRACE((" received Neighbor Solicitation\n")); - handle_neighbor_solicitation(buffer); - break; - - case ND_NEIGHBOR_ADVERT: - TRACE((" received Neighbor Advertisement\n")); - handle_neighbor_advertisement(buffer); - break; - } - - gBufferModule->free(buffer); - return B_OK; -} - - -static status_t ipv6_datalink_up(net_datalink_protocol* _protocol) { ipv6_datalink_protocol* protocol = (ipv6_datalink_protocol*)_protocol; @@ -1058,6 +1093,7 @@ return B_ERROR; } + net_datalink_protocol_module_info gIPv6DataLinkModule = { { "network/datalink_protocols/ipv6_datagram/v1", @@ -1067,7 +1103,6 @@ ipv6_datalink_init, ipv6_datalink_uninit, ipv6_datalink_send_data, - ipv6_datalink_receive_data, ipv6_datalink_up, ipv6_datalink_down, ipv6_datalink_control, @@ -1075,6 +1110,14 @@ ipv6_datalink_leave_multicast, }; +net_ndp_module_info gIPv6NDPModule = { + { + "network/datalink_protocols/ipv6_datagram/ndp/v1", + 0, + NULL + }, + ndp_receive_data +}; module_dependency module_dependencies[] = { {NET_STACK_MODULE_NAME, (module_info**)&sStackModule}, @@ -1085,5 +1128,6 @@ module_info* modules[] = { (module_info*)&gIPv6DataLinkModule, + (module_info*)&gIPv6NDPModule, NULL }; Added: haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ndp.h =================================================================== --- haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ndp.h (rev 0) +++ haiku/trunk/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ndp.h 2010-07-28 17:09:12 UTC (rev 37793) @@ -0,0 +1,19 @@ +/* + * Copyright 2010, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef IPV6_NDP_H +#define IPV6_NDP_H + + +#include <net_buffer.h> + + +struct net_ndp_module_info { + module_info info; + + status_t (*receive_data)(net_buffer* buffer); +}; + + +#endif // IPV6_NDP_H Modified: haiku/trunk/src/add-ons/kernel/network/datalink_protocols/loopback_frame/loopback_frame.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/network/datalink_protocols/loopback_frame/loopback_frame.cpp 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/datalink_protocols/loopback_frame/loopback_frame.cpp 2010-07-28 17:09:12 UTC (rev 37793) @@ -171,7 +171,6 @@ loopback_frame_init, loopback_frame_uninit, loopback_frame_send_data, - NULL, // receive_data loopback_frame_up, loopback_frame_down, loopback_frame_control, Modified: haiku/trunk/src/add-ons/kernel/network/protocols/icmp6/Jamfile =================================================================== --- haiku/trunk/src/add-ons/kernel/network/protocols/icmp6/Jamfile 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/protocols/icmp6/Jamfile 2010-07-28 17:09:12 UTC (rev 37793) @@ -11,6 +11,8 @@ } UsePrivateHeaders kernel net ; +UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network protocols ] : true ; +UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network datalink_protocols ] : true ; KernelAddon icmp6 : icmp6.cpp Modified: haiku/trunk/src/add-ons/kernel/network/protocols/icmp6/icmp6.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/network/protocols/icmp6/icmp6.cpp 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/protocols/icmp6/icmp6.cpp 2010-07-28 17:09:12 UTC (rev 37793) @@ -8,6 +8,7 @@ #include <net_protocol.h> #include <net_stack.h> #include <net_datalink_protocol.h> +#include <NetUtilities.h> #include <NetBufferUtilities.h> #include <KernelExport.h> @@ -19,7 +20,7 @@ #include <stdlib.h> #include <string.h> -#include "../ipv6/ipv6_utils.h" // ipv6_checksum() +#include <ipv6_datagram/ndp.h> #define TRACE_ICMP6 @@ -35,7 +36,7 @@ net_buffer_module_info *gBufferModule; static net_stack_module_info *sStackModule; -static net_datalink_protocol_module_info *sIPv6DatalinkModule; +static net_ndp_module_info *sIPv6NDPModule; net_protocol * @@ -212,39 +213,37 @@ TRACE((" got type %u, code %u, checksum 0x%x\n", header.icmp6_type, header.icmp6_code, header.icmp6_cksum)); - // compute and check the checksum - uint16 checksum; - checksum = gBufferModule->checksum(buffer, 0, buffer->size, false); - checksum = ipv6_checksum(&((sockaddr_in6*)buffer->source)->sin6_addr, - &((sockaddr_in6*)buffer->destination)->sin6_addr, - buffer->size, IPPROTO_ICMPV6, checksum); + net_domain* domain; + if (buffer->interface != NULL) + domain = buffer->interface->domain; + else + domain = sStackModule->get_domain(buffer->source->sa_family); - TRACE((" computed checksum: %ld\n", checksum)); + // TODO: possible? + if (domain == NULL || domain->module == NULL) + return B_ERROR; - if (checksum != 0) - return B_BAD_DATA; + net_address_module_info* addressModule = domain->address_module; + // compute and check the checksum + if (Checksum::PseudoHeader(addressModule, gBufferModule, buffer, + IPPROTO_ICMPV6) != 0) + return B_BAD_DATA; + switch (header.icmp6_type) { case ICMP6_ECHO_REPLY: break; case ICMP6_ECHO_REQUEST: { - net_domain *domain; if (buffer->interface != NULL) { - domain = buffer->interface->domain; - // We only reply to echo requests of our local interface; we // don't reply to broadcast requests if (!domain->address_module->equal_addresses( buffer->interface->address, buffer->destination)) break; - } else - domain = sStackModule->get_domain(buffer->source->sa_family); + } - if (domain == NULL || domain->module == NULL) - break; - net_buffer *reply = gBufferModule->duplicate(buffer); if (reply == NULL) return B_NO_MEMORY; @@ -260,11 +259,8 @@ header.Sync(); - checksum = gBufferModule->checksum(buffer, 0, buffer->size, false); - *ICMP6ChecksumField(reply) = - ipv6_checksum(&((sockaddr_in6*)buffer->source)->sin6_addr, - &((sockaddr_in6*)buffer->destination)->sin6_addr, - buffer->size, IPPROTO_ICMPV6, checksum); + *ICMP6ChecksumField(reply) = Checksum::PseudoHeader(addressModule, + gBufferModule, buffer, IPPROTO_ICMPV6); status_t status = domain->module->send_data(NULL, reply); if (status < B_OK) { @@ -274,8 +270,8 @@ } default: - // forward unrecognized messages to datalink layer - return sIPv6DatalinkModule->receive_data(buffer); + // unrecognized messages go to neighbor discovery protocol handler + return sIPv6NDPModule->receive_data(buffer); } gBufferModule->free(buffer); @@ -383,8 +379,8 @@ module_dependency module_dependencies[] = { {NET_STACK_MODULE_NAME, (module_info **)&sStackModule}, {NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule}, - {"network/datalink_protocols/ipv6_datagram/v1", - (module_info **)&sIPv6DatalinkModule}, + {"network/datalink_protocols/ipv6_datagram/ndp/v1", + (module_info **)&sIPv6NDPModule}, {} }; Modified: haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/ipv4_address.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/ipv4_address.cpp 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/protocols/ipv4/ipv4_address.cpp 2010-07-28 17:09:12 UTC (rev 37793) @@ -507,7 +507,7 @@ 0, NULL }, - true, // has_broadcast_address + NET_ADDRESS_MODULE_FLAG_BROADCAST_ADDRESS, ipv4_copy_address, ipv4_mask_address, ipv4_equal_addresses, Modified: haiku/trunk/src/add-ons/kernel/network/protocols/ipv6/ipv6.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/network/protocols/ipv6/ipv6.cpp 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/protocols/ipv6/ipv6.cpp 2010-07-28 17:09:12 UTC (rev 37793) @@ -52,13 +52,13 @@ struct IPv6Header { - struct ip6_hdr h; + struct ip6_hdr header; - uint8 ProtocolVersion() const { return h.ip6_vfc & IPV6_VERSION_MASK; } - uint8 ServiceType() const { return ntohl(h.ip6_flow) >> 20;} - uint16 PayloadLength() const { return ntohs(h.ip6_plen); } - const in6_addr& Dst() const { return h.ip6_dst; } - const in6_addr& Src() const { return h.ip6_src; } + uint8 ProtocolVersion() const { return header.ip6_vfc & IPV6_VERSION_MASK; } + uint8 ServiceType() const { return ntohl(header.ip6_flow) >> 20;} + uint16 PayloadLength() const { return ntohs(header.ip6_plen); } + const in6_addr& Dst() const { return header.ip6_dst; } + const in6_addr& Src() const { return header.ip6_src; } uint16 GetTransportHeaderOffset(net_buffer* buffer) const; }; @@ -139,7 +139,7 @@ IPv6Header::GetTransportHeaderOffset(net_buffer* buffer) const { uint16 offset = sizeof(struct ip6_hdr); - uint8 next = h.ip6_nxt; + uint8 next = header.ip6_nxt; // these are the extension headers that might be supported one day while (next == IPPROTO_HOPOPTS @@ -192,10 +192,11 @@ dprintf(" version: %d\n", header.ProtocolVersion() >> 4); dprintf(" service_type: %d\n", header.ServiceType()); dprintf(" payload_length: %d\n", header.PayloadLength()); - dprintf(" next_header: %d\n", header.h.ip6_nxt); - dprintf(" hop_limit: %d\n", header.h.ip6_hops); - dprintf(" source: %s\n", ip6_sprintf(&header.h.ip6_src, addrbuf)); - dprintf(" destination: %s\n", ip6_sprintf(&header.h.ip6_dst, addrbuf)); + dprintf(" next_header: %d\n", header.header.ip6_nxt); + dprintf(" hop_limit: %d\n", header.header.ip6_hops); + dprintf(" source: %s\n", ip6_sprintf(&header.header.ip6_src, addrbuf)); + dprintf(" destination: %s\n", + ip6_sprintf(&header.header.ip6_dst, addrbuf)); #endif } @@ -968,8 +969,6 @@ uint16 transportHeaderOffset = header.GetTransportHeaderOffset(buffer); uint8 protocol = buffer->protocol; - buffer->hoplimit = header.h.ip6_hlim; - // remove any trailing/padding data status_t status = gBufferModule->trim(buffer, packetLength); if (status != B_OK) @@ -979,8 +978,15 @@ // TODO: check for fragmentation // + // tell the buffer to preserve removed ipv6 header - may need it later + gBufferModule->store_header(buffer); + + TRACE("store_header for %p\n", buffer); + + // remove ipv6 headers for now gBufferModule->remove_header(buffer, transportHeaderOffset); + // deliver the data to raw sockets raw_receive_data(buffer); net_protocol_module_info* module = receiving_protocol(protocol); @@ -1029,30 +1035,45 @@ ssize_t -ipv6_process_ancillary_data_no_container(net_protocol* protocol, +ipv6_process_ancillary_data_no_container(net_protocol* _protocol, net_buffer* buffer, void* msgControl, size_t msgControlLen) { + ipv6_protocol* protocol = (ipv6_protocol*)_protocol; ssize_t bytesWritten = 0; - if (((ipv6_protocol*)protocol)->receive_hoplimit != 0) { + if (protocol->receive_hoplimit != 0) { TRACE("receive_hoplimit"); if (msgControlLen < CMSG_SPACE(sizeof(int))) return B_NO_MEMORY; + TRACE("restore_header for %p\n", buffer); + + if (gBufferModule->stored_header_length(buffer) + < (int)sizeof(ip6_hdr)) + return B_ERROR; + + IPv6Header header; + if (gBufferModule->restore_header(buffer, 0, &header, sizeof(ip6_hdr)) + != B_OK) + return B_ERROR; + + if (header.ProtocolVersion() != IPV6_VERSION) + return B_ERROR; + cmsghdr* messageHeader = (cmsghdr*)((char*)msgControl + bytesWritten); messageHeader->cmsg_len = CMSG_LEN(sizeof(int)); messageHeader->cmsg_level = IPPROTO_IPV6; messageHeader->cmsg_type = IPV6_HOPLIMIT; - int hoplimit = buffer->hoplimit; + int hoplimit = header.header.ip6_hlim; memcpy(CMSG_DATA(messageHeader), &hoplimit, sizeof(int)); bytesWritten += CMSG_SPACE(sizeof(int)); msgControlLen -= CMSG_SPACE(sizeof(int)); } - if (((ipv6_protocol*)protocol)->receive_pktinfo != 0) { + if (protocol->receive_pktinfo != 0) { TRACE("receive_pktinfo"); if (msgControlLen < CMSG_SPACE(sizeof(struct in6_pktinfo))) @@ -1161,7 +1182,6 @@ return init_ipv6(); case B_MODULE_UNINIT: return uninit_ipv6(); - default: return B_ERROR; } Modified: haiku/trunk/src/add-ons/kernel/network/protocols/ipv6/ipv6_address.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/network/protocols/ipv6/ipv6_address.cpp 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/protocols/ipv6/ipv6_address.cpp 2010-07-28 17:09:12 UTC (rev 37793) @@ -247,8 +247,8 @@ continue; for (uint8 bit = 0; bit < 8; bit++) { - if (pmask[i] & (1 << bit)) - return bit; + if ((pmask[i] & (1 << (7 - bit))) == 0) + return i * 8 + bit; } } @@ -276,7 +276,7 @@ } else if (pmask[i] == 0) { zero = true; } else { - for (int8 bit = 7; bit > 0; bit--) { + for (int8 bit = 7; bit >= 0; bit--) { if (pmask[i] & (1 << bit)) { if (zero) return false; @@ -520,8 +520,8 @@ return B_BAD_VALUE; in6_addr &a = ((sockaddr_in6 *)address)->sin6_addr; - for (uint32 i = 0; i < sizeof(in6_addr); i++) - (*checksum) << a.s6_addr[i]; + for (uint32 i = 0; i < sizeof(in6_addr); i += 2) + (*checksum) << *(uint16*)(a.s6_addr + i); return B_OK; } @@ -544,7 +544,7 @@ 0, NULL }, - false, // has_broadcast_address + 0, // flags ipv6_copy_address, ipv6_mask_address, ipv6_equal_addresses, Modified: haiku/trunk/src/add-ons/kernel/network/protocols/l2cap/l2cap_address.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/network/protocols/l2cap/l2cap_address.cpp 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/protocols/l2cap/l2cap_address.cpp 2010-07-28 17:09:12 UTC (rev 37793) @@ -413,7 +413,7 @@ 0, NULL }, - true, // has_broadcast_address + NET_ADDRESS_MODULE_FLAG_BROADCAST_ADDRESS, l2cap_copy_address, l2cap_mask_address, l2cap_equal_addresses, Modified: haiku/trunk/src/add-ons/kernel/network/protocols/tcp/tcp.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/network/protocols/tcp/tcp.cpp 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/protocols/tcp/tcp.cpp 2010-07-28 17:09:12 UTC (rev 37793) @@ -756,6 +756,13 @@ NULL); if (status < B_OK) return status; + status = gStackModule->register_domain_protocols(AF_INET6, + SOCK_STREAM, 0, + "network/protocols/tcp/v1", + "network/protocols/ipv6/v1", + NULL); + if (status < B_OK) + return status; status = gStackModule->register_domain_protocols(AF_INET, SOCK_STREAM, IPPROTO_TCP, @@ -764,11 +771,22 @@ NULL); if (status < B_OK) return status; + status = gStackModule->register_domain_protocols(AF_INET6, SOCK_STREAM, + IPPROTO_TCP, + "network/protocols/tcp/v1", + "network/protocols/ipv6/v1", + NULL); + if (status < B_OK) + return status; status = gStackModule->register_domain_receiving_protocol(AF_INET, IPPROTO_TCP, "network/protocols/tcp/v1"); if (status < B_OK) return status; + status = gStackModule->register_domain_receiving_protocol(AF_INET6, + IPPROTO_TCP, "network/protocols/tcp/v1"); + if (status < B_OK) + return status; add_debugger_command("tcp_endpoints", dump_endpoints, "lists all open TCP endpoints"); Modified: haiku/trunk/src/add-ons/kernel/network/protocols/unix/UnixAddress.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/network/protocols/unix/UnixAddress.cpp 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/protocols/unix/UnixAddress.cpp 2010-07-28 17:09:12 UTC (rev 37793) @@ -290,7 +290,7 @@ 0, NULL }, - true, // has_broadcast_address + NET_ADDRESS_MODULE_FLAG_BROADCAST_ADDRESS, unix_copy_address, unix_mask_address, unix_equal_addresses, Modified: haiku/trunk/src/add-ons/kernel/network/stack/datalink.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/network/stack/datalink.cpp 2010-07-28 16:26:53 UTC (rev 37792) +++ haiku/trunk/src/add-ons/kernel/network/stack/datalink.cpp 2010-07-28 17:09:12 UTC (rev 37793) @@ -30,7 +30,9 @@ #include <stdio.h> #include <string.h> -#include <netinet6/in6.h> // TODO +// TODO: this is only needed for IPv6 multicast route code; +// remove it when the code will be refactored +#include <netinet6/in6.h> struct datalink_protocol : net_protocol { @@ -752,7 +754,8 @@ // reset the broadcast address if the address family has such sockaddr* broadcast; - if (interface->domain->address_module->has_broadcast_address) { + if ((interface->domain->address_module->flags + & NET_ADDRESS_MODULE_FLAG_BROADCAST_ADDRESS) != 0) { broadcast = reallocate_address(&interface->destination, request.ifr_addr.sa_len); } else { @@ -971,7 +974,6 @@ interface_protocol_init, interface_protocol_uninit, interface_protocol_send_data, - NULL, // receive_data interface_protocol_up, interface_protocol_down, interface_protocol_control,