diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index 0644d3d2e..1dbd8a58f 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -41,6 +41,14 @@ grub_net_arp_resolve (struct grub_net_network_level_interface *inf, char *aux, arp_data[128]; int i; + if (proto_addr->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 + && proto_addr->ipv4 == 0xffffffff) + { + hw_addr->type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; + grub_memset (hw_addr->mac, -1, 6); + return GRUB_ERR_NONE; + } + /* Check cache table. */ entry = arp_find_entry (proto_addr); if (entry) diff --git a/grub-core/net/drivers/emu/emunet.c b/grub-core/net/drivers/emu/emunet.c index ee4ba4773..d1e49a2f4 100644 --- a/grub-core/net/drivers/emu/emunet.c +++ b/grub-core/net/drivers/emu/emunet.c @@ -13,8 +13,8 @@ static int fd; -static grub_err_t -send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)), +static grub_err_t +send_card_buffer (const struct grub_net_card *dev __attribute__ ((unused)), struct grub_net_buff *pack) { ssize_t actual; @@ -27,7 +27,7 @@ send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)), } static grub_ssize_t -get_card_packet (struct grub_net_card *dev __attribute__ ((unused)), +get_card_packet (const struct grub_net_card *dev __attribute__ ((unused)), struct grub_net_buff *pack) { ssize_t actual; diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index d29193afe..f1bc8c1d0 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -27,12 +27,14 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, } grub_err_t -grub_net_recv_ethernet_packet (struct grub_net_buff *nb) +grub_net_recv_ethernet_packet (struct grub_net_buff * nb, + const struct grub_net_card * card) { struct etherhdr *eth; struct llchdr *llch; struct snaphdr *snaph; grub_uint16_t type; + grub_net_link_level_address_t hwaddress; eth = (struct etherhdr *) nb->data; type = grub_be_to_cpu16 (eth->type); @@ -51,7 +53,10 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb) } } - /* ARP packet. */ + hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; + grub_memcpy (hwaddress.mac, eth->dst, sizeof (hwaddress.mac)); + + /* ARP packet. */ if (type == GRUB_NET_ETHERTYPE_ARP) { grub_net_arp_receive (nb); @@ -59,7 +64,7 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb) } /* IP packet. */ if (type == GRUB_NET_ETHERTYPE_IP) - grub_net_recv_ip_packets (nb); + grub_net_recv_ip_packets (nb, card, &hwaddress); return GRUB_ERR_NONE; } diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c index 4adc2b028..808532a4a 100644 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@ -25,9 +25,9 @@ ipchksum (void *ipv, int len) } grub_err_t -grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *target, - struct grub_net_buff *nb) +grub_net_send_ip_packet (struct grub_net_network_level_interface * inf, + const grub_net_network_level_address_t * target, + struct grub_net_buff * nb) { struct iphdr *iph; static int id = 0x2400; @@ -54,43 +54,58 @@ grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, err = grub_net_arp_resolve (inf, target, &ll_target_addr); if (err) return err; - return send_ethernet_packet (inf, nb, ll_target_addr, GRUB_NET_ETHERTYPE_IP); + return send_ethernet_packet (inf, nb, ll_target_addr, + GRUB_NET_ETHERTYPE_IP); } -/* -static int -ip_filter (struct grub_net_buff *nb) +grub_err_t +grub_net_recv_ip_packets (struct grub_net_buff * nb, + const struct grub_net_card * card, + const grub_net_link_level_address_t * hwaddress) { struct iphdr *iph = (struct iphdr *) nb->data; grub_err_t err; + struct grub_net_network_level_interface *inf; - if (nb->end - nb->data < (signed) sizeof (*iph)) - return 0; - - if (iph->protocol != 0x11 || - iph->dest != inf->address.ipv4) - return 0; - - grub_netbuff_pull (nb, sizeof (iph)); - err = grub_net_put_packet (&inf->nl_pending, nb); + err = grub_netbuff_pull (nb, sizeof (*iph)); if (err) + return err; + + FOR_NET_NETWORK_LEVEL_INTERFACES (inf) + { + if (inf->card == card + && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 + && inf->address.ipv4 == iph->dest + && grub_net_hwaddr_cmp (&inf->hwaddress, hwaddress) == 0) + break; + } + if (!inf) { - grub_print_error (); - return 0; + FOR_NET_NETWORK_LEVEL_INTERFACES (inf) + if (inf->card == card + && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC + && grub_net_hwaddr_cmp (&inf->hwaddress, hwaddress) == 0) + break; + } + if (!inf) + { + if (iph->protocol == IP_UDP + && grub_net_hwaddr_cmp (&card->default_address, hwaddress) == 0) + { + struct udphdr *udph; + udph = (struct udphdr *) nb->data; + grub_netbuff_pull (nb, sizeof (*udph)); + if (grub_be_to_cpu16 (udph->dst) == 68) + grub_net_process_dhcp (nb, card); + } + grub_netbuff_free (nb); + return GRUB_ERR_NONE; } - return 1; -} -*/ -grub_err_t -grub_net_recv_ip_packets (struct grub_net_buff *nb) -{ - struct iphdr *iph = (struct iphdr *) nb->data; - grub_netbuff_pull (nb, sizeof (*iph)); switch (iph->protocol) { case IP_UDP: - return grub_net_recv_udp_packet (nb); + return grub_net_recv_udp_packet (nb, inf); break; default: grub_netbuff_free (nb); diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 1232b3c74..2da60256c 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -16,6 +16,7 @@ * along with GRUB. If not, see . */ +#include #include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -54,8 +56,11 @@ static struct grub_fs grub_net_fs; static inline void grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) { - grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), - GRUB_AS_LIST (inter)); + *inter->prev = inter->next; + if (inter->next) + inter->next->prev = inter->prev; + inter->next = 0; + inter->prev = 0; } static inline void @@ -112,6 +117,8 @@ match_net (const grub_net_network_level_netaddress_t *net, return 0; switch (net->type) { + case GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC: + return 0; case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: { grub_int32_t mask = ((1 << net->ipv4.masksize) - 1) << (32 - net->ipv4.masksize); @@ -229,6 +236,9 @@ grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf) { switch (target->type) { + case GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC: + grub_strcpy (buf, "promisc"); + return; case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: { grub_uint32_t n = grub_be_to_cpu32 (target->ipv4); @@ -270,6 +280,23 @@ hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str) grub_printf ("Unsupported hw address type %d\n", addr->type); } +int +grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, + const grub_net_link_level_address_t *b) +{ + if (a->type < b->type) + return -1; + if (a->type > b->type) + return +1; + switch (a->type) + { + case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET: + return grub_memcmp (a->mac, b->mac, sizeof (a->mac)); + } + grub_printf ("Unsupported hw address type %d\n", a->type); + return 1; +} + /* FIXME: implement this. */ static char * hwaddr_set_env (struct grub_env_var *var __attribute__ ((unused)), @@ -307,12 +334,16 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa grub_register_variable_hook (name, 0, addr_set_env); } - grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), - GRUB_AS_LIST (inter)); + inter->prev = &grub_net_network_level_interfaces; + inter->next = grub_net_network_level_interfaces; + if (inter->next) + inter->next->prev = &inter->next; + grub_net_network_level_interfaces = inter; } struct grub_net_network_level_interface * -grub_net_add_addr (const char *name, struct grub_net_card *card, +grub_net_add_addr (const char *name, + const struct grub_net_card *card, grub_net_network_level_address_t addr, grub_net_link_level_address_t hwaddress, grub_net_interface_flags_t flags) @@ -488,6 +519,9 @@ print_net_address (const grub_net_network_level_netaddress_t *target) { switch (target->type) { + case GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC: + grub_printf ("promisc\n"); + break; case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: { grub_uint32_t n = grub_be_to_cpu32 (target->ipv4.base); @@ -546,6 +580,23 @@ grub_cmd_listcards (struct grub_command *cmd __attribute__ ((unused)), return GRUB_ERR_NONE; } +static grub_err_t +grub_cmd_listaddrs (struct grub_command *cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + struct grub_net_network_level_interface *inf; + FOR_NET_NETWORK_LEVEL_INTERFACES (inf) + { + char bufh[MAX_STR_HWADDR_LEN]; + char bufn[GRUB_NET_MAX_STR_ADDR_LEN]; + hwaddr_to_str (&inf->hwaddress, bufh); + grub_net_addr_to_str (&inf->address, bufn); + grub_printf ("%s %s %s\n", inf->name, bufh, bufn); + } + return GRUB_ERR_NONE; +} + grub_net_app_level_t grub_net_app_level_list; struct grub_net_socket *grub_net_sockets; @@ -649,22 +700,27 @@ grub_net_fs_close (grub_file_t file) static void receive_packets (struct grub_net_card *card) { - /* Maybe should be better have a fixed number of packets for each card - and just mark them as used and not used. */ - struct grub_net_buff *nb; - grub_ssize_t actual; - nb = grub_netbuff_alloc (1500); - if (!nb) + while (1) { - grub_print_error (); - return; - } + /* Maybe should be better have a fixed number of packets for each card + and just mark them as used and not used. */ + struct grub_net_buff *nb; + grub_ssize_t actual; + nb = grub_netbuff_alloc (1500); + if (!nb) + { + grub_print_error (); + return; + } - actual = card->driver->recv (card, nb); - if (actual < 0) - grub_netbuff_free (nb); - else - grub_net_recv_ethernet_packet (nb); + actual = card->driver->recv (card, nb); + if (actual < 0) + { + grub_netbuff_free (nb); + break; + } + grub_net_recv_ethernet_packet (nb, card); + } grub_print_error (); } @@ -828,9 +884,10 @@ parse_dhcp_vendor (const char *name, void *vend, int limit) #define OFFSET_OF(x, y) ((grub_uint8_t *)((y)->x) - (grub_uint8_t *)(y)) struct grub_net_network_level_interface * -grub_net_configure_by_dhcp_ack (const char *name, struct grub_net_card *card, +grub_net_configure_by_dhcp_ack (const char *name, + const struct grub_net_card *card, grub_net_interface_flags_t flags, - struct grub_net_bootp_ack *bp, + const struct grub_net_bootp_packet *bp, grub_size_t size) { grub_net_network_level_address_t addr; @@ -889,6 +946,38 @@ grub_net_configure_by_dhcp_ack (const char *name, struct grub_net_card *card, return inter; } +void +grub_net_process_dhcp (struct grub_net_buff *nb, + const struct grub_net_card *card) +{ + char *name; + struct grub_net_network_level_interface *inf; + + name = grub_xasprintf ("%s:dhcp", card->name); + if (!name) + { + grub_print_error (); + return; + } + grub_net_configure_by_dhcp_ack (name, card, + 0, (const struct grub_net_bootp_packet *) nb->data, + (nb->tail - nb->data)); + grub_free (name); + if (grub_errno) + grub_print_error (); + else + { + FOR_NET_NETWORK_LEVEL_INTERFACES(inf) + if (grub_memcmp (inf->name, card->name, grub_strlen (card->name)) == 0 + && grub_memcmp (inf->name + grub_strlen (card->name), + ":dhcp_tmp", sizeof (":dhcp_tmp") - 1) == 0) + { + grub_net_network_level_interface_unregister (inf); + break; + } + } +} + static char hexdigit (grub_uint8_t val) { @@ -1011,6 +1100,131 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), "unrecognised format specification %s", args[3]); } +static grub_err_t +grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_card *card; + struct grub_net_network_level_interface *ifaces; + grub_size_t ncards = 0; + unsigned j = 0; + int interval; + grub_err_t err; + + FOR_NET_CARDS (card) + { + if (argc > 0 && grub_strcmp (card->name, args[0]) != 0) + continue; + ncards++; + } + + ifaces = grub_zalloc (ncards * sizeof (ifaces[0])); + if (!ifaces) + return grub_errno; + + j = 0; + FOR_NET_CARDS (card) + { + if (argc > 0 && grub_strcmp (card->name, args[0]) != 0) + continue; + ifaces[j].card = card; + ifaces[j].next = &ifaces[j+1]; + if (j) + ifaces[j].prev = &ifaces[j-1].next; + ifaces[j].name = grub_xasprintf ("%s:dhcp_tmp", card->name); + if (!ifaces[j].name) + { + unsigned i; + for (i = 0; i < j; i++) + grub_free (ifaces[i].name); + grub_free (ifaces); + return grub_errno; + } + ifaces[j].address.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC; + grub_memcpy (&ifaces[j].hwaddress, &card->default_address, + sizeof (ifaces[j].hwaddress)); + j++; + } + ifaces[ncards - 1].next = grub_net_network_level_interfaces; + if (grub_net_network_level_interfaces) + grub_net_network_level_interfaces->prev = & ifaces[ncards - 1].next; + grub_net_network_level_interfaces = &ifaces[0]; + ifaces[0].prev = &grub_net_network_level_interfaces; + for (interval = 200; interval < 10000; interval *= 2) + { + int done = 0; + for (j = 0; j < ncards; j++) + { + struct grub_net_bootp_packet *pack; + struct grub_datetime date; + grub_int32_t t; + struct grub_net_buff *nb; + struct udphdr *udph; + grub_net_network_level_address_t target; + + if (!ifaces[j].prev) + continue; + nb = grub_netbuff_alloc (sizeof (*pack)); + if (!nb) + return grub_errno; + err = grub_netbuff_reserve (nb, sizeof (*pack) + 64 + 128); + if (err) + return err; + err = grub_netbuff_push (nb, sizeof (*pack) + 64); + if (err) + return err; + pack = (void *) nb->data; + done = 1; + grub_memset (pack, 0, sizeof (*pack) + 64); + pack->opcode = 1; + pack->hw_type = 1; + pack->hw_len = 6; + err = grub_get_datetime (&date); + if (err || !grub_datetime2unixtime (&date, &t)) + { + grub_errno = GRUB_ERR_NONE; + t = 0; + } + pack->ident = grub_cpu_to_be32 (t); + pack->seconds = 0;//grub_cpu_to_be16 (t); + + grub_memcpy (&pack->mac_addr, &ifaces[j].hwaddress.mac, 6); + + grub_netbuff_push (nb, sizeof (*udph)); + + udph = (struct udphdr *) nb->data; + udph->src = grub_cpu_to_be16 (68); + udph->dst = grub_cpu_to_be16 (67); + udph->chksum = 0; + udph->len = grub_cpu_to_be16 (nb->tail - nb->data); + + target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + target.ipv4 = 0xffffffff; + + err = grub_net_send_ip_packet (&ifaces[j], &target, nb); + if (err) + return err; + } + if (!done) + break; + grub_net_poll_cards (interval); + } + + err = GRUB_ERR_NONE; + for (j = 0; j < ncards; j++) + { + if (!ifaces[j].prev) + continue; + grub_error_push (); + grub_net_network_level_interface_unregister (&ifaces[j]); + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "couldn't configure %s", + ifaces[j].card->name); + } + + return err; +} + + static struct grub_fs grub_net_fs = { .name = "netfs", @@ -1023,7 +1237,8 @@ static struct grub_fs grub_net_fs = .mtime = NULL, }; static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; -static grub_command_t cmd_lsroutes, cmd_lscards, cmd_getdhcp; +static grub_command_t cmd_lsroutes, cmd_lscards, cmd_getdhcp, cmd_bootp; +static grub_command_t cmd_dhcp, cmd_lsaddr; GRUB_MOD_INIT(net) { @@ -1043,6 +1258,14 @@ GRUB_MOD_INIT(net) "", N_("list network routes")); cmd_lscards = grub_register_command ("net_ls_cards", grub_cmd_listcards, "", N_("list network cards")); + cmd_lsaddr = grub_register_command ("net_ls_addr", grub_cmd_listaddrs, + "", N_("list network addresses")); + cmd_bootp = grub_register_command ("net_bootp", grub_cmd_bootp, + "[CARD]", + N_("perform a bootp autoconfiguration")); + cmd_dhcp = grub_register_command ("net_dhcp", grub_cmd_bootp, + "[CARD]", + N_("perform a bootp autoconfiguration")); cmd_getdhcp = grub_register_command ("net_get_dhcp_option", grub_cmd_dhcpopt, N_("VAR INTERFACE NUMBER DESCRIPTION"), N_("retrieve DHCP option and save it into VAR. If VAR is - then print the value.")); @@ -1060,6 +1283,7 @@ GRUB_MOD_FINI(net) grub_unregister_command (cmd_delroute); grub_unregister_command (cmd_lsroutes); grub_unregister_command (cmd_lscards); + grub_unregister_command (cmd_lsaddr); grub_unregister_command (cmd_getdhcp); grub_fs_unregister (&grub_net_fs); grub_net_open = NULL; diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index ac3b3e9db..545862092 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -24,7 +24,7 @@ tftp_open (struct grub_file *file, const char *filename) tftp_data_t data; grub_err_t err; - data = grub_malloc (sizeof *data); + data = grub_malloc (sizeof (*data)); if (!data) return grub_errno; @@ -86,7 +86,7 @@ tftp_open (struct grub_file *file, const char *filename) /* Retry. */ /*err = grub_net_send_udp_packet (file->device->net->socket, &nb); if (err) - return err; */ + return err; */ } if (file->device->net->socket->status == 0) @@ -154,8 +154,8 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) } grub_netbuff_clear (&nb_ack); grub_netbuff_reserve (&nb_ack, 128); - grub_netbuff_push (&nb_ack, sizeof (tftph->opcode) - + sizeof (tftph->u.ack.block)); + grub_netbuff_push (&nb_ack, sizeof (tftph->opcode) + + sizeof (tftph->u.ack.block)); tftph = (struct tftphdr *) nb_ack.data; tftph->opcode = grub_cpu_to_be16 (TFTP_ACK); @@ -180,12 +180,12 @@ static struct grub_net_app_protocol grub_tftp_protocol = .close = tftp_close }; -GRUB_MOD_INIT(tftp) +GRUB_MOD_INIT (tftp) { grub_net_app_level_register (&grub_tftp_protocol); } -GRUB_MOD_FINI(tftp) +GRUB_MOD_FINI (tftp) { grub_net_app_level_unregister (&grub_tftp_protocol); } diff --git a/grub-core/net/udp.c b/grub-core/net/udp.c index 86220bf0f..cc7534ea1 100644 --- a/grub-core/net/udp.c +++ b/grub-core/net/udp.c @@ -24,7 +24,8 @@ grub_net_send_udp_packet (const grub_net_socket_t socket, } grub_err_t -grub_net_recv_udp_packet (struct grub_net_buff *nb) +grub_net_recv_udp_packet (struct grub_net_buff * nb, + struct grub_net_network_level_interface * inf) { struct udphdr *udph; grub_net_socket_t sock; @@ -33,7 +34,8 @@ grub_net_recv_udp_packet (struct grub_net_buff *nb) FOR_NET_SOCKETS (sock) { - if (grub_be_to_cpu16 (udph->dst) == sock->in_port) + if (grub_be_to_cpu16 (udph->dst) == sock->in_port + && inf == sock->inf && sock->app) { if (sock->status == 0) sock->out_port = grub_be_to_cpu16 (udph->src); @@ -41,7 +43,7 @@ grub_net_recv_udp_packet (struct grub_net_buff *nb) /* App protocol remove its own reader. */ sock->app->read (sock, nb); - /* If there is data, puts packet in socket list. */ + /* If there is data, puts packet in socket list. */ if ((nb->tail - nb->data) > 0) grub_net_put_packet (&sock->packs, nb); else @@ -49,6 +51,8 @@ grub_net_recv_udp_packet (struct grub_net_buff *nb) return GRUB_ERR_NONE; } } + if (grub_be_to_cpu16 (udph->dst) == 68) + grub_net_process_dhcp (nb, inf->card); grub_netbuff_free (nb); return GRUB_ERR_NONE; } diff --git a/include/grub/emu/export.h b/include/grub/emu/export.h new file mode 100644 index 000000000..1e2f0432b --- /dev/null +++ b/include/grub/emu/export.h @@ -0,0 +1,6 @@ +void EXPORT_FUNC (open64) (void); +void EXPORT_FUNC (close) (void); +void EXPORT_FUNC (read) (void); +void EXPORT_FUNC (write) (void); +void EXPORT_FUNC (ioctl) (void); + diff --git a/include/grub/net.h b/include/grub/net.h index f9745acec..5d99cace3 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -62,8 +62,10 @@ struct grub_net_card_driver char *name; grub_err_t (*init) (struct grub_net_card *dev); grub_err_t (*fini) (struct grub_net_card *dev); - grub_err_t (*send) (struct grub_net_card *dev, struct grub_net_buff *buf); - grub_ssize_t (*recv) (struct grub_net_card *dev, struct grub_net_buff *buf); + grub_err_t (*send) (const struct grub_net_card *dev, + struct grub_net_buff *buf); + grub_ssize_t (*recv) (const struct grub_net_card *dev, + struct grub_net_buff *buf); }; extern struct grub_net_card_driver *grub_net_card_drivers; @@ -116,6 +118,7 @@ struct grub_net_network_level_interface; typedef enum grub_network_level_protocol_id { + GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC, GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 } grub_network_level_protocol_id_t; @@ -243,12 +246,13 @@ extern grub_err_t (*EXPORT_VAR (grub_file_net_seek)) (struct grub_file *file, gr struct grub_net_network_level_interface { struct grub_net_network_level_interface *next; + struct grub_net_network_level_interface **prev; char *name; - struct grub_net_card *card; + const struct grub_net_card *card; grub_net_network_level_address_t address; grub_net_link_level_address_t hwaddress; grub_net_interface_flags_t flags; - struct grub_net_bootp_ack *dhcp_ack; + struct grub_net_bootp_packet *dhcp_ack; grub_size_t dhcp_acklen; void *data; }; @@ -291,7 +295,8 @@ grub_net_session_recv (struct grub_net_session *session, void *buf, } struct grub_net_network_level_interface * -grub_net_add_addr (const char *name, struct grub_net_card *card, +grub_net_add_addr (const char *name, + const struct grub_net_card *card, grub_net_network_level_address_t addr, grub_net_link_level_address_t hwaddress, grub_net_interface_flags_t flags); @@ -369,7 +374,7 @@ grub_net_add_route_gw (const char *name, typedef grub_uint8_t grub_net_bootp_mac_addr_t[GRUB_NET_BOOTP_MAC_ADDR_LEN]; -struct grub_net_bootp_ack +struct grub_net_bootp_packet { grub_uint8_t opcode; grub_uint8_t hw_type; /* hardware type. */ @@ -391,11 +396,21 @@ struct grub_net_bootp_ack #define GRUB_NET_BOOTP_RFC1048_MAGIC 0x63825363L struct grub_net_network_level_interface * -grub_net_configure_by_dhcp_ack (const char *name, struct grub_net_card *card, +grub_net_configure_by_dhcp_ack (const char *name, + const struct grub_net_card *card, grub_net_interface_flags_t flags, - struct grub_net_bootp_ack *bp, + const struct grub_net_bootp_packet *bp, grub_size_t size); +void +grub_net_process_dhcp (struct grub_net_buff *nb, + const struct grub_net_card *card); + +int +grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, + const grub_net_link_level_address_t *b); + + /* Currently suppoerted adresses: IPv4: XXX.XXX.XXX.XXX @@ -420,8 +435,11 @@ typedef int grub_err_t grub_net_recv_link_layer (struct grub_net_network_level_interface *inf, grub_net_packet_handler_t handler); -grub_err_t -grub_net_recv_ip_packets (struct grub_net_buff *nb); + +grub_err_t +grub_net_recv_ip_packets (struct grub_net_buff *nb, + const struct grub_net_card *card, + const grub_net_link_level_address_t *hwaddress); grub_err_t grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h index 7ff7a4562..a841dc12c 100644 --- a/include/grub/net/ethernet.h +++ b/include/grub/net/ethernet.h @@ -12,19 +12,6 @@ struct etherhdr grub_uint16_t type; } __attribute__ ((packed)); -#define PCP(x) x & 0xe000 -#define CFI(x) x & 0x1000 -#define VID(x) x & 0x0fff -#define PRINT_ETH_ADDR(name,addr) grub_printf("%s %x:%x:%x:%x:%x:%x\n",\ - name,\ - addr[0],\ - addr[1],\ - addr[2],\ - addr[3],\ - addr[4],\ - addr[5]\ - ) - struct llchdr { grub_uint8_t dsap; @@ -52,6 +39,7 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, grub_net_link_level_address_t target_addr, grub_uint16_t ethertype); grub_err_t -grub_net_recv_ethernet_packet (struct grub_net_buff *nb); +grub_net_recv_ethernet_packet (struct grub_net_buff *nb, + const struct grub_net_card *card); #endif diff --git a/include/grub/net/netbuff.h b/include/grub/net/netbuff.h index 8ce508ead..245e813c3 100644 --- a/include/grub/net/netbuff.h +++ b/include/grub/net/netbuff.h @@ -26,5 +26,5 @@ grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff ,grub_size_t len grub_err_t grub_netbuff_clear (struct grub_net_buff *net_buff); struct grub_net_buff * grub_netbuff_alloc ( grub_size_t len ); grub_err_t grub_netbuff_free (struct grub_net_buff *net_buff); -grub_err_t grub_netbuff_clear (struct grub_net_buff *net_buff); + #endif diff --git a/include/grub/net/udp.h b/include/grub/net/udp.h index 86311ccf1..eacf3325c 100644 --- a/include/grub/net/udp.h +++ b/include/grub/net/udp.h @@ -14,8 +14,9 @@ struct udphdr grub_err_t grub_net_send_udp_packet (const grub_net_socket_t socket , struct grub_net_buff *nb); -grub_err_t -grub_net_recv_udp_packet (struct grub_net_buff *nb); +grub_err_t +grub_net_recv_udp_packet (struct grub_net_buff *nb, + struct grub_net_network_level_interface *inf); #define FOR_NET_UDP_PACKETS(inf, var) FOR_PACKETS(inf->udp_pending, var)