* IPv4 must always set the net_buffer::interface_address on incoming buffers; it
didn't do that for broadcasts - this is still not a full solution as it won't work for link layer broadcasts, but this should fix most DHCP problems. * IPv4 multicast doesn't do that yet. * Only send ICMP errors if it hasn't been a link layer broadcast. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38356 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1579,7 +1579,8 @@ ipv4_receive_data(net_buffer* buffer)
|
|||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
// lower layers notion of broadcast or multicast have no relevance to us
|
// lower layers notion of broadcast or multicast have no relevance to us
|
||||||
// TODO: they actually have when deciding whether to send an ICMP error
|
// other than deciding whether to send an ICMP error
|
||||||
|
bool wasMulticast = (buffer->flags & (MSG_BCAST | MSG_MCAST)) != 0;
|
||||||
buffer->flags &= ~(MSG_BCAST | MSG_MCAST);
|
buffer->flags &= ~(MSG_BCAST | MSG_MCAST);
|
||||||
|
|
||||||
sockaddr_in destination;
|
sockaddr_in destination;
|
||||||
@@ -1587,27 +1588,41 @@ ipv4_receive_data(net_buffer* buffer)
|
|||||||
|
|
||||||
if (header.destination == INADDR_BROADCAST) {
|
if (header.destination == INADDR_BROADCAST) {
|
||||||
buffer->flags |= MSG_BCAST;
|
buffer->flags |= MSG_BCAST;
|
||||||
|
|
||||||
|
// Find first interface with a matching family
|
||||||
|
// TODO: support for ethernet broadcasts!
|
||||||
|
// TODO: we might need to send it to all interfaces if it's an ethernet
|
||||||
|
// broadcast as well!
|
||||||
|
sDatalinkModule->is_local_link_address(sDomain, true,
|
||||||
|
buffer->destination, &buffer->interface_address);
|
||||||
} else if (IN_MULTICAST(ntohl(header.destination))) {
|
} else if (IN_MULTICAST(ntohl(header.destination))) {
|
||||||
buffer->flags |= MSG_MCAST;
|
buffer->flags |= MSG_MCAST;
|
||||||
|
// TODO: must set buffer->interface_address!
|
||||||
} else {
|
} else {
|
||||||
uint32 matchedAddressType = 0;
|
uint32 matchedAddressType = 0;
|
||||||
|
|
||||||
// test if the packet is really for us
|
// test if the packet is really for us
|
||||||
if (!sDatalinkModule->is_local_address(sDomain, (sockaddr*)&destination,
|
if (!sDatalinkModule->is_local_address(sDomain, (sockaddr*)&destination,
|
||||||
&buffer->interface_address, &matchedAddressType)
|
&buffer->interface_address, &matchedAddressType)) {
|
||||||
&& !sDatalinkModule->is_local_link_address(sDomain, true,
|
sDatalinkModule->is_local_link_address(sDomain, true,
|
||||||
buffer->destination, &buffer->interface_address)) {
|
buffer->destination, &buffer->interface_address);
|
||||||
TRACE(" ipv4_receive_data(): packet was not for us %x -> %x",
|
} else {
|
||||||
ntohl(header.source), ntohl(header.destination));
|
// copy over special address types (MSG_BCAST or MSG_MCAST):
|
||||||
|
buffer->flags |= matchedAddressType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer->interface_address == NULL) {
|
||||||
|
TRACE(" ipv4_receive_data(): packet was not for us %x -> %x",
|
||||||
|
ntohl(header.source), ntohl(header.destination));
|
||||||
|
|
||||||
|
if (!wasMulticast) {
|
||||||
// Send ICMP error: Host unreachable
|
// Send ICMP error: Host unreachable
|
||||||
sDomain->module->error_reply(NULL, buffer, B_NET_ERROR_UNREACH_HOST,
|
sDomain->module->error_reply(NULL, buffer, B_NET_ERROR_UNREACH_HOST,
|
||||||
NULL);
|
NULL);
|
||||||
return B_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy over special address types (MSG_BCAST or MSG_MCAST):
|
return B_ERROR;
|
||||||
buffer->flags |= matchedAddressType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set net_buffer's source/destination address
|
// set net_buffer's source/destination address
|
||||||
|
|||||||
Reference in New Issue
Block a user