Skip to content

Commit

Permalink
Fixes for #2.
Browse files Browse the repository at this point in the history
  • Loading branch information
perlun committed Aug 24, 2015
1 parent f0aaf58 commit 01b81d8
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 137 deletions.
106 changes: 37 additions & 69 deletions servers/network/ipv4/dhcp.c
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
/* $Id$ */
/* Abstract: DHCP (client) support. */
/* Author: Per Lundberg <per@halleluja.nu> */
// Abstract: DHCP (client) support.
// Author: Per Lundberg <per@halleluja.nu>
//
// © Copyright 1999-2000 chaos development
// © Copyright 2007 chaos development
// © Copyright 2015 chaos development

/* Copyright 1999-2000 chaos development. */
/* Copyright 2007 chaos development. */

#include "config.h"
#include "ipv4.h"
#include "udp.h"
#include "dhcp.h"

/* DHCP functions. */

void dhcp_assign(ipv4_interface_type *ipv4_interface,
ipc_structure_type *ethernet_structure)
// DHCP functions.
void dhcp_assign(ipv4_interface_type *ipv4_interface, ipc_structure_type *ethernet_structure)
{
dhcp_packet_type dhcp_packet;
dhcp_option_message_type dhcp_option_message;
Expand All @@ -27,24 +24,19 @@ void dhcp_assign(ipv4_interface_type *ipv4_interface,
u32 transaction_id;
unsigned int index = 0;

/* Get a random value to use as transaction ID. */

// Get a random value to use as transaction ID.
transaction_id = random(0xFFFF);

log_print_formatted(&log_structure, LOG_URGENCY_DEBUG,
"ID: %u.", (unsigned int) transaction_id);

/* Allocate memory for the reply. */
log_print_formatted(&log_structure, LOG_URGENCY_DEBUG, "ID: %u.", (unsigned int) transaction_id);

// Allocate memory for the reply.
memory_allocate((void **) data_pointer, data_size);
dhcp_reply = (dhcp_packet_type *) data;

/* Zap the DHCP packet over to the enemy. */

// Zap the DHCP packet over to the enemy.
memory_set_u8((u8 *) &dhcp_packet, 0, sizeof(dhcp_packet_type));

/* Request IP settings from a DHCP server. */

// Request IP settings from a DHCP server.
ipv4_ethernet_header_create(ethernet_broadcast,
ipv4_interface->hardware_address,
IPV4_ETHERNET_PROTOCOL_IPV4,
Expand All @@ -63,13 +55,11 @@ void dhcp_assign(ipv4_interface_type *ipv4_interface,
dhcp_packet.dhcp_message.operation = BOOTREQUEST;
dhcp_packet.dhcp_message.transaction_id = transaction_id;

/* 10Base-X. */
/* FIXME */

// 10Base-X.
// FIXME
dhcp_packet.dhcp_message.hardware_type = 1;

/* Length of hardware address. */

// Length of hardware address.
dhcp_packet.dhcp_message.header_length = IPV4_ETHERNET_ADDRESS_LENGTH;
dhcp_packet.dhcp_message.magic_cookie[0] = 99;
dhcp_packet.dhcp_message.magic_cookie[1] = 130;
Expand All @@ -80,27 +70,22 @@ void dhcp_assign(ipv4_interface_type *ipv4_interface,
dhcp_option_message.length = 1;
dhcp_option_message.type = DHCPDISCOVER;

memory_copy(&dhcp_packet.dhcp_message.client_hardware_address,
&ipv4_interface->hardware_address, 6);

/* Send this packet to the ethernet server. */
memory_copy(&dhcp_packet.dhcp_message.client_hardware_address, &ipv4_interface->hardware_address, 6);

// Send this packet to the ethernet server.
memory_set_u8((u8 *) data, 0, data_size);
message_parameter.protocol = IPC_PROTOCOL_ETHERNET;
message_parameter.message_class = IPC_ETHERNET_PACKET_SEND;
message_parameter.length = (sizeof(dhcp_packet) +
sizeof(dhcp_option_message_type));
message_parameter.length = (sizeof(dhcp_packet) + sizeof(dhcp_option_message_type));
message_parameter.data = data;
message_parameter.block = TRUE;

memory_copy((u8 *) data, &dhcp_packet, sizeof(dhcp_packet_type));
memory_copy((u8 *) data + sizeof(dhcp_packet_type),
&dhcp_option_message, sizeof(dhcp_option_message_type));
memory_copy((u8 *) data + sizeof(dhcp_packet_type), &dhcp_option_message, sizeof(dhcp_option_message_type));

ipc_send(ethernet_structure->output_mailbox_id, &message_parameter);

/* Wait for a reply. */

// Wait for a reply.
memory_set_u8((u8 *) data, 0, data_size);

do
Expand All @@ -111,27 +96,19 @@ void dhcp_assign(ipv4_interface_type *ipv4_interface,
&data_size);
}
while (!(message_parameter.message_class == IPC_ETHERNET_PACKET_RECEIVED &&
(dhcp_reply->ethernet_header.protocol_type ==
system_byte_swap_u16(IPV4_ETHERNET_PROTOCOL_IPV4)) &&
dhcp_reply->ethernet_header.protocol_type == system_byte_swap_u16(IPV4_ETHERNET_PROTOCOL_IPV4) &&
dhcp_reply->ipv4_header.protocol == IP_PROTOCOL_UDP &&
(dhcp_reply->udp_header.destination_port ==
system_byte_swap_u16(UDP_DHCP_REPLY)) &&
dhcp_reply->udp_header.destination_port == system_byte_swap_u16(UDP_DHCP_REPLY) &&
dhcp_reply->dhcp_message.transaction_id == transaction_id));

/* Tell the DHCP server we want this IP address. But first, save
information about the IP, netmask, and gateway addresses. */

/* Parse the DHCP options. */

dhcp_options =
(u8 *) &((dhcp_packet_type *) data)->dhcp_message.dhcp_options;

/* End of options. */
// Tell the DHCP server we want this IP address. But first, save information about the IP, netmask, and gateway addresses.
// Parse the DHCP options.
dhcp_options = (u8 *) &((dhcp_packet_type *) data)->dhcp_message.dhcp_options;

// End of options.
while (dhcp_options[index] != 255)
{
/* Ignore any zero bytes. */

// Ignore any zero bytes.
if (dhcp_options[index] == 0)
{
index++;
Expand All @@ -140,30 +117,26 @@ void dhcp_assign(ipv4_interface_type *ipv4_interface,

switch (dhcp_options[index])
{
/* Netmask. */

// Netmask.
case 1:
{
ipv4_interface->netmask = *((u32 *)(&dhcp_options[index + 2]));
break;
}

/* Gateway. */

// Gateway.
case 3:
{
ipv4_interface->gateway = *((u32 *)(&dhcp_options[index + 2]));
break;
}
}

/* Go to next option */

// Go to next option
dhcp_options += dhcp_options[index + 1] + 2;
}

/* Tell the server we want this address. */

// Tell the server we want this address.
ipv4_header_create(MAX_U32, 0, IP_PROTOCOL_UDP, sizeof(udp_header_type) +
sizeof(dhcp_message_type) +
sizeof(dhcp_option_message_type) +
Expand All @@ -185,8 +158,7 @@ void dhcp_assign(ipv4_interface_type *ipv4_interface,
dhcp_option_requested_ip.ip =
((dhcp_packet_type *) data)->dhcp_message.assigned_ip_address;

/* Send this packet to the ethernet server. */

// Send this packet to the ethernet server.
message_parameter.message_class = IPC_ETHERNET_PACKET_SEND;
message_parameter.length = (sizeof(dhcp_packet) +
sizeof(dhcp_option_message_type) +
Expand All @@ -204,24 +176,21 @@ void dhcp_assign(ipv4_interface_type *ipv4_interface,

ipc_send(ethernet_structure->output_mailbox_id, &message_parameter);

/* ...and wait for an answer */

// ...and wait for an answer
memory_set_u8((u8 *) data, 0, 1024);

message_parameter.message_class = IPC_CLASS_NONE;

do
{
system_call_mailbox_receive(ethernet_structure->input_mailbox_id,
&message_parameter);
system_call_mailbox_receive(ethernet_structure->input_mailbox_id, &message_parameter);

}
while (!((message_parameter.message_class == IPC_ETHERNET_PACKET_RECEIVED &&
dhcp_reply->ethernet_header.protocol_type ==
system_byte_swap_u16(IPV4_ETHERNET_PROTOCOL_IPV4) &&
dhcp_reply->ipv4_header.protocol == IP_PROTOCOL_UDP &&
(dhcp_reply->udp_header.destination_port ==
system_byte_swap_u16(UDP_DHCP_REPLY)) &&
dhcp_reply->udp_header.destination_port == system_byte_swap_u16(UDP_DHCP_REPLY) &&
dhcp_reply->dhcp_message.transaction_id == transaction_id)));

ipv4_interface->ip_address = dhcp_option_requested_ip.ip;
Expand All @@ -242,8 +211,7 @@ void dhcp_assign(ipv4_interface_type *ipv4_interface,
(ipv4_interface->gateway >> 16) & 0xFF,
ipv4_interface->gateway >> 24);

/* Indicate that this interface is using DHCP. */

// Indicate that this interface is using DHCP.
ipv4_interface->dhcp = TRUE;
ipv4_interface->up = TRUE;
}
96 changes: 28 additions & 68 deletions servers/network/ipv4/dhcp.h
Original file line number Diff line number Diff line change
@@ -1,51 +1,33 @@
/* $Id$ */
/* Abstract: DHCP structures and function prototypes. */
/* Author: Per Lundberg <per@halleluja.nu>. */
// Abstract: DHCP structures and function prototypes.
// Author: Per Lundberg <per@halleluja.nu>.
//
// © Copyright 1999-2000 chaos development
// © Copyright 2007 chaos development
// © Copyright 2015 chaos development

/* Copyright 1999-2000 chaos development. */

/* This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA. */

#ifndef __DHCP_H__
#define __DHCP_H__
#pragma once

#include <ipc/ipc.h>
#include <system/system.h>

#include "ipv4.h"
#include "udp.h"

/* For a full description of how this works, see RFC 2131. */

// For a full description of how this works, see RFC 2131.
enum
{
BOOTREQUEST = 1,
BOOTREPLY
};

/* Optional tags. */

// Optional tags.
enum
{
DHCP_OPTION_REQUESTED_IP = 50,
DHCP_OPTION_MESSAGE_TYPE = 53,
};

/* DHCP message types. */

// DHCP message types.
enum
{
DHCPDISCOVER = 1,
Expand All @@ -58,83 +40,65 @@ enum
DHCPINFORM
};

/* A standard DHCP message. */

// A standard DHCP message.
typedef struct
{
/* Message type. 1 = BOOTREQUEST, 2 = BOOTREPLY. */

// Message type. 1 = BOOTREQUEST, 2 = BOOTREPLY.
u8 operation;

/* 1 = 10Base-X. FIXME: Support this field properly. */

// 1 = 10Base-X. FIXME: Support this field properly.
u8 hardware_type;

u8 header_length;

/* Set to zero by client and updated by relay agents. */

// Set to zero by client and updated by relay agents.
u8 hops;

/* Transaction ID, chosen by client and used to identify the
session. */

// Transaction ID, chosen by client and used to identify the session.
u32 transaction_id;

/* Filled in by the client and shows the seconds elapsed since
the address requisition started. */

// Filled in by the client and shows the seconds elapsed since the address requisition started.
u16 seconds;
u16 flags;

/* Only filled in if IP is up. */

// Only filled in if IP is up.
u32 client_ip_address;

/* Used by BOOTREPLY. */

// Used by BOOTREPLY.
u32 assigned_ip_address;
u32 next_server_ip_address;
u32 relay_agent_ip_address;
u8 client_hardware_address[16];

/* Optional server host name. */

// Optional server host name.
u8 server_host_name[64];

/* Boot file name. */

// Boot file name.
u8 file[128];

/* Should be 99, 130, 83, 99 */

// Should be 99, 130, 83, 99
u8 magic_cookie[4];

/* DHCP options are stored right here. */

// DHCP options are stored right here.
u8 dhcp_options[0];
} __attribute__((packed)) dhcp_message_type;

typedef struct
{
/* 53. */

// 53.
u8 code;

/* 1. */

// 1.
u8 length;
u8 type;
} __attribute__((packed)) dhcp_option_message_type;

typedef struct
{
/* 50. */

// 50.
u8 code;

/* 1. */

// 1.
u8 length;
u32 ip;
} __attribute__((packed)) dhcp_option_requested_ip_type;
Expand All @@ -147,9 +111,5 @@ typedef struct
dhcp_message_type dhcp_message;
} __attribute__((packed)) dhcp_packet_type;

/* Function prototypes. */

extern void dhcp_assign(ipv4_interface_type *ipv4_interface,
ipc_structure_type *ethernet_structure);

#endif /* !__DHCP_H__ */
// Function prototypes.
extern void dhcp_assign(ipv4_interface_type *ipv4_interface, ipc_structure_type *ethernet_structure);

0 comments on commit 01b81d8

Please sign in to comment.