L4Re Operating System Framework
Interface and Usage Documentation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
request.h
1/*
2 * Copyright (C) 2016-2017, 2020, 2022, 2024 Kernkonzept GmbH.
3 * Author(s): Jean Wolter <jean.wolter@kernkonzept.com>
4 *
5 * License: see LICENSE.spdx (in this directory or the directories above)
6 */
7#pragma once
8
9#include "mac_addr.h"
10#include "virtio_net.h"
11#include "virtio_net_buffer.h"
12#include "vlan.h"
13
14#include <l4/l4virtio/server/virtio>
15
16
34{
35public:
36 virtual ~Net_transfer() = default;
37
41 void const *req_id() const { return _req_id; }
42
46 virtual void copy_header(Virtio_net::Hdr *dst_header) const = 0;
47
54 Buffer &cur_buf() { return _cur_buf; }
55
65 virtual bool done() = 0;
66
67protected:
68 Buffer _cur_buf;
69 void const *_req_id;
70};
71
72class Net_request
73{
74public:
76 Mac_addr dst_mac() const
77 {
78 return (_pkt.pos && _pkt.left >= Mac_addr::Addr_length)
79 ? Mac_addr(_pkt.pos)
80 : Mac_addr(Mac_addr::Addr_unknown);
81 }
82
84 Mac_addr src_mac() const
85 {
86 return (_pkt.pos && _pkt.left >= Mac_addr::Addr_length * 2)
87 ? Mac_addr(_pkt.pos + Mac_addr::Addr_length)
88 : Mac_addr(Mac_addr::Addr_unknown);
89 }
90
91 bool has_vlan() const
92 {
93 if (!_pkt.pos || _pkt.left < 14)
94 return false;
95
96 uint8_t *p = reinterpret_cast<uint8_t *>(_pkt.pos);
97 return p[12] == 0x81U && p[13] == 0x00U;
98 }
99
100 uint16_t vlan_id() const
101 {
102 if (!has_vlan() || _pkt.left < 16)
103 return VLAN_ID_NATIVE;
104
105 uint8_t *p = reinterpret_cast<uint8_t *>(_pkt.pos);
106 return (uint16_t{p[14]} << 8 | p[15]) & 0xfffU;
107 }
108
120 uint8_t const *buffer(size_t *size) const
121 {
122 *size = _pkt.left;
123 return reinterpret_cast<uint8_t const *>(_pkt.pos);
124 }
125
126 void dump_pkt() const
127 {
128 Dbg pkt_debug(Dbg::Packet, Dbg::Debug, "PKT");
129 if (pkt_debug.is_active())
130 {
131 pkt_debug.cprintf("\t");
132 src_mac().print(pkt_debug);
133 pkt_debug.cprintf(" -> ");
134 dst_mac().print(pkt_debug);
135 pkt_debug.cprintf("\n");
136
137 Dbg pkt_trace(Dbg::Packet, Dbg::Trace, "PKT");
138 if (pkt_trace.is_active() && _pkt.left >= 14)
139 {
140 uint8_t const *packet = reinterpret_cast<uint8_t const *>(_pkt.pos);
141 pkt_trace.cprintf("\n\tEthertype: ");
142 uint16_t ether_type = uint16_t{packet[12]} << 8 | packet[13];
143 char const *protocol;
144 switch (ether_type)
145 {
146 case 0x0800: protocol = "IPv4"; break;
147 case 0x0806: protocol = "ARP"; break;
148 case 0x8100: protocol = "Vlan"; break;
149 case 0x86dd: protocol = "IPv6"; break;
150 case 0x8863: protocol = "PPPoE Discovery"; break;
151 case 0x8864: protocol = "PPPoE Session"; break;
152 default: protocol = nullptr;
153 }
154 if (protocol)
155 pkt_trace.cprintf("%s\n", protocol);
156 else
157 pkt_trace.cprintf("%04x\n", ether_type);
158 }
159 }
160 }
161
162protected:
163 Buffer _pkt;
164};
165
A wrapper class around the value of a MAC address.
Definition mac_addr.h:20
A network request to only a single destination.
Definition request.h:34
virtual void copy_header(Virtio_net::Hdr *dst_header) const =0
Populate the virtio-net header for the destination.
void const * req_id() const
Identifier for the underlying Net_request, used for logging purposes.
Definition request.h:41
virtual bool done()=0
Check whether the transfer has been completed, i.e.
Buffer & cur_buf()
Buffer containing (a part of) the packet data.
Definition request.h:54
Data buffer used to transfer packets.