#include <grub/net/ip.h>
#include <grub/time.h>
-static struct arp_entry arp_table[SIZE_ARP_TABLE];
+static struct arp_entry arp_table[10];
static grub_int8_t new_table_entry = -1;
static
static struct arp_entry *
arp_find_entry (const grub_net_network_level_address_t *proto)
{
- grub_uint8_t i;
- for(i=0;i < SIZE_ARP_TABLE; i++)
+ unsigned i;
+ for(i = 0; i < ARRAY_SIZE (arp_table); i++)
{
if(arp_table[i].avail == 1 &&
arp_table[i].nl_address.ipv4 == proto->ipv4)
return GRUB_ERR_NONE;
}
/* Build a request packet */
- nb = grub_malloc (2048);
+ nb = grub_netbuff_alloc (2048);
+ if (!nb)
+ return grub_errno;
grub_netbuff_reserve(nb, 2048);
grub_netbuff_push(nb, sizeof(*arp_header) + 2 * (6 + 6));
arp_header = (struct arphdr *)nb->data;
- arp_header->hrd = 0;
- arp_header->pro = 0;
+ arp_header->hrd = grub_cpu_to_be16 (GRUB_NET_ARPHRD_ETHERNET);
+ arp_header->pro = grub_cpu_to_be16 (GRUB_NET_ETHERTYPE_IP);
arp_header->hln = 6;
- arp_header->pln = 6;
- arp_header->op = ARP_REQUEST;
+ arp_header->pln = 4;
+ arp_header->op = grub_cpu_to_be16 (ARP_REQUEST);
aux = (grub_uint8_t *)arp_header + sizeof(*arp_header);
/* Sender hardware address */
grub_memcpy(aux, &inf->hwaddress.mac, 6);
aux += 6;
/* Sender protocol address */
grub_memcpy(aux, &inf->address.ipv4, 4);
- aux += 6;
+ aux += 4;
/* Target hardware address */
- for(i=0; i < 6; i++)
+ for(i = 0; i < 6; i++)
aux[i] = 0x00;
aux += 6;
/* Target protocol address */
grub_memset (&target_hw_addr.mac, 0xff, 6);
- send_ethernet_packet (inf, nb, target_hw_addr, ARP_ETHERTYPE);
+ send_ethernet_packet (inf, nb, target_hw_addr, GRUB_NET_ETHERTYPE_ARP);
grub_netbuff_clear(nb);
grub_netbuff_reserve(nb, 2048);
start_time = grub_get_time_ms();
do
{
- grub_net_recv_ethernet_packet (inf, nb, ARP_ETHERTYPE);
+ grub_net_recv_ethernet_packet (inf, nb, GRUB_NET_ETHERTYPE_ARP);
/* Now check cache table again */
entry = arp_find_entry(proto_addr);
if (entry)
grub_netbuff_clear(nb);
return GRUB_ERR_NONE;
}
- current_time = grub_get_time_ms();
+ current_time = grub_get_time_ms();
if (current_time - start_time > 3000)
break;
} while (! entry);
}
grub_err_t
-grub_net_arp_receive(struct grub_net_network_level_interface *inf,
- struct grub_net_buff *nb)
+grub_net_arp_receive (struct grub_net_network_level_interface *inf,
+ struct grub_net_buff *nb)
{
struct arphdr *arp_header = (struct arphdr *)nb->data;
struct arp_entry *entry;
- grub_uint8_t merge = 0;
grub_uint8_t *sender_hardware_address, *sender_protocol_address;
grub_uint8_t *target_hardware_address, *target_protocol_address;
grub_net_network_level_address_t hwaddress;
- sender_hardware_address = (grub_uint8_t *)arp_header + sizeof(*arp_header);
+ 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;
entry = arp_find_entry(&hwaddress);
/* Update sender hardware address */
if (entry)
+ grub_memcpy(entry->ll_address.mac, sender_hardware_address, 6);
+ else
{
- grub_memcpy(entry->ll_address.mac, sender_hardware_address, 6);
- merge = 1;
- }
- /* Am I the protocol address target? */
- if (! grub_memcmp(target_protocol_address, inf->hwaddress.mac, 6))
- {
- /* Add sender to cache table */
- if (! merge)
- {
+ /* Add sender to cache table */
if (new_table_entry == -1)
- arp_init_table();
+ arp_init_table();
entry = &(arp_table[new_table_entry]);
entry->avail = 1;
grub_memcpy(&entry->nl_address.ipv4, sender_protocol_address, 4);
grub_memcpy(entry->ll_address.mac, sender_hardware_address, 6);
new_table_entry++;
- if (new_table_entry == SIZE_ARP_TABLE)
- new_table_entry = 0;
- }
- if (arp_header->op == ARP_REQUEST)
- {
- grub_net_link_level_address_t aux;
- /* Swap hardware fields */
- grub_memcpy(target_hardware_address, sender_hardware_address, arp_header->hln);
- grub_memcpy(sender_hardware_address, inf->hwaddress.mac, 6);
- grub_memcpy(aux.mac, sender_protocol_address, 6);
- grub_memcpy(sender_protocol_address, target_protocol_address, arp_header->pln);
- grub_memcpy(target_protocol_address, aux.mac, arp_header->pln);
- /* Change operation to REPLY and send packet */
- arp_header->op = ARP_REPLY;
- grub_memcpy (aux.mac, target_hardware_address, 6);
- send_ethernet_packet (inf, nb, aux, ARP_ETHERTYPE);
- }
+ if (new_table_entry == ARRAY_SIZE (arp_table))
+ new_table_entry = 0;
+ }
+
+ /* Am I the protocol address target? */
+ if (grub_memcmp(target_protocol_address, inf->hwaddress.mac, 6) == 0
+ && grub_be_to_cpu16 (arp_header->op) == ARP_REQUEST)
+ {
+ grub_net_link_level_address_t aux;
+ /* Swap hardware fields */
+ grub_memcpy(target_hardware_address, sender_hardware_address, arp_header->hln);
+ grub_memcpy(sender_hardware_address, inf->hwaddress.mac, 6);
+ grub_memcpy(aux.mac, sender_protocol_address, 6);
+ grub_memcpy(sender_protocol_address, target_protocol_address, arp_header->pln);
+ grub_memcpy(target_protocol_address, aux.mac, arp_header->pln);
+ /* Change operation to REPLY and send packet */
+ arp_header->op = grub_be_to_cpu16 (ARP_REPLY);
+ grub_memcpy (aux.mac, target_hardware_address, 6);
+ send_ethernet_packet (inf, nb, aux, GRUB_NET_ETHERTYPE_ARP);
}
return GRUB_ERR_NONE;
}
+
+#include <grub/dl.h>
#include <grub/net/netbuff.h>
#include <sys/socket.h>
-#include <netpacket/packet.h>
-#include <net/ethernet.h> /* the L2 protocols */
#include <grub/net.h>
+#include <sys/types.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <grub/term.h>
-static grub_err_t
-card_open (struct grub_net_card *dev)
-{
- dev->data_num = socket (AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
- if (dev->data_num < 0)
- return grub_error (GRUB_ERR_IO, "couldn't open packet interface");
- return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-card_close (struct grub_net_card *dev)
-{
- close (dev->data_num);
- return GRUB_ERR_NONE;
-}
+static int fd;
static grub_err_t
-send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack)
+send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)),
+ struct grub_net_buff *pack)
{
ssize_t actual;
- actual = write (dev->data_num, pack->data, pack->tail - pack->data);
+ actual = write (fd, pack->data, pack->tail - pack->data);
if (actual < 0)
return grub_error (GRUB_ERR_IO, "couldn't send packets");
return GRUB_ERR_NONE;
}
-static grub_err_t
-get_card_packet (struct grub_net_card *dev, struct grub_net_buff *pack)
+static grub_size_t
+get_card_packet (struct grub_net_card *dev __attribute__ ((unused)),
+ struct grub_net_buff *pack)
{
ssize_t actual;
grub_netbuff_clear(pack);
- actual = read (dev->data_num, pack->data, 1500);
+ actual = read (fd, pack->data, 1500);
if (actual < 0)
- return grub_error (GRUB_ERR_IO, "couldn't receive packets");
+ {
+ grub_error (GRUB_ERR_IO, "couldn't receive packets");
+ return -1;
+ }
grub_netbuff_put (pack, actual);
- return GRUB_ERR_NONE;
+ return actual;
}
static struct grub_net_card_driver emudriver =
{
.name = "emu",
- .init = card_open,
- .fini = card_close,
.send = send_card_buffer,
.recv = get_card_packet
};
+static struct grub_net_card emucard =
+{
+ .name = "emu0",
+ .driver = &emudriver,
+ .default_address = {
+ .type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET,
+ { .mac = { 0, 1, 2, 3, 4, 5} }
+ },
+ .flags = 0
+};
+
GRUB_MOD_INIT(emunet)
{
- grub_net_card_driver_register (&emudriver);
+ struct ifreq ifr;
+ // char fullname[64];
+ fd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK);
+ if (fd < 0)
+ return;
+ grub_memset (&ifr, 0, sizeof (ifr));
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ if (ioctl (fd, TUNSETIFF, &ifr) < 0)
+ {
+ close (fd);
+ fd = -1;
+ return;
+ }
+ grub_net_card_register (&emucard);
}
-GRUB_MODE_FINI(emunet)
+GRUB_MOD_FINI(emunet)
{
- grub_net_card_driver_unregister (&emudriver);
+ if (fd >= 0)
+ {
+ close (fd);
+ grub_net_card_unregister (&emucard);
+ }
}
inf->card->driver->recv (inf->card, nb);
eth = (struct etherhdr *) nb->data;
- type = eth->type;
+ type = grub_be_to_cpu16 (eth->type);
grub_netbuff_pull(nb,sizeof (*eth));
- if (eth->type <=1500)
+ if (type <= 1500)
{
llch = (struct llchdr *) nb->data;
type = llch->dsap & LLCADDRMASK;
}
/* ARP packet */
- if (type == ARP_ETHERTYPE)
- {
- grub_net_arp_receive(inf, nb);
- if (ethertype == ARP_ETHERTYPE)
- return GRUB_ERR_NONE;
- }
+ if (type == GRUB_NET_ETHERTYPE_ARP)
+ grub_net_arp_receive(inf, nb);
/* IP packet */
- else if(type == IP_ETHERTYPE && ethertype == IP_ETHERTYPE)
+ if(type == GRUB_NET_ETHERTYPE_IP && ethertype == GRUB_NET_ETHERTYPE_IP)
return GRUB_ERR_NONE;
return GRUB_ERR_NONE;
if (err)
return err;
- return send_ethernet_packet (inf, nb, ll_target_addr, IP_ETHERTYPE);
+ return send_ethernet_packet (inf, nb, ll_target_addr, GRUB_NET_ETHERTYPE_IP);
}
static int
grub_err_t
grub_net_recv_ip_packets (struct grub_net_network_level_interface *inf)
{
- struct grub_net_buff nb;
- grub_net_recv_ethernet_packet (inf, &nb, IP_ETHERTYPE);
- ip_filter (&nb, inf);
+ struct grub_net_buff *nb;
+ nb = grub_netbuff_alloc (2048);
+ if (!nb)
+ return grub_errno;
+ grub_net_recv_ethernet_packet (inf, nb, GRUB_NET_ETHERTYPE_IP);
+ ip_filter (nb, inf);
return GRUB_ERR_NONE;
}
*ip = grub_cpu_to_le32 (newip);
if (rest)
*rest = ptr - 1;
- return 0;
+ return 1;
}
static int
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("three arguments expected"));
FOR_NET_CARDS (card)
- if (grub_strcmp (card->name, args[1]))
+ if (grub_strcmp (card->name, args[1]) == 0)
break;
if (card == NULL)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("card not found"));
struct grub_net_network_level_interface *inter;
FOR_NET_NETWORK_LEVEL_INTERFACES (inter)
- if (grub_strcmp (inter->name, args[2]))
+ if (grub_strcmp (inter->name, args[2]) == 0)
break;
if (!inter)
#include <grub/dl.h>
#include <grub/file.h>
-struct {
- int block_size;
- int size;
-} tftp_file;
-static int block;
-
-
-static char *get_tok_val(char **tok, char **val, char **str_opt,char *end);
-static void process_option(char *tok, char *val);
-
-static char *
-get_tok_val(char **tok, char **val,char **str_opt,char *end)
-{
- char *p = *str_opt;
- *tok = p;
- p += grub_strlen(p) + 1;
-
- if(p > end)
- return NULL;
-
- *val = p;
- p += grub_strlen(p) + 1;
- *str_opt = p;
- return *tok;
-}
-
-static void
-process_option(char *tok, char *val)
-{
- if (!grub_strcmp(tok,"blksize"))
- {
- tftp_file.block_size = grub_strtoul (val,NULL,0);
- return;
- }
-
- if (!grub_strcmp(tok,"tsize"))
- {
- tftp_file.size = grub_strtoul (val,NULL,0);
- return;
- }
-
-}
-
-//void tftp_open (char *options);
-
-/*send read request*/
static grub_err_t
tftp_open (struct grub_file *file, const char *filename)
{
struct tftphdr *tftph;
char *rrq;
+ char *ptr;
int rrqlen;
int hdrlen;
- struct grub_net_buff nb;
+ struct grub_net_buff *nb;
grub_net_network_level_address_t addr;
grub_err_t err;
+ sizeof ("tftp,") - 1, &addr);
if (err)
return err;
-
- grub_memset (&nb, 0, sizeof (nb));
- grub_netbuff_push (&nb,sizeof (*tftph));
- tftph = (struct tftphdr *) nb.data;
+ nb = grub_netbuff_alloc (2048);
+ if (!nb)
+ return grub_errno;
+
+ grub_netbuff_reserve (nb,2048);
+ grub_netbuff_push (nb,sizeof (*tftph));
+
+ tftph = (struct tftphdr *) nb->data;
rrq = (char *) tftph->u.rrq;
rrqlen = 0;
- tftph->opcode = TFTP_RRQ;
+ tftph->opcode = grub_cpu_to_be16 (TFTP_RRQ);
grub_strcpy (rrq, filename);
rrqlen += grub_strlen (filename) + 1;
rrq += grub_strlen (filename) + 1;
- /*passar opcoes como parametro ou usar default?*/
grub_strcpy (rrq,"octet");
rrqlen += grub_strlen ("octet") + 1;
rrq += grub_strlen ("octet") + 1;
- //grub_strcpy (rrq,"netascii");
- //rrqlen += grub_strlen ("netascii") + 1;
- //rrq += grub_strlen ("netascii") + 1;
-
grub_strcpy (rrq,"blksize");
rrqlen += grub_strlen("blksize") + 1;
rrq += grub_strlen ("blksize") + 1;
grub_strcpy (rrq,"0");
rrqlen += grub_strlen ("0") + 1;
- rrq += grub_strlen ("0") + 1;
+ rrq += grub_strlen ("0") + 1;
hdrlen = sizeof (tftph->opcode) + rrqlen;
- grub_netbuff_unput (&nb,nb.tail - (nb.data+hdrlen));
+ grub_netbuff_unput (nb,nb->tail - (nb->data+hdrlen));
+
+ err = grub_net_send_udp_packet (&addr,
+ nb, TFTP_CLIENT_PORT, TFTP_SERVER_PORT);
+ if (err)
+ return err;
+
+ /* Receive OACK. */
+ grub_netbuff_clear (nb);
+ grub_netbuff_reserve (nb,2048);
+
+ do
+ {
+ err = grub_net_recv_udp_packet (&addr, nb,
+ TFTP_CLIENT_PORT, TFTP_SERVER_PORT);
+ if (err)
+ return err;
+ }
+ while (nb->tail == nb->data);
- grub_net_send_udp_packet (&addr,
- &nb, TFTP_CLIENT_PORT, TFTP_SERVER_PORT);
+ file->size = 0;
- grub_net_send_udp_packet (&addr, &nb, TFTP_CLIENT_PORT, TFTP_SERVER_PORT);
- /*Receive OACK*/
- grub_netbuff_clear (&nb);
- grub_netbuff_reserve (&nb,2048);
- file->size = tftp_file.size;
+ for (ptr = nb->data; ptr < nb->tail; )
+ grub_printf ("%02x ", *ptr);
- return grub_net_recv_udp_packet (&addr, &nb,
- TFTP_CLIENT_PORT, TFTP_SERVER_PORT);
+ for (ptr = nb->data; ptr < nb->tail; )
+ {
+ if (grub_memcmp (ptr, "tsize\0=", sizeof ("tsize\0=") - 1) == 0)
+ {
+ file->size = grub_strtoul (ptr + sizeof ("tsize\0=") - 1, 0, 0);
+ grub_errno = GRUB_ERR_NONE;
+ }
+ while (ptr < nb->tail && *ptr)
+ ptr++;
+ ptr++;
+ }
+ return GRUB_ERR_NONE;
}
static grub_ssize_t
tftp_receive (struct grub_file *file, char *buf, grub_size_t len)
{
struct tftphdr *tftph;
- char *token,*value,*temp;
+ // char *token,*value,*temp;
grub_err_t err;
grub_net_network_level_address_t addr;
struct grub_net_buff nb;
TFTP_CLIENT_PORT, TFTP_SERVER_PORT);
tftph = (struct tftphdr *) nb.data;
- switch (tftph->opcode)
+ switch (grub_be_to_cpu16 (tftph->opcode))
{
- case TFTP_OACK:
- /*process oack packet*/
- temp = (char *) tftph->u.oack.data;
- while(get_tok_val(&token,&value,&temp,nb.tail))
- {
- process_option(token,value);
- }
-
- //buff_clean
- grub_netbuff_clear(&nb);
- // grub_printf("OACK---------------------------------------------------------\n");
- //grub_printf("block_size=%d\n",tftp_file.block_size);
- // grub_printf("file_size=%d\n",tftp_file.size);
- // grub_printf("OACK---------------------------------------------------------\n");
- block = 0;
- break;
case TFTP_DATA:
grub_netbuff_pull (&nb,sizeof (tftph->opcode) + sizeof (tftph->u.data.block));
- if (tftph->u.data.block == block + 1)
- {
- block = tftph->u.data.block;
+ // if (tftph->u.data.block == block + 1)
+ //{
+ // block = tftph->u.data.block;
grub_memcpy (buf, nb.data, len);
- }
- else
- grub_netbuff_clear(&nb);
- break;
+ //}
+ //else
+ //grub_netbuff_clear(&nb);
+ break;
case TFTP_ERROR:
grub_netbuff_clear (&nb);
- return grub_error (GRUB_ERR_ACCESS_DENIED, (char *)tftph->u.err.errmsg);
- break;
+ return grub_error (GRUB_ERR_IO, (char *)tftph->u.err.errmsg);
}
nb.data = nb.tail = nb.end;
grub_netbuff_push (&nb,sizeof (tftph->opcode) + sizeof (tftph->u.ack.block));
tftph = (struct tftphdr *) nb.data;
- tftph->opcode = TFTP_ACK;
- tftph->u.ack.block = block;
+ tftph->opcode = grub_cpu_to_be16 (TFTP_ACK);
+ // tftph->u.ack.block = block;
return grub_net_send_udp_packet (&addr, &nb, TFTP_CLIENT_PORT, TFTP_SERVER_PORT);
}
#include <grub/misc.h>
#include <grub/net.h>
-/* IANA ARP constant to define hardware type as ethernet */
-#define ARPHRD_ETHERNET 1
-/* IANA Ethertype */
-#define ARP_ETHERTYPE 0x806
-
-/* Size for cache table */
-#define SIZE_ARP_TABLE 5
+enum
+{
+/* IANA ARP constant to define hardware type as ethernet. */
+ GRUB_NET_ARPHRD_ETHERNET = 1
+};
/* ARP header operation codes */
#define ARP_REQUEST 1
grub_uint16_t type;
} __attribute__ ((packed));
+/* IANA Ethertype */
+enum
+{
+ GRUB_NET_ETHERTYPE_IP = 0x0800,
+ GRUB_NET_ETHERTYPE_ARP = 0x0806
+};
+
+
grub_err_t
send_ethernet_packet (struct grub_net_network_level_interface *inf,
struct grub_net_buff *nb,
#define GRUB_NET_IP_HEADER 1
#include <grub/misc.h>
-#define IP_ETHERTYPE 0x800 /* IANA Ethertype */
-
struct iphdr {
grub_uint8_t verhdrlen;
grub_uint8_t service;