loopback_frame: apply an ethernet header for packet capture

* the packet capture expects frames, so loopback_frame should actually apply framing and deframing
for loopback packets.
* datalink: set the address for host routes
* device_interfaces: call the deframing if any in device_enqueue_buffer()
tested with ping 127.0.0.1 and ping6 ::1, while removing the local flag on both routes.

Change-Id: I2085735bdac3bb85908189a2e1acb2540818c7bd
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6451
Reviewed-by: Fredrik Holmqvist <fredrik.holmqvist@gmail.com>
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
Jérôme Duval 2023-05-18 18:19:04 +02:00 committed by waddlesplash
parent 9ef39f3c0c
commit e2b57695fc
3 changed files with 41 additions and 1 deletions

View File

@ -35,6 +35,10 @@ status_t
loopback_deframe(net_device* device, net_buffer* buffer)
{
// there is not that much to do...
NetBufferHeaderRemover<ether_header> bufferHeader(buffer);
if (bufferHeader.Status() != B_OK)
return bufferHeader.Status();
return B_OK;
}
@ -102,6 +106,28 @@ loopback_frame_uninit(net_datalink_protocol* protocol)
status_t
loopback_frame_send_data(net_datalink_protocol* protocol, net_buffer* buffer)
{
NetBufferPrepend<ether_header> bufferHeader(buffer);
if (bufferHeader.Status() != B_OK)
return bufferHeader.Status();
ether_header &header = bufferHeader.Data();
switch (buffer->interface_address->domain->family) {
case AF_INET:
header.type = B_HOST_TO_BENDIAN_INT16(ETHER_TYPE_IP);
break;
case AF_INET6:
header.type = B_HOST_TO_BENDIAN_INT16(ETHER_TYPE_IPV6);
break;
default:
header.type = 0;
break;
}
memset(header.source, 0, ETHER_ADDRESS_LENGTH);
memset(header.destination, 0, ETHER_ADDRESS_LENGTH);
bufferHeader.Sync();
return protocol->next->module->send_data(protocol->next, buffer);
}

View File

@ -360,6 +360,14 @@ datalink_send_routed_data(struct net_route* route, net_buffer* buffer)
return ENETUNREACH;
}
if ((route->flags & RTF_HOST) != 0) {
TRACE(" host route\n");
// We set the interface address here, so the buffer is delivered
// directly to the domain in interfaces.cpp:device_consumer_thread()
address->AcquireReference();
set_interface_address(buffer->interface_address, address);
}
if ((route->flags & RTF_LOCAL) != 0) {
TRACE(" local route\n");

View File

@ -821,7 +821,13 @@ device_enqueue_buffer(net_device* device, net_buffer* buffer)
if (interface == NULL)
return B_DEVICE_NOT_FOUND;
status_t status = fifo_enqueue_buffer(&interface->receive_queue, buffer);
status_t status = interface->deframe_func(interface->device, buffer);
if (status != B_OK) {
gNetBufferModule.free(buffer);
return status;
}
status = fifo_enqueue_buffer(&interface->receive_queue, buffer);
put_device_interface(interface);
return status;