SayoriOS 0.3.3

arp.c
1 #include "common.h"
2 #include "net/arp.h"
3 #include "net/cards.h"
4 #include "mem/vmm.h"
5 #include "net/endianess.h"
6 #include "lib/string.h"
7 #include "io/ports.h"
8 #include "net/ethernet.h"
9
10 uint8_t default_broadcast_mac_address[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
11
12 arp_table_entry_t arp_table[ARP_TABLE_MAX_SIZE] = {0};
13 size_t arp_table_curr = 0;
14
15 void arp_handle_packet(netcard_entry_t* card, arp_packet_t* arp_packet, size_t len) {
16 uint8_t dest_mac[6];
17 uint8_t dest_ip[4];
18
19 memcpy(dest_mac, arp_packet->src_mac, 6);
20 memcpy(dest_ip, arp_packet->src_ip, 4);
21
22 if(ntohs(arp_packet->opcode) == ARP_REQUEST) {
23 qemu_warn("ARP REQUEST");
24
25 if(memcmp((const char*)arp_packet->dest_ip, (const char*)card->ipv4_addr, 4) != 0) {
26 // Set source MAC address, IP address (hardcode the IP address as 10.2.2.3 until we really get one...)
27 card->get_mac_addr(arp_packet->src_mac);
28
29 arp_packet->src_ip[0] = card->ipv4_addr[0];
30 arp_packet->src_ip[1] = card->ipv4_addr[1];
31 arp_packet->src_ip[2] = card->ipv4_addr[2];
32 arp_packet->src_ip[3] = card->ipv4_addr[3];
33
34 // Set destination MAC address, IP address
35 memcpy(arp_packet->dest_mac, dest_mac, 6);
36 memcpy(arp_packet->dest_ip, dest_ip, 4);
37
38 // Set opcode
39 arp_packet->opcode = htons(ARP_REPLY);
40
41 // Set lengths
42 arp_packet->hardware_addr_len = 6;
43 arp_packet->protocol_addr_len = 4;
44
45 // Set hardware type
46 arp_packet->hardware_type = htons(HARDWARE_TYPE_ETHERNET);
47
48 // Set protocol = IPv4
49 arp_packet->protocol = htons(ETHERNET_TYPE_IPV4);
50
51 // Now send it with ethernet
52 ethernet_send_packet(card, dest_mac, (uint8_t*)arp_packet, sizeof(arp_packet_t), ETHERNET_TYPE_ARP);
53 }
54 } else if(ntohs(arp_packet->opcode) == ARP_REPLY){
55 qemu_log("ARP REPLY");
56
57 qemu_log("Source IP: %d.%d.%d.%d", arp_packet->src_ip[0], arp_packet->src_ip[1], arp_packet->src_ip[2], arp_packet->src_ip[3]);
58 qemu_log("Source MAC: %x:%x:%x:%x:%x:%x",
59 arp_packet->src_mac[0],
60 arp_packet->src_mac[1],
61 arp_packet->src_mac[2],
62 arp_packet->src_mac[3],
63 arp_packet->src_mac[4],
64 arp_packet->src_mac[5]);
65 qemu_log("Destination IP: %d.%d.%d.%d",
66 arp_packet->dest_ip[0],
67 arp_packet->dest_ip[1],
68 arp_packet->dest_ip[2],
69 arp_packet->dest_ip[3]);
70 qemu_log("Destination MAC: %x:%x:%x:%x:%x:%x",
71 arp_packet->dest_mac[0],
72 arp_packet->dest_mac[1],
73 arp_packet->dest_mac[2],
74 arp_packet->dest_mac[3],
75 arp_packet->dest_mac[4],
76 arp_packet->dest_mac[5]);
77 } else {
78 qemu_log("Got unknown ARP opcode (%d)", arp_packet->opcode);
79 }
80
81 // Now, store the ip-mac address mapping relation
82
83 arp_lookup_add(dest_mac, dest_ip);
84
85 }
86
87 void arp_send_packet(netcard_entry_t* card, uint8_t* dest_mac, uint8_t* dest_ip) {
88 arp_packet_t* arp_packet = kcalloc(sizeof(arp_packet_t), 1);
89
90 card->get_mac_addr(arp_packet->src_mac);
91
92 arp_packet->src_ip[0] = card->ipv4_addr[0];
93 arp_packet->src_ip[1] = card->ipv4_addr[1];
94 arp_packet->src_ip[2] = card->ipv4_addr[2];
95 arp_packet->src_ip[3] = card->ipv4_addr[3];
96
97 // Set destination MAC address, IP address
98 memcpy(arp_packet->dest_mac, dest_mac, 6);
99 memcpy(arp_packet->dest_ip, dest_ip, 4);
100
101 // Set opcode
102 arp_packet->opcode = htons(ARP_REQUEST);
103
104 // Set lengths
105 arp_packet->hardware_addr_len = 6;
106 arp_packet->protocol_addr_len = 4;
107
108 // Set hardware type
109 arp_packet->hardware_type = htons(HARDWARE_TYPE_ETHERNET);
110
111 // Set protocol = IPv4
112 arp_packet->protocol = htons(ETHERNET_TYPE_IPV4);
113
114 // Now send it with ethernet
115 ethernet_send_packet(
116 card,
117 default_broadcast_mac_address,
118 (uint8_t*)arp_packet,
119 sizeof(arp_packet_t),
120 ETHERNET_TYPE_ARP);
121 }
122
123 void arp_lookup_add(uint8_t* ret_hardware_addr, uint8_t * ip_addr) {
124 qemu_note("lookup add: [%x:%x:%x:%x:%x:%x] is [%d.%d.%d.%d]",
125 ret_hardware_addr[0],
126 ret_hardware_addr[1],
127 ret_hardware_addr[2],
128 ret_hardware_addr[3],
129 ret_hardware_addr[4],
130 ret_hardware_addr[5],
131 ip_addr[0],
132 ip_addr[1],
133 ip_addr[2],
134 ip_addr[3]);
135
136 memcpy(&arp_table[arp_table_curr].ip_addr, ip_addr, 4);
137 memcpy(&arp_table[arp_table_curr].mac_addr, ret_hardware_addr, 6);
138
139 if(arp_table_curr < ARP_TABLE_MAX_SIZE) {
140 arp_table_curr++;
141 }
142
143 if(arp_table_curr >= ARP_TABLE_MAX_SIZE) {
144 arp_table_curr = 0;
145 }
146 }
147
148 bool arp_lookup(uint8_t* ret_hardware_addr, const uint8_t* ip_addr) {
149 uint32_t ip_entry = *((uint32_t*)(ip_addr));
150
151 qemu_log("Looking up: %d.%d.%d.%d", ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);
152
153 for(int i = 0; i < ARP_TABLE_MAX_SIZE; i++) {
154 if(arp_table[i].ip_addr == ip_entry) {
155 memcpy(ret_hardware_addr, arp_table[i].mac_addr, 6);
156 qemu_ok("Found %x:%x:%x:%x:%x:%x!",
157 arp_table[i].mac_addr[0],
158 arp_table[i].mac_addr[1],
159 arp_table[i].mac_addr[2],
160 arp_table[i].mac_addr[3],
161 arp_table[i].mac_addr[4],
162 arp_table[i].mac_addr[5]);
163 return true;
164 }
165 }
166
167 qemu_err("Failed!");
168
169 return false;
170 }
171
172 void arp_init() {
173 uint8_t broadcast_ip[4];
174 uint8_t broadcast_mac[6];
175
176 memset(broadcast_ip, 0xff, 4);
177 memset(broadcast_mac, 0xff, 6);
178
179 arp_lookup_add(broadcast_mac, broadcast_ip);
180 }
common.h
Основные определения ядра
memset
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
Definition: string.c:203
memcpy
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173
memcmp
int32_t memcmp(const char *s1, const char *s2, size_t n)
Сравнение массивов
Definition: string.c:305
arp_packet
Definition: arp.h:11
arp_table_entry
Definition: arp.h:25
netcard_entry_t
Definition: cards.h:5