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 }
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173
Definition: cards.h:5