* 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
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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<neighbor_discovery_header> 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<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)
|
||||
{
|
||||
@@ -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<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)
|
||||
{
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 @@ typedef NetBufferField<uint16, offsetof(icmp6_hdr, icmp6_cksum)> 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},
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 @@ 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,
|
||||
|
||||
Reference in New Issue
Block a user