diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index 541b89411..c7b5d0573 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -6,7 +6,7 @@ #include #include -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 @@ -19,8 +19,8 @@ void arp_init_table(void) 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) @@ -48,24 +48,26 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, 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 */ @@ -73,7 +75,7 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, 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); @@ -81,7 +83,7 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, 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) @@ -90,7 +92,7 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, 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); @@ -99,17 +101,16 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, } 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; @@ -118,40 +119,36 @@ grub_net_arp_receive(struct grub_net_network_level_interface *inf, 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; } diff --git a/grub-core/net/drivers/emu/emunet.c b/grub-core/net/drivers/emu/emunet.c index 8914a1d95..9e4e66dce 100644 --- a/grub-core/net/drivers/emu/emunet.c +++ b/grub-core/net/drivers/emu/emunet.c @@ -1,68 +1,92 @@ + +#include #include #include -#include -#include /* the L2 protocols */ #include +#include +#include +#include +#include +#include +#include +#include + +static int fd; 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 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); + } } diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index a40e1f795..cbda4c875 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -38,10 +38,10 @@ grub_net_recv_ethernet_packet (struct grub_net_network_level_interface *inf, 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; @@ -55,14 +55,10 @@ grub_net_recv_ethernet_packet (struct grub_net_network_level_interface *inf, } /* 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; diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c index 023564a5a..9a96ef532 100644 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@ -54,7 +54,7 @@ grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, 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 @@ -84,8 +84,11 @@ ip_filter (struct grub_net_buff *nb, 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; } diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 5205e1938..54663f4b0 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -92,7 +92,7 @@ parse_ip (const char *val, grub_uint32_t *ip, const char **rest) *ip = grub_cpu_to_le32 (newip); if (rest) *rest = ptr - 1; - return 0; + return 1; } static int @@ -341,7 +341,7 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), 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")); @@ -464,7 +464,7 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), 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) diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index b9e3f49c4..16b60eeb6 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -9,60 +9,15 @@ #include #include -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; @@ -70,29 +25,28 @@ tftp_open (struct grub_file *file, const char *filename) + 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; @@ -107,29 +61,53 @@ tftp_open (struct grub_file *file, const char *filename) 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)); - grub_net_send_udp_packet (&addr, - &nb, TFTP_CLIENT_PORT, TFTP_SERVER_PORT); + err = grub_net_send_udp_packet (&addr, + nb, TFTP_CLIENT_PORT, TFTP_SERVER_PORT); + if (err) + return err; - 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; + /* Receive OACK. */ + grub_netbuff_clear (nb); + grub_netbuff_reserve (nb,2048); - return grub_net_recv_udp_packet (&addr, &nb, - TFTP_CLIENT_PORT, TFTP_SERVER_PORT); + do + { + err = grub_net_recv_udp_packet (&addr, nb, + TFTP_CLIENT_PORT, TFTP_SERVER_PORT); + if (err) + return err; + } + while (nb->tail == nb->data); + + file->size = 0; + + for (ptr = nb->data; ptr < nb->tail; ) + grub_printf ("%02x ", *ptr); + + 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; @@ -143,38 +121,21 @@ tftp_receive (struct grub_file *file, char *buf, grub_size_t len) 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; @@ -182,8 +143,8 @@ tftp_receive (struct grub_file *file, char *buf, grub_size_t len) 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); } diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h index 1475086e4..691fda307 100644 --- a/include/grub/net/arp.h +++ b/include/grub/net/arp.h @@ -3,13 +3,11 @@ #include #include -/* 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 diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h index b4f07992b..7a0235be6 100644 --- a/include/grub/net/ethernet.h +++ b/include/grub/net/ethernet.h @@ -38,6 +38,14 @@ struct snaphdr 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, diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h index 765d8005e..6f748bbf3 100644 --- a/include/grub/net/ip.h +++ b/include/grub/net/ip.h @@ -2,8 +2,6 @@ #define GRUB_NET_IP_HEADER 1 #include -#define IP_ETHERTYPE 0x800 /* IANA Ethertype */ - struct iphdr { grub_uint8_t verhdrlen; grub_uint8_t service;