6 #include "net/ethernet.h"
7 #include "net/endianess.h"
9 #include "debug/hexview.h"
10 #include "lib/stdlib.h"
17 void ipv4_handle_packet(
netcard_entry_t *card,
char *packet,
size_t packet_size) {
18 ETH_IPv4_PKG* ipv4_pkt = (ETH_IPv4_PKG*)packet;
20 ipv4_pkt->TotalLength = ntohs(ipv4_pkt->TotalLength);
23 qemu_log(
" |--- Version: %x", ipv4_pkt->Version);
24 qemu_log(
" |--- DSF: %x", ipv4_pkt->DSF);
25 qemu_log(
" |--- TotalLength: %x", ipv4_pkt->TotalLength);
26 qemu_log(
" |--- ID: %x", ipv4_pkt->ID);
27 qemu_log(
" |--- Flags: %x", ipv4_pkt->Flags);
28 qemu_log(
" |--- TimeLife: %x", ipv4_pkt->TimeLife);
29 qemu_log(
" |--- Protocol: %x", ipv4_pkt->Protocol);
30 qemu_log(
" |--- Checksum: %x", ipv4_pkt->Checksum);
31 qemu_log(
" |--- Source: %d.%d.%d.%d", ipv4_pkt->Source[0], ipv4_pkt->Source[1], ipv4_pkt->Source[2], ipv4_pkt->Source[3]);
32 qemu_log(
" |--- Destination: %d.%d.%d.%d", ipv4_pkt->Destination[0], ipv4_pkt->Destination[1], ipv4_pkt->Destination[2], ipv4_pkt->Destination[3]);
35 ethernet_frame_t* eth_frame = (packet -
sizeof(ethernet_frame_t));
36 qemu_log(
" |--- Phys source: %x:%x:%x:%x:%x:%x",
37 eth_frame->src_mac[0],
38 eth_frame->src_mac[1],
39 eth_frame->src_mac[2],
40 eth_frame->src_mac[3],
41 eth_frame->src_mac[4],
42 eth_frame->src_mac[5]);
45 arp_lookup_add(eth_frame->src_mac, ipv4_pkt->Source);
47 if (ipv4_pkt->Protocol == ETH_IPv4_HEAD_UDP) {
48 udp_handle_packet(card, (udp_packet_t *) (packet +
sizeof(ETH_IPv4_PKG)));
49 }
else if(ipv4_pkt->Protocol == ETH_IPv4_HEAD_ICMPv4) {
50 qemu_err(
"ICMP not implemented!");
52 icmp_handle_packet(card, packet +
sizeof(ETH_IPv4_PKG));
53 }
else if(ipv4_pkt->Protocol == ETH_IPv4_HEAD_TCP) {
54 qemu_note(
"HANDLING TCP!");
56 tcp_handle_packet(card, (
tcp_packet_t*)(packet +
sizeof(ETH_IPv4_PKG)));
58 qemu_log(
" | |--- Header: [%x] %s", ipv4_pkt->Protocol,
"Unknown");
59 qemu_log(
" | |--- RAW: %d bytes", packet_size -
sizeof(ETH_IPv4_PKG));
64 uint16_t ipv4_checksum(ETH_IPv4_PKG* packet) {
67 size_t array_size =
sizeof(ETH_IPv4_PKG) / 2;
68 uint16_t*
array = (uint16_t*)packet;
71 for(
int i = 0; i < array_size; i++) {
72 sum += bit_flip_short(
array[i]);
75 uint32_t carry = sum >> 16;
76 sum = sum & 0x0000ffff;
82 void ipv4_send_packet(
netcard_entry_t *card, uint8_t dest_ip[4],
const void *data,
size_t size, uint8_t protocol) {
83 ETH_IPv4_PKG* ipv4_pkt = kcalloc(1,
sizeof(ETH_IPv4_PKG) + size);
84 char* pkt_data = (
char*)ipv4_pkt +
sizeof(ETH_IPv4_PKG);
86 qemu_log(
"IP send: %d bytes", size);
88 ipv4_pkt->Version = 4;
89 ipv4_pkt->HeaderLength = 5;
90 memcpy(ipv4_pkt->Destination, dest_ip, 4);
91 memcpy(ipv4_pkt->Source, card->ipv4_addr, 4);
93 ipv4_pkt->TimeLife = 64;
94 ipv4_pkt->TotalLength = htons(
sizeof(ETH_IPv4_PKG) + size);
95 ipv4_pkt->Protocol = protocol;
96 ipv4_pkt->Checksum = 0;
99 ipv4_pkt->Checksum = htons(ipv4_checksum(ipv4_pkt));
101 memcpy(pkt_data, data, size);
103 uint8_t dest_mac[6] = {0};
104 uint8_t arp_zero[6] = {0};
108 while(!arp_lookup(dest_mac, dest_ip) && --spin) {
109 arp_send_packet(card, arp_zero, dest_ip);
113 qemu_err(
"%u.%u.%u.%u is unreachable", dest_ip[0], dest_ip[1], dest_ip[2], dest_ip[3]);
118 qemu_log(
"Total IP packet size: %d",
sizeof(ETH_IPv4_PKG) + size);
120 ethernet_send_packet(card, dest_mac, (uint8_t *) ipv4_pkt,
sizeof(ETH_IPv4_PKG) + size, ETHERNET_TYPE_IPV4);
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.