Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions .idea/DHCP-implementation.iml

This file was deleted.

18 changes: 18 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 0 additions & 8 deletions .idea/modules.xml

This file was deleted.

Binary file modified bin/client
Binary file not shown.
Binary file added bin/server
Binary file not shown.
9 changes: 9 additions & 0 deletions include/dhcp_server.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef DHCP_SERVER_H
#define DHCP_SERVER_H

#include <stdio.h>
#include <stdlib.h>

int run_server(void);

#endif
10 changes: 6 additions & 4 deletions include/net_utils.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#ifndef NET_UTILS_H
#define NET_UTILS_H

#include <stdint.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <time.h>
#include <stdlib.h>

#define DHCP_SNAME_SIZE 64
#define DHCP_FILE_SIZE 128
Expand Down Expand Up @@ -51,10 +51,12 @@ enum DHCP_MESSAGE {
DHCP_INFORM = 8,
};

int get_dhcp_type(DHCPPacket *packet);

// --- DECLARACIONES CORRECTAS Y FINALES ---
// Corregido el nombre a "get_mac_address" y la firma
int get_mac_address(const char *if_name, uint8_t *mac_buffer);
// Corregida la firma para aceptar un puntero a la MAC
DHCPPacket create_dhcp_packet(uint8_t *mac_addr, enum DHCP_OP op, enum DHCP_MESSAGE tipo_msg, size_t *packet_size);
DHCPPacket create_dhcp_packet(uint32_t xid, uint8_t *mac_addr, enum DHCP_MESSAGE tipo_msg, uint32_t *requested_ip, uint32_t *server_id, size_t *packet_size);

#endif
#endif
22 changes: 13 additions & 9 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@ CC = gcc
CFLAGS = -Wall -Wextra -Iinclude
SRC_DIR = src
BIN_DIR = bin
SRC = $(wildcard $(SRC_DIR)/*.c)
OBJ = $(SRC:.c=.o)
BIN = $(BIN_DIR)/client
CLIENT_SRC = $(SRC_DIR)/main.c $(SRC_DIR)/dhcp_client.c $(SRC_DIR)/net_utils.c
SERVER_SRC = $(SRC_DIR)/main.c $(SRC_DIR)/dhcp_server.c $(SRC_DIR)/net_utils.c
CLIENT_BIN = $(BIN_DIR)/client
SERVER_BIN = $(BIN_DIR)/server

.PHONY: all clean
.PHONY: all clean client server

$(BIN): $(OBJ)
all: client server

client: $(CLIENT_SRC)
@mkdir -p $(BIN_DIR)
$(CC) $(CFLAGS) $^ -o $@
$(CC) $(CFLAGS) -DCLIENT_MAIN $(CLIENT_SRC) -o $(CLIENT_BIN)

%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
server: $(SERVER_SRC)
@mkdir -p $(BIN_DIR)
$(CC) $(CFLAGS) -DSERVER_MAIN $(SERVER_SRC) -o $(SERVER_BIN)

clean:
rm -f $(OBJ) $(BIN)
rm -f $(BIN_DIR)/client $(BIN_DIR)/server
114 changes: 107 additions & 7 deletions src/dhcp_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ int start_client(const char *if_name) {
srand(time(0));

uint8_t mac_addr[6];
const char *interface_name = "enp7s0";
const char *interface_name = "wlo1";

if (get_mac_address(interface_name, mac_addr) != 0) {
fprintf(stderr, "No se pudo obtener la dirección MAC de la interfaz %s\n", interface_name);
Expand All @@ -31,8 +31,13 @@ int start_client(const char *if_name) {
mac_addr[0], mac_addr[1], mac_addr[2],
mac_addr[3], mac_addr[4], mac_addr[5]);

//Generar el xid una SOLA VEZ
uint32_t xid = htonl((uint32_t)rand()); //Rand genera el numero y htonl lo convierte a big-endian

size_t packet_size;
DHCPPacket dhcp_packet = create_dhcp_packet(mac_addr, BOOTREQUEST, DHCP_DISCOVER, &packet_size);

//NULL La ip solicitada y el server_id, porque no los tenemos xd
DHCPPacket dhcp_packet = create_dhcp_packet(xid, mac_addr, DHCP_DISCOVER, NULL,NULL, &packet_size);

int socket_fd;
struct sockaddr_in server_addr;
Expand Down Expand Up @@ -105,20 +110,115 @@ int start_client(const char *if_name) {
printf("Paquete recibido (%ld bytes)\n", recibido);

DHCPPacket *respuesta = (DHCPPacket *)buffer;
if (respuesta->op != BOOTREPLY) {
printf("Respuesta no válida: op = %d\n", respuesta->op);
if(respuesta->op != BOOTREPLY || respuesta->xid != xid) {
printf("Respuesta no válida o xid no coincide\n");
close(socket_fd);
return EXIT_FAILURE;
}

printf("IP ofrecida: %s\n", inet_ntoa(*(struct in_addr *)&respuesta->yiaddr));

// PARTE DEL REQUEST DEL CLIENTE AL SERVIDOR

//1. Definir una funcion get server id que reciba la respuesta del servidor y extraiga el server_id

uint32_t get_server_id(DHCPPacket *pkt) {
uint8_t *options = pkt->options;
uint8_t *ptr = options + 4; // Saltar el magic cookie
uint8_t *end = options + DHCP_OPTIONS_SIZE;
while (ptr < end && *ptr != 255) {
uint8_t opt_code = *ptr++;
if (opt_code == 0) {
continue;
}
uint8_t opt_len = *ptr++;
if (opt_code == 54) {
uint32_t server_id;
memcpy(&server_id, ptr, sizeof(server_id));
return server_id;
}
ptr += opt_len;
}
return 0;
}

enum DHCP_MESSAGE get_dhcp_message_type(DHCPPacket *pkt) {
uint8_t *options = pkt->options;
uint8_t *ptr = options + 4; // Saltar el magic cookie
uint8_t *end = options + DHCP_OPTIONS_SIZE;
while (ptr < end && *ptr != 255) {
uint8_t opt_code = *ptr++;
if (opt_code == 0) {
continue;
}
uint8_t opt_len = *ptr++;
if (opt_code == 53) {
return (enum DHCP_MESSAGE)*ptr;
}
ptr += opt_len;
}
return 0;
}

uint32_t server_id = get_server_id(respuesta);

if (server_id == 0) {
printf("No se encontró el Server Identifier en la respuesta\n");
close(socket_fd);
return EXIT_FAILURE;
}

size_t request_packet_size;
DHCPPacket dhcp_request = create_dhcp_packet(xid, mac_addr, DHCP_REQUEST, &respuesta->yiaddr, &server_id, &request_packet_size);

if (sendto(socket_fd, &dhcp_request, request_packet_size, 0,
(struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Error al enviar el paquete DHCP REQUEST");
close(socket_fd);
return EXIT_FAILURE;
}

printf("Paquete dhcp REQUEST enviado (%ld bytes)\n", request_packet_size);

printf("Pedimos la IP %s al servidor con ID %s\n",
inet_ntoa(*(struct in_addr *)&respuesta->yiaddr),
inet_ntoa(*(struct in_addr *)&server_id));

// PARTE DEL REQUEST DEL CLIENTE AL SERVIDOR
printf("Esperando respuesta DHCP ACK o NAK...\n");

memset(buffer, 0, sizeof(buffer));

// Supongo que primero hay que crear el fuquin paquete:
recibido = recvfrom(socket_fd, buffer, sizeof(buffer), 0, NULL, NULL);

if (recibido < 0) {
perror("Error al recibir paquete DHCP ACK o NAK");
close(socket_fd);
return EXIT_FAILURE;
}

// DHCPPacket dhcp_request = create_dhcp_packet();
printf("Paquete recibido (%ld bytes)\n", recibido);

DHCPPacket *respuesta_final = (DHCPPacket *)buffer;

if(respuesta_final->xid != xid) {
printf("Respuesta no válida o xid no coincide\n");
close(socket_fd);
return EXIT_FAILURE;
}

enum DHCP_MESSAGE msg_type = get_dhcp_message_type(respuesta_final);

switch (msg_type) {
case DHCP_ACK:
printf("Mensaje tipo DHCP_ACK recibido\n");
break;
case DHCP_NAK:
printf("Mensaje tipo DHCP_NAK recibido\n");
break;
default:
printf("Mensaje tipo desconocido recibido: %d\n", msg_type);
break;
}

close(socket_fd);
return 0;
Expand Down
Loading