Added ARP protocol to network stack and fixed bug in grub_netbuff_alloc function.

* include/grub/net/arp.h: added arp header, arp cache entry and related constants and functions
* net/arp.c: added functions arp_init_table, arp_find_entry, arp_resolve and arp_receive
* net/ethernet.c (send_ethernet_packet): replaced hardcoded hardware address by parameter target_addr
* net/ethernet.c (recv_ethernet_packet): added call to arp_receive when packet is of type 0x803 (ARP) and only return when packet is of type determined by parameter ethertype
* net/ip.c (send_ip_packet): added call to arp_resolve to determine hardware address of destination
* net/netbuff.c (grub_netbuff_alloc): fixed swapped parameters in call to grub_memalign
This commit is contained in:
Paulo de Rezende Pinatti 2010-08-13 14:42:16 -03:00
parent 7c978f0690
commit 10830203a0
12 changed files with 335 additions and 56 deletions

View file

@ -22,6 +22,7 @@
#include <grub/disk.h> #include <grub/disk.h>
#include <grub/file.h> #include <grub/file.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/net.h>
#include <grub/net/arp.h> #include <grub/net/arp.h>
#include <grub/net/ip.h> #include <grub/net/ip.h>
#include <grub/net/udp.h> #include <grub/net/udp.h>
@ -95,7 +96,7 @@ retrieve_field(const char *src, char **field, const char **rest)
static grub_err_t static grub_err_t
parse_ip (const char *val, grub_uint32_t *ip, const char **rest) parse_ip (const char *val, grub_uint32_t *ip, const char **rest)
{ {
grub_uint32_t newip = 0; grub_uint8_t *p = (grub_uint8_t *) ip;
unsigned long t; unsigned long t;
int i; int i;
const char *ptr = val; const char *ptr = val;
@ -107,8 +108,7 @@ parse_ip (const char *val, grub_uint32_t *ip, const char **rest)
return grub_errno; return grub_errno;
if (t & ~0xff) if (t & ~0xff)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
newip >>= 8; p[i] = (grub_uint8_t) t;
newip |= (t << 24);
if (i != 3 && *ptr != '.') if (i != 3 && *ptr != '.')
return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
ptr++; ptr++;
@ -116,7 +116,6 @@ parse_ip (const char *val, grub_uint32_t *ip, const char **rest)
ptr = ptr - 1; ptr = ptr - 1;
if ( *ptr != '\0' && *ptr != ',') if ( *ptr != '\0' && *ptr != ',')
return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
*ip = newip;
if (rest) if (rest)
*rest = ptr; *rest = ptr;
return 0; return 0;
@ -305,12 +304,33 @@ grub_ofnetfs_open (struct grub_file *file , const char *name )
char *datap; char *datap;
int amount = 0; int amount = 0;
grub_addr_t found_addr; grub_addr_t found_addr;
grub_netdisk_data_t netdisk_data = (grub_netdisk_data_t) file->device->disk->data;
// TODO: replace getting IP and MAC from bootp by routing functions
struct grub_net_network_layer_interface net_interface;
struct grub_net_card net_card;
struct grub_net_addr ila, lla;
ila.addr = (grub_uint8_t *) &(bootp_pckt->yiaddr);
ila.len = 4;
lla.addr = (grub_uint8_t *) &(bootp_pckt->chaddr);
lla.len = 6;
net_card.ila = &ila;
net_card.lla = &lla;
net_interface.card = &net_card;
// END TODO
if(! netdisk_data)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments missing");
if(netdisk_data->protocol == GRUB_NETDISK_PROTOCOL_TFTP)
stack = grub_net_protocol_stack_get ("tftp");
else
return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid protocol specified");
stack = grub_net_protocol_stack_get ("tftp");
app_interface = (struct grub_net_application_transport_interface *) stack->interface; app_interface = (struct grub_net_application_transport_interface *) stack->interface;
pack = grub_netbuff_alloc (80*1024); app_interface->inner_layer->data = (void *) &(netdisk_data->server_ip);
grub_netbuff_reserve (pack,80*1024); pack = grub_netbuff_alloc (2048);
file_size = app_interface->app_prot->get_file_size(NULL,stack,pack,(char *) name); grub_netbuff_reserve (pack,2048);
file_size = app_interface->app_prot->get_file_size(&net_interface,stack,pack,(char *) name);
for (found_addr = 0x800000; found_addr < + 2000 * 0x100000; found_addr += 0x100000) for (found_addr = 0x800000; found_addr < + 2000 * 0x100000; found_addr += 0x100000)
{ {
@ -320,16 +340,16 @@ grub_ofnetfs_open (struct grub_file *file , const char *name )
file->data = (void *) found_addr; file->data = (void *) found_addr;
grub_netbuff_clear(pack); grub_netbuff_clear(pack);
grub_netbuff_reserve (pack,80*1024); grub_netbuff_reserve (pack,2048);
app_interface->app_prot->open (NULL,stack,pack,(char *) name); app_interface->app_prot->open (&net_interface,stack,pack,(char *) name);
if (grub_errno != GRUB_ERR_NONE) if (grub_errno != GRUB_ERR_NONE)
goto error; goto error;
do do
{ {
grub_netbuff_clear(pack); grub_netbuff_clear(pack);
grub_netbuff_reserve (pack,80*1024); grub_netbuff_reserve (pack,2048);
app_interface->app_prot->recv (NULL,stack,pack); app_interface->app_prot->recv (&net_interface,stack,pack);
if (grub_errno != GRUB_ERR_NONE) if (grub_errno != GRUB_ERR_NONE)
goto error; goto error;
if ((pack->tail - pack->data)) if ((pack->tail - pack->data))
@ -340,8 +360,8 @@ grub_ofnetfs_open (struct grub_file *file , const char *name )
grub_memcpy(datap , pack->data, pack->tail - pack->data); grub_memcpy(datap , pack->data, pack->tail - pack->data);
} }
grub_netbuff_clear(pack); grub_netbuff_clear(pack);
grub_netbuff_reserve (pack,80*1024); grub_netbuff_reserve (pack,2048);
app_interface->app_prot->send_ack (NULL,stack,pack); app_interface->app_prot->send_ack (&net_interface,stack,pack);
if (grub_errno != GRUB_ERR_NONE) if (grub_errno != GRUB_ERR_NONE)
goto error; goto error;

View file

@ -1,17 +1,42 @@
#ifndef GRUB_NET_ARP_HEADER #ifndef GRUB_NET_ARP_HEADER
#define GRUB_NET_ARP_HEADER 1 #define GRUB_NET_ARP_HEADER 1
#include <grub/misc.h>
#include <grub/net.h>
#include <grub/net/protocol.h>
#include <grub/net/ethernet.h> /* IANA ARP constant to define hardware type as ethernet */
struct arphdr{ #define ARPHRD_ETHERNET 1
grub_int16_t hwtype; /* hardware type (must be ARPHRD_ETHER) */ /* IANA Ethertype */
grub_int16_t protocol; /* protocol type (must be ETH_P_IP) */ #define ARP_ETHERTYPE 0x806
grub_int8_t hwlen; /* hardware address length (must be 6) */
grub_int8_t protolen; /* protocol address length (must be 4) */ /* Size for cache table */
grub_uint16_t opcode; /* ARP opcode */ #define SIZE_ARP_TABLE 5
grub_uint8_t shwaddr[6]; /* sender's hardware address */
grub_uint32_t sipaddr; /* sender's IP address */ /* ARP header operation codes */
grub_uint8_t thwaddr[6]; /* target's hardware address */ #define ARP_REQUEST 1
grub_uint32_t tipaddr; /* target's IP address */ #define ARP_REPLY 2
}__attribute__ ((packed));
struct arp_entry {
grub_uint8_t avail;
struct grub_net_network_layer_protocol *nl_protocol;
struct grub_net_link_layer_protocol *ll_protocol;
struct grub_net_addr nl_address;
struct grub_net_addr ll_address;
};
struct arphdr {
grub_uint16_t hrd;
grub_uint16_t pro;
grub_uint8_t hln;
grub_uint8_t pln;
grub_uint16_t op;
} __attribute__ ((packed));
extern grub_err_t arp_receive(struct grub_net_network_layer_interface *inf __attribute__ ((unused)),
struct grub_net_network_link_interface *net_link_inf, struct grub_net_buff *nb);
extern grub_err_t arp_resolve(struct grub_net_network_layer_interface *inf __attribute__ ((unused)),
struct grub_net_network_link_interface *net_link_inf, struct grub_net_addr *proto_addr,
struct grub_net_addr *hw_addr);
#endif #endif

View file

@ -37,7 +37,7 @@ struct grub_net_network_link_interface
}; };
extern struct grub_net_protocol_stack *grub_net_protocol_stacks; struct grub_net_protocol_stack *grub_net_protocol_stacks;
static inline void static inline void
grub_net_stack_register (struct grub_net_protocol_stack *stack) grub_net_stack_register (struct grub_net_protocol_stack *stack)
{ {

View file

@ -2,6 +2,7 @@
#define GRUB_NET_IP_HEADER 1 #define GRUB_NET_IP_HEADER 1
#include <grub/misc.h> #include <grub/misc.h>
#define IP_ETHERTYPE 0x800 /* IANA Ethertype */
struct iphdr { struct iphdr {
grub_uint8_t verhdrlen; grub_uint8_t verhdrlen;

View file

@ -8,7 +8,7 @@
struct grub_net_protocol; struct grub_net_protocol;
struct grub_net_protocol_stack; struct grub_net_protocol_stack;
struct grub_net_network_layer_interface; struct grub_net_network_layer_interface;
struct grub_net_addr;
typedef enum grub_network_layer_protocol_id typedef enum grub_network_layer_protocol_id
{ {
@ -57,6 +57,7 @@ struct grub_net_network_layer_protocol
struct grub_net_network_layer_protocol *next; struct grub_net_network_layer_protocol *next;
char *name; char *name;
grub_net_protocol_id_t id; grub_net_protocol_id_t id;
grub_uint16_t type; /* IANA Ethertype */
//grub_network_layer_protocol_id_t id; //grub_network_layer_protocol_id_t id;
grub_err_t (*ntoa) (char *name, grub_net_network_layer_address_t *addr); grub_err_t (*ntoa) (char *name, grub_net_network_layer_address_t *addr);
char * (*aton) (union grub_net_network_layer_address addr); char * (*aton) (union grub_net_network_layer_address addr);
@ -76,11 +77,14 @@ struct grub_net_link_layer_protocol
struct grub_net_link_layer_protocol *next; struct grub_net_link_layer_protocol *next;
char *name; char *name;
grub_uint16_t type; /* ARP hardware type */
grub_net_protocol_id_t id; grub_net_protocol_id_t id;
grub_err_t (*send) (struct grub_net_network_layer_interface *inf , grub_err_t (*send) (struct grub_net_network_layer_interface *inf ,
struct grub_net_network_link_interface *net_link_inf, struct grub_net_buff *nb); struct grub_net_network_link_interface *net_link_inf, struct grub_net_buff *nb,
struct grub_net_addr target_addr, grub_uint16_t ethertype);
grub_err_t (*recv) (struct grub_net_network_layer_interface *inf , grub_err_t (*recv) (struct grub_net_network_layer_interface *inf ,
struct grub_net_network_link_interface *net_link_inf, struct grub_net_buff *nb); struct grub_net_network_link_interface *net_link_inf, struct grub_net_buff *nb,
grub_uint16_t ethertype);
}; };
extern struct grub_net_network_layer_protocol *grub_net_network_layer_protocols; extern struct grub_net_network_layer_protocol *grub_net_network_layer_protocols;

207
net/arp.c
View file

@ -0,0 +1,207 @@
#include <grub/net/arp.h>
#include <grub/net/netbuff.h>
#include <grub/net/interface.h>
#include <grub/mm.h>
#include <grub/net.h>
#include <grub/net/ethernet.h>
#include <grub/net/ip.h>
#include <grub/time.h>
#include <grub/net/ieee1275/interface.h>
static struct arp_entry arp_table[SIZE_ARP_TABLE];
static grub_int8_t new_table_entry = -1;
static void arp_init_table(void)
{
struct arp_entry *entry = &(arp_table[0]);
for(;entry<=&(arp_table[SIZE_ARP_TABLE-1]);entry++)
{
entry->avail = 0;
entry->nl_protocol = NULL;
entry->ll_protocol = NULL;
entry->nl_address.addr = NULL;
entry->nl_address.len = 0;
entry->ll_address.addr = NULL;
entry->ll_address.len = 0;
}
new_table_entry = 0;
}
static struct arp_entry *
arp_find_entry(struct grub_net_network_link_interface *net_link_inf, const void *proto_address, grub_uint8_t address_len)
{
grub_uint8_t i;
for(i=0;i < SIZE_ARP_TABLE; i++)
{
if(arp_table[i].avail == 1 &&
arp_table[i].nl_protocol->type == net_link_inf->net_prot->type &&
arp_table[i].ll_protocol->type == net_link_inf->link_prot->type &&
(!grub_memcmp(arp_table[i].nl_address.addr, proto_address, address_len)))
return &(arp_table[i]);
}
return NULL;
}
grub_err_t arp_resolve(struct grub_net_network_layer_interface *inf __attribute__ ((unused)),
struct grub_net_network_link_interface *net_link_inf, struct grub_net_addr *proto_addr,
struct grub_net_addr *hw_addr)
{
struct arp_entry *entry;
struct grub_net_buff *nb;
struct arphdr *arp_header;
struct grub_net_addr target_hw_addr;
grub_uint8_t *aux, i;
/* Check cache table */
entry = arp_find_entry(net_link_inf, proto_addr->addr, proto_addr->len);
if (entry)
{
hw_addr->addr = grub_malloc(entry->ll_address.len);
if (! hw_addr->addr)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory");
grub_memcpy(hw_addr->addr, entry->ll_address.addr, entry->ll_address.len);
hw_addr->len = entry->ll_address.len;
return GRUB_ERR_NONE;
}
/* Build a request packet */
nb = grub_netbuff_alloc (2048);
grub_netbuff_reserve(nb, 2048);
grub_netbuff_push(nb, sizeof(*arp_header) + 2*(inf->card->lla->len + inf->card->ila->len));
arp_header = (struct arphdr *)nb->data;
arp_header->hrd = net_link_inf->link_prot->type;
arp_header->pro = net_link_inf->net_prot->type;
arp_header->hln = inf->card->lla->len;
arp_header->pln = inf->card->ila->len;
arp_header->op = ARP_REQUEST;
aux = (grub_uint8_t *)arp_header + sizeof(*arp_header);
/* Sender hardware address */
grub_memcpy(aux, inf->card->lla->addr, inf->card->lla->len);
aux += inf->card->lla->len;
/* Sender protocol address */
grub_memcpy(aux, inf->card->ila->addr, inf->card->ila->len);
aux += inf->card->ila->len;
/* Target hardware address */
for(i=0; i < inf->card->lla->len; i++)
aux[i] = 0x00;
aux += inf->card->lla->len;
/* Target protocol address */
grub_memcpy(aux, proto_addr->addr, inf->card->ila->len);
target_hw_addr.addr = grub_malloc(inf->card->lla->len);
target_hw_addr.len = inf->card->lla->len;
for(i=0; i < target_hw_addr.len; i++)
(target_hw_addr.addr)[i] = 0xFF;
net_link_inf->link_prot->send(inf, net_link_inf, nb, target_hw_addr, ARP_ETHERTYPE);
grub_free(target_hw_addr.addr);
grub_netbuff_clear(nb);
grub_netbuff_reserve(nb, 2048);
grub_uint64_t start_time, current_time;
start_time = grub_get_time_ms();
do
{
net_link_inf->link_prot->recv(inf, net_link_inf, nb, ARP_ETHERTYPE);
/* Now check cache table again */
entry = arp_find_entry(net_link_inf, proto_addr->addr, proto_addr->len);
if (entry)
{
hw_addr->addr = grub_malloc(entry->ll_address.len);
if (! hw_addr->addr)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory");
grub_memcpy(hw_addr->addr, entry->ll_address.addr, entry->ll_address.len);
hw_addr->len = entry->ll_address.len;
grub_netbuff_clear(nb);
return GRUB_ERR_NONE;
}
current_time = grub_get_time_ms();
if (current_time - start_time > TIMEOUT_TIME_MS)
break;
} while (! entry);
grub_netbuff_clear(nb);
return grub_error (GRUB_ERR_TIMEOUT, "Timeout: could not resolve hardware address.");
}
grub_err_t arp_receive(struct grub_net_network_layer_interface *inf __attribute__ ((unused)),
struct grub_net_network_link_interface *net_link_inf, struct grub_net_buff *nb)
{
struct arphdr *arp_header = (struct arphdr *)nb->data;
struct arp_entry *entry;
grub_uint8_t merge = 0;
/* Verify hardware type, protocol type, hardware address length, protocol address length */
if (arp_header->hrd != net_link_inf->link_prot->type || arp_header->pro != net_link_inf->net_prot->type ||
arp_header->hln != inf->card->lla->len || arp_header->pln != inf->card->ila->len)
return GRUB_ERR_NONE;
grub_uint8_t *sender_hardware_address, *sender_protocol_address, *target_hardware_address, *target_protocol_address;
sender_hardware_address = (grub_uint8_t *)arp_header + sizeof(*arp_header);
sender_protocol_address = sender_hardware_address + arp_header->hln;
target_hardware_address = sender_protocol_address + arp_header->pln;
target_protocol_address = target_hardware_address + arp_header->hln;
/* Check if the sender is in the cache table */
entry = arp_find_entry(net_link_inf, sender_protocol_address, arp_header->pln);
/* Update sender hardware address */
if (entry)
{
if (entry->ll_address.addr)
grub_free(entry->ll_address.addr);
entry->ll_address.addr = grub_malloc(arp_header->hln);
if (! entry->ll_address.addr)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory");
grub_memcpy(entry->ll_address.addr, sender_hardware_address, arp_header->hln);
entry->ll_address.len = arp_header->hln;
merge = 1;
}
/* Am I the protocol address target? */
if (! grub_memcmp(target_protocol_address, inf->card->ila->addr, arp_header->pln))
{
/* Add sender to cache table */
if (! merge)
{
if (new_table_entry == -1)
arp_init_table();
entry = &(arp_table[new_table_entry]);
entry->avail = 1;
entry->ll_protocol = net_link_inf->link_prot;
entry->nl_protocol = net_link_inf->net_prot;
if (entry->nl_address.addr)
grub_free(entry->nl_address.addr);
entry->nl_address.addr = grub_malloc(arp_header->pln);
if (! entry->nl_address.addr)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory");
grub_memcpy(entry->nl_address.addr, sender_protocol_address, arp_header->pln);
entry->nl_address.len = arp_header->pln;
if (entry->ll_address.addr)
grub_free(entry->ll_address.addr);
entry->ll_address.addr = grub_malloc(arp_header->hln);
if (! entry->ll_address.addr)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory");
grub_memcpy(entry->ll_address.addr, sender_hardware_address, arp_header->hln);
entry->ll_address.len = arp_header->hln;
new_table_entry++;
if (new_table_entry == SIZE_ARP_TABLE)
new_table_entry = 0;
}
if (arp_header->op == ARP_REQUEST)
{
struct grub_net_addr aux;
/* Swap hardware fields */
grub_memcpy(target_hardware_address, sender_hardware_address, arp_header->hln);
grub_memcpy(sender_hardware_address, inf->card->lla->addr, arp_header->hln);
/* Swap protocol fields */
aux.addr = grub_malloc(arp_header->pln);
if (! aux.addr)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory");
grub_memcpy(aux.addr, sender_protocol_address, arp_header->pln);
grub_memcpy(sender_protocol_address, target_protocol_address, arp_header->pln);
grub_memcpy(target_protocol_address, aux.addr, arp_header->pln);
grub_free(aux.addr);
/* Change operation to REPLY and send packet */
arp_header->op = ARP_REPLY;
aux.addr = target_hardware_address;
aux.len = arp_header->hln;
net_link_inf->link_prot->send(inf, net_link_inf, nb, aux, ARP_ETHERTYPE);
}
}
return GRUB_ERR_NONE;
}

View file

@ -8,24 +8,21 @@
#include <grub/net/interface.h> #include <grub/net/interface.h>
#include <grub/net.h> #include <grub/net.h>
#include <grub/time.h> #include <grub/time.h>
#include <grub/net/arp.h>
static grub_err_t static grub_err_t
send_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ ((unused)), send_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ ((unused)),
struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb) struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb,
struct grub_net_addr target_addr, grub_uint16_t ethertype)
{ {
struct etherhdr *eth; struct etherhdr *eth;
grub_netbuff_push (nb,sizeof(*eth)); grub_netbuff_push (nb,sizeof(*eth));
eth = (struct etherhdr *) nb->data; eth = (struct etherhdr *) nb->data;
eth->dst[0] = 0x00; grub_memcpy(eth->dst, target_addr.addr, target_addr.len);
eth->dst[1] = 0x11; grub_memcpy(eth->src, bootp_pckt->chaddr, 6);
eth->dst[2] = 0x25; eth->type = ethertype;
eth->dst[3] = 0xca;
eth->dst[4] = 0x1f;
eth->dst[5] = 0x01;
grub_memcpy (eth->src, bootp_pckt -> chaddr,6);
eth->type = 0x0800;
return send_card_buffer(nb); return send_card_buffer(nb);
// return inf->card->driver->send(inf->card,nb); // return inf->card->driver->send(inf->card,nb);
@ -34,7 +31,8 @@ send_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__
static grub_err_t static grub_err_t
recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ ((unused)), recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ ((unused)),
struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb) struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb,
grub_uint16_t ethertype)
{ {
struct etherhdr *eth; struct etherhdr *eth;
grub_uint64_t start_time, current_time; grub_uint64_t start_time, current_time;
@ -63,11 +61,16 @@ recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__
} }
} }
/*change for grub_memcmp*/ /* ARP packet */
//if( eth->src[0] == 0x00 && eth->src[1] == 0x11 && eth->src[2] == 0x25 && if (type == ARP_ETHERTYPE)
// eth->src[3] == 0xca && eth->src[4] == 0x1f && eth->src[5] == 0x01 && type == 0x800) {
if(type == 0x800) arp_receive(inf, net_link_inf, nb);
return 0; if (ethertype == ARP_ETHERTYPE)
return GRUB_ERR_NONE;
}
/* IP packet */
else if(type == IP_ETHERTYPE && ethertype == IP_ETHERTYPE)
return GRUB_ERR_NONE;
current_time = grub_get_time_ms (); current_time = grub_get_time_ms ();
if (current_time - start_time > TIMEOUT_TIME_MS) if (current_time - start_time > TIMEOUT_TIME_MS)
@ -77,7 +80,7 @@ recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__
- verify if the next layer is the desired one. - verify if the next layer is the desired one.
- if not. get another packet. - if not. get another packet.
- remove ethernet header from buffer*/ - remove ethernet header from buffer*/
return 0; return GRUB_ERR_NONE;
} }
@ -85,6 +88,7 @@ static struct grub_net_link_layer_protocol grub_ethernet_protocol =
{ {
.name = "ethernet", .name = "ethernet",
.id = GRUB_NET_ETHERNET_ID, .id = GRUB_NET_ETHERNET_ID,
.type = ARPHRD_ETHERNET,
.send = send_ethernet_packet, .send = send_ethernet_packet,
.recv = recv_ethernet_packet .recv = recv_ethernet_packet
}; };

View file

@ -22,7 +22,6 @@ INTERFACE_REGISTER_FUNCTIONS("link");*/
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/net/interface.h> #include <grub/net/interface.h>
struct grub_net_protocol_stack *grub_net_protocol_stacks;
struct grub_net_protocol_stack struct grub_net_protocol_stack
*grub_net_protocol_stack_get (char *name) *grub_net_protocol_stack_get (char *name)
{ {

View file

@ -1,6 +1,7 @@
#include <grub/net/ip.h> #include <grub/net/ip.h>
#include <grub/net/ieee1275/interface.h> #include <grub/net/ieee1275/interface.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/net/arp.h>
#include <grub/net/ethernet.h> #include <grub/net/ethernet.h>
#include <grub/net/interface.h> #include <grub/net/interface.h>
#include <grub/net/type_net.h> #include <grub/net/type_net.h>
@ -36,6 +37,8 @@ send_ip_packet (struct grub_net_network_layer_interface *inf,
struct iphdr *iph; struct iphdr *iph;
static int id = 0x2400; static int id = 0x2400;
struct grub_net_addr nl_target_addr, ll_target_addr;
grub_err_t rc;
grub_netbuff_push(nb,sizeof(*iph)); grub_netbuff_push(nb,sizeof(*iph));
iph = (struct iphdr *) nb->data; iph = (struct iphdr *) nb->data;
@ -51,12 +54,26 @@ send_ip_packet (struct grub_net_network_layer_interface *inf,
iph->ttl = 0xff; iph->ttl = 0xff;
iph->protocol = 0x11; iph->protocol = 0x11;
iph->src = (grub_uint32_t) bootp_pckt -> yiaddr; //inf->address.ipv4; // *((grub_uint32_t *)inf->card->ila->addr); iph->src = (grub_uint32_t) bootp_pckt -> yiaddr; //inf->address.ipv4; // *((grub_uint32_t *)inf->card->ila->addr);
iph->dest = (grub_uint32_t) bootp_pckt -> siaddr;//inf->address.ipv4;// *((grub_uint32_t *)inf->ila->addr); // iph->dest = (grub_uint32_t) bootp_pckt -> siaddr;//inf->address.ipv4;// *((grub_uint32_t *)inf->ila->addr);
iph->dest = *((grub_uint32_t *) (trans_net_inf->data));
iph->chksum = 0 ; iph->chksum = 0 ;
iph->chksum = ipchksum((void *)nb->data, sizeof(*iph)); iph->chksum = ipchksum((void *)nb->data, sizeof(*iph));
return trans_net_inf->inner_layer->link_prot->send(inf,trans_net_inf->inner_layer,nb); /* Determine link layer target address via ARP */
nl_target_addr.len = sizeof(iph->dest);
nl_target_addr.addr = grub_malloc(nl_target_addr.len);
if (! nl_target_addr.addr)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory");
grub_memcpy(nl_target_addr.addr, &(iph->dest), nl_target_addr.len);
rc = arp_resolve(inf, trans_net_inf->inner_layer, &nl_target_addr, &ll_target_addr);
grub_free(nl_target_addr.addr);
if (rc != GRUB_ERR_NONE)
return rc;
rc = trans_net_inf->inner_layer->link_prot->send(inf,trans_net_inf->inner_layer,nb,ll_target_addr, IP_ETHERTYPE);
grub_free(ll_target_addr.addr);
return rc;
//return protstack->next->prot->send(inf,protstack->next,nb); //return protstack->next->prot->send(inf,protstack->next,nb);
} }
@ -70,11 +87,12 @@ recv_ip_packet (struct grub_net_network_layer_interface *inf,
start_time = grub_get_time_ms(); start_time = grub_get_time_ms();
while (1) while (1)
{ {
trans_net_inf->inner_layer->link_prot->recv(inf,trans_net_inf->inner_layer,nb); trans_net_inf->inner_layer->link_prot->recv(inf,trans_net_inf->inner_layer,nb,IP_ETHERTYPE);
iph = (struct iphdr *) nb->data; iph = (struct iphdr *) nb->data;
if (iph->protocol == 0x11 && if (iph->protocol == 0x11 &&
iph->dest == (grub_uint32_t) bootp_pckt -> yiaddr && iph->dest == (grub_uint32_t) bootp_pckt -> yiaddr &&
iph->src == (grub_uint32_t) bootp_pckt -> siaddr ) //iph->src == (grub_uint32_t) bootp_pckt -> siaddr )
iph->src == *((grub_uint32_t *) (trans_net_inf->data)) )
{ {
grub_netbuff_pull(nb,sizeof(*iph)); grub_netbuff_pull(nb,sizeof(*iph));
return 0; return 0;
@ -99,6 +117,7 @@ static struct grub_net_network_layer_protocol grub_ipv4_protocol =
{ {
.name = "ipv4", .name = "ipv4",
.id = GRUB_NET_IPV4_ID, .id = GRUB_NET_IPV4_ID,
.type = IP_ETHERTYPE,
.send = send_ip_packet, .send = send_ip_packet,
.recv = recv_ip_packet .recv = recv_ip_packet
}; };

View file

@ -72,7 +72,7 @@ struct grub_net_buff *grub_netbuff_alloc ( grub_size_t len )
len = NETBUFFMINLEN; len = NETBUFFMINLEN;
len = ALIGN_UP (len,NETBUFF_ALIGN); len = ALIGN_UP (len,NETBUFF_ALIGN);
data = grub_memalign (len + sizeof (*nb),NETBUFF_ALIGN); data = grub_memalign (NETBUFF_ALIGN, len + sizeof (*nb));
nb = (struct grub_net_buff *) ((int)data + len); nb = (struct grub_net_buff *) ((int)data + len);
nb->head = nb->data = nb->tail = data; nb->head = nb->data = nb->tail = data;
nb->end = (char *) nb; nb->end = (char *) nb;

View file

@ -113,7 +113,7 @@ tftp_open (struct grub_net_network_layer_interface *inf __attribute((unused)),
app_interface->trans_prot->send (inf,protstack->interface,nb); app_interface->trans_prot->send (inf,protstack->interface,nb);
/*Receive OACK*/ /*Receive OACK*/
grub_netbuff_clear (nb); grub_netbuff_clear (nb);
grub_netbuff_reserve (nb,80*1024); grub_netbuff_reserve (nb,2048);
return app_interface->app_prot->recv(inf,protstack,nb); return app_interface->app_prot->recv(inf,protstack,nb);
} }
@ -215,7 +215,7 @@ static int tftp_file_size (struct grub_net_network_layer_interface* inf ,
tftp_open (inf, protocol_stack,nb, filename); tftp_open (inf, protocol_stack,nb, filename);
grub_netbuff_clear (nb); grub_netbuff_clear (nb);
grub_netbuff_reserve (nb,80*1024); grub_netbuff_reserve (nb,2048);
tftp_send_err (inf, protocol_stack,nb,"Abort transference.",0); tftp_send_err (inf, protocol_stack,nb,"Abort transference.",0);
return tftp_file.size; return tftp_file.size;

View file

@ -54,7 +54,7 @@ grub_normal_print_device_info (const char *name)
grub_printf_(N_("Protocol: %s"), "Unknown"); grub_printf_(N_("Protocol: %s"), "Unknown");
grub_putchar ('\n'); grub_putchar ('\n');
grub_putchar ('\t'); grub_putchar ('\t');
grub_printf_(N_("Server IP: %d.%d.%d.%d"), data->server_ip & 0xff, data->server_ip >> 8 & 0xff, data->server_ip >> 16 & 0xff, data->server_ip >> 24 & 0xff); grub_printf_(N_("Server IP: %d.%d.%d.%d"), data->server_ip >> 24 & 0xff, data->server_ip >> 16 & 0xff, data->server_ip >> 8 & 0xff, data->server_ip & 0xff);
if (data->username) if (data->username)
{ {
grub_putchar ('\n'); grub_putchar ('\n');