* Minor cleanup.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31079 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2009-06-17 10:00:26 +00:00
parent 75557e0ac3
commit e5c5e337e4

View File

@ -96,22 +96,25 @@ struct ipv4_packet_key {
}; };
class FragmentPacket { class FragmentPacket {
public: public:
FragmentPacket(const ipv4_packet_key &key); FragmentPacket(const ipv4_packet_key &key);
~FragmentPacket(); ~FragmentPacket();
status_t AddFragment(uint16 start, uint16 end, net_buffer *buffer, status_t AddFragment(uint16 start, uint16 end,
bool lastFragment); net_buffer *buffer, bool lastFragment);
status_t Reassemble(net_buffer *to); status_t Reassemble(net_buffer *to);
bool IsComplete() const { return fReceivedLastFragment && fBytesLeft == 0; } bool IsComplete() const
{ return fReceivedLastFragment
&& fBytesLeft == 0; }
static uint32 Hash(void *_packet, const void *_key, uint32 range); static uint32 Hash(void *_packet, const void *_key, uint32 range);
static int Compare(void *_packet, const void *_key); static int Compare(void *_packet, const void *_key);
static int32 NextOffset() { return offsetof(FragmentPacket, fNext); } static int32 NextOffset()
{ return offsetof(FragmentPacket, fNext); }
static void StaleTimer(struct net_timer *timer, void *data); static void StaleTimer(struct net_timer *timer, void *data);
private: private:
FragmentPacket *fNext; FragmentPacket *fNext;
struct ipv4_packet_key fKey; struct ipv4_packet_key fKey;
bool fReceivedLastFragment; bool fReceivedLastFragment;
@ -121,8 +124,9 @@ class FragmentPacket {
}; };
class RawSocket : public DoublyLinkedListLinkImpl<RawSocket>, public DatagramSocket<> { class RawSocket
public: : public DoublyLinkedListLinkImpl<RawSocket>, public DatagramSocket<> {
public:
RawSocket(net_socket *socket); RawSocket(net_socket *socket);
}; };
@ -152,7 +156,10 @@ struct MulticastStateHash {
struct ipv4_protocol : net_protocol { struct ipv4_protocol : net_protocol {
ipv4_protocol() ipv4_protocol()
: multicast_filter(this) {} :
multicast_filter(this)
{
}
RawSocket *raw; RawSocket *raw;
uint8 service_type; uint8 service_type;
@ -301,7 +308,7 @@ FragmentPacket::AddFragment(uint16 start, uint16 end, net_buffer *buffer,
status_t status = gBufferModule->merge(buffer, previous, false); status_t status = gBufferModule->merge(buffer, previous, false);
TRACE(" merge previous: %s", strerror(status)); TRACE(" merge previous: %s", strerror(status));
if (status < B_OK) { if (status != B_OK) {
fFragments.Insert(next, previous); fFragments.Insert(next, previous);
return status; return status;
} }
@ -327,7 +334,7 @@ FragmentPacket::AddFragment(uint16 start, uint16 end, net_buffer *buffer,
status_t status = gBufferModule->merge(buffer, next, true); status_t status = gBufferModule->merge(buffer, next, true);
TRACE(" merge next: %s", strerror(status)); TRACE(" merge next: %s", strerror(status));
if (status < B_OK) { if (status != B_OK) {
fFragments.Insert((net_buffer *)previous->link.next, next); fFragments.Insert((net_buffer *)previous->link.next, next);
return status; return status;
} }
@ -389,7 +396,7 @@ FragmentPacket::Reassemble(net_buffer *to)
buffer = fragment; buffer = fragment;
} else } else
status = gBufferModule->merge(buffer, fragment, true); status = gBufferModule->merge(buffer, fragment, true);
if (status < B_OK) if (status != B_OK)
return status; return status;
} else } else
buffer = fragment; buffer = fragment;
@ -484,8 +491,39 @@ dump_ipv4_header(ipv4_header &header)
#endif #endif
/*! static int
Attempts to re-assemble fragmented packets. dump_ipv4_multicast(int argc, char *argv[])
{
MulticastState::Iterator it = sMulticastState->GetIterator();
while (it.HasNext()) {
IPv4GroupInterface *state = it.Next();
char addressBuffer[64];
kprintf("%p: group <%s, %s, %s {", state, state->Interface()->name,
print_address(&state->Address(), addressBuffer,
sizeof(addressBuffer)),
state->Mode() == IPv4GroupInterface::kExclude
? "Exclude" : "Include");
int count = 0;
IPv4GroupInterface::AddressSet::Iterator it
= state->Sources().GetIterator();
while (it.HasNext()) {
kprintf("%s%s", count > 0 ? ", " : "", print_address(&it.Next(),
addressBuffer, sizeof(addressBuffer)));
count++;
}
kprintf("}> sock %p\n", state->Parent()->Socket());
}
return 0;
}
/*! Attempts to re-assemble fragmented packets.
\return B_OK if everything went well; if it could reassemble the packet, \a _buffer \return B_OK if everything went well; if it could reassemble the packet, \a _buffer
will point to its buffer, otherwise, it will be \c NULL. will point to its buffer, otherwise, it will be \c NULL.
\return various error codes if something went wrong (mostly B_NO_MEMORY) \return various error codes if something went wrong (mostly B_NO_MEMORY)
@ -538,7 +576,8 @@ reassemble_fragments(const ipv4_header &header, net_buffer **_buffer)
if (packet->IsComplete()) { if (packet->IsComplete()) {
hash_remove(sFragmentHash, packet); hash_remove(sFragmentHash, packet);
// no matter if reassembling succeeds, we won't need this packet anymore // no matter if reassembling succeeds, we won't need this packet
// anymore
status = packet->Reassemble(buffer); status = packet->Reassemble(buffer);
delete packet; delete packet;
@ -553,8 +592,7 @@ reassemble_fragments(const ipv4_header &header, net_buffer **_buffer)
} }
/*! /*! Fragments the incoming buffer and send all fragments via the specified
Fragments the incoming buffer and send all fragments via the specified
\a route. \a route.
*/ */
static status_t static status_t
@ -564,7 +602,7 @@ send_fragments(ipv4_protocol *protocol, struct net_route *route,
TRACE_SK(protocol, "SendFragments(%lu bytes, mtu %lu)", buffer->size, mtu); TRACE_SK(protocol, "SendFragments(%lu bytes, mtu %lu)", buffer->size, mtu);
NetBufferHeaderReader<ipv4_header> originalHeader(buffer); NetBufferHeaderReader<ipv4_header> originalHeader(buffer);
if (originalHeader.Status() < B_OK) if (originalHeader.Status() != B_OK)
return originalHeader.Status(); return originalHeader.Status();
uint16 headerLength = originalHeader->HeaderLength(); uint16 headerLength = originalHeader->HeaderLength();
@ -576,12 +614,13 @@ send_fragments(ipv4_protocol *protocol, struct net_route *route,
if (headerBuffer == NULL) if (headerBuffer == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
// TODO we need to make sure ipv4_header is contiguous or // TODO: we need to make sure ipv4_header is contiguous or
// use another construct. // use another construct.
NetBufferHeaderReader<ipv4_header> bufferHeader(headerBuffer); NetBufferHeaderReader<ipv4_header> bufferHeader(headerBuffer);
ipv4_header *header = &bufferHeader.Data(); ipv4_header *header = &bufferHeader.Data();
// adapt MTU to be a multiple of 8 (fragment offsets can only be specified this way) // Adapt MTU to be a multiple of 8 (fragment offsets can only be specified
// this way)
mtu -= headerLength; mtu -= headerLength;
mtu &= ~7; mtu &= ~7;
TRACE(" adjusted MTU to %ld\n", mtu); TRACE(" adjusted MTU to %ld\n", mtu);
@ -596,7 +635,8 @@ send_fragments(ipv4_protocol *protocol, struct net_route *route,
header->fragment_offset = htons((lastFragment ? 0 : IP_MORE_FRAGMENTS) header->fragment_offset = htons((lastFragment ? 0 : IP_MORE_FRAGMENTS)
| (fragmentOffset >> 3)); | (fragmentOffset >> 3));
header->checksum = 0; header->checksum = 0;
header->checksum = gStackModule->checksum((uint8 *)header, headerLength); header->checksum = gStackModule->checksum((uint8 *)header,
headerLength);
// TODO: compute the checksum only for those parts that changed? // TODO: compute the checksum only for those parts that changed?
TRACE(" send fragment of %ld bytes (%ld bytes left)\n", fragmentLength, bytesLeft); TRACE(" send fragment of %ld bytes (%ld bytes left)\n", fragmentLength, bytesLeft);
@ -625,7 +665,7 @@ send_fragments(ipv4_protocol *protocol, struct net_route *route,
break; break;
} }
if (status < B_OK) { if (status != B_OK) {
gBufferModule->free(fragmentBuffer); gBufferModule->free(fragmentBuffer);
break; break;
} }
@ -660,8 +700,8 @@ deliver_multicast(net_protocol_module_info *module, net_buffer *buffer,
// as Multicast filters are installed with an IPv4 protocol // as Multicast filters are installed with an IPv4 protocol
// reference, we need to go and find the appropriate instance // reference, we need to go and find the appropriate instance
// related to the 'receiving protocol' with module 'module'. // related to the 'receiving protocol' with module 'module'.
net_protocol *proto = net_protocol *proto
state->Parent()->Socket()->socket->first_protocol; = state->Parent()->Socket()->socket->first_protocol;
while (proto && proto->module != module) while (proto && proto->module != module)
proto = proto->next; proto = proto->next;
@ -725,7 +765,7 @@ IPv4Multicast::JoinGroup(IPv4GroupInterface *state)
status_t status = intf->first_info->join_multicast(intf->first_protocol, status_t status = intf->first_info->join_multicast(intf->first_protocol,
fill_sockaddr_in(&groupAddr, state->Address())); fill_sockaddr_in(&groupAddr, state->Address()));
if (status < B_OK) if (status != B_OK)
return status; return status;
sMulticastState->Insert(state); sMulticastState->Insert(state);
@ -761,7 +801,8 @@ receiving_protocol(uint8 protocol)
if (module != NULL) if (module != NULL)
return module; return module;
if (gStackModule->get_domain_receiving_protocol(sDomain, protocol, &module) == B_OK) if (gStackModule->get_domain_receiving_protocol(sDomain, protocol,
&module) == B_OK)
sReceivingProtocol[protocol] = module; sReceivingProtocol[protocol] = module;
return module; return module;
@ -826,13 +867,13 @@ ipv4_delta_membership(ipv4_protocol *protocol, int option,
if (option == IP_DROP_MEMBERSHIP if (option == IP_DROP_MEMBERSHIP
|| option == IP_DROP_SOURCE_MEMBERSHIP) || option == IP_DROP_SOURCE_MEMBERSHIP)
return EADDRNOTAVAIL; return EADDRNOTAVAIL;
else
return EINVAL; return B_BAD_VALUE;
} }
break; break;
} }
if (status < B_OK) if (status != B_OK)
return status; return status;
status = ipv4_delta_group(state, option, interface, sourceAddr); status = ipv4_delta_group(state, option, interface, sourceAddr);
@ -930,6 +971,32 @@ ipv4_generic_delta_membership(ipv4_protocol *protocol, int option,
} }
static status_t
get_int_option(void *target, size_t length, int value)
{
if (length != sizeof(int))
return B_BAD_VALUE;
return user_memcpy(target, &value, sizeof(int));
}
template<typename Type> static status_t
set_int_option(Type &target, const void *_value, size_t length)
{
int value;
if (length != sizeof(int))
return B_BAD_VALUE;
if (user_memcpy(&value, _value, sizeof(int)) != B_OK)
return B_BAD_ADDRESS;
target = value;
return B_OK;
}
// #pragma mark - // #pragma mark -
@ -960,8 +1027,7 @@ ipv4_uninit_protocol(net_protocol *_protocol)
} }
/*! /*! Since open() is only called on the top level protocol, when we get here
Since open() is only called on the top level protocol, when we get here
it means we are on a SOCK_RAW socket. it means we are on a SOCK_RAW socket.
*/ */
status_t status_t
@ -974,7 +1040,7 @@ ipv4_open(net_protocol *_protocol)
return B_NO_MEMORY; return B_NO_MEMORY;
status_t status = raw->InitCheck(); status_t status = raw->InitCheck();
if (status < B_OK) { if (status != B_OK) {
delete raw; delete raw;
return status; return status;
} }
@ -1029,32 +1095,6 @@ ipv4_accept(net_protocol *protocol, struct net_socket **_acceptedSocket)
} }
static status_t
get_int_option(void *target, size_t length, int value)
{
if (length != sizeof(int))
return B_BAD_VALUE;
return user_memcpy(target, &value, sizeof(int));
}
template<typename Type> static status_t
set_int_option(Type &target, const void *_value, size_t length)
{
int value;
if (length != sizeof(int))
return B_BAD_VALUE;
if (user_memcpy(&value, _value, sizeof(int)) < B_OK)
return B_BAD_ADDRESS;
target = value;
return B_OK;
}
status_t status_t
ipv4_control(net_protocol *_protocol, int level, int option, void *value, ipv4_control(net_protocol *_protocol, int level, int option, void *value,
size_t *_length) size_t *_length)
@ -1073,17 +1113,19 @@ ipv4_getsockopt(net_protocol *_protocol, int level, int option, void *value,
ipv4_protocol *protocol = (ipv4_protocol *)_protocol; ipv4_protocol *protocol = (ipv4_protocol *)_protocol;
if (level == IPPROTO_IP) { if (level == IPPROTO_IP) {
if (option == IP_HDRINCL) if (option == IP_HDRINCL) {
return get_int_option(value, *_length, return get_int_option(value, *_length,
(protocol->flags & IP_FLAG_HEADER_INCLUDED) != 0); (protocol->flags & IP_FLAG_HEADER_INCLUDED) != 0);
else if (option == IP_TTL) }
if (option == IP_TTL)
return get_int_option(value, *_length, protocol->time_to_live); return get_int_option(value, *_length, protocol->time_to_live);
else if (option == IP_TOS) if (option == IP_TOS)
return get_int_option(value, *_length, protocol->service_type); return get_int_option(value, *_length, protocol->service_type);
else if (IP_MULTICAST_TTL) if (IP_MULTICAST_TTL) {
return get_int_option(value, *_length, return get_int_option(value, *_length,
protocol->multicast_time_to_live); protocol->multicast_time_to_live);
else if (option == IP_ADD_MEMBERSHIP }
if (option == IP_ADD_MEMBERSHIP
|| option == IP_DROP_MEMBERSHIP || option == IP_DROP_MEMBERSHIP
|| option == IP_BLOCK_SOURCE || option == IP_BLOCK_SOURCE
|| option == IP_UNBLOCK_SOURCE || option == IP_UNBLOCK_SOURCE
@ -1099,11 +1141,11 @@ ipv4_getsockopt(net_protocol *_protocol, int level, int option, void *value,
// ``An error of EOPNOTSUPP is returned if these options are // ``An error of EOPNOTSUPP is returned if these options are
// used with getsockopt().'' // used with getsockopt().''
return EOPNOTSUPP; return EOPNOTSUPP;
} else { }
dprintf("IPv4::getsockopt(): get unknown option: %d\n", option); dprintf("IPv4::getsockopt(): get unknown option: %d\n", option);
return ENOPROTOOPT; return ENOPROTOOPT;
} }
}
return sSocketModule->get_option(protocol->socket, level, option, value, return sSocketModule->get_option(protocol->socket, level, option, value,
_length); _length);
@ -1121,70 +1163,75 @@ ipv4_setsockopt(net_protocol *_protocol, int level, int option,
int headerIncluded; int headerIncluded;
if (length != sizeof(int)) if (length != sizeof(int))
return B_BAD_VALUE; return B_BAD_VALUE;
if (user_memcpy(&headerIncluded, value, sizeof(headerIncluded)) < B_OK) if (user_memcpy(&headerIncluded, value, sizeof(headerIncluded))
!= B_OK)
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
if (headerIncluded) if (headerIncluded)
protocol->flags |= IP_FLAG_HEADER_INCLUDED; protocol->flags |= IP_FLAG_HEADER_INCLUDED;
else else
protocol->flags &= ~IP_FLAG_HEADER_INCLUDED; protocol->flags &= ~IP_FLAG_HEADER_INCLUDED;
return B_OK; return B_OK;
} else if (option == IP_TTL) { }
if (option == IP_TTL)
return set_int_option(protocol->time_to_live, value, length); return set_int_option(protocol->time_to_live, value, length);
} else if (option == IP_TOS) { if (option == IP_TOS)
return set_int_option(protocol->service_type, value, length); return set_int_option(protocol->service_type, value, length);
} else if (option == IP_MULTICAST_TTL) { if (option == IP_MULTICAST_TTL) {
return set_int_option(protocol->multicast_time_to_live, value, return set_int_option(protocol->multicast_time_to_live, value,
length); length);
} else if (option == IP_ADD_MEMBERSHIP }
|| option == IP_DROP_MEMBERSHIP) { if (option == IP_ADD_MEMBERSHIP || option == IP_DROP_MEMBERSHIP) {
ip_mreq mreq; ip_mreq mreq;
if (length != sizeof(ip_mreq)) if (length != sizeof(ip_mreq))
return B_BAD_VALUE; return B_BAD_VALUE;
if (user_memcpy(&mreq, value, sizeof(ip_mreq)) < B_OK) if (user_memcpy(&mreq, value, sizeof(ip_mreq)) != B_OK)
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
return ipv4_delta_membership(protocol, option, &mreq.imr_interface, return ipv4_delta_membership(protocol, option, &mreq.imr_interface,
&mreq.imr_multiaddr, NULL); &mreq.imr_multiaddr, NULL);
} else if (option == IP_BLOCK_SOURCE }
if (option == IP_BLOCK_SOURCE
|| option == IP_UNBLOCK_SOURCE || option == IP_UNBLOCK_SOURCE
|| option == IP_ADD_SOURCE_MEMBERSHIP || option == IP_ADD_SOURCE_MEMBERSHIP
|| option == IP_DROP_SOURCE_MEMBERSHIP) { || option == IP_DROP_SOURCE_MEMBERSHIP) {
ip_mreq_source mreq; ip_mreq_source mreq;
if (length != sizeof(ip_mreq_source)) if (length != sizeof(ip_mreq_source))
return B_BAD_VALUE; return B_BAD_VALUE;
if (user_memcpy(&mreq, value, sizeof(ip_mreq_source)) < B_OK) if (user_memcpy(&mreq, value, sizeof(ip_mreq_source)) != B_OK)
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
return ipv4_delta_membership(protocol, option, &mreq.imr_interface, return ipv4_delta_membership(protocol, option, &mreq.imr_interface,
&mreq.imr_multiaddr, &mreq.imr_sourceaddr); &mreq.imr_multiaddr, &mreq.imr_sourceaddr);
} else if (option == MCAST_LEAVE_GROUP }
|| option == MCAST_JOIN_GROUP) { if (option == MCAST_LEAVE_GROUP || option == MCAST_JOIN_GROUP) {
group_req greq; group_req greq;
if (length != sizeof(group_req)) if (length != sizeof(group_req))
return B_BAD_VALUE; return B_BAD_VALUE;
if (user_memcpy(&greq, value, sizeof(group_req)) < B_OK) if (user_memcpy(&greq, value, sizeof(group_req)) != B_OK)
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
return ipv4_generic_delta_membership(protocol, option, return ipv4_generic_delta_membership(protocol, option,
greq.gr_interface, &greq.gr_group, NULL); greq.gr_interface, &greq.gr_group, NULL);
} else if (option == MCAST_BLOCK_SOURCE }
if (option == MCAST_BLOCK_SOURCE
|| option == MCAST_UNBLOCK_SOURCE || option == MCAST_UNBLOCK_SOURCE
|| option == MCAST_JOIN_SOURCE_GROUP || option == MCAST_JOIN_SOURCE_GROUP
|| option == MCAST_LEAVE_SOURCE_GROUP) { || option == MCAST_LEAVE_SOURCE_GROUP) {
group_source_req greq; group_source_req greq;
if (length != sizeof(group_source_req)) if (length != sizeof(group_source_req))
return B_BAD_VALUE; return B_BAD_VALUE;
if (user_memcpy(&greq, value, sizeof(group_source_req)) < B_OK) if (user_memcpy(&greq, value, sizeof(group_source_req)) != B_OK)
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
return ipv4_generic_delta_membership(protocol, option, return ipv4_generic_delta_membership(protocol, option,
greq.gsr_interface, &greq.gsr_group, &greq.gsr_source); greq.gsr_interface, &greq.gsr_group, &greq.gsr_source);
} else { }
dprintf("IPv4::setsockopt(): set unknown option: %d\n", option); dprintf("IPv4::setsockopt(): set unknown option: %d\n", option);
return ENOPROTOOPT; return ENOPROTOOPT;
} }
}
return sSocketModule->set_option(protocol->socket, level, option, return sSocketModule->set_option(protocol->socket, level, option,
value, length); value, length);
@ -1260,22 +1307,22 @@ ipv4_send_routed_data(net_protocol *_protocol, struct net_route *route,
if (destination.sin_addr.s_addr == INADDR_ANY) if (destination.sin_addr.s_addr == INADDR_ANY)
return EDESTADDRREQ; return EDESTADDRREQ;
else if ((interface->device->flags & IFF_BROADCAST) != 0
if ((interface->device->flags & IFF_BROADCAST) != 0
&& (destination.sin_addr.s_addr == INADDR_BROADCAST && (destination.sin_addr.s_addr == INADDR_BROADCAST
|| destination.sin_addr.s_addr || destination.sin_addr.s_addr
== broadcastAddress.sin_addr.s_addr)) { == broadcastAddress.sin_addr.s_addr)) {
if (protocol && !(protocol->socket->options & SO_BROADCAST)) if (protocol && !(protocol->socket->options & SO_BROADCAST))
return B_BAD_VALUE; return B_BAD_VALUE;
buffer->flags |= MSG_BCAST; buffer->flags |= MSG_BCAST;
} else if (IN_MULTICAST(ntohl(destination.sin_addr.s_addr))) { } else if (IN_MULTICAST(ntohl(destination.sin_addr.s_addr)))
buffer->flags |= MSG_MCAST; buffer->flags |= MSG_MCAST;
}
// Add IP header (if needed) // Add IP header (if needed)
if (!headerIncluded) { if (!headerIncluded) {
NetBufferPrepend<ipv4_header> header(buffer); NetBufferPrepend<ipv4_header> header(buffer);
if (header.Status() < B_OK) if (header.Status() != B_OK)
return header.Status(); return header.Status();
header->version = IP_VERSION; header->version = IP_VERSION;
@ -1284,13 +1331,15 @@ ipv4_send_routed_data(net_protocol *_protocol, struct net_route *route,
header->total_length = htons(buffer->size); header->total_length = htons(buffer->size);
header->id = htons(atomic_add(&sPacketID, 1)); header->id = htons(atomic_add(&sPacketID, 1));
header->fragment_offset = 0; header->fragment_offset = 0;
if (protocol) if (protocol) {
header->time_to_live = (buffer->flags & MSG_MCAST) ? header->time_to_live = (buffer->flags & MSG_MCAST)
protocol->multicast_time_to_live : protocol->time_to_live; ? protocol->multicast_time_to_live : protocol->time_to_live;
else } else {
header->time_to_live = (buffer->flags & MSG_MCAST) ? header->time_to_live = (buffer->flags & MSG_MCAST)
kDefaultMulticastTTL : kDefaultTTL; ? kDefaultMulticastTTL : kDefaultTTL;
header->protocol = protocol ? protocol->socket->protocol : buffer->protocol; }
header->protocol = protocol
? protocol->socket->protocol : buffer->protocol;
header->checksum = 0; header->checksum = 0;
header->source = source.sin_addr.s_addr; header->source = source.sin_addr.s_addr;
@ -1298,7 +1347,7 @@ ipv4_send_routed_data(net_protocol *_protocol, struct net_route *route,
} else { } else {
// if IP_HDRINCL, check if the source address is set // if IP_HDRINCL, check if the source address is set
NetBufferHeaderReader<ipv4_header> header(buffer); NetBufferHeaderReader<ipv4_header> header(buffer);
if (header.Status() < B_OK) if (header.Status() != B_OK)
return header.Status(); return header.Status();
if (header->source == 0) { if (header->source == 0) {
@ -1312,11 +1361,13 @@ ipv4_send_routed_data(net_protocol *_protocol, struct net_route *route,
if (buffer->size > 0xffff) if (buffer->size > 0xffff)
return EMSGSIZE; return EMSGSIZE;
if (checksumNeeded) if (checksumNeeded) {
*IPChecksumField(buffer) = gBufferModule->checksum(buffer, 0, *IPChecksumField(buffer) = gBufferModule->checksum(buffer, 0,
sizeof(ipv4_header), true); sizeof(ipv4_header), true);
}
TRACE_SK(protocol, " SendRoutedData(): header chksum: %ld, buffer checksum: %ld", TRACE_SK(protocol, " SendRoutedData(): header chksum: %ld, buffer "
"checksum: %ld",
gBufferModule->checksum(buffer, 0, sizeof(ipv4_header), true), gBufferModule->checksum(buffer, 0, sizeof(ipv4_header), true),
gBufferModule->checksum(buffer, 0, buffer->size, true)); gBufferModule->checksum(buffer, 0, buffer->size, true));
@ -1342,7 +1393,7 @@ ipv4_send_data(net_protocol *_protocol, net_buffer *buffer)
if (protocol && (protocol->flags & IP_FLAG_HEADER_INCLUDED)) { if (protocol && (protocol->flags & IP_FLAG_HEADER_INCLUDED)) {
if (buffer->size < sizeof(ipv4_header)) if (buffer->size < sizeof(ipv4_header))
return EINVAL; return B_BAD_VALUE;
sockaddr_in *source = (sockaddr_in *)buffer->source; sockaddr_in *source = (sockaddr_in *)buffer->source;
sockaddr_in *destination = (sockaddr_in *)buffer->destination; sockaddr_in *destination = (sockaddr_in *)buffer->destination;
@ -1422,7 +1473,7 @@ ipv4_receive_data(net_buffer *buffer)
TRACE("ReceiveData(%p [%ld bytes])", buffer, buffer->size); TRACE("ReceiveData(%p [%ld bytes])", buffer, buffer->size);
NetBufferHeaderReader<ipv4_header> bufferHeader(buffer); NetBufferHeaderReader<ipv4_header> bufferHeader(buffer);
if (bufferHeader.Status() < B_OK) if (bufferHeader.Status() != B_OK)
return bufferHeader.Status(); return bufferHeader.Status();
ipv4_header &header = bufferHeader.Data(); ipv4_header &header = bufferHeader.Data();
@ -1442,7 +1493,8 @@ ipv4_receive_data(net_buffer *buffer)
return B_BAD_DATA; return B_BAD_DATA;
struct sockaddr_in &source = *(struct sockaddr_in *)buffer->source; struct sockaddr_in &source = *(struct sockaddr_in *)buffer->source;
struct sockaddr_in &destination = *(struct sockaddr_in *)buffer->destination; struct sockaddr_in &destination
= *(struct sockaddr_in *)buffer->destination;
fill_sockaddr_in(&source, header.source); fill_sockaddr_in(&source, header.source);
fill_sockaddr_in(&destination, header.destination); fill_sockaddr_in(&destination, header.destination);
@ -1472,7 +1524,7 @@ ipv4_receive_data(net_buffer *buffer)
// remove any trailing/padding data // remove any trailing/padding data
status_t status = gBufferModule->trim(buffer, packetLength); status_t status = gBufferModule->trim(buffer, packetLength);
if (status < B_OK) if (status != B_OK)
return status; return status;
// check for fragmentation // check for fragmentation
@ -1509,7 +1561,7 @@ ipv4_receive_data(net_buffer *buffer)
return EAFNOSUPPORT; return EAFNOSUPPORT;
} }
if (buffer->flags & MSG_MCAST) { if ((buffer->flags & MSG_MCAST) != 0) {
// Unfortunely historical reasons dictate that the IP multicast // Unfortunely historical reasons dictate that the IP multicast
// model be a little different from the unicast one. We deliver // model be a little different from the unicast one. We deliver
// this frame directly to all sockets registered with interest // this frame directly to all sockets registered with interest
@ -1548,37 +1600,6 @@ ipv4_error_reply(net_protocol *protocol, net_buffer *causedError, uint32 code,
} }
static int
dump_ipv4_multicast(int argc, char *argv[])
{
MulticastState::Iterator it = sMulticastState->GetIterator();
while (it.HasNext()) {
IPv4GroupInterface *state = it.Next();
char addrBuf[64];
kprintf("%p: group <%s, %s, %s {", state, state->Interface()->name,
print_address(&state->Address(), addrBuf, sizeof(addrBuf)),
state->Mode() == IPv4GroupInterface::kExclude ? "Exclude" :
"Include");
int count = 0;
IPv4GroupInterface::AddressSet::Iterator it =
state->Sources().GetIterator();
while (it.HasNext()) {
kprintf("%s%s", count > 0 ? ", " : "", print_address(&it.Next(),
addrBuf, sizeof(addrBuf)));
count++;
}
kprintf("}> sock %p\n", state->Parent()->Socket());
}
return 0;
}
// #pragma mark - // #pragma mark -
@ -1601,7 +1622,7 @@ init_ipv4()
} }
status = sMulticastState->Init(); status = sMulticastState->Init();
if (status < B_OK) if (status != B_OK)
goto err5; goto err5;
sFragmentHash = hash_init(MAX_HASH_FRAGMENTS, FragmentPacket::NextOffset(), sFragmentHash = hash_init(MAX_HASH_FRAGMENTS, FragmentPacket::NextOffset(),
@ -1616,12 +1637,12 @@ init_ipv4()
status = gStackModule->register_domain_protocols(AF_INET, SOCK_RAW, 0, status = gStackModule->register_domain_protocols(AF_INET, SOCK_RAW, 0,
"network/protocols/ipv4/v1", NULL); "network/protocols/ipv4/v1", NULL);
if (status < B_OK) if (status != B_OK)
goto err6; goto err6;
status = gStackModule->register_domain(AF_INET, "internet", &gIPv4Module, status = gStackModule->register_domain(AF_INET, "internet", &gIPv4Module,
&gIPv4AddressModule, &sDomain); &gIPv4AddressModule, &sDomain);
if (status < B_OK) if (status != B_OK)
goto err6; goto err6;
add_debugger_command("ipv4_multicast", dump_ipv4_multicast, add_debugger_command("ipv4_multicast", dump_ipv4_multicast,