From b216fbd0774446feb184ec1be17bb52bcbd75bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 28 Jul 2010 17:09:12 +0000 Subject: [PATCH] * Applied next work in progress patch by Atis that takes into account most of my comments so far. Thanks! git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37793 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/net/net_datalink.h | 4 +- headers/private/net/net_datalink_protocol.h | 1 - .../network/datalink_protocols/arp/arp.cpp | 1 - .../ethernet_frame/ethernet_frame.cpp | 1 - .../ipv4_datagram/ipv4_datagram.cpp | 2 +- .../datalink_protocols/ipv6_datagram/Jamfile | 1 + .../ipv6_datagram/ipv6_datagram.cpp | 114 ++++++++++++------ .../datalink_protocols/ipv6_datagram/ndp.h | 19 +++ .../loopback_frame/loopback_frame.cpp | 1 - .../kernel/network/protocols/icmp6/Jamfile | 2 + .../kernel/network/protocols/icmp6/icmp6.cpp | 54 ++++----- .../network/protocols/ipv4/ipv4_address.cpp | 2 +- .../kernel/network/protocols/ipv6/ipv6.cpp | 56 ++++++--- .../network/protocols/ipv6/ipv6_address.cpp | 12 +- .../network/protocols/l2cap/l2cap_address.cpp | 2 +- .../kernel/network/protocols/tcp/tcp.cpp | 18 +++ .../network/protocols/unix/UnixAddress.cpp | 2 +- src/add-ons/kernel/network/stack/datalink.cpp | 8 +- 18 files changed, 200 insertions(+), 100 deletions(-) create mode 100644 src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ndp.h diff --git a/headers/private/net/net_datalink.h b/headers/private/net/net_datalink.h index cee52de71f..5e905e78a0 100644 --- a/headers/private/net/net_datalink.h +++ b/headers/private/net/net_datalink.h @@ -98,9 +98,11 @@ struct net_datalink_module_info { 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); diff --git a/headers/private/net/net_datalink_protocol.h b/headers/private/net/net_datalink_protocol.h index 48f500ca13..edaa94b4d4 100644 --- a/headers/private/net/net_datalink_protocol.h +++ b/headers/private/net/net_datalink_protocol.h @@ -24,7 +24,6 @@ struct net_datalink_protocol_module_info { 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); diff --git a/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp b/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp index a1c5584204..6c3ad9fdd8 100644 --- a/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp +++ b/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp @@ -1095,7 +1095,6 @@ static net_datalink_protocol_module_info sARPModule = { arp_init_protocol, arp_uninit_protocol, arp_send_data, - NULL, // receive_data arp_up, arp_down, arp_control, diff --git a/src/add-ons/kernel/network/datalink_protocols/ethernet_frame/ethernet_frame.cpp b/src/add-ons/kernel/network/datalink_protocols/ethernet_frame/ethernet_frame.cpp index c709b8bf24..52c15da78b 100644 --- a/src/add-ons/kernel/network/datalink_protocols/ethernet_frame/ethernet_frame.cpp +++ b/src/add-ons/kernel/network/datalink_protocols/ethernet_frame/ethernet_frame.cpp @@ -210,7 +210,6 @@ static net_datalink_protocol_module_info sEthernetFrameModule = { ethernet_frame_init, ethernet_frame_uninit, ethernet_frame_send_data, - NULL, // receive_data ethernet_frame_up, ethernet_frame_down, ethernet_frame_control, diff --git a/src/add-ons/kernel/network/datalink_protocols/ipv4_datagram/ipv4_datagram.cpp b/src/add-ons/kernel/network/datalink_protocols/ipv4_datagram/ipv4_datagram.cpp index c0804ff15e..b39d8074a6 100644 --- a/src/add-ons/kernel/network/datalink_protocols/ipv4_datagram/ipv4_datagram.cpp +++ b/src/add-ons/kernel/network/datalink_protocols/ipv4_datagram/ipv4_datagram.cpp @@ -127,6 +127,7 @@ ipv4_datalink_std_ops(int32 op, ...) return B_ERROR; } + net_datalink_protocol_module_info gIPv4DataLinkModule = { { "network/datalink_protocols/ipv4_datagram/v1", @@ -136,7 +137,6 @@ net_datalink_protocol_module_info gIPv4DataLinkModule = { ipv4_datalink_init, ipv4_datalink_uninit, ipv4_datalink_send_data, - NULL, // receive_data ipv4_datalink_up, ipv4_datalink_down, ipv4_datalink_control, diff --git a/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/Jamfile b/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/Jamfile index 1daaf0c336..f65a1c841f 100644 --- a/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/Jamfile +++ b/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/Jamfile @@ -12,6 +12,7 @@ if $(TARGET_PLATFORM) != haiku { UsePrivateKernelHeaders ; UsePrivateHeaders kernel net ; +UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network protocols ] : true ; KernelAddon ipv6_datagram : ipv6_datagram.cpp diff --git a/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp b/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp index e757c35367..0d53047605 100644 --- a/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp +++ b/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp @@ -31,8 +31,9 @@ #include -#include "../../protocols/ipv6/jenkins.h" // TODO: move this file -#include "../../protocols/ipv6/ipv6_address.h" +#include +#include +#include "ndp.h" #define TRACE_NDP @@ -83,6 +84,18 @@ struct neighbor_discovery_header { 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; @@ -532,8 +545,10 @@ ndp_update_local(ipv6_datalink_protocol* protocol) static status_t -handle_neighbor_solicitation(net_buffer* buffer) +ndp_receive_solicitation(net_buffer* buffer, bool* reuseBuffer) { + *reuseBuffer = false; + NetBufferHeaderReader bufferHeader(buffer); if (bufferHeader.Status() < B_OK) return bufferHeader.Status(); @@ -594,22 +609,19 @@ handle_neighbor_solicitation(net_buffer* buffer) 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) @@ -641,6 +653,53 @@ handle_neighbor_advertisement(net_buffer* buffer) } +static void +ndp_receive_router_advertisement(net_buffer* buffer) +{ + NetBufferHeaderReader 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 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) { @@ -897,30 +956,6 @@ ipv6_datalink_send_data(net_datalink_protocol* _protocol, net_buffer* buffer) } -static status_t -ipv6_datalink_receive_data(net_buffer* buffer) -{ - NetBufferHeaderReader 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) { @@ -1058,6 +1093,7 @@ ipv6_datalink_std_ops(int32 op, ...) return B_ERROR; } + net_datalink_protocol_module_info gIPv6DataLinkModule = { { "network/datalink_protocols/ipv6_datagram/v1", @@ -1067,7 +1103,6 @@ net_datalink_protocol_module_info gIPv6DataLinkModule = { 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 @@ net_datalink_protocol_module_info gIPv6DataLinkModule = { 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_dependency module_dependencies[] = { module_info* modules[] = { (module_info*)&gIPv6DataLinkModule, + (module_info*)&gIPv6NDPModule, NULL }; diff --git a/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ndp.h b/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ndp.h new file mode 100644 index 0000000000..25f7888139 --- /dev/null +++ b/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ndp.h @@ -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 + + +struct net_ndp_module_info { + module_info info; + + status_t (*receive_data)(net_buffer* buffer); +}; + + +#endif // IPV6_NDP_H diff --git a/src/add-ons/kernel/network/datalink_protocols/loopback_frame/loopback_frame.cpp b/src/add-ons/kernel/network/datalink_protocols/loopback_frame/loopback_frame.cpp index 56a97a7f15..2f23a47fde 100644 --- a/src/add-ons/kernel/network/datalink_protocols/loopback_frame/loopback_frame.cpp +++ b/src/add-ons/kernel/network/datalink_protocols/loopback_frame/loopback_frame.cpp @@ -171,7 +171,6 @@ static net_datalink_protocol_module_info sLoopbackFrameModule = { loopback_frame_init, loopback_frame_uninit, loopback_frame_send_data, - NULL, // receive_data loopback_frame_up, loopback_frame_down, loopback_frame_control, diff --git a/src/add-ons/kernel/network/protocols/icmp6/Jamfile b/src/add-ons/kernel/network/protocols/icmp6/Jamfile index 30199a7e0e..132b227d9b 100644 --- a/src/add-ons/kernel/network/protocols/icmp6/Jamfile +++ b/src/add-ons/kernel/network/protocols/icmp6/Jamfile @@ -11,6 +11,8 @@ if $(TARGET_PLATFORM) != haiku { } 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 diff --git a/src/add-ons/kernel/network/protocols/icmp6/icmp6.cpp b/src/add-ons/kernel/network/protocols/icmp6/icmp6.cpp index 151b220b0a..9e2221c761 100644 --- a/src/add-ons/kernel/network/protocols/icmp6/icmp6.cpp +++ b/src/add-ons/kernel/network/protocols/icmp6/icmp6.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -19,7 +20,7 @@ #include #include -#include "../ipv6/ipv6_utils.h" // ipv6_checksum() +#include #define TRACE_ICMP6 @@ -35,7 +36,7 @@ typedef NetBufferField ICMP6ChecksumFi 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,17 +213,22 @@ icmp6_receive_data(net_buffer *buffer) TRACE((" got type %u, code %u, checksum 0x%x\n", header.icmp6_type, header.icmp6_code, header.icmp6_cksum)); + net_domain* domain; + if (buffer->interface != NULL) + domain = buffer->interface->domain; + else + domain = sStackModule->get_domain(buffer->source->sa_family); + + // TODO: possible? + if (domain == NULL || domain->module == NULL) + return B_ERROR; + + net_address_module_info* addressModule = domain->address_module; + // 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); - - TRACE((" computed checksum: %ld\n", checksum)); - - if (checksum != 0) - return B_BAD_DATA; + if (Checksum::PseudoHeader(addressModule, gBufferModule, buffer, + IPPROTO_ICMPV6) != 0) + return B_BAD_DATA; switch (header.icmp6_type) { case ICMP6_ECHO_REPLY: @@ -230,20 +236,13 @@ icmp6_receive_data(net_buffer *buffer) 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) @@ -260,11 +259,8 @@ icmp6_receive_data(net_buffer *buffer) 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 @@ icmp6_receive_data(net_buffer *buffer) } 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 @@ net_protocol_module_info sICMP6Module = { 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}, {} }; diff --git a/src/add-ons/kernel/network/protocols/ipv4/ipv4_address.cpp b/src/add-ons/kernel/network/protocols/ipv4/ipv4_address.cpp index d35d4c7a8c..59fc13862a 100644 --- a/src/add-ons/kernel/network/protocols/ipv4/ipv4_address.cpp +++ b/src/add-ons/kernel/network/protocols/ipv4/ipv4_address.cpp @@ -507,7 +507,7 @@ net_address_module_info gIPv4AddressModule = { 0, NULL }, - true, // has_broadcast_address + NET_ADDRESS_MODULE_FLAG_BROADCAST_ADDRESS, ipv4_copy_address, ipv4_mask_address, ipv4_equal_addresses, diff --git a/src/add-ons/kernel/network/protocols/ipv6/ipv6.cpp b/src/add-ons/kernel/network/protocols/ipv6/ipv6.cpp index 248752cc47..556c43857a 100644 --- a/src/add-ons/kernel/network/protocols/ipv6/ipv6.cpp +++ b/src/add-ons/kernel/network/protocols/ipv6/ipv6.cpp @@ -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 @@ uint16 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 @@ dump_ipv6_header(IPv6Header &header) 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 @@ ipv6_receive_data(net_buffer* buffer) 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 @@ ipv6_receive_data(net_buffer* buffer) // 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 @@ ipv6_error_reply(net_protocol* protocol, net_buffer* causedError, uint32 code, 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 @@ ipv6_std_ops(int32 op, ...) return init_ipv6(); case B_MODULE_UNINIT: return uninit_ipv6(); - default: return B_ERROR; } diff --git a/src/add-ons/kernel/network/protocols/ipv6/ipv6_address.cpp b/src/add-ons/kernel/network/protocols/ipv6/ipv6_address.cpp index 00d2429dbf..108bc1076f 100644 --- a/src/add-ons/kernel/network/protocols/ipv6/ipv6_address.cpp +++ b/src/add-ons/kernel/network/protocols/ipv6/ipv6_address.cpp @@ -247,8 +247,8 @@ ipv6_first_mask_bit(const sockaddr *_mask) 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 @@ ipv6_check_mask(const sockaddr *_mask) } 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 @@ ipv6_checksum_address(struct Checksum *checksum, const sockaddr *address) 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 @@ net_address_module_info gIPv6AddressModule = { 0, NULL }, - false, // has_broadcast_address + 0, // flags ipv6_copy_address, ipv6_mask_address, ipv6_equal_addresses, diff --git a/src/add-ons/kernel/network/protocols/l2cap/l2cap_address.cpp b/src/add-ons/kernel/network/protocols/l2cap/l2cap_address.cpp index c4a3472f2c..4d1521c24d 100644 --- a/src/add-ons/kernel/network/protocols/l2cap/l2cap_address.cpp +++ b/src/add-ons/kernel/network/protocols/l2cap/l2cap_address.cpp @@ -413,7 +413,7 @@ net_address_module_info gL2cap4AddressModule = { 0, NULL }, - true, // has_broadcast_address + NET_ADDRESS_MODULE_FLAG_BROADCAST_ADDRESS, l2cap_copy_address, l2cap_mask_address, l2cap_equal_addresses, diff --git a/src/add-ons/kernel/network/protocols/tcp/tcp.cpp b/src/add-ons/kernel/network/protocols/tcp/tcp.cpp index d8e45baba3..e48301bf1f 100644 --- a/src/add-ons/kernel/network/protocols/tcp/tcp.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/tcp.cpp @@ -756,6 +756,13 @@ tcp_init() 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 @@ tcp_init() 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"); diff --git a/src/add-ons/kernel/network/protocols/unix/UnixAddress.cpp b/src/add-ons/kernel/network/protocols/unix/UnixAddress.cpp index bbde876c9c..0f580e5f4f 100644 --- a/src/add-ons/kernel/network/protocols/unix/UnixAddress.cpp +++ b/src/add-ons/kernel/network/protocols/unix/UnixAddress.cpp @@ -290,7 +290,7 @@ net_address_module_info gAddressModule = { 0, NULL }, - true, // has_broadcast_address + NET_ADDRESS_MODULE_FLAG_BROADCAST_ADDRESS, unix_copy_address, unix_mask_address, unix_equal_addresses, diff --git a/src/add-ons/kernel/network/stack/datalink.cpp b/src/add-ons/kernel/network/stack/datalink.cpp index 9dd1acc305..532d897d95 100644 --- a/src/add-ons/kernel/network/stack/datalink.cpp +++ b/src/add-ons/kernel/network/stack/datalink.cpp @@ -30,7 +30,9 @@ #include #include -#include // TODO +// TODO: this is only needed for IPv6 multicast route code; +// remove it when the code will be refactored +#include struct datalink_protocol : net_protocol { @@ -752,7 +754,8 @@ interface_protocol_control(net_datalink_protocol* _protocol, int32 option, // 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 @@ net_datalink_protocol_module_info gDatalinkInterfaceProtocolModule = { interface_protocol_init, interface_protocol_uninit, interface_protocol_send_data, - NULL, // receive_data interface_protocol_up, interface_protocol_down, interface_protocol_control,