Max OS 0.3
Loading...
Searching...
No Matches
ipv4.cpp
Go to the documentation of this file.
1
9#include <net/ipv4.h>
10
11using namespace MaxOS;
12using namespace MaxOS::common;
13using namespace MaxOS::net;
14using namespace MaxOS::memory;
15using namespace MaxOS::drivers;
16using namespace MaxOS::drivers::ethernet;
17
23
24 internet_protocol_handler->register_ipv_4_address_resolver(this);
25
26}
27
28
29IPV4AddressResolver::~IPV4AddressResolver() = default;
30
40
50
58
59 // Store vars
60 this->internet_protocol_handler = internet_protocol_handler;
61 this->ip_protocol = protocol;
62
63 //Register handler
65
66}
67
68IPV4PayloadHandler::~IPV4PayloadHandler() = default;
69
85
94
95
96 //Pass to backend
98
99}
100
110InternetProtocolHandler::InternetProtocolHandler(EthernetFrameHandler* backend, InternetProtocolAddress own_internet_protocol_address, InternetProtocolAddress default_gateway_internet_protocol_address, SubnetMask subnet_mask, OutputStream* error_messages)
112 //Store vars
113 this->own_internet_protocol_address = own_internet_protocol_address;
114 this->default_gateway_internet_protocol_address = default_gateway_internet_protocol_address;
115 this->subnet_mask = subnet_mask;
116 this->error_messages = error_messages;
117}
118
119InternetProtocolHandler::~InternetProtocolHandler() = default;
120
131
132 error_messages->write("IP: Handling packet\n");
133
134 //Check if the size is big enough to contain an ethernet frame
135 if(size < sizeof(IPV4Header))
136 return false;
137
138 //Convert to struct for easier use
140 bool send_back = false;
141
142 //Only handle if it is for this device
143 if(ip_message->destination_ip == get_internet_protocol_address()) {
144 uint32_t length = ip_message->total_length; //Get length of the message
145 if(length >
146 size) //Check if the length is bigger than the size of the message
147 length = size; //If so, set length to size (this stops heartbleed attacks as it will not read past the end of the message, which the attacker could have filled with data)
148
149 // Get the handler for the protocol
153 if(handler != nullptr) {
154 send_back = handler->handle_internet_protocol_payload(ip_message->source_ip, ip_message->destination_ip,
156 length - sizeof(IPV4Header));
157 }
158 }
159
160
161 }
162
163 //If the data is to be sent back again
164 if(send_back) {
165
166 //Swap source and destination
167 uint32_t temp = ip_message->destination_ip; //Store destination IP
168 ip_message->destination_ip = ip_message->source_ip; //Set destination IP to source IP
169 ip_message->source_ip = temp; //Set source IP to destination IP
170
171 ip_message->time_to_live = 0x40; //Reset TTL
172 ip_message->checksum = checksum((uint16_t*) ip_message, 4 *
173 ip_message->header_length); //Reset checksum as the source and destination IP have changed so has the time to live and therefore there is a different header
174
175 }
176
177 error_messages->write("IP: Handled packet\n");
178 return send_back;
179}
180
181
191
192 auto* buffer = (uint8_t*) MemoryManager::kmalloc(
193 sizeof(IPV4Header) + size); //Allocate memory for the message
194 auto* message = (IPV4Header*) buffer; //Convert to struct for easier use
195
196 message->version = 4; //Set version
197 message->header_length = sizeof(IPV4Header) /
198 4; //Set header length
199 message->type_of_service = 0; //Set type of service (not private)
200
201 message->total_length = size +
202 sizeof(IPV4Header); //Set total length
203 message->total_length = ((message->total_length & 0xFF00)
204 >> 8) // Convert to big endian (Swap bytes)
205 | ((message->total_length & 0x00FF)
206 << 8); // Convert to big endian (Swap bytes)
207
208 message->identifier = 0x100; //Set identification TODO: do properly
209 message->flags_and_offset = 0x0040; //Set flags/offset, 0x40 because we are not fragmenting (TODO: doesnt work for packets bigger than 1500 bytes)
210
211 message->time_to_live = 0x40; //Set time to live
212 message->protocol = protocol; //Set protocol
213
214 message->destination_ip = dst_ip_be; //Set destination IP
215 message->source_ip = get_internet_protocol_address(); //Set source IP
216
217 message->checksum = 0; //Set checksum to 0, init with 0 as checksum funct will also add this value
218 message->checksum = checksum((uint16_t*) message,
219 sizeof(IPV4Header)); //Calculate checksum
220
221 //Copy data
222 uint8_t* data_buffer = buffer +
223 sizeof(IPV4Header); //Get pointer to the data
224 for(uint32_t i = 0; i <
225 size; i++) //Loop through data
226 data_buffer[i] = data[i]; //Copy data
227
228 //Check if the destination is on the same subnet, The if condition determines if the destination device is on the same Local network as the source device . and if they are not on the same local network then we resolve the ip address of the gateway .
229 InternetProtocolAddress route = dst_ip_be; //Set route to destination IP by default
231 subnet_mask)) //Check if the destination is on the same subnet
232 route = default_gateway_internet_protocol_address; //If not, set route to gateway IP
233 //Print debug info
235
236 //Send message
237 frame_handler->send_ethernet_frame(mac, this->handled_type, buffer, size + sizeof(IPV4Header)); //Send message
239 buffer); //Free memory
240}
241
250
251 uint32_t temp = 0; //Init sum
252
253 for(uint32_t i = 0; i < length_in_bytes /
254 2; i++) //Loop through data (/2 bc bytes)
255 temp += ((data[i] & 0xFF00) >> 8) |
256 ((data[i] & 0x00FF) << 8); //Add data to sum in big endian
257
258 if(length_in_bytes %
259 2) //If there is an odd number of bytes
260 temp += ((uint16_t) ((char*) data)[length_in_bytes - 1])
261 << 8; //Add the last byte to the sum
262
263 while(temp &
264 0xFFFF0000) //While there is a carry
265 temp = (temp & 0xFFFF) +
266 (temp >> 16); //Add the carry to the sum
267
268 return ((~temp & 0xFF00) >> 8) | ((~temp & 0x00FF) << 8);
269}
270
281
299
307 uint8_t digits[4];
308
310 for(unsigned char& digit : digits)
311 digit = 0;
312
313 for(size_t i = 0; i < address.length(); i++) {
314 if(address[i] == '.') {
316 continue;
317 }
318
319 digits[current_digit] *= 10;
320 digits[current_digit] += address[i] - '0';
321 }
322
324}
325
339
348
357
A stream that strings can be written to.
void write(string string_to_write) override
Writes a string to the output stream.
Stores the left, top, width and height of a rectangle.
Definition rectangle.h:22
static void * kmalloc(size_t size)
Allocates a block of memory in the KERNEL space.
static void kfree(void *pointer)
Frees a block of memory using the kernel memory manager.
Handles incoming Ethernet Frames and routes them to the appropriate payload handlers.
void send_ethernet_frame(uint64_t destination_mac, uint16_t frame_type, uint8_t *data, uint32_t size)
send an packet via the backend driver
drivers::ethernet::MediaAccessControlAddress get_mac()
Get the MAC address of this device.
Handles a specific type of Ethernet Frame payload.
uint16_t handled_type
The Ethernet frame type this handler handles.
EthernetFrameHandler * frame_handler
The Ethernet frame handler this payload handler is connected to.
Resolves IP addresses to MAC addresses.
Definition ipv4.h:53
virtual void store(InternetProtocolAddress internet_protocol_address, drivers::ethernet::MediaAccessControlAddress media_access_control_address)
Stores an IP address to MAC address mapping. (Default, does nothing, override for use)
Definition ipv4.cpp:47
IPV4AddressResolver(InternetProtocolHandler *internet_protocol_handler)
Construct a new IPV4 Address Resolver object and register it with the Internet Protocol Handler.
Definition ipv4.cpp:22
virtual drivers::ethernet::MediaAccessControlAddress resolve(InternetProtocolAddress address)
Resolves an IP address to a MAC address. (Default, returns broadcast address, override for use)
Definition ipv4.cpp:37
Handles the payload of a specific IP protocol.
Definition ipv4.h:66
virtual bool handle_internet_protocol_payload(net::InternetProtocolAddress src_ip_be, net::InternetProtocolAddress dst_ip_be, uint8_t *internetprotocol_payload, uint32_t size)
Called when an IP packet is received. (Deafult, does nothing, overide for use)
Definition ipv4.cpp:79
void send(InternetProtocolAddress destination_ip, uint8_t *payload_data, uint32_t size)
Sends an IP packet.
Definition ipv4.cpp:93
uint8_t ip_protocol
The IP protocol this handler handles.
Definition ipv4.h:71
InternetProtocolHandler * internet_protocol_handler
The Internet protocol handler this payload handler is connected to.
Definition ipv4.h:70
IPV4PayloadHandler(InternetProtocolHandler *internet_protocol_handler, uint8_t protocol)
Construct a new IPV4 Payload Handler object and register it with the Internet Protocol Handler.
Definition ipv4.cpp:57
Handles IPv4 packets over Ethernet frames.
Definition ipv4.h:85
SubnetMask subnet_mask
The subnet mask.
Definition ipv4.h:98
static SubnetMask create_subnet_mask(uint8_t digit1, uint8_t digit2, uint8_t digit3, uint8_t digit4)
Creates a subnet mask from four digits.
Definition ipv4.cpp:336
common::OutputStream * error_messages
Stream to output error messages to.
Definition ipv4.h:94
InternetProtocolAddress get_internet_protocol_address() const
Gets the IP address of this device.
Definition ipv4.cpp:345
common::Map< uint8_t, IPV4PayloadHandler * > ipv_4_payload_handlers
Map of IP protocol numbers to their payload handlers.
Definition ipv4.h:91
void connect_ipv_4_payload_handler(IPV4PayloadHandler *ipv_4_payload_handler)
Connects an IP protocol payload handler.
Definition ipv4.cpp:363
IPV4AddressResolver * resolver
The IP address resolver.
Definition ipv4.h:93
static InternetProtocolAddress create_internet_protocol_address(uint8_t digit1, uint8_t digit2, uint8_t digit3, uint8_t digit4)
Creates an IP address from four digits.
Definition ipv4.cpp:292
static InternetProtocolAddress parse(string address)
Parses a string representation of an IP address.
Definition ipv4.cpp:306
InternetProtocolAddress default_gateway_internet_protocol_address
The IP address of the default gateway.
Definition ipv4.h:97
bool handle_ethernetframe_payload(uint8_t *ethernetframe_payload, uint32_t size) override
Called when an IP packet is received.
Definition ipv4.cpp:130
void send_internet_protocol_packet(uint32_t dst_ip_be, uint8_t protocol, const uint8_t *data, uint32_t size)
Sends an IP packet.
Definition ipv4.cpp:190
drivers::ethernet::MediaAccessControlAddress get_media_access_control_address()
Gets the MAC address of this device.
Definition ipv4.cpp:354
static uint16_t checksum(const uint16_t *data, uint32_t length_in_bytes)
Creates a checksum for the given data.
Definition ipv4.cpp:249
InternetProtocolAddress own_internet_protocol_address
The IP address of this device.
Definition ipv4.h:96
void register_ipv_4_address_resolver(IPV4AddressResolver *ipv4_resolver)
Registers an IP address resolver.
Definition ipv4.cpp:276
InternetProtocolHandler(EthernetFrameHandler *backend, InternetProtocolAddress own_internet_protocol_address, InternetProtocolAddress default_gateway_internet_protocol_address, SubnetMask subnet_mask, common::OutputStream *error_messages)
Construct a new Internet Protocol Handler object.
Definition ipv4.cpp:110
uint64_t MediaAccessControlAddress
Used to make MAC addresses more readable.
Definition ethernet.h:21
Defines classes and structures for handling Internet Protocol version 4 (IPv4) packets.
uint32_t SubnetMask
A subnet mask.
Definition ipv4.h:19
uint32_t InternetProtocolAddress
An IPv4 address.
Definition ipv4.h:18
The header of an IPv4 packet.
Definition ipv4.h:28