SayoriOS 0.3.3

dhcp.c
1 #include "net/cards.h"
2 #include "net/dhcp.h"
3 #include "net/endianess.h"
4 #include "mem/vmm.h"
5 #include "lib/rand.h"
6 #include "net/udp.h"
7 #include "io/ports.h"
8
9 void dhcp_discover(netcard_entry_t* card) {
10 // DHCP-клиент должен быть готов принять DHCP-сообщение длиной в 576 байт.
11
12 dhcp_packet_t* packet = kcalloc(sizeof(dhcp_packet_t), 1);
13
14 uint8_t card_mac[6] = {0};
15 card->get_mac_addr(card_mac);
16
17 packet->op = DHCP_REQUEST;
18 packet->hardware_type = 0x01; // Ethernet
19 packet->hardware_addr_len = 0x06; // Mac address is 6 bytes long
20 packet->hops = 0;
21 packet->xid = ntohl((size_t)rand());
22 packet->seconds = 0;
23 packet->flags = htons(0x8000);
24 packet->client_ip = 0;
25 packet->your_ip = 0;
26 packet->server_ip = 0;
27 packet->gateway_ip = 0;
28
29 memcpy(packet->client_hardware_addr, card_mac, 6);
30
31 uint8_t* options_field = packet->options;
32
33 *((uint32_t*)options_field) = htonl(0x63825363);
34
35 // Discover DHCP
36 options_field[4] = 53;
37 options_field[5] = 1;
38 options_field[6] = 1;
39
40 // Address resolution
41 options_field[7] = 50;
42 options_field[8] = 4;
43
44 // Last known IP-Address
45 options_field[9] = 0;
46 options_field[10] = 0;
47 options_field[11] = 0;
48 options_field[12] = 0;
49
50 // Host name
51 options_field[13] = 12;
52 options_field[14] = 7;
53 options_field[15] = 'S';
54 options_field[16] = 'a';
55 options_field[17] = 'y';
56 options_field[18] = 'o';
57 options_field[19] = 'r';
58 options_field[20] = 'i';
59 options_field[21] = 0;
60
61 // End
62 options_field[22] = 0xff;
63
64 uint8_t dest_ip[4] = {0xff, 0xff, 0xff, 0xff};
65
66 qemu_log("DHCP size: %d", sizeof(dhcp_packet_t));
67 udp_send_packet(card, dest_ip, 68, 67, packet, sizeof(dhcp_packet_t));
68
69 kfree(packet);
70 }
71
72 void dhcp_request(netcard_entry_t* card, const uint8_t req_ip[4]) {
73 dhcp_packet_t* packet = kcalloc(sizeof(dhcp_packet_t), 1);
74
75 uint8_t card_mac[6] = {0};
76 card->get_mac_addr(card_mac);
77
78 packet->op = DHCP_REQUEST;
79 packet->hardware_type = 0x01; // Ethernet
80 packet->hardware_addr_len = 0x06; // Mac address is 6 bytes long
81 packet->hops = 0;
82 packet->xid = ntohl((size_t)rand());
83 packet->seconds = 0;
84 packet->flags = htons(0x8000);
85 packet->client_ip = 0;
86 packet->your_ip = 0;
87 packet->server_ip = 0;
88 packet->gateway_ip = 0;
89
90 memcpy(packet->client_hardware_addr, card_mac, 6);
91
92 uint8_t* options_field = packet->options;
93
94 *((uint32_t*)options_field) = htonl(0x63825363);
95
96 // Discover DHCP
97 options_field[4] = 53;
98 options_field[5] = 1;
99 options_field[6] = 3;
100
101 // Address resolution
102 options_field[7] = 50;
103 options_field[8] = 4;
104
105 // Last known IP-Address
106 options_field[9] = req_ip[0];
107 options_field[10] = req_ip[1];
108 options_field[11] = req_ip[2];
109 options_field[12] = req_ip[3];
110
111 // Host name
112 options_field[13] = 12;
113 options_field[14] = 7;
114 options_field[15] = 'S';
115 options_field[16] = 'a';
116 options_field[17] = 'y';
117 options_field[18] = 'o';
118 options_field[19] = 'r';
119 options_field[20] = 'i';
120 options_field[21] = 0;
121
122 // End
123 options_field[22] = 0xff;
124
125 uint8_t dest_ip[4] = {0xff, 0xff, 0xff, 0xff};
126 // udp_send_packet(card, dest_ip, 68, 67, packet, 576);
127
128 qemu_log("DHCP size: %d", sizeof(dhcp_packet_t));
129 udp_send_packet(card, dest_ip, 68, 67, packet, sizeof(dhcp_packet_t));
130
131 kfree(packet);
132 }
133
134 void dhcp_handle_packet(netcard_entry_t* card, dhcp_packet_t* packet) {
135 uint8_t* options = packet->options + 4;
136
137 char* my_ip = (char*)&packet->your_ip;
138 char* sv_ip = (char*)&packet->server_ip;
139
140 qemu_log("DHCP");
141 qemu_log("Operation: %d", packet->op);
142 qemu_log("Client IP: %x", packet->client_ip);
143 qemu_log("Your IP: %x (%d.%d.%d.%d)", packet->your_ip, (unsigned char)my_ip[0], (unsigned char)my_ip[1], (unsigned char)my_ip[2], (unsigned char)my_ip[3]);
144 qemu_log("Server IP: %x (%d.%d.%d.%d)", packet->server_ip, (unsigned char)sv_ip[0], (unsigned char)sv_ip[1], (unsigned char)sv_ip[2], (unsigned char)sv_ip[3]);
145 qemu_log("Gateway IP: %x", packet->gateway_ip);
146
147 size_t msgtype = *options;
148 qemu_log("First option is: %d", *options);
149
150 if(msgtype == 53) {
151 uint8_t type = *(options + 2);
152
153 if(type == 2) {
154 qemu_ok("Request!");
155 // Does not work because it executes in IRQ
156 // dhcp_request(card, (uint8_t *) &packet->your_ip);
157 } else if(type == 5) {
158 memcpy(card->ipv4_addr, my_ip, 4);
159
160 qemu_ok("Acquired an IP address: %u.%u.%u.%u", card->ipv4_addr[0], card->ipv4_addr[1], card->ipv4_addr[2], card->ipv4_addr[3]);
161 }
162
163 qemu_log("Type: %d", type);
164 }
165 }
166
167 void dhcp_init_all_cards() {
168 for(int i = 0; i < netcards_get_count(); i++) {
169 netcard_entry_t* card = netcard_get(i);
170
171 qemu_log("Initializing DHCP for: %s", card->name);
172
173 dhcp_discover(card);
174 dhcp_request(card, card->ipv4_addr);
175 }
176 }
memcpy
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173
netcard_entry_t
Definition: cards.h:5