ICMP: Pass FRAGMENTATION_NEEDED and REDIRECT info up the stack.
Using the new net_error_data parameter to error_received. Move the "update routing table" TODO into the IPv4 module, since the ICMP module doesn't deal with the routing table at all, while the IPv4 module already does. Also add a missing endian swap in ICMP error_reply. Change-Id: I1135eaa442f515d656143c76ab130be19cdcbaf2 Reviewed-on: https://review.haiku-os.org/c/haiku/+/9400 Reviewed-by: waddlesplash <[email protected]> Reviewed-by: Jérôme Duval <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
f9a86ebeab
commit
d31febdefa
@@ -544,23 +544,40 @@ icmp_receive_data(net_buffer* buffer)
|
|||||||
case ICMP_TYPE_SOURCE_QUENCH:
|
case ICMP_TYPE_SOURCE_QUENCH:
|
||||||
case ICMP_TYPE_PARAMETER_PROBLEM:
|
case ICMP_TYPE_PARAMETER_PROBLEM:
|
||||||
case ICMP_TYPE_TIME_EXCEEDED:
|
case ICMP_TYPE_TIME_EXCEEDED:
|
||||||
|
case ICMP_TYPE_REDIRECT:
|
||||||
{
|
{
|
||||||
net_domain* domain = get_domain(buffer);
|
net_domain* domain = get_domain(buffer);
|
||||||
if (domain == NULL)
|
if (domain == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
net_error error = icmp_to_net_error(header.type, header.code);
|
||||||
|
if (error == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
net_error_data dataStorage = {};
|
||||||
|
net_error_data* data = NULL;
|
||||||
|
if (error == B_NET_ERROR_MESSAGE_SIZE) {
|
||||||
|
data = &dataStorage;
|
||||||
|
data->mtu = ntohs(header.path_mtu.next_mtu);
|
||||||
|
|
||||||
|
// IPv4 minimum fragment size is 68 bytes, so if the "next MTU" is
|
||||||
|
// smaller than that, we can be sure it's invalid.
|
||||||
|
if (data->mtu < 68)
|
||||||
|
data = NULL;
|
||||||
|
} else if (error == B_NET_ERROR_REDIRECT_HOST) {
|
||||||
|
data = &dataStorage;
|
||||||
|
sockaddr_in& gateway = (sockaddr_in&)data->gateway;
|
||||||
|
gateway.sin_len = sizeof(sockaddr_in);
|
||||||
|
gateway.sin_family = AF_INET;
|
||||||
|
gateway.sin_addr.s_addr = header.redirect.gateway;
|
||||||
|
}
|
||||||
|
|
||||||
// Deliver the error to the domain protocol which will
|
// Deliver the error to the domain protocol which will
|
||||||
// propagate the error to the upper protocols
|
// propagate the error to the upper protocols
|
||||||
net_error error = icmp_to_net_error(header.type, header.code);
|
bufferHeader.Remove();
|
||||||
if (error != 0) {
|
return domain->module->error_received(error, data, buffer);
|
||||||
bufferHeader.Remove();
|
|
||||||
return domain->module->error_received(error, NULL, buffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case ICMP_TYPE_REDIRECT:
|
|
||||||
// TODO: Update the routing table
|
|
||||||
case ICMP_TYPE_TIMESTAMP_REQUEST:
|
case ICMP_TYPE_TIMESTAMP_REQUEST:
|
||||||
case ICMP_TYPE_TIMESTAMP_REPLY:
|
case ICMP_TYPE_TIMESTAMP_REPLY:
|
||||||
case ICMP_TYPE_INFO_REQUEST:
|
case ICMP_TYPE_INFO_REQUEST:
|
||||||
@@ -662,7 +679,7 @@ icmp_error_reply(net_protocol* protocol, net_buffer* buffer, net_error error,
|
|||||||
icmpHeader->parameter_problem.pointer = errorData->error_offset;
|
icmpHeader->parameter_problem.pointer = errorData->error_offset;
|
||||||
break;
|
break;
|
||||||
case B_NET_ERROR_MESSAGE_SIZE:
|
case B_NET_ERROR_MESSAGE_SIZE:
|
||||||
icmpHeader->path_mtu.next_mtu = errorData->mtu;
|
icmpHeader->path_mtu.next_mtu = htons(errorData->mtu);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -1920,6 +1920,10 @@ ipv4_error_received(net_error error, net_error_data* errorData, net_buffer* buff
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (error == B_NET_ERROR_REDIRECT_HOST) {
|
||||||
|
// TODO: Update the routing table!
|
||||||
|
}
|
||||||
|
|
||||||
buffer->protocol = header.protocol;
|
buffer->protocol = header.protocol;
|
||||||
|
|
||||||
bufferHeader.Remove(headerLength);
|
bufferHeader.Remove(headerLength);
|
||||||
|
|||||||
Reference in New Issue
Block a user