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 }
Основные определения ядра
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
Definition: string.c:203
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173
int32_t memcmp(const char *s1, const char *s2, size_t n)
Сравнение массивов
Definition: string.c:305
Definition: arp.h:11
Definition: arp.h:25
Definition: cards.h:5