From 4931b0984b1a526c6c86a47b200c2dbb58d2fa50 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 3 Mar 2010 20:09:48 +0100 Subject: [PATCH 01/19] Network infrastructure --- commands/net.c | 296 ++++++++++++++++++++++++++++++++++++++++++ commands/probe.c | 2 +- conf/common.rmk | 6 + include/grub/device.h | 6 +- include/grub/err.h | 5 +- include/grub/net.h | 248 +++++++++++++++++++++++++++++------ kern/fs.c | 2 +- 7 files changed, 522 insertions(+), 43 deletions(-) create mode 100644 commands/net.c diff --git a/commands/net.c b/commands/net.c new file mode 100644 index 000000000..288ba4c2a --- /dev/null +++ b/commands/net.c @@ -0,0 +1,296 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB 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 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +struct grub_net_route *grub_net_routes = NULL; +struct grub_net_network_level_interface *grub_net_network_level_interfaces = NULL; +struct grub_net_card *grub_net_cards = NULL; +struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL; + +grub_err_t +grub_net_resolve_address (struct grub_net_network_level_protocol **prot, + char *name, + grub_net_network_level_address_t *addr) +{ + FOR_NET_NETWORK_LEVEL_PROTOCOLS (*prot) + { + grub_err_t err; + err = grub_net_resolve_address_in_protocol (*prot, name, addr); + if (err == GRUB_ERR_NET_BAD_ADDRESS) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + if (err) + return err; + return GRUB_ERR_NONE; + } + return grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("Unrecognised address %s"), + name); +} + +grub_err_t +grub_net_route_address (grub_net_network_level_address_t addr, + grub_net_network_level_address_t *gateway, + struct grub_net_network_level_interface **interf) +{ + struct grub_net_route *route; + int depth = 0; + int routecnt = 0; + struct grub_net_network_level_protocol *prot = NULL; + grub_net_network_level_address_t curtarget = addr; + + *gateway = addr; + + FOR_NET_ROUTES(route) + routecnt++; + + for (depth = 0; depth < routecnt + 2; depth++) + { + FOR_NET_ROUTES(route) + { + if (depth && prot != route->prot) + continue; + prot = route->prot; + if (!route->prot->match_net (route->target, curtarget)) + continue; + + if (route->is_gateway) + { + if (depth == 0) + *gateway = route->gw; + curtarget = route->gw; + break; + } + *interf = route->interface; + return GRUB_ERR_NONE; + } + if (route == NULL) + return grub_error (GRUB_ERR_NET_NO_ROUTE, "destination unreachable"); + } + + return grub_error (GRUB_ERR_NET_ROUTE_LOOP, "route loop detected"); +} + +static grub_err_t +grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_network_level_interface *inter; + + if (argc != 4) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + FOR_NET_NETWORK_LEVEL_INTERFACES (inter) + if (grub_strcmp (inter->name, args[1])) + break; + if (inter == NULL) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found")); + + inter->protocol->fini (inter); + grub_net_network_level_interface_unregister (inter); + grub_free (inter->name); + grub_free (inter); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_card *card; + struct grub_net_network_level_protocol *prot; + grub_err_t err; + grub_net_network_level_address_t addr; + struct grub_net_network_level_interface *inter; + + if (argc != 4) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("four arguments expected")); + + FOR_NET_CARDS (card) + if (grub_strcmp (card->name, args[1])) + break; + if (card == NULL) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("card not found")); + + FOR_NET_NETWORK_LEVEL_PROTOCOLS (prot) + if (grub_strcmp (prot->name, args[2])) + break; + + if (card == NULL) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("protocol not found")); + + err = grub_net_resolve_address_in_protocol (prot, args[3], &addr); + if (err) + return err; + + inter = grub_zalloc (sizeof (*inter)); + if (!inter) + return grub_errno; + + inter->name = grub_strdup (args[0]); + inter->protocol = prot; + grub_memcpy (&(inter->address), &addr, sizeof (inter->address)); + inter->card = card; + + err = prot->init (inter); + if (err) + { + grub_free (inter->name); + grub_free (inter); + return err; + } + grub_net_network_level_interface_register (inter); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_delroute (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_route *route; + struct grub_net_route **prev; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + for (prev = &grub_net_routes, route = *prev; route; prev = &((*prev)->next), + route = *prev) + if (grub_strcmp (route->name, args[0]) == 0) + { + *prev = route->next; + grub_free (route->name); + grub_free (route); + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_network_level_protocol *prot; + struct grub_net_route *route; + + if (argc < 3) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("At least 3 arguments are expected")); + + route = grub_zalloc (sizeof (*route)); + if (!route) + return grub_errno; + + route->name = grub_strdup (args[0]); + if (!route->name) + { + grub_free (route); + return grub_errno; + } + + FOR_NET_NETWORK_LEVEL_PROTOCOLS(prot) + { + grub_err_t err; + err = prot->net_ntoa (args[1], &(route->target)); + if (err == GRUB_ERR_NET_BAD_ADDRESS) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + if (err) + return err; + break; + } + + if (!prot) + { + grub_free (route->name); + grub_free (route); + return grub_error (GRUB_ERR_NET_BAD_ADDRESS, + N_("Unrecognised address %s"), args[1]); + } + + if (grub_strcmp (args[2], "gw") == 0 && argc >= 4) + { + grub_err_t err; + route->is_gateway = 1; + err = grub_net_resolve_address_in_protocol (prot, + args[3], &(route->gw)); + if (err) + { + grub_free (route->name); + grub_free (route); + return err; + } + } + else + { + struct grub_net_network_level_interface *inter; + route->is_gateway = 0; + + FOR_NET_NETWORK_LEVEL_INTERFACES (inter) + if (grub_strcmp (inter->name, args[2])) + break; + + if (!inter) + { + grub_free (route->name); + grub_free (route); + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("Unrecognised interface %s"), args[2]); + } + route->interface = inter; + } + + grub_net_route_register (route); + + return GRUB_ERR_NONE; +} + +static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; + +GRUB_MOD_INIT(net) +{ + cmd_addaddr = grub_register_command ("net_add_addr", grub_cmd_addaddr, + "SHORTNAME CARD PROTOCOL ADDRESS", + N_("Add a network address.")); + cmd_deladdr = grub_register_command ("net_del_addr", grub_cmd_deladdr, + "SHORTNAME", + N_("Delete a network address.")); + cmd_addroute = grub_register_command ("net_add_route", grub_cmd_addroute, + "SHORTNAME NET [INTERFACE| gw GATEWAY]", + N_("Add a network route.")); + cmd_delroute = grub_register_command ("net_del_route", grub_cmd_delroute, + "SHORTNAME", + N_("Delete a network route.")); +} + +GRUB_MOD_FINI(net) +{ + grub_unregister_command (cmd_addaddr); + grub_unregister_command (cmd_deladdr); + grub_unregister_command (cmd_addroute); + grub_unregister_command (cmd_delroute); +} diff --git a/commands/probe.c b/commands/probe.c index c2cc599e9..002ede85e 100644 --- a/commands/probe.c +++ b/commands/probe.c @@ -72,7 +72,7 @@ grub_cmd_probe (grub_extcmd_t cmd, int argc, char **args) { const char *val = "none"; if (dev->net) - val = dev->net->dev->name; + val = dev->net->name; if (dev->disk) val = dev->disk->dev->name; if (state[0].set) diff --git a/conf/common.rmk b/conf/common.rmk index 0f67622b5..cee808a35 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -828,4 +828,10 @@ bin_UTILITIES += grub-mkpasswd-pbkdf2 grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/emu/misc.c kern/emu/mm.c kern/err.c grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1 +pkglib_MODULES += net.mod +net_mod_SOURCES = commands/net.c +net_mod_CFLAGS = $(COMMON_CFLAGS) +net_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/gcry.mk + diff --git a/include/grub/device.h b/include/grub/device.h index f0e8a8ca8..d68c26e66 100644 --- a/include/grub/device.h +++ b/include/grub/device.h @@ -24,8 +24,12 @@ #include struct grub_disk; -struct grub_net; struct grub_fs; +struct grub_net +{ + char *name; + struct grub_fs *fs; +}; struct grub_device { diff --git a/include/grub/err.h b/include/grub/err.h index e44705389..493796d62 100644 --- a/include/grub/err.h +++ b/include/grub/err.h @@ -54,7 +54,10 @@ typedef enum GRUB_ERR_MENU, GRUB_ERR_TIMEOUT, GRUB_ERR_IO, - GRUB_ERR_ACCESS_DENIED + GRUB_ERR_ACCESS_DENIED, + GRUB_ERR_NET_BAD_ADDRESS, + GRUB_ERR_NET_ROUTE_LOOP, + GRUB_ERR_NET_NO_ROUTE } grub_err_t; diff --git a/include/grub/net.h b/include/grub/net.h index c6d71d5b6..4ca873f74 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2007 Free Software Foundation, Inc. + * Copyright (C) 2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,54 +19,224 @@ #ifndef GRUB_NET_HEADER #define GRUB_NET_HEADER 1 -#include -#include #include +#include +#include -struct grub_net; +struct grub_net_card; -struct grub_net_dev +struct grub_net_card_driver { - /* The device name. */ - const char *name; - - /* FIXME: Just a template. */ - int (*probe) (struct grub_net *net, const void *addr); - void (*reset) (struct grub_net *net); - int (*poll) (struct grub_net *net); - void (*transmit) (struct grub_net *net, const void *destip, - unsigned srcsock, unsigned destsock, const void *packet); - void (*disable) (struct grub_net *net); - - /* The next net device. */ - struct grub_net_dev *next; + grub_err_t (*send) (struct grub_net_card *dev, void *buf, + grub_size_t buflen); + grub_size_t (*recv) (struct grub_net_card *dev, void *buf, + grub_size_t buflen); }; -typedef struct grub_net_dev *grub_net_dev_t; -struct grub_fs; - -struct grub_net +struct grub_net_card { - /* The net name. */ - const char *name; - - /* The underlying disk device. */ - grub_net_dev_t dev; - - /* The binding filesystem. */ - struct grub_fs *fs; - - /* FIXME: More data would be required, such as an IP address, a mask, - a gateway, etc. */ - - /* Device-specific data. */ + struct grub_net_card *next; + char *name; + struct grub_net_card_driver *driver; void *data; }; -typedef struct grub_net *grub_net_t; -/* FIXME: How to abstract networks? More consideration is necessary. */ +struct grub_net_network_level_interface; + +typedef union grub_net_network_level_address +{ + grub_uint32_t ipv4; +} grub_net_network_level_netaddress_t; + +typedef union grub_net_network_level_netaddress +{ + struct { + grub_uint32_t base; + int masksize; + } ipv4; +} grub_net_network_level_address_t; + +typedef enum grub_network_level_protocol_id +{ + GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 +} grub_network_level_protocol_id_t; + +struct grub_net_network_level_interface; + +struct grub_net_network_level_protocol +{ + struct grub_net_network_level_protocol *next; + char *name; + grub_network_level_protocol_id_t id; + grub_err_t (*ntoa) (char *name, grub_net_network_level_address_t *addr); + char * (*aton) (union grub_net_network_level_address addr); + grub_err_t (*net_ntoa) (char *name, + grub_net_network_level_netaddress_t *addr); + char * (*net_aton) (grub_net_network_level_netaddress_t addr); + int (* match_net) (grub_net_network_level_netaddress_t net, + grub_net_network_level_address_t addr); + grub_err_t (*init) (struct grub_net_network_level_interface *dev); + grub_err_t (*fini) (struct grub_net_network_level_interface *dev); + grub_err_t (*send) (struct grub_net_network_level_interface *dev, void *buf, + grub_size_t buflen); + grub_size_t (*recv) (struct grub_net_network_level_interface *dev, void *buf, + grub_size_t buflen); +}; + +struct grub_net_network_level_interface +{ + struct grub_net_network_level_interface *next; + char *name; + /* Underlying protocol. */ + struct grub_net_network_level_protocol *protocol; + struct grub_net_card *card; + union grub_net_network_level_address address; + void *data; +}; + +struct grub_net_route +{ + struct grub_net_route *next; + grub_net_network_level_netaddress_t target; + char *name; + struct grub_net_network_level_protocol *prot; + int is_gateway; + union + { + struct grub_net_network_level_interface *interface; + grub_net_network_level_address_t gw; + }; +}; + +struct grub_net_session; + +struct grub_net_session_level_protocol +{ + void (*close) (struct grub_net_session *session); + grub_ssize_t (*recv) (struct grub_net_session *session, void *buf, + grub_size_t size); + grub_err_t (*send) (struct grub_net_session *session, void *buf, + grub_size_t size); +}; + +struct grub_net_session +{ + struct grub_net_session_level_protocol *protocol; + void *data; +}; + +static inline void +grub_net_session_close (struct grub_net_session *session) +{ + session->protocol->close (session); +} + +static inline grub_err_t +grub_net_session_send (struct grub_net_session *session, void *buf, + grub_size_t size) +{ + return session->protocol->send (session, buf, size); +} + +static inline grub_ssize_t +grub_net_session_recv (struct grub_net_session *session, void *buf, + grub_size_t size) +{ + return session->protocol->recv (session, buf, size); +} + +extern struct grub_net_network_level_interface *grub_net_network_level_interfaces; + +static inline void +grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), + GRUB_AS_LIST (inter)); +} + +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)); +} + +#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) + +extern struct grub_net_route *grub_net_routes; + +static inline void +grub_net_route_register (struct grub_net_route *route) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_routes), + GRUB_AS_LIST (route)); +} + +static inline void +grub_net_route_unregister (struct grub_net_route *route) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_routes), + GRUB_AS_LIST (route)); +} + +#define FOR_NET_ROUTES(var) for (var = grub_net_routes; var; var = var->next) + +extern struct grub_net_card *grub_net_cards; + +static inline void +grub_net_card_register (struct grub_net_card *card) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_cards), + GRUB_AS_LIST (card)); +} + +static inline void +grub_net_card_unregister (struct grub_net_card *card) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_cards), + GRUB_AS_LIST (card)); +} + +#define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next) + +extern struct grub_net_network_level_protocol *grub_net_network_level_protocols; + +static inline void +grub_net_network_level_protocol_register (struct grub_net_network_level_protocol *prot) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_protocols), + GRUB_AS_LIST (prot)); +} + +static inline void +grub_net_network_level_protocol_unregister (struct grub_net_network_level_protocol *prot) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_protocols), + GRUB_AS_LIST (prot)); +} + +#define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_level_protocols; (var); (var) = (var)->next) + +static inline grub_err_t +grub_net_resolve_address_in_protocol (struct grub_net_network_level_protocol *prot, + char *name, + grub_net_network_level_address_t *addr) +{ + return prot->ntoa (name, addr); +} + +struct grub_net_session * +grub_net_open_tcp (char *address, grub_uint16_t port); + +grub_err_t +grub_net_resolve_address (struct grub_net_network_level_protocol **prot, + char *name, + grub_net_network_level_address_t *addr); + +grub_err_t +grub_net_route_address (grub_net_network_level_address_t addr, + grub_net_network_level_address_t *gateway, + struct grub_net_network_level_interface **interf); -/* Note: Networks are very different from disks, because networks must - be initialized before used, and the status is persistent. */ #endif /* ! GRUB_NET_HEADER */ diff --git a/kern/fs.c b/kern/fs.c index cf800f4cc..8ffb93c8b 100644 --- a/kern/fs.c +++ b/kern/fs.c @@ -94,7 +94,7 @@ grub_fs_probe (grub_device_t device) count--; } } - else if (device->net->fs) + else if (device->net) return device->net->fs; grub_error (GRUB_ERR_UNKNOWN_FS, "unknown filesystem"); From 066528b4b18ed5870be40ef333bc85d2344ee812 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Tue, 27 Apr 2010 18:05:35 -0300 Subject: [PATCH 02/19] Initial Implementation of TFTP protocol and new protocol structs. --- conf/powerpc-ieee1275.rmk | 8 +- include/grub/net.h | 19 ++++- include/grub/net/arp.h | 23 ++++++ include/grub/net/device.h | 7 ++ include/grub/net/ethernet.h | 12 +++ include/grub/net/ieee1275/interface.h | 21 ++++++ include/grub/net/interface.h | 17 +++++ include/grub/net/ip.h | 25 +++++++ include/grub/net/netbuff.h | 27 +++++++ include/grub/net/protocol.h | 50 +++++++++++++ include/grub/net/tftp.h | 74 +++++++++++++++++++ include/grub/net/type_net.h | 7 ++ include/grub/net/udp.h | 22 ++++++ net/arp.c | 0 net/device.c | 0 net/ethernet.c | 54 ++++++++++++++ net/ieee1275/interface.c | 80 ++++++++++++++++++++ net/interface.c | 0 net/ip.c | 95 ++++++++++++++++++++++++ net/netbuff.c | 72 ++++++++++++++++++ net/protocol.c | 21 ++++++ net/tftp.c | 102 ++++++++++++++++++++++++++ net/udp.c | 59 +++++++++++++++ 23 files changed, 789 insertions(+), 6 deletions(-) create mode 100644 include/grub/net/arp.h create mode 100644 include/grub/net/device.h create mode 100644 include/grub/net/ethernet.h create mode 100644 include/grub/net/ieee1275/interface.h create mode 100644 include/grub/net/interface.h create mode 100644 include/grub/net/ip.h create mode 100644 include/grub/net/netbuff.h create mode 100644 include/grub/net/protocol.h create mode 100644 include/grub/net/tftp.h create mode 100644 include/grub/net/type_net.h create mode 100644 include/grub/net/udp.h create mode 100644 net/arp.c create mode 100644 net/device.c create mode 100644 net/ethernet.c create mode 100644 net/ieee1275/interface.c create mode 100644 net/interface.c create mode 100644 net/ip.c create mode 100644 net/netbuff.c create mode 100644 net/protocol.c create mode 100644 net/tftp.c create mode 100644 net/udp.c diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index be95b30ba..14d04f93e 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -3,7 +3,10 @@ # Images. -kernel_img_HEADERS += ieee1275/ieee1275.h +<<<<<<< TREE +kernel_img_HEADERS += ieee1275/ieee1275.h \ + command.h i18n.h env_private.h net/ip.h net/udp.h net/ethernet.h net/arp.h net/tftp.h\ + net/ieee1275/interface.h net/type_net.h net.h net/interface.h net/protocol.h net/netbuff.h # Programs pkglib_PROGRAMS = kernel.img @@ -20,7 +23,8 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \ kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/generic/millisleep.c kern/time.c \ - symlist.c kern/$(target_cpu)/cache.S + symlist.c kern/$(target_cpu)/cache.S net/ip.c net/tftp.c net/udp.c net/ethernet.c net/arp.c \ + net/ieee1275/interface.c net/interface.c net/protocol.c net/netbuff.c kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x200000,-Bstatic diff --git a/include/grub/net.h b/include/grub/net.h index 4ca873f74..75efd51d6 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -22,15 +22,20 @@ #include #include #include +#include struct grub_net_card; struct grub_net_card_driver { - grub_err_t (*send) (struct grub_net_card *dev, void *buf, - grub_size_t buflen); - grub_size_t (*recv) (struct grub_net_card *dev, void *buf, - grub_size_t buflen); + grub_err_t (*send) (struct grub_net_card *dev,struct grub_net_buff *nb); + grub_size_t (*recv) (struct grub_net_card *dev,struct grub_net_buff *nb); +}; + +struct grub_net_addr +{ + grub_uint8_t *addr; + grub_size_t len; }; struct grub_net_card @@ -38,6 +43,12 @@ struct grub_net_card struct grub_net_card *next; char *name; struct grub_net_card_driver *driver; + /*transport layer address*/ + struct grub_net_addr *tla; + /*internet layer address*/ + struct grub_net_addr *ila; + /*link layer address*/ + struct grub_net_addr *lla; void *data; }; diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h new file mode 100644 index 000000000..0ac2ec832 --- /dev/null +++ b/include/grub/net/arp.h @@ -0,0 +1,23 @@ +#ifndef GRUB_NET_ARP_HEADER +#define GRUB_NET_ARP_HEADER 1 + +#include +struct arprequest { + grub_int16_t hwtype; /* hardware type (must be ARPHRD_ETHER) */ + grub_int16_t protocol; /* protocol type (must be ETH_P_IP) */ + grub_int8_t hwlen; /* hardware address length (must be 6) */ + grub_int8_t protolen; /* protocol address length (must be 4) */ + grub_uint16_t opcode; /* ARP opcode */ + grub_uint8_t shwaddr[6]; /* sender's hardware address */ + grub_uint32_t sipaddr; /* sender's IP address */ + grub_uint8_t thwaddr[6]; /* target's hardware address */ + grub_uint32_t tipaddr; /* target's IP address */ +}__attribute__ ((packed)); + + +struct arp_pkt{ + struct etherhdr ether; + struct arprequest arpr; +} __attribute__ ((packed)); + +#endif diff --git a/include/grub/net/device.h b/include/grub/net/device.h new file mode 100644 index 000000000..9f1b9bf1d --- /dev/null +++ b/include/grub/net/device.h @@ -0,0 +1,7 @@ +struct grub_net_card +{ + struct grub_net_card *next; + char *name; + struct grub_net_card_driver *driver; + void *data; +}; diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h new file mode 100644 index 000000000..46aa04f60 --- /dev/null +++ b/include/grub/net/ethernet.h @@ -0,0 +1,12 @@ +#ifndef GRUB_NET_ETHERNET_HEADER +#define GRUB_NET_ETHERNET_HEADER 1 +#include +struct etherhdr { + grub_uint8_t dst[6]; + grub_uint8_t src[6]; + grub_uint16_t type; +} __attribute__ ((packed)) ; + +void ethernet_ini(void); +void ethernet_fini(void); +#endif diff --git a/include/grub/net/ieee1275/interface.h b/include/grub/net/ieee1275/interface.h new file mode 100644 index 000000000..edc242cab --- /dev/null +++ b/include/grub/net/ieee1275/interface.h @@ -0,0 +1,21 @@ +#ifndef GRUB_IEEE1275_INTERFACE_HEADER +#define GRUB_IEEE1275_INTERFACE_HEADER 1 + +#include +#include +#include + +grub_ofnet_t EXPORT_VAR(grub_net); + +grub_bootp_t EXPORT_VAR(bootp_pckt); +grub_uint32_t get_server_ip(void); +grub_uint32_t get_client_ip(void); +grub_uint8_t* get_server_mac (void); +grub_uint8_t* get_client_mac (void); + +int send_card_buffer (void *buffer,int buff_len); +int get_card_buffer (void *buffer,int buff_len); +int card_open (void); +int card_close (void); + +#endif diff --git a/include/grub/net/interface.h b/include/grub/net/interface.h new file mode 100644 index 000000000..0e11c86ba --- /dev/null +++ b/include/grub/net/interface.h @@ -0,0 +1,17 @@ +#ifndef GRUB_INTERFACE_HEADER +#define GRUB_INTERFACE_HEADER +#include +#include +/* +extern struct grub_net_topprotocol; + +struct grub_net_interface +{ + struct grub_net_card *card; + struct grub_net_topprotocol* topprot; + struct grub_net_addr *tla; + struct grub_net_addr *ila; + struct grub_net_addr *lla; +}; +*/ +#endif diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h new file mode 100644 index 000000000..e1f45dcfa --- /dev/null +++ b/include/grub/net/ip.h @@ -0,0 +1,25 @@ +#ifndef GRUB_NET_IP_HEADER +#define GRUB_NET_IP_HEADER 1 +#include + + +struct iphdr { + grub_uint8_t verhdrlen; + grub_uint8_t service; + grub_uint16_t len; + grub_uint16_t ident; + grub_uint16_t frags; + grub_uint8_t ttl; + grub_uint8_t protocol; + grub_uint16_t chksum; + grub_uint32_t src; + grub_uint32_t dest; +} __attribute__ ((packed)) ; + +#define IP_UDP 17 /* UDP protocol */ +#define IP_BROADCAST 0xFFFFFFFF + +grub_uint16_t ipchksum(void *ipv, int len); +void ipv4_ini(void); +void ipv4_fini(void); +#endif diff --git a/include/grub/net/netbuff.h b/include/grub/net/netbuff.h new file mode 100644 index 000000000..7d63be1f5 --- /dev/null +++ b/include/grub/net/netbuff.h @@ -0,0 +1,27 @@ +#ifndef GRUB_NETBUFF_HEADER +#define GRUB_NETBUFF_HEADER + +#include + +#define NETBUFF_ALIGN 2048 +#define NETBUFFMINLEN 64 + +struct grub_net_buff +{ + /*Pointer to the start of the buffer*/ + char *head; + /*Pointer to the data */ + char *data; + /*Pointer to the tail */ + char *tail; + /*Pointer to the end of the buffer*/ + char *end; +}; + +grub_err_t grub_netbuff_put (struct grub_net_buff *net_buff ,grub_size_t len); +grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff ,grub_size_t len); +grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len); +grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buff ,grub_size_t len); +grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff ,grub_size_t len); +struct grub_net_buff * grub_netbuff_alloc ( grub_size_t len ); +#endif diff --git a/include/grub/net/protocol.h b/include/grub/net/protocol.h new file mode 100644 index 000000000..2c979481b --- /dev/null +++ b/include/grub/net/protocol.h @@ -0,0 +1,50 @@ +#ifndef GRUB_PROTOCOL_HEADER +#define GRUB_PROTOCOL_HEADER +#include +#include +#include +#include +struct protocol_operations; +struct grub_net_protocol; +struct grub_net_interface; + +struct grub_net_protocol +{ + struct grub_net_protocol *next; + char *name; + grub_err_t (*open) (struct grub_net_interface* inf, + struct grub_net_protocol *prot, struct grub_net_buff *nb); + grub_err_t (*open_confirm) (struct grub_net_interface *inf, + struct grub_net_protocol *prot, struct grub_net_buff *nb); + grub_err_t (*get_payload) (struct grub_net_interface *inf, + struct grub_net_protocol *prot, struct grub_net_buff *nb); + grub_err_t (*get_payload_confirm) (struct grub_net_interface* inf, + struct grub_net_protocol *prot, struct grub_net_buff *nb); + grub_err_t (*close) (struct grub_net_interface *inf, + struct grub_net_protocol *prot, struct grub_net_buff *nb); + grub_err_t (*send) (struct grub_net_interface *inf , + struct grub_net_protocol *prot, struct grub_net_buff *nb); + grub_err_t (*recv) (struct grub_net_interface *inf , + struct grub_net_protocol *prot, struct grub_net_buff *nb); +}; + +typedef struct grub_net_protocol *grub_net_protocol_t; + +struct grub_net_interface +{ + struct grub_net_card *card; + struct grub_net_protocol* prot; + char *path; + char *username; + char *password; + /*transport layer addres*/ + struct grub_net_addr *tla; + /*internet layer addres*/ + struct grub_net_addr *ila; + /*link layer addres*/ + struct grub_net_addr *lla; +}; + +void grub_protocol_register (grub_net_protocol_t prot); +void grub_protocol_unregister (grub_net_protocol_t prot); +#endif diff --git a/include/grub/net/tftp.h b/include/grub/net/tftp.h new file mode 100644 index 000000000..4148096c5 --- /dev/null +++ b/include/grub/net/tftp.h @@ -0,0 +1,74 @@ +#ifndef GRUB_NET_TFTP_HEADER +#define GRUB_NET_TFTP_HEADER 1 + +#include +#include +#include + +/* IP port for the MTFTP server used for Intel's PXE */ +#define MTFTP_SERVER_PORT 75 +#define MTFTP_CLIENT_PORT 76 + +#define TFTP_DEFAULTSIZE_PACKET 512 +#define TFTP_MAX_PACKET 1432 + +/* IP port for the TFTP server */ +#define TFTP_SERVER_PORT 69 +#define TFTP_CLIENT_PORT 2000 + + +/* We define these based on what's in arpa/tftp.h. We just like our + * names better, cause they're clearer */ +#define TFTP_RRQ 1 +#define TFTP_WRQ 2 +#define TFTP_DATA 3 +#define TFTP_ACK 4 +#define TFTP_ERROR 5 +#define TFTP_OACK 6 + +#define TFTP_CODE_EOF 1 +#define TFTP_CODE_MORE 2 +#define TFTP_CODE_ERROR 3 +#define TFTP_CODE_BOOT 4 +#define TFTP_CODE_CFG 5 + +#define TFTP_EUNDEF 0 /* not defined */ +#define TFTP_ENOTFOUND 1 /* file not found */ +#define TFTP_EACCESS 2 /* access violation */ +#define TFTP_ENOSPACE 3 /* disk full or allocation exceeded */ +#define TFTP_EBADOP 4 /* illegal TFTP operation */ +#define TFTP_EBADID 5 /* unknown transfer ID */ +#define TFTP_EEXISTS 6 /* file already exists */ +#define TFTP_ENOUSER 7 /* no such user */ +#define TFTP_DEFAULT_FILENAME "kernel" + + + + + + /* * own here because this is cleaner, and maps to the same data layout. + * */ +struct tftphdr { + grub_uint16_t opcode; + union { + grub_int8_t rrq[TFTP_DEFAULTSIZE_PACKET]; + struct { + grub_uint16_t block; + grub_int8_t download[TFTP_MAX_PACKET]; + } data; + struct { + grub_uint16_t block; + } ack; + struct { + grub_uint16_t errcode; + grub_int8_t errmsg[TFTP_DEFAULTSIZE_PACKET]; + } err; + struct { + grub_int8_t data[TFTP_DEFAULTSIZE_PACKET+2]; + } oack; + } u; +} __attribute__ ((packed)) ; + +void tftp_ini(void); +void tftp_fini(void); +#endif diff --git a/include/grub/net/type_net.h b/include/grub/net/type_net.h new file mode 100644 index 000000000..33f2d802d --- /dev/null +++ b/include/grub/net/type_net.h @@ -0,0 +1,7 @@ +#ifndef GRUB_TYPES_NET_HEADER +#define GRUB_TYPES_NET_HEADER 1 + +#define UDP_PCKT 0x11 +#define IP_PCKT 0x0800 + +#endif diff --git a/include/grub/net/udp.h b/include/grub/net/udp.h new file mode 100644 index 000000000..dbfcecef0 --- /dev/null +++ b/include/grub/net/udp.h @@ -0,0 +1,22 @@ +#ifndef GRUB_NET_UDP_HEADER +#define GRUB_NET_UDP_HEADER 1 +#include +/* +typedef enum + { + GRUB_PROT_TFTP + } protocol_type; +*/ + +#define GRUB_PROT_TFTP 1 + +struct udphdr { + grub_uint16_t src; + grub_uint16_t dst; + grub_uint16_t len; + grub_uint16_t chksum; +} __attribute__ ((packed)); + +void udp_ini(void); +void udp_fini(void); +#endif diff --git a/net/arp.c b/net/arp.c new file mode 100644 index 000000000..e69de29bb diff --git a/net/device.c b/net/device.c new file mode 100644 index 000000000..e69de29bb diff --git a/net/ethernet.c b/net/ethernet.c new file mode 100644 index 000000000..fc64803e7 --- /dev/null +++ b/net/ethernet.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_err_t +send_ethernet_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot __attribute__ ((unused)) + ,struct grub_net_buff *nb) +{ + + struct etherhdr *eth; + grub_err_t err; + + if((err = grub_netbuff_push (nb,sizeof(*eth)) ) != GRUB_ERR_NONE) + return err; + eth = (struct etherhdr *) nb->data; + grub_memcpy (eth->src,inf->card->lla->addr,6 * sizeof (grub_uint8_t )); + grub_memcpy (eth->dst,inf->lla->addr,6 * sizeof (grub_uint8_t )); + eth->type = 0x0800; + + return inf->card->driver->send(inf->card,nb); +} + +static struct grub_net_protocol grub_ethernet_protocol = +{ + .name = "udp", + .send = send_ethernet_packet +}; + +void ethernet_ini(void) +{ + grub_protocol_register (&grub_ethernet_protocol); +} + +void ethernet_fini(void) +{ + grub_protocol_unregister (&grub_ethernet_protocol); +} +/* +int read_ethernet_packet(buffer,bufflen, int type) +{ + + struct etherhdr eth; + eth.type = 0; + + get_card_buffer (ð,sizeof (eth)); + + + +}*/ diff --git a/net/ieee1275/interface.c b/net/ieee1275/interface.c new file mode 100644 index 000000000..5a246ffa5 --- /dev/null +++ b/net/ieee1275/interface.c @@ -0,0 +1,80 @@ +#include +#include + +grub_uint32_t get_server_ip (void) +{ + return bootp_pckt->siaddr; +} + +grub_uint32_t get_client_ip (void) +{ + return bootp_pckt->yiaddr; +} + +grub_uint8_t* get_server_mac (void) +{ + grub_uint8_t *mac; + + mac = grub_malloc (6 * sizeof(grub_uint8_t)); + mac[0] = 0x00 ; + mac[1] = 0x11 ; + mac[2] = 0x25 ; + mac[3] = 0xca ; + mac[4] = 0x1f ; + mac[5] = 0x01 ; + + return mac; + +} + +grub_uint8_t* get_client_mac (void) +{ + grub_uint8_t *mac; + + mac = grub_malloc (6 * sizeof (grub_uint8_t)); + mac[0] = 0x0a ; + mac[1] = 0x11 ; + mac[2] = 0xbd ; + mac[3] = 0xe3 ; + mac[4] = 0xe3 ; + mac[5] = 0x04 ; + + return mac; +} + +static grub_ieee1275_ihandle_t handle; +int card_open (void) +{ + + grub_ieee1275_open (grub_net->dev , &handle); + return 1;//error + +} +int card_close (void) +{ + + if (handle) + grub_ieee1275_close (handle); + return 0; +} + + +int send_card_buffer (void *buffer,int buff_len) +{ + + int actual; + + grub_ieee1275_write (handle,buffer,buff_len,&actual); + + return actual; +} + +int get_card_buffer (void *buffer,int buff_len) +{ + + int actual; + + grub_ieee1275_read (handle,buffer,buff_len,&actual); + + return actual; +} diff --git a/net/interface.c b/net/interface.c new file mode 100644 index 000000000..e69de29bb diff --git a/net/ip.c b/net/ip.c new file mode 100644 index 000000000..c669ff6d7 --- /dev/null +++ b/net/ip.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct grub_net_protocol *grub_ipv4_prot; + +grub_uint16_t +ipchksum(void *ipv, int len) +{ + grub_uint16_t *ip = (grub_uint16_t *)ipv; + grub_uint32_t sum = 0; + + + len >>= 1; + while (len--) { + sum += *(ip++); + if (sum > 0xFFFF) + sum -= 0xFFFF; + } + + return((~sum) & 0x0000FFFF); +} + + +static grub_err_t +send_ip_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot, struct grub_net_buff *nb ) +{ + + struct iphdr *iph; + grub_err_t err; + + if((err = grub_netbuff_push(nb,sizeof(*iph)) ) != GRUB_ERR_NONE) + return err; + iph = (struct iphdr *) nb->data; + + /*FIXME dont work in litte endian machines*/ + //grub_uint8_t ver = 4; + //grub_uint8_t hdrlen = sizeof (struct iphdr)/4; + iph->verhdrlen = (4<<4 | 5); + iph->service = 0; + iph->len = sizeof(*iph); + iph->ident = 0x2b5f; + iph->frags = 0; + iph->ttl = 0xff; + iph->protocol = 0x11; + //grub_memcpy(&(iph->src) ,inf->card->ila->addr,inf->card->ila->len); + iph->src = *((grub_uint32_t *)inf->card->ila->addr); + //grub_memcpy(&(iph->dest) ,inf->ila->addr,inf->ila->len); + iph->dest = *((grub_uint32_t *)inf->ila->addr); + + iph->chksum = 0 ; + iph->chksum = ipchksum((void *)nb->head, sizeof(*iph)); + + + return prot->next->send(inf,prot->next,nb); +} + +static struct grub_net_protocol grub_ipv4_protocol = +{ + .name = "ipv4", + .send = send_ip_packet, + .recv = NULL +}; + +void ipv4_ini(void) +{ + grub_protocol_register (&grub_ipv4_protocol); +} + +void ipv4_fini(void) +{ + grub_protocol_unregister (&grub_ipv4_protocol); +} + +/* +int read_ip_packet (void *buffer,int *bufflen) +{ + struct iphdr iph; + iph.protocol = 0; + + while ( iph.protocol != IP_UDP) + { + read_ethernet_packet(buffer,bufflen,IP_PROTOCOL); + grub_memcpy (&iph,buffer,sizeof (iph)); + } + + buffer += sizeof (iph); + *buff_len -= sizeof (iph); + +}*/ diff --git a/net/netbuff.c b/net/netbuff.c new file mode 100644 index 000000000..342260f43 --- /dev/null +++ b/net/netbuff.c @@ -0,0 +1,72 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB 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 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include + + +grub_err_t grub_netbuff_put (struct grub_net_buff *net_buff ,grub_size_t len) +{ + net_buff->tail += len; + if (net_buff->tail > net_buff->end) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return GRUB_ERR_NONE; +} + +grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff ,grub_size_t len) +{ + net_buff->tail -= len; + if (net_buff->tail < net_buff->head) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return GRUB_ERR_NONE; +} + +grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len) +{ + net_buff->data -= len; + if (net_buff->data < net_buff->head) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return GRUB_ERR_NONE; +} + +grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buff ,grub_size_t len) +{ + net_buff->data += len; + if (net_buff->data > net_buff->end) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return GRUB_ERR_NONE; +} + +grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff ,grub_size_t len) +{ + net_buff->data += len; + net_buff->tail += len; + if ((net_buff->tail > net_buff->end) || (net_buff->data > net_buff->end)) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return GRUB_ERR_NONE; +} + +struct grub_net_buff * grub_netbuff_alloc ( grub_size_t len ) +{ + if (len < NETBUFFMINLEN) + len = NETBUFFMINLEN; + len = ALIGN_UP (len,NETBUFF_ALIGN); + return (struct grub_net_buff *) grub_memalign (len,NETBUFF_ALIGN); +} diff --git a/net/protocol.c b/net/protocol.c new file mode 100644 index 000000000..a6117dc2c --- /dev/null +++ b/net/protocol.c @@ -0,0 +1,21 @@ +#include + +static grub_net_protocol_t grub_net_protocols; + +void grub_protocol_register (grub_net_protocol_t prot) +{ + prot->next = grub_net_protocols; + grub_net_protocols = prot; +} + +void grub_protocol_unregister (grub_net_protocol_t prot) +{ + grub_net_protocol_t *p, q; + + for (p = &grub_net_protocols, q = *p; q; p = &(q->next), q = q->next) + if (q == prot) + { + *p = q->next; + break; + } +} diff --git a/net/tftp.c b/net/tftp.c new file mode 100644 index 000000000..fdca184e9 --- /dev/null +++ b/net/tftp.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*send read request*/ +static grub_err_t +send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protocol *prot,struct grub_net_buff *nb) +{ + /*Start TFTP header*/ + + struct tftphdr *tftph; + char *rrq; + int rrqlen; + int hdrlen; + grub_err_t err; + + if((err = grub_netbuff_push (nb,sizeof(*tftph))) != GRUB_ERR_NONE) + return err; + + tftph = (struct tftphdr *) nb->data; + + rrq = (char *) tftph->u.rrq; + rrqlen = 0; + + tftph->opcode = TFTP_RRQ; + grub_strcpy (rrq,inf->path); + rrqlen += grub_strlen (inf->path) + 1; + rrq += grub_strlen (inf->path) + 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,"blksize"); + rrqlen += grub_strlen("blksize") + 1; + rrq += grub_strlen ("blksize") + 1; + + grub_strcpy (rrq,"1024"); + rrqlen += grub_strlen ("1024") + 1; + rrq += grub_strlen ("1024") + 1; + + grub_strcpy (rrq,"tsize"); + rrqlen += grub_strlen ("tsize") + 1; + rrq += grub_strlen ("tsize") + 1; + + grub_strcpy (rrq,"0"); + rrqlen += grub_strlen ("0") + 1; + rrq += grub_strlen ("0") + 1; + hdrlen = sizeof (tftph->opcode) + rrqlen; + + grub_netbuff_unput (nb,nb->tail - (nb->data+hdrlen)); + + return prot->next->send(inf,prot->next,nb); +} + +/* +int send_tftp_ack(int block, int port){ + + tftp_t pckt; + int pcktlen; + pckt.opcode = TFTP_ACK; + pckt.u.ack.block = block; + pcktlen = sizeof (pckt.opcode) + sizeof (pckt.u.ack.block); + + port = 4; + return 0;// send_udp_packet (&pckt,pcktlen,TFTP_CLIENT_PORT,port); +} + +*/ + +static struct grub_net_protocol grub_tftp_protocol = +{ + .name = "tftp", + .open = send_tftp_rr + +}; + +void tftp_ini(void) +{ + grub_protocol_register (&grub_tftp_protocol); +} + +void tftp_fini(void) +{ + grub_protocol_unregister (&grub_tftp_protocol); +} +/* +int read_tftp_pckt (grub_uint16_t port, void *buffer, int &buff_len){ + + + read_udp_packet (port,buffer,buff_len); + + +}*/ diff --git a/net/udp.c b/net/udp.c new file mode 100644 index 000000000..600eec542 --- /dev/null +++ b/net/udp.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +/*Assumes that there is allocated memory to the header before the buffer address. */ +static grub_err_t +send_udp_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot, struct grub_net_buff *nb) +{ + + struct udphdr *udph; + grub_err_t err; + + if((err = grub_netbuff_push (nb,sizeof(*udph)) ) != GRUB_ERR_NONE) + return err; + + udph = (struct udphdr *) nb->data; + udph->src = *((grub_uint16_t *) inf->card->tla->addr); + udph->dst = *((grub_uint16_t *) inf->tla->addr); + /*no chksum*/ + udph->chksum = 0; + udph->len = sizeof (sizeof (*udph)) + nb->end - nb->head; + + return prot->next->send(inf,prot->next,nb); +} + +static struct grub_net_protocol grub_udp_protocol = +{ + .name = "udp", + .send = send_udp_packet +}; + +void udp_ini(void) +{ + grub_protocol_register (&grub_udp_protocol); +} + +void udp_fini(void) +{ + grub_protocol_unregister (&grub_udp_protocol); +} + +/* +int read_udp_packet (grub_uint16_t port,void *buffer,int *buff_len) +{ + + struct udphdr udph; + udph.dst = 0; + + while ( udph.dst != port) + { + read_ip_packet (buffer,bufflen); + grub_memcpy (&udph,buffer,sizeof (udph)); + } + + buffer += sizeof (udph); + *buff_len -= sizeof (udph); + +}*/ From 8d402bc9a8041f0ed15290901e0ff5f115ed5cc0 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Thu, 29 Apr 2010 17:56:09 -0300 Subject: [PATCH 03/19] small change in the interface structure. --- include/grub/net.h | 14 ++++++++++++++ include/grub/net/interface.h | 18 ++++++++++++++---- include/grub/net/protocol.h | 33 +++++++++------------------------ net/ethernet.c | 3 ++- net/ip.c | 5 +++-- net/tftp.c | 5 +++-- net/udp.c | 5 +++-- 7 files changed, 48 insertions(+), 35 deletions(-) diff --git a/include/grub/net.h b/include/grub/net.h index 75efd51d6..f021f0e9c 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -26,8 +26,22 @@ struct grub_net_card; +typedef enum +{ + GRUB_NET_TFTP_ID, + GRUB_NET_UDP_ID, + GRUB_NET_IPV4_ID, + GRUB_NET_IPV6_ID, + GRUB_NET_ETHERNET_ID, + GRUB_NET_ARP_ID, + GRUB_NET_DHCP_ID + +}protocol_type_t; + struct grub_net_card_driver { + 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 *nb); grub_size_t (*recv) (struct grub_net_card *dev,struct grub_net_buff *nb); }; diff --git a/include/grub/net/interface.h b/include/grub/net/interface.h index 0e11c86ba..2e0ddfcc8 100644 --- a/include/grub/net/interface.h +++ b/include/grub/net/interface.h @@ -2,16 +2,26 @@ #define GRUB_INTERFACE_HEADER #include #include -/* -extern struct grub_net_topprotocol; + +struct grub_net_protstack +{ + struct grub_net_protstack *next; + struct grub_net_protocol* prot; +}; struct grub_net_interface { struct grub_net_card *card; - struct grub_net_topprotocol* topprot; + struct grub_net_protstack* protstack; + char *path; + char *username; + char *password; + /*transport layer addres*/ struct grub_net_addr *tla; + /*internet layer addres*/ struct grub_net_addr *ila; + /*link layer addres*/ struct grub_net_addr *lla; }; -*/ + #endif diff --git a/include/grub/net/protocol.h b/include/grub/net/protocol.h index 2c979481b..1efc2ab7b 100644 --- a/include/grub/net/protocol.h +++ b/include/grub/net/protocol.h @@ -4,47 +4,32 @@ #include #include #include -struct protocol_operations; + struct grub_net_protocol; struct grub_net_interface; +struct grub_net_protstack; struct grub_net_protocol { struct grub_net_protocol *next; char *name; grub_err_t (*open) (struct grub_net_interface* inf, - struct grub_net_protocol *prot, struct grub_net_buff *nb); + struct grub_net_protstack *protstack, struct grub_net_buff *nb); grub_err_t (*open_confirm) (struct grub_net_interface *inf, - struct grub_net_protocol *prot, struct grub_net_buff *nb); + struct grub_net_protstack *protstack, struct grub_net_buff *nb); grub_err_t (*get_payload) (struct grub_net_interface *inf, - struct grub_net_protocol *prot, struct grub_net_buff *nb); + struct grub_net_protstack *protstack, struct grub_net_buff *nb); grub_err_t (*get_payload_confirm) (struct grub_net_interface* inf, - struct grub_net_protocol *prot, struct grub_net_buff *nb); + struct grub_net_protstack *protstack, struct grub_net_buff *nb); grub_err_t (*close) (struct grub_net_interface *inf, - struct grub_net_protocol *prot, struct grub_net_buff *nb); + struct grub_net_protstack *protstack, struct grub_net_buff *nb); grub_err_t (*send) (struct grub_net_interface *inf , - struct grub_net_protocol *prot, struct grub_net_buff *nb); + struct grub_net_protstack *protstack, struct grub_net_buff *nb); grub_err_t (*recv) (struct grub_net_interface *inf , - struct grub_net_protocol *prot, struct grub_net_buff *nb); + struct grub_net_protstack *protstack, struct grub_net_buff *nb); }; typedef struct grub_net_protocol *grub_net_protocol_t; - -struct grub_net_interface -{ - struct grub_net_card *card; - struct grub_net_protocol* prot; - char *path; - char *username; - char *password; - /*transport layer addres*/ - struct grub_net_addr *tla; - /*internet layer addres*/ - struct grub_net_addr *ila; - /*link layer addres*/ - struct grub_net_addr *lla; -}; - void grub_protocol_register (grub_net_protocol_t prot); void grub_protocol_unregister (grub_net_protocol_t prot); #endif diff --git a/net/ethernet.c b/net/ethernet.c index fc64803e7..8c13966c1 100644 --- a/net/ethernet.c +++ b/net/ethernet.c @@ -6,9 +6,10 @@ #include #include #include +#include static grub_err_t -send_ethernet_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot __attribute__ ((unused)) +send_ethernet_packet (struct grub_net_interface *inf,struct grub_net_protstack *protstack __attribute__ ((unused)) ,struct grub_net_buff *nb) { diff --git a/net/ip.c b/net/ip.c index c669ff6d7..6fe58adb0 100644 --- a/net/ip.c +++ b/net/ip.c @@ -5,6 +5,7 @@ #include #include #include +#include #include struct grub_net_protocol *grub_ipv4_prot; @@ -28,7 +29,7 @@ ipchksum(void *ipv, int len) static grub_err_t -send_ip_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot, struct grub_net_buff *nb ) +send_ip_packet (struct grub_net_interface *inf, struct grub_net_protstack *protstack, struct grub_net_buff *nb ) { struct iphdr *iph; @@ -57,7 +58,7 @@ send_ip_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot, iph->chksum = ipchksum((void *)nb->head, sizeof(*iph)); - return prot->next->send(inf,prot->next,nb); + return protstack->next->prot->send(inf,protstack->next,nb); } static struct grub_net_protocol grub_ipv4_protocol = diff --git a/net/tftp.c b/net/tftp.c index fdca184e9..3f481fe58 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -8,10 +8,11 @@ #include #include #include +#include /*send read request*/ static grub_err_t -send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protocol *prot,struct grub_net_buff *nb) +send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protstack *protstack,struct grub_net_buff *nb) { /*Start TFTP header*/ @@ -58,7 +59,7 @@ send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protocol *prot,str grub_netbuff_unput (nb,nb->tail - (nb->data+hdrlen)); - return prot->next->send(inf,prot->next,nb); + return protstack->next->prot->send(inf,protstack->next,nb); } /* diff --git a/net/udp.c b/net/udp.c index 600eec542..2a4a7690b 100644 --- a/net/udp.c +++ b/net/udp.c @@ -3,9 +3,10 @@ #include #include #include +#include /*Assumes that there is allocated memory to the header before the buffer address. */ static grub_err_t -send_udp_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot, struct grub_net_buff *nb) +send_udp_packet (struct grub_net_interface *inf, struct grub_net_protstack *protstack, struct grub_net_buff *nb) { struct udphdr *udph; @@ -21,7 +22,7 @@ send_udp_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot, udph->chksum = 0; udph->len = sizeof (sizeof (*udph)) + nb->end - nb->head; - return prot->next->send(inf,prot->next,nb); + return protstack->next->prot->send(inf,protstack->next,nb); } static struct grub_net_protocol grub_udp_protocol = From d17a9fea4ac98b3aebea13f2b280c98afcd19c03 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Mon, 21 Jun 2010 19:05:14 -0300 Subject: [PATCH 04/19] Add interface struct for communication between protocols and protocols stack. Changed the protocols structs to use one struct for each layer. --- include/grub/net/arp.h | 8 +- include/grub/net/ieee1275/interface.h | 14 ++-- include/grub/net/interface.h | 77 ++++++++++++++---- include/grub/net/netbuff.h | 3 + include/grub/net/protocol.h | 110 ++++++++++++++++++++------ include/grub/net/tftp.h | 6 +- include/grub/net/type_net.h | 25 ++++++ include/grub/net/udp.h | 19 ++--- 8 files changed, 194 insertions(+), 68 deletions(-) diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h index 0ac2ec832..86ae2deea 100644 --- a/include/grub/net/arp.h +++ b/include/grub/net/arp.h @@ -2,7 +2,7 @@ #define GRUB_NET_ARP_HEADER 1 #include -struct arprequest { +struct arphdr{ grub_int16_t hwtype; /* hardware type (must be ARPHRD_ETHER) */ grub_int16_t protocol; /* protocol type (must be ETH_P_IP) */ grub_int8_t hwlen; /* hardware address length (must be 6) */ @@ -14,10 +14,4 @@ struct arprequest { grub_uint32_t tipaddr; /* target's IP address */ }__attribute__ ((packed)); - -struct arp_pkt{ - struct etherhdr ether; - struct arprequest arpr; -} __attribute__ ((packed)); - #endif diff --git a/include/grub/net/ieee1275/interface.h b/include/grub/net/ieee1275/interface.h index edc242cab..16f624c05 100644 --- a/include/grub/net/ieee1275/interface.h +++ b/include/grub/net/ieee1275/interface.h @@ -4,17 +4,15 @@ #include #include #include +#include -grub_ofnet_t EXPORT_VAR(grub_net); -grub_bootp_t EXPORT_VAR(bootp_pckt); -grub_uint32_t get_server_ip(void); -grub_uint32_t get_client_ip(void); -grub_uint8_t* get_server_mac (void); -grub_uint8_t* get_client_mac (void); +grub_ofnet_t grub_net; -int send_card_buffer (void *buffer,int buff_len); -int get_card_buffer (void *buffer,int buff_len); +grub_bootp_t bootp_pckt; + +int send_card_buffer (struct grub_net_buff *pack); +int get_card_packet (struct grub_net_buff *pack); int card_open (void); int card_close (void); diff --git a/include/grub/net/interface.h b/include/grub/net/interface.h index 2e0ddfcc8..4d100fd75 100644 --- a/include/grub/net/interface.h +++ b/include/grub/net/interface.h @@ -1,27 +1,70 @@ #ifndef GRUB_INTERFACE_HEADER #define GRUB_INTERFACE_HEADER -#include -#include +//#include +#include +#include +#include -struct grub_net_protstack +struct grub_net_protocol_stack { - struct grub_net_protstack *next; - struct grub_net_protocol* prot; + struct grub_net_protocol_stack *next; + char *name; + grub_net_protocol_id_t id; + void *interface; }; -struct grub_net_interface +struct grub_net_application_transport_interface { - struct grub_net_card *card; - struct grub_net_protstack* protstack; - char *path; - char *username; - char *password; - /*transport layer addres*/ - struct grub_net_addr *tla; - /*internet layer addres*/ - struct grub_net_addr *ila; - /*link layer addres*/ - struct grub_net_addr *lla; + struct grub_net_transport_network_interface *inner_layer; + void *data; + struct grub_net_application_layer_protocol *app_prot; + struct grub_net_transport_layer_protocol *trans_prot; }; +struct grub_net_transport_network_interface +{ + struct grub_net_network_link_interface *inner_layer; + void *data; + struct grub_net_transport_layer_protocol *trans_prot; + struct grub_net_network_layer_protocol *net_prot; +}; + +struct grub_net_network_link_interface +{ + void *data; + struct grub_net_network_layer_protocol *net_prot; + struct grub_net_link_layer_protocol *link_prot; +}; + + +extern struct grub_net_protocol_stack *grub_net_protocol_stacks; +static inline void +grub_net_stack_register (struct grub_net_protocol_stack *stack) +{ + + grub_list_push (GRUB_AS_LIST_P (&grub_net_protocol_stacks), + GRUB_AS_LIST (stack)); +} +/* +void grub_net_stack_unregister (struct grub_net_protocol_stack *stack) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_protocol_stacks), + GRUB_AS_LIST (stack)); +}*/ + +struct grub_net_protocol_stack *grub_net_protocol_stack_get (char *name); + +/* +static inline void +grub_net_interface_application_transport_register (struct grub_net_application_transport_interface); +static inline void +grub_net_interface_application_transport_unregister (struct grub_net_application_transport_interface); +static inline void +grub_net_interface_transport_network_register (struct grub_net_transport_network_interface); +static inline void +grub_net_interface_transport_network_unregister (struct grub_net_transport_network_interface); +static inline void +grub_net_interface_network_link_register (struct grub_net_network_link_interface); +static inline void +grub_net_interface_network_link_unregister (struct grub_net_network_link_interface);*/ #endif diff --git a/include/grub/net/netbuff.h b/include/grub/net/netbuff.h index 7d63be1f5..8ce508ead 100644 --- a/include/grub/net/netbuff.h +++ b/include/grub/net/netbuff.h @@ -23,5 +23,8 @@ grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff ,grub_size_t len); grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len); grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buff ,grub_size_t len); 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/protocol.h b/include/grub/net/protocol.h index 1efc2ab7b..b7a3e5d3b 100644 --- a/include/grub/net/protocol.h +++ b/include/grub/net/protocol.h @@ -1,35 +1,101 @@ #ifndef GRUB_PROTOCOL_HEADER #define GRUB_PROTOCOL_HEADER #include -#include +#include #include -#include +#include struct grub_net_protocol; -struct grub_net_interface; -struct grub_net_protstack; +struct grub_net_protocol_stack; +struct grub_net_network_layer_interface; -struct grub_net_protocol + +typedef enum grub_network_layer_protocol_id { - struct grub_net_protocol *next; + GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 +} grub_network_layer_protocol_id_t; + +struct grub_net_application_layer_protocol +{ + struct grub_net_application_layer_protocol *next; char *name; - grub_err_t (*open) (struct grub_net_interface* inf, - struct grub_net_protstack *protstack, struct grub_net_buff *nb); - grub_err_t (*open_confirm) (struct grub_net_interface *inf, - struct grub_net_protstack *protstack, struct grub_net_buff *nb); - grub_err_t (*get_payload) (struct grub_net_interface *inf, - struct grub_net_protstack *protstack, struct grub_net_buff *nb); - grub_err_t (*get_payload_confirm) (struct grub_net_interface* inf, - struct grub_net_protstack *protstack, struct grub_net_buff *nb); - grub_err_t (*close) (struct grub_net_interface *inf, - struct grub_net_protstack *protstack, struct grub_net_buff *nb); - grub_err_t (*send) (struct grub_net_interface *inf , - struct grub_net_protstack *protstack, struct grub_net_buff *nb); - grub_err_t (*recv) (struct grub_net_interface *inf , - struct grub_net_protstack *protstack, struct grub_net_buff *nb); + grub_net_protocol_id_t id; + int (*get_file_size) (struct grub_net_network_layer_interface* inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb,char *filename); + grub_err_t (*open) (struct grub_net_network_layer_interface* inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb,char *filename); + grub_err_t (*send_ack) (struct grub_net_network_layer_interface* inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb); + grub_err_t (*send) (struct grub_net_network_layer_interface *inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb); + grub_err_t (*recv) (struct grub_net_network_layer_interface *inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb); + grub_err_t (*close) (struct grub_net_network_layer_interface *inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb); }; +struct grub_net_transport_layer_protocol +{ + struct grub_net_transport_layer_protocol *next; + char *name; + grub_net_protocol_id_t id; + //grub_transport_layer_protocol_id_t id; + grub_err_t (*open) (struct grub_net_network_layer_interface* inf, + struct grub_net_application_transport_interface *app_trans_inf, struct grub_net_buff *nb); + grub_err_t (*send_ack) (struct grub_net_network_layer_interface* inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb); + grub_err_t (*send) (struct grub_net_network_layer_interface *inf, + struct grub_net_application_transport_interface *app_trans_inf, struct grub_net_buff *nb); + grub_err_t (*recv) (struct grub_net_network_layer_interface *inf, + struct grub_net_application_transport_interface *app_trans_inf, struct grub_net_buff *nb); + grub_err_t (*close) (struct grub_net_network_layer_interface *inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb); +}; + +struct grub_net_network_layer_protocol +{ + struct grub_net_network_layer_protocol *next; + char *name; + grub_net_protocol_id_t id; + //grub_network_layer_protocol_id_t id; + grub_err_t (*ntoa) (char *name, grub_net_network_layer_address_t *addr); + char * (*aton) (union grub_net_network_layer_address addr); + grub_err_t (*net_ntoa) (char *name, + grub_net_network_layer_netaddress_t *addr); + char * (*net_aton) (grub_net_network_layer_netaddress_t addr); + int (* match_net) (grub_net_network_layer_netaddress_t net, + grub_net_network_layer_address_t addr); + grub_err_t (*send) (struct grub_net_network_layer_interface *inf , + struct grub_net_transport_network_interface *trans_net_inf, struct grub_net_buff *nb); + grub_err_t (*recv) (struct grub_net_network_layer_interface *inf , + struct grub_net_transport_network_interface *trans_net_inf, struct grub_net_buff *nb); +}; + +struct grub_net_link_layer_protocol +{ + + struct grub_net_link_layer_protocol *next; + char *name; + grub_net_protocol_id_t id; + 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); + 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); +}; + +extern struct grub_net_network_layer_protocol *grub_net_network_layer_protocols; + typedef struct grub_net_protocol *grub_net_protocol_t; -void grub_protocol_register (grub_net_protocol_t prot); -void grub_protocol_unregister (grub_net_protocol_t prot); +void grub_net_application_layer_protocol_register (struct grub_net_application_layer_protocol *prot); +void grub_net_application_layer_protocol_unregister (struct grub_net_application_layer_protocol *prot); +struct grub_net_application_layer_protocol *grub_net_application_layer_protocol_get (grub_net_protocol_id_t id); +void grub_net_transport_layer_protocol_register (struct grub_net_transport_layer_protocol *prot); +void grub_net_transport_layer_protocol_unregister (struct grub_net_transport_layer_protocol *prot); +struct grub_net_transport_layer_protocol *grub_net_transport_layer_protocol_get (grub_net_protocol_id_t id); +void grub_net_network_layer_protocol_register (struct grub_net_network_layer_protocol *prot); +void grub_net_network_layer_protocol_unregister (struct grub_net_network_layer_protocol *prot); +struct grub_net_network_layer_protocol *grub_net_network_layer_protocol_get (grub_net_protocol_id_t id); +void grub_net_link_layer_protocol_register (struct grub_net_link_layer_protocol *prot); +void grub_net_link_layer_protocol_unregister (struct grub_net_link_layer_protocol *prot); +struct grub_net_link_layer_protocol *grub_net_link_layer_protocol_get (grub_net_protocol_id_t id); #endif diff --git a/include/grub/net/tftp.h b/include/grub/net/tftp.h index 4148096c5..1f1c48616 100644 --- a/include/grub/net/tftp.h +++ b/include/grub/net/tftp.h @@ -14,7 +14,7 @@ /* IP port for the TFTP server */ #define TFTP_SERVER_PORT 69 -#define TFTP_CLIENT_PORT 2000 +#define TFTP_CLIENT_PORT 26300 /* We define these based on what's in arpa/tftp.h. We just like our @@ -42,10 +42,6 @@ #define TFTP_ENOUSER 7 /* no such user */ #define TFTP_DEFAULT_FILENAME "kernel" - - - - /* * own here because this is cleaner, and maps to the same data layout. * */ struct tftphdr { diff --git a/include/grub/net/type_net.h b/include/grub/net/type_net.h index 33f2d802d..276c50bf9 100644 --- a/include/grub/net/type_net.h +++ b/include/grub/net/type_net.h @@ -1,7 +1,32 @@ #ifndef GRUB_TYPES_NET_HEADER #define GRUB_TYPES_NET_HEADER 1 +#include + #define UDP_PCKT 0x11 #define IP_PCKT 0x0800 +typedef enum +{ + GRUB_NET_TFTP_ID, + GRUB_NET_UDP_ID, + GRUB_NET_IPV4_ID, + GRUB_NET_IPV6_ID, + GRUB_NET_ETHERNET_ID, + GRUB_NET_ARP_ID, + GRUB_NET_DHCP_ID +}grub_net_protocol_id_t; + +typedef union grub_net_network_layer_address +{ + grub_uint32_t ipv4; +} grub_net_network_layer_netaddress_t; + +typedef union grub_net_network_layer_netaddress +{ + struct { + grub_uint32_t base; + int masksize; + } ipv4; +} grub_net_network_layer_address_t; #endif diff --git a/include/grub/net/udp.h b/include/grub/net/udp.h index dbfcecef0..dfc1776a4 100644 --- a/include/grub/net/udp.h +++ b/include/grub/net/udp.h @@ -1,22 +1,23 @@ #ifndef GRUB_NET_UDP_HEADER #define GRUB_NET_UDP_HEADER 1 #include -/* -typedef enum - { - GRUB_PROT_TFTP - } protocol_type; -*/ -#define GRUB_PROT_TFTP 1 - -struct udphdr { +struct udphdr +{ grub_uint16_t src; grub_uint16_t dst; grub_uint16_t len; grub_uint16_t chksum; } __attribute__ ((packed)); +struct udp_interf +{ + grub_uint16_t src; + grub_uint16_t dst; +}; + + + void udp_ini(void); void udp_fini(void); #endif From c3639ae731b7043f641090b38995a73aceda70c9 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Mon, 21 Jun 2010 19:13:26 -0300 Subject: [PATCH 05/19] File manipulation. Based in OF implementation. For debug porpouse and will be changed later. --- fs/ieee1275/ofnet.c | 355 ++++++++++++++++++++++++++++++++++ include/grub/ieee1275/ofnet.h | 95 +++++++++ 2 files changed, 450 insertions(+) create mode 100644 fs/ieee1275/ofnet.c create mode 100644 include/grub/ieee1275/ofnet.h diff --git a/fs/ieee1275/ofnet.c b/fs/ieee1275/ofnet.c new file mode 100644 index 000000000..196aadcf2 --- /dev/null +++ b/fs/ieee1275/ofnet.c @@ -0,0 +1,355 @@ +/* ofnet.c - Driver to provide access to the ofnet filesystem */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFFERADDR 0X00000000 +#define BUFFERSIZE 0x02000000 +#define U64MAXSIZE 18446744073709551615ULL + + +//static grub_ieee1275_ihandle_t handle = 0; + + +static int +grub_ofnet_iterate (int (*hook) (const char *name)) +{ + if (hook ("net")) + return 1; + return 0; +} + +static grub_err_t +grub_ofnet_open (const char *name, grub_disk_t disk) +{ + + + if (grub_strcmp (name, "network")) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a net disk"); + + disk->total_sectors = U64MAXSIZE; + disk->id = (unsigned long) "net"; + + disk->has_partitions = 0; + disk->data = 0; + + return GRUB_ERR_NONE; +} + +static void +grub_ofnet_close (grub_disk_t disk __attribute((unused))) +{ +} + +static grub_err_t +grub_ofnet_read (grub_disk_t disk __attribute((unused)), + grub_disk_addr_t sector __attribute((unused)), + grub_size_t size __attribute((unused)), + char *buf __attribute((unused))) +{ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_ofnet_write (grub_disk_t disk __attribute((unused)), + grub_disk_addr_t sector __attribute((unused)), + grub_size_t size __attribute((unused)), + const char *buf __attribute((unused))) +{ + return GRUB_ERR_NONE; +} + +static struct grub_disk_dev grub_ofnet_dev = + { + .name = "net", + .id = GRUB_DISK_DEVICE_OFNET_ID, + .iterate = grub_ofnet_iterate, + .open = grub_ofnet_open, + .close = grub_ofnet_close, + .read = grub_ofnet_read, + .write = grub_ofnet_write, + .next = 0 + }; + +static grub_err_t +grub_ofnetfs_dir (grub_device_t device , + const char *path __attribute((unused)), + int (*hook) (const char *filename, + const struct grub_dirhook_info *info) __attribute((unused))) +{ + if(grub_strcmp (device->disk->name,"network")) + { + return grub_error (GRUB_ERR_BAD_FS, "not an net filesystem"); + } + return GRUB_ERR_NONE; +} + +static grub_ssize_t +grub_ofnetfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + grub_size_t actual; + actual = len <= (file->size - file->offset)?len:file->size - file->offset; + grub_memcpy(buf, (void *)( (grub_addr_t) file->data + (grub_addr_t)file->offset), actual); + return actual; +} + +static grub_err_t +grub_ofnetfs_close (grub_file_t file) +{ + grub_ieee1275_release ((grub_addr_t) file->data,file->size); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_ofnetfs_open (struct grub_file *file , const char *name ) +{ + //void *buffer; + //grub_addr_t addr; + if (name[0] == '/') + name++; + if(grub_strcmp (file->device->disk->name,"network")) + { + + return 1; + } + grub_printf("name = %s\n",name); + + struct grub_net_protocol_stack *stack; + struct grub_net_buff *pack; + struct grub_net_application_transport_interface *app_interface; + int file_size; + char *datap; + int amount = 0; + grub_addr_t found_addr; + + stack = grub_net_protocol_stack_get ("tftp"); + app_interface = (struct grub_net_application_transport_interface *) stack->interface; + pack = grub_netbuff_alloc (80*1024); + grub_netbuff_reserve (pack,80*1024); + file_size = app_interface->app_prot->get_file_size(NULL,stack,pack,(char *) name); + + + for (found_addr = 0x800000; found_addr < + 2000 * 0x100000; found_addr += 0x100000) + { + grub_printf("traing to claim %d bytes at 0x%x\n",file_size,found_addr); + if (grub_claimmap (found_addr , file_size) != -1) + break; + } + grub_printf("Claimed %d bytes at 0x%x\n",file_size,found_addr); + file->data = (void *) found_addr; + grub_printf("file->data = 0x%x\n",(int)file->data); + grub_printf("file_size = %d\n",file_size); + grub_printf("OPEN\n"); + grub_netbuff_clear(pack); + grub_netbuff_reserve (pack,80*1024); + app_interface->app_prot->open (NULL,stack,pack,(char *) name); + + do { + //if (app_interface->app_prot->recv (NULL,stack,pack) == GRUB_ERR_NONE) + grub_printf("RECEIVE PACKET\n"); + grub_netbuff_clear(pack); + grub_netbuff_reserve (pack,80*1024); + app_interface->app_prot->recv (NULL,stack,pack); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + grub_printf("RECEIVED PACKET\n"); + // { + grub_printf("payload_size= %d\n",pack->tail - pack->data); + grub_printf("amount= %d\n",amount); + grub_printf("file_size= %d\n",file_size); + datap = (char *)file->data + amount; + amount += (pack->tail - pack->data); + grub_printf("datap = 0x%x\n",(int)datap ); + // amount += pack->tail - pack->data; + grub_memcpy(datap, pack->data, pack->tail - pack->data); + grub_printf("SEND ACK\n"); + + grub_netbuff_clear(pack); + grub_netbuff_reserve (pack,80*1024); + app_interface->app_prot->send_ack (NULL,stack,pack); + + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + grub_printf("SENT ACK\n"); + //} + // file->data = grub_realloc(file->data,amount); + + }while (amount < file_size); + grub_printf("transfer complete\n"); + file->size = file_size; + +// grub_netbuff_free(pack); + /*Start ARP header*/ + // arp.arpr.hwtype = 0x1; /* hardware type (must be ARPHRD_ETHER) */ + // arp.arpr.protocol = 0x0800; /* protocol type (must be ETH_P_IP) */ + // arp.arpr.hwlen = 0x6; /* hardware address length (must be 6) */ + // arp.arpr.protolen = 0x4; /* protocol address length (must be 4) */ + // arp.arpr.opcode = 0x1; /* ARP opcode */ + + + /*arp.arpr.shwaddr[0] =0x0a ; + arp.arpr.shwaddr[1] =0x11 ; + arp.arpr.shwaddr[2] =0xbd ; + arp.arpr.shwaddr[3] =0xe3 ; + arp.arpr.shwaddr[4] =0xe3 ; + arp.arpr.shwaddr[5] =0x04 ; + arp.arpr.sipaddr = dhcp_pckt -> yiaddr; */ /* sender's IP address */ + /*arp.arpr.thwaddr[0] =0; + arp.arpr.thwaddr[1] =0; + arp.arpr.thwaddr[2] =0; + arp.arpr.thwaddr[3] =0; + arp.arpr.thwaddr[4] =0; + arp.arpr.thwaddr[5] =0; + arp.arpr.tipaddr = dhcp_pckt -> siaddr; */ /* target's IP address */ + /*END ARP header */ + return grub_errno; +} + + +static grub_err_t +grub_ofnetfs_label (grub_device_t device __attribute ((unused)), + char **label __attribute ((unused))) +{ + *label = 0; + return GRUB_ERR_NONE; +} + +static struct grub_fs grub_ofnetfs_fs = + { + .name = "ofnetfs", + .dir = grub_ofnetfs_dir, + .open = grub_ofnetfs_open, + .read = grub_ofnetfs_read, + .close = grub_ofnetfs_close, + .label = grub_ofnetfs_label, + .next = 0 + }; + +static char * +grub_ieee1275_get_devargs (const char *path) +{ + int len; + char *colon = grub_strchr (path, ':'); + len = colon - path; + if (! colon) + return 0; + + return grub_strndup (path,len); +} + +static int +grub_ofnet_detect (void) +{ + + char *devalias; + char bootpath[64]; /* XXX check length */ + grub_ieee1275_phandle_t root; + grub_uint32_t net_type; + + grub_ieee1275_finddevice ("/chosen", &grub_ieee1275_chosen); + if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath, + sizeof (bootpath), 0)) + { + /* Should never happen. */ + grub_printf ("/chosen/bootpath property missing!\n"); + return 0; + } + devalias = grub_ieee1275_get_aliasdevname (bootpath); + + if (grub_strcmp(devalias ,"network")) + return 0; + + grub_net = grub_malloc (sizeof *grub_net ); + grub_net->name = "net"; + grub_net->dev = grub_ieee1275_get_devargs (bootpath); + grub_ieee1275_finddevice ("/", &root); + grub_ieee1275_get_integer_property (root, "ibm,fw-net-compatibility", + &net_type, sizeof net_type, 0); + grub_printf("root = %d\n",root); + grub_printf("net_type= %d\n",net_type); + grub_net->type = net_type; + + return 1; +} + + +#define IPMASK 0x000000FF +#define IPSIZE 16 +#define IPTEMPLATE "%d.%d.%d.%d" +char * +grub_ip2str (grub_uint32_t ip) +{ + char* str_ip; +// str_ip = grub_malloc(IPSIZE); + str_ip = grub_xasprintf (IPTEMPLATE, ip >> 24 & IPMASK, ip >> 16 & IPMASK, ip >> 8 & IPMASK, ip & IPMASK); + grub_printf ("str_ip = %s\n",str_ip); + grub_printf ("template = "IPTEMPLATE"\n" , ip >> 24 & IPMASK, ip >> 16 & IPMASK, ip >> 8 & IPMASK, ip & IPMASK); + return str_ip; +} + +void +grub_get_netinfo (grub_ofnet_t netinfo,grub_bootp_t packet) +{ + netinfo->sip = grub_ip2str(packet->siaddr); + netinfo->cip = grub_ip2str(packet->yiaddr); + netinfo->gat = grub_ip2str(packet->giaddr); + grub_printf("packet->siaddr = %x\n",packet->siaddr); + grub_printf("netinfo-> = %s\n",netinfo->sip); + grub_printf("packet->yiaddr = %x\n",packet->yiaddr); + grub_printf("netinfo-> = %s\n",netinfo->cip); + grub_printf("packet->giaddr = %x\n",packet->giaddr); + grub_printf("netinfo-> = %s\n",netinfo->gat); +} +void +grub_ofnet_init(void) +{ + tftp_ini (); + bootp_pckt = grub_getbootp (); + if(grub_ofnet_detect ()) + { + grub_get_netinfo (grub_net, bootp_pckt ); + grub_disk_dev_register (&grub_ofnet_dev); + grub_fs_register (&grub_ofnetfs_fs); + } + card_open (); +} +void +grub_ofnet_fini(void) +{ + grub_fs_unregister (&grub_ofnetfs_fs); + grub_disk_dev_unregister (&grub_ofnet_dev); +} diff --git a/include/grub/ieee1275/ofnet.h b/include/grub/ieee1275/ofnet.h new file mode 100644 index 000000000..7daadf61d --- /dev/null +++ b/include/grub/ieee1275/ofnet.h @@ -0,0 +1,95 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007 Free Software Foundation, Inc. + * + * GRUB 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 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_OFNET_HEADER +#define GRUB_OFNET_HEADER 1 + +#include +#include +#include + +extern void grub_ofnet_init(void); +extern void grub_ofnet_fini(void); +/* +struct grub_net; + +struct grub_net_dev +{ + / The device name. / + const char *name; + + / FIXME: Just a template. / + int (*probe) (struct grub_net *net, const void *addr); + void (*reset) (struct grub_net *net); + int (*poll) (struct grub_net *net); + void (*transmit) (struct grub_net *net, const void *destip, + unsigned srcsock, unsigned destsock, const void *packet); + void (*disable) (struct grub_net *net); + + / The next net device. / + struct grub_net_dev *next; +}; +typedef struct grub_net_dev *grub_net_dev_t; + +struct grub_fs; +*/ +struct grub_ofnet +{ + /* The net name. */ + const char *name; + + /* The OF device string. */ + char *dev; + /*server ip*/ + char *sip; + /*client ip*/ + char *cip; + /*gateway*/ + char *gat; + /**/ + int type; +}; + +typedef struct grub_ofnet *grub_ofnet_t; + +struct grub_bootp { + grub_uint8_t op; /* 1 = BOOTREQUEST, 2 = BOOTREPLY */ + grub_uint8_t htype; /* Hardware address type. */ + grub_uint8_t hlen; /* Hardware address length */ + grub_uint8_t hops; /* Used by gateways in cross-gateway booting. */ + grub_uint32_t xid; /* Transaction ID */ + grub_uint16_t secs; /* Seconds elapsed. */ + grub_uint16_t unused; /* Unused. */ + grub_uint32_t ciaddr; /* Client IP address, */ + grub_uint32_t yiaddr; /* Client IP address filled by server. */ + grub_uint32_t siaddr; /* Server IP address. */ + grub_uint32_t giaddr; /* Gateway IP address. */ + unsigned char chaddr [16]; /* Client hardware address */ + char sname [64]; /* Server name */ + char file [128]; /* Boot filename */ +// grub_uint32_t filesize ; /*File size (testing)*/ + unsigned char vend [64]; +}; + +typedef struct grub_bootp* grub_bootp_t; + +char * grub_get_filestr(const char * ); +char * grub_ip2str (grub_uint32_t ip); +void grub_get_netinfo (grub_ofnet_t netinfo,grub_bootp_t packet); +grub_bootp_t grub_getbootp (void); +#endif /* ! GRUB_NET_HEADER */ From 60cdb895da65aaa09dcb256d03063c3a711a61e2 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Mon, 21 Jun 2010 19:15:45 -0300 Subject: [PATCH 06/19] Adaptation for the new protocols and interface structs. implementation of receive in the protocols. Also all unwanted packets are discarded. --- commands/net.c | 38 ++++---- include/grub/net.h | 118 ++++++------------------ net/ethernet.c | 88 ++++++++++++------ net/interface.c | 38 ++++++++ net/ip.c | 66 ++++++++++---- net/netbuff.c | 41 +++++++-- net/protocol.c | 50 ++++++---- net/tftp.c | 223 ++++++++++++++++++++++++++++++++++++++------- net/udp.c | 69 +++++++++++--- 9 files changed, 505 insertions(+), 226 deletions(-) diff --git a/commands/net.c b/commands/net.c index 288ba4c2a..b8ceb36f4 100644 --- a/commands/net.c +++ b/commands/net.c @@ -23,14 +23,14 @@ #include struct grub_net_route *grub_net_routes = NULL; -struct grub_net_network_level_interface *grub_net_network_level_interfaces = NULL; +struct grub_net_network_layer_interface *grub_net_network_layer_interfaces = NULL; struct grub_net_card *grub_net_cards = NULL; -struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL; +struct grub_net_network_layer_protocol *grub_net_network_layer_protocols = NULL; grub_err_t -grub_net_resolve_address (struct grub_net_network_level_protocol **prot, +grub_net_resolve_address (struct grub_net_network_layer_protocol **prot, char *name, - grub_net_network_level_address_t *addr) + grub_net_network_layer_address_t *addr) { FOR_NET_NETWORK_LEVEL_PROTOCOLS (*prot) { @@ -50,15 +50,15 @@ grub_net_resolve_address (struct grub_net_network_level_protocol **prot, } grub_err_t -grub_net_route_address (grub_net_network_level_address_t addr, - grub_net_network_level_address_t *gateway, - struct grub_net_network_level_interface **interf) +grub_net_route_address (grub_net_network_layer_address_t addr, + grub_net_network_layer_address_t *gateway, + struct grub_net_network_layer_interface **interf) { struct grub_net_route *route; int depth = 0; int routecnt = 0; - struct grub_net_network_level_protocol *prot = NULL; - grub_net_network_level_address_t curtarget = addr; + struct grub_net_network_layer_protocol *prot = NULL; + grub_net_network_layer_address_t curtarget = addr; *gateway = addr; @@ -96,7 +96,7 @@ static grub_err_t grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), int argc, char **args) { - struct grub_net_network_level_interface *inter; + struct grub_net_network_layer_interface *inter; if (argc != 4) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); @@ -107,8 +107,8 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), if (inter == NULL) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found")); - inter->protocol->fini (inter); - grub_net_network_level_interface_unregister (inter); +// inter->protocol->fini (inter); + grub_net_network_layer_interface_unregister (inter); grub_free (inter->name); grub_free (inter); @@ -120,10 +120,10 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), int argc, char **args) { struct grub_net_card *card; - struct grub_net_network_level_protocol *prot; + struct grub_net_network_layer_protocol *prot; grub_err_t err; - grub_net_network_level_address_t addr; - struct grub_net_network_level_interface *inter; + grub_net_network_layer_address_t addr; + struct grub_net_network_layer_interface *inter; if (argc != 4) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("four arguments expected")); @@ -154,14 +154,14 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), grub_memcpy (&(inter->address), &addr, sizeof (inter->address)); inter->card = card; - err = prot->init (inter); + // err = prot->init (inter); if (err) { grub_free (inter->name); grub_free (inter); return err; } - grub_net_network_level_interface_register (inter); + grub_net_network_layer_interface_register (inter); return GRUB_ERR_NONE; } @@ -192,7 +192,7 @@ static grub_err_t grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), int argc, char **args) { - struct grub_net_network_level_protocol *prot; + struct grub_net_network_layer_protocol *prot; struct grub_net_route *route; if (argc < 3) @@ -247,7 +247,7 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), } else { - struct grub_net_network_level_interface *inter; + struct grub_net_network_layer_interface *inter; route->is_gateway = 0; FOR_NET_NETWORK_LEVEL_INTERFACES (inter) diff --git a/include/grub/net.h b/include/grub/net.h index f021f0e9c..abb8a3167 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -23,20 +23,11 @@ #include #include #include +#include +#include struct grub_net_card; -typedef enum -{ - GRUB_NET_TFTP_ID, - GRUB_NET_UDP_ID, - GRUB_NET_IPV4_ID, - GRUB_NET_IPV6_ID, - GRUB_NET_ETHERNET_ID, - GRUB_NET_ARP_ID, - GRUB_NET_DHCP_ID - -}protocol_type_t; struct grub_net_card_driver { @@ -66,76 +57,36 @@ struct grub_net_card void *data; }; -struct grub_net_network_level_interface; +//struct grub_net_network_layer_interface; -typedef union grub_net_network_level_address +struct grub_net_network_layer_interface { - grub_uint32_t ipv4; -} grub_net_network_level_netaddress_t; - -typedef union grub_net_network_level_netaddress -{ - struct { - grub_uint32_t base; - int masksize; - } ipv4; -} grub_net_network_level_address_t; - -typedef enum grub_network_level_protocol_id -{ - GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 -} grub_network_level_protocol_id_t; - -struct grub_net_network_level_interface; - -struct grub_net_network_level_protocol -{ - struct grub_net_network_level_protocol *next; - char *name; - grub_network_level_protocol_id_t id; - grub_err_t (*ntoa) (char *name, grub_net_network_level_address_t *addr); - char * (*aton) (union grub_net_network_level_address addr); - grub_err_t (*net_ntoa) (char *name, - grub_net_network_level_netaddress_t *addr); - char * (*net_aton) (grub_net_network_level_netaddress_t addr); - int (* match_net) (grub_net_network_level_netaddress_t net, - grub_net_network_level_address_t addr); - grub_err_t (*init) (struct grub_net_network_level_interface *dev); - grub_err_t (*fini) (struct grub_net_network_level_interface *dev); - grub_err_t (*send) (struct grub_net_network_level_interface *dev, void *buf, - grub_size_t buflen); - grub_size_t (*recv) (struct grub_net_network_level_interface *dev, void *buf, - grub_size_t buflen); -}; - -struct grub_net_network_level_interface -{ - struct grub_net_network_level_interface *next; + struct grub_net_network_layer_interface *next; char *name; /* Underlying protocol. */ - struct grub_net_network_level_protocol *protocol; + struct grub_net_network_layer_protocol *protocol; struct grub_net_card *card; - union grub_net_network_level_address address; + union grub_net_network_layer_address address; void *data; }; struct grub_net_route { struct grub_net_route *next; - grub_net_network_level_netaddress_t target; + grub_net_network_layer_netaddress_t target; char *name; - struct grub_net_network_level_protocol *prot; + struct grub_net_network_layer_protocol *prot; int is_gateway; union { - struct grub_net_network_level_interface *interface; - grub_net_network_level_address_t gw; + struct grub_net_network_layer_interface *interface; + grub_net_network_layer_address_t gw; }; }; struct grub_net_session; -struct grub_net_session_level_protocol +struct grub_net_session_layer_protocol { void (*close) (struct grub_net_session *session); grub_ssize_t (*recv) (struct grub_net_session *session, void *buf, @@ -146,7 +97,7 @@ struct grub_net_session_level_protocol struct grub_net_session { - struct grub_net_session_level_protocol *protocol; + struct grub_net_session_layer_protocol *protocol; void *data; }; @@ -170,23 +121,23 @@ grub_net_session_recv (struct grub_net_session *session, void *buf, return session->protocol->recv (session, buf, size); } -extern struct grub_net_network_level_interface *grub_net_network_level_interfaces; +struct grub_net_network_layer_interface *grub_net_network_layer_interfaces; static inline void -grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter) +grub_net_network_layer_interface_register (struct grub_net_network_layer_interface *inter) { - grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), + grub_list_push (GRUB_AS_LIST_P (&grub_net_network_layer_interfaces), GRUB_AS_LIST (inter)); } static inline void -grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) +grub_net_network_layer_interface_unregister (struct grub_net_network_layer_interface *inter) { - grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), + grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_layer_interfaces), GRUB_AS_LIST (inter)); } -#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) +#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_layer_interfaces; var; var = var->next) extern struct grub_net_route *grub_net_routes; @@ -224,28 +175,13 @@ grub_net_card_unregister (struct grub_net_card *card) #define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next) -extern struct grub_net_network_level_protocol *grub_net_network_level_protocols; -static inline void -grub_net_network_level_protocol_register (struct grub_net_network_level_protocol *prot) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_protocols), - GRUB_AS_LIST (prot)); -} - -static inline void -grub_net_network_level_protocol_unregister (struct grub_net_network_level_protocol *prot) -{ - grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_protocols), - GRUB_AS_LIST (prot)); -} - -#define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_level_protocols; (var); (var) = (var)->next) +#define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_layer_protocols; (var); (var) = (var)->next) static inline grub_err_t -grub_net_resolve_address_in_protocol (struct grub_net_network_level_protocol *prot, +grub_net_resolve_address_in_protocol (struct grub_net_network_layer_protocol *prot, char *name, - grub_net_network_level_address_t *addr) + grub_net_network_layer_address_t *addr) { return prot->ntoa (name, addr); } @@ -254,14 +190,14 @@ struct grub_net_session * grub_net_open_tcp (char *address, grub_uint16_t port); grub_err_t -grub_net_resolve_address (struct grub_net_network_level_protocol **prot, +grub_net_resolve_address (struct grub_net_network_layer_protocol **prot, char *name, - grub_net_network_level_address_t *addr); + grub_net_network_layer_address_t *addr); grub_err_t -grub_net_route_address (grub_net_network_level_address_t addr, - grub_net_network_level_address_t *gateway, - struct grub_net_network_level_interface **interf); +grub_net_route_address (grub_net_network_layer_address_t addr, + grub_net_network_layer_address_t *gateway, + struct grub_net_network_layer_interface **interf); #endif /* ! GRUB_NET_HEADER */ diff --git a/net/ethernet.c b/net/ethernet.c index 8c13966c1..a4bdbff5b 100644 --- a/net/ethernet.c +++ b/net/ethernet.c @@ -5,51 +5,85 @@ #include #include #include -#include #include +#include static grub_err_t -send_ethernet_packet (struct grub_net_interface *inf,struct grub_net_protstack *protstack __attribute__ ((unused)) - ,struct grub_net_buff *nb) +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 etherhdr *eth; - grub_err_t err; - - if((err = grub_netbuff_push (nb,sizeof(*eth)) ) != GRUB_ERR_NONE) - return err; + struct etherhdr *eth; + + grub_netbuff_push (nb,sizeof(*eth)); eth = (struct etherhdr *) nb->data; - grub_memcpy (eth->src,inf->card->lla->addr,6 * sizeof (grub_uint8_t )); - grub_memcpy (eth->dst,inf->lla->addr,6 * sizeof (grub_uint8_t )); + eth->dst[0] =0x00; + eth->dst[1] =0x11; + eth->dst[2] =0x25; + eth->dst[3] =0xca; + eth->dst[4] =0x1f; + eth->dst[5] =0x01; + eth->src[0] =0x0a; + eth->src[1] =0x11; + eth->src[2] =0xbd; + eth->src[3] =0xe3; + eth->src[4] =0xe3; + eth->src[5] =0x04; + eth->type = 0x0800; - - return inf->card->driver->send(inf->card,nb); + + return send_card_buffer(nb); +// return inf->card->driver->send(inf->card,nb); } -static struct grub_net_protocol grub_ethernet_protocol = + +static grub_err_t +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) { - .name = "udp", - .send = send_ethernet_packet + struct etherhdr *eth; + while (1) + { + get_card_packet (nb); + eth = (struct etherhdr *) nb->data; + /*change for grub_memcmp*/ + if( eth->src[0] == 0x00 && eth->src[1] == 0x11 && eth->src[2] == 0x25 && + eth->src[3] == 0xca && eth->src[4] == 0x1f && eth->src[5] == 0x01 && eth->type == 0x800) + { + //grub_printf("ethernet eth->dst %x:%x:%x:%x:%x:%x\n",eth->dst[0], + // eth->dst[1],eth->dst[2],eth->dst[3],eth->dst[4],eth->dst[5]); + // grub_printf("ethernet eth->src %x:%x:%x:%x:%x:%x\n",eth->src[0],eth->src[1], + // eth->src[2],eth->src[3],eth->src[4],eth->src[5]); + //grub_printf("ethernet eth->type 0x%x\n",eth->type); + //grub_printf("out from ethernet\n"); + grub_netbuff_pull(nb,sizeof(*eth)); + return 0; + } + } +/* - get ethernet header + - verify if the next layer is the desired one. + - if not. get another packet. + - remove ethernet header from buffer*/ + return 0; +} + + +static struct grub_net_link_layer_protocol grub_ethernet_protocol = +{ + .name = "ethernet", + .id = GRUB_NET_ETHERNET_ID, + .send = send_ethernet_packet, + .recv = recv_ethernet_packet }; void ethernet_ini(void) { - grub_protocol_register (&grub_ethernet_protocol); + grub_net_link_layer_protocol_register (&grub_ethernet_protocol); } void ethernet_fini(void) { - grub_protocol_unregister (&grub_ethernet_protocol); + grub_net_link_layer_protocol_unregister (&grub_ethernet_protocol); } -/* -int read_ethernet_packet(buffer,bufflen, int type) -{ - - struct etherhdr eth; - eth.type = 0; - - get_card_buffer (ð,sizeof (eth)); - -}*/ diff --git a/net/interface.c b/net/interface.c index e69de29bb..bacabf4cb 100644 --- a/net/interface.c +++ b/net/interface.c @@ -0,0 +1,38 @@ +/*#include + +#define INTERFACE_REGISTER_FUNCTIONS(layerprevious,layernext) \ +struct grub_net_##layername_layer_protocol *grub_net_##layername_layer_protocols;\ +\ +void grub_net_##layerprevious_##layernext_interface_register (struct grub_net_##layername_layer_protocol *prot)\ +{\ + grub_list_push (GRUB_AS_LIST_P (&grub_net_##layername_layer_protocols),\ + GRUB_AS_LIST (prot));\ +}\ +\ +void grub_net_##layerprevious_##layernext_interface_unregister (struct grub_net_##layername_layer_protocol *prot);\ +{\ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_##layername_layer_protocols),\ + GRUB_AS_LIST (prot));\ +}\ + +INTERFACE_REGISTER_FUNCTIONS("application","transport"); +INTERFACE_REGISTER_FUNCTIONS("transport","network"); +INTERFACE_REGISTER_FUNCTIONS("network","link"); +INTERFACE_REGISTER_FUNCTIONS("link");*/ + +#include +#include +struct grub_net_protocol_stack *grub_net_protocol_stacks; +struct grub_net_protocol_stack + *grub_net_protocol_stack_get (char *name) +{ + struct grub_net_protocol_stack *p; + + for (p = grub_net_protocol_stacks; p; p = p->next) + { + if (!grub_strcmp(p->name,name)) + return p; + } + + return NULL; +} diff --git a/net/ip.c b/net/ip.c index 6fe58adb0..5eaa74f90 100644 --- a/net/ip.c +++ b/net/ip.c @@ -1,11 +1,11 @@ #include -#include #include #include #include -#include -#include #include +#include +#include +#include #include struct grub_net_protocol *grub_ipv4_prot; @@ -29,14 +29,14 @@ ipchksum(void *ipv, int len) static grub_err_t -send_ip_packet (struct grub_net_interface *inf, struct grub_net_protstack *protstack, struct grub_net_buff *nb ) +send_ip_packet (struct grub_net_network_layer_interface *inf, + struct grub_net_transport_network_interface *trans_net_inf, struct grub_net_buff *nb ) { struct iphdr *iph; - grub_err_t err; + static int id = 0x2400; - if((err = grub_netbuff_push(nb,sizeof(*iph)) ) != GRUB_ERR_NONE) - return err; + grub_netbuff_push(nb,sizeof(*iph)); iph = (struct iphdr *) nb->data; /*FIXME dont work in litte endian machines*/ @@ -44,38 +44,64 @@ send_ip_packet (struct grub_net_interface *inf, struct grub_net_protstack *prots //grub_uint8_t hdrlen = sizeof (struct iphdr)/4; iph->verhdrlen = (4<<4 | 5); iph->service = 0; - iph->len = sizeof(*iph); - iph->ident = 0x2b5f; + iph->len = nb->tail - nb-> data;//sizeof(*iph); + iph->ident = ++id; iph->frags = 0; iph->ttl = 0xff; iph->protocol = 0x11; - //grub_memcpy(&(iph->src) ,inf->card->ila->addr,inf->card->ila->len); - iph->src = *((grub_uint32_t *)inf->card->ila->addr); - //grub_memcpy(&(iph->dest) ,inf->ila->addr,inf->ila->len); - iph->dest = *((grub_uint32_t *)inf->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->chksum = 0 ; - iph->chksum = ipchksum((void *)nb->head, sizeof(*iph)); + iph->chksum = ipchksum((void *)nb->data, sizeof(*iph)); - - return protstack->next->prot->send(inf,protstack->next,nb); + return trans_net_inf->inner_layer->link_prot->send(inf,trans_net_inf->inner_layer,nb); + //return protstack->next->prot->send(inf,protstack->next,nb); } -static struct grub_net_protocol grub_ipv4_protocol = +static grub_err_t +recv_ip_packet (struct grub_net_network_layer_interface *inf, + struct grub_net_transport_network_interface *trans_net_inf, struct grub_net_buff *nb ) +{ + + struct iphdr *iph; + while (1) + { + trans_net_inf->inner_layer->link_prot->recv(inf,trans_net_inf->inner_layer,nb); + iph = (struct iphdr *) nb->data; + if (iph->dest == 0x0908eaaa && iph->src == 0x0908ea92 && iph->protocol == 0x11) + { + grub_netbuff_pull(nb,sizeof(*iph)); + return 0; + } + } +/* grub_printf("ip.src 0x%x\n",iph->src); + grub_printf("ip.dst 0x%x\n",iph->dest); + grub_printf("ip.len 0x%x\n",iph->len); + grub_printf("ip.protocol 0x%x\n",iph->protocol); + */ + /* - get ip header + - verify if is the next layer is correct + -*/ + return 0; +} + +static struct grub_net_network_layer_protocol grub_ipv4_protocol = { .name = "ipv4", + .id = GRUB_NET_IPV4_ID, .send = send_ip_packet, - .recv = NULL + .recv = recv_ip_packet }; void ipv4_ini(void) { - grub_protocol_register (&grub_ipv4_protocol); + grub_net_network_layer_protocol_register (&grub_ipv4_protocol); } void ipv4_fini(void) { - grub_protocol_unregister (&grub_ipv4_protocol); + grub_net_network_layer_protocol_unregister (&grub_ipv4_protocol); } /* diff --git a/net/netbuff.c b/net/netbuff.c index 342260f43..136d55bc4 100644 --- a/net/netbuff.c +++ b/net/netbuff.c @@ -26,7 +26,7 @@ grub_err_t grub_netbuff_put (struct grub_net_buff *net_buff ,grub_size_t len) { net_buff->tail += len; if (net_buff->tail > net_buff->end) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return grub_error (GRUB_ERR_OUT_OF_RANGE, "put out of the packet range."); return GRUB_ERR_NONE; } @@ -34,15 +34,20 @@ grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff ,grub_size_t len) { net_buff->tail -= len; if (net_buff->tail < net_buff->head) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return grub_error (GRUB_ERR_OUT_OF_RANGE, "unput out of the packet range."); return GRUB_ERR_NONE; } grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len) { net_buff->data -= len; +/* grub_printf("push len =%d\n",len); + grub_printf("pack->head =%x\n",(unsigned int)net_buff->head); + grub_printf("pack->data =%x\n",(unsigned int)net_buff->data); + grub_printf("pack->tail =%x\n",(unsigned int)net_buff->tail); + grub_printf("pack->end =%x\n",(unsigned int)net_buff->end);*/ if (net_buff->data < net_buff->head) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return grub_error (GRUB_ERR_OUT_OF_RANGE, "push out of the packet range."); return GRUB_ERR_NONE; } @@ -50,7 +55,7 @@ grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buff ,grub_size_t len) { net_buff->data += len; if (net_buff->data > net_buff->end) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return grub_error (GRUB_ERR_OUT_OF_RANGE, "pull out of the packet range."); return GRUB_ERR_NONE; } @@ -59,14 +64,36 @@ grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff ,grub_size_t len net_buff->data += len; net_buff->tail += len; if ((net_buff->tail > net_buff->end) || (net_buff->data > net_buff->end)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return grub_error (GRUB_ERR_OUT_OF_RANGE, "reserve out of the packet range."); return GRUB_ERR_NONE; } -struct grub_net_buff * grub_netbuff_alloc ( grub_size_t len ) +struct grub_net_buff *grub_netbuff_alloc ( grub_size_t len ) { + struct grub_net_buff *nb; + void *data; + if (len < NETBUFFMINLEN) len = NETBUFFMINLEN; + len = ALIGN_UP (len,NETBUFF_ALIGN); - return (struct grub_net_buff *) grub_memalign (len,NETBUFF_ALIGN); + data = grub_memalign (len + sizeof (*nb),NETBUFF_ALIGN); + nb = (struct grub_net_buff *) ((int)data + len); + nb->head = nb->data = nb->tail = data; + nb->end = (char *) nb; + + return nb; +} + +grub_err_t grub_netbuff_free (struct grub_net_buff *net_buff) +{ + grub_free (net_buff); + return 0; + +} + +grub_err_t grub_netbuff_clear (struct grub_net_buff *net_buff) +{ + net_buff->data = net_buff->tail = net_buff->head; + return 0; } diff --git a/net/protocol.c b/net/protocol.c index a6117dc2c..05d4471d2 100644 --- a/net/protocol.c +++ b/net/protocol.c @@ -1,21 +1,37 @@ #include +#include +#include -static grub_net_protocol_t grub_net_protocols; - -void grub_protocol_register (grub_net_protocol_t prot) -{ - prot->next = grub_net_protocols; - grub_net_protocols = prot; +#define PROTOCOL_REGISTER_FUNCTIONS(layername) \ +struct grub_net_##layername##_layer_protocol *grub_net_##layername##_layer_protocols;\ +\ +void grub_net_##layername##_layer_protocol_register (struct grub_net_##layername##_layer_protocol *prot)\ +{\ + grub_list_push (GRUB_AS_LIST_P (&grub_net_##layername##_layer_protocols),\ + GRUB_AS_LIST (prot));\ +}\ +\ +void grub_net_##layername##_layer_protocol_unregister (struct grub_net_##layername##_layer_protocol *prot)\ +{\ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_##layername##_layer_protocols),\ + GRUB_AS_LIST (prot));\ +}\ +\ +struct grub_net_##layername##_layer_protocol \ + *grub_net_##layername##_layer_protocol_get (grub_net_protocol_id_t id)\ +{\ + struct grub_net_##layername##_layer_protocol *p;\ +\ + for (p = grub_net_##layername##_layer_protocols; p; p = p->next)\ + {\ + if (p->id == id)\ + return p;\ + }\ + \ + return NULL; \ } -void grub_protocol_unregister (grub_net_protocol_t prot) -{ - grub_net_protocol_t *p, q; - - for (p = &grub_net_protocols, q = *p; q; p = &(q->next), q = q->next) - if (q == prot) - { - *p = q->next; - break; - } -} +PROTOCOL_REGISTER_FUNCTIONS(application); +PROTOCOL_REGISTER_FUNCTIONS(transport); +PROTOCOL_REGISTER_FUNCTIONS(network); +PROTOCOL_REGISTER_FUNCTIONS(link); diff --git a/net/tftp.c b/net/tftp.c index 3f481fe58..1f04ef47e 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -4,42 +4,94 @@ #include #include #include -#include #include #include -#include #include +#include +#include +#include + +int block,rrq_count=0; +struct { + int block_size; + int size; +} tftp_file; + + +char *get_tok_val(char **tok, char **val, char **str_opt,char *end); +void process_option(char *tok, char *val); + +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; +} + +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 -send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protstack *protstack,struct grub_net_buff *nb) +tftp_open (struct grub_net_network_layer_interface *inf __attribute((unused)), + struct grub_net_protocol_stack *protstack,struct grub_net_buff *nb, char *filename) { - /*Start TFTP header*/ - struct tftphdr *tftph; char *rrq; int rrqlen; int hdrlen; - grub_err_t err; + struct udp_interf *udp_interf; + struct grub_net_application_transport_interface *app_interface = (struct grub_net_application_transport_interface *) protstack->interface; - if((err = grub_netbuff_push (nb,sizeof(*tftph))) != GRUB_ERR_NONE) - return err; + app_interface = (struct grub_net_application_transport_interface *) protstack->interface; + grub_netbuff_push (nb,sizeof (*tftph)); + udp_interf = (struct udp_interf *) app_interface->data; + udp_interf->src = TFTP_CLIENT_PORT + rrq_count++; + grub_printf("open tfpt udp_port = %d\n",udp_interf->src); + udp_interf->dst = TFTP_SERVER_PORT; tftph = (struct tftphdr *) nb->data; rrq = (char *) tftph->u.rrq; rrqlen = 0; tftph->opcode = TFTP_RRQ; - grub_strcpy (rrq,inf->path); - rrqlen += grub_strlen (inf->path) + 1; - rrq += grub_strlen (inf->path) + 1; + 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; @@ -59,39 +111,146 @@ send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protstack *protsta grub_netbuff_unput (nb,nb->tail - (nb->data+hdrlen)); - return protstack->next->prot->send(inf,protstack->next,nb); + app_interface->trans_prot->send (inf,protstack->interface,nb); + /*Receive OACK*/ + return app_interface->app_prot->recv(inf,protstack,nb); } -/* -int send_tftp_ack(int block, int port){ - - tftp_t pckt; - int pcktlen; - pckt.opcode = TFTP_ACK; - pckt.u.ack.block = block; - pcktlen = sizeof (pckt.opcode) + sizeof (pckt.u.ack.block); - - port = 4; - return 0;// send_udp_packet (&pckt,pcktlen,TFTP_CLIENT_PORT,port); -} - -*/ - -static struct grub_net_protocol grub_tftp_protocol = +static grub_err_t +tftp_receive (struct grub_net_network_layer_interface *inf __attribute((unused)), + struct grub_net_protocol_stack *protstack,struct grub_net_buff *nb) { - .name = "tftp", - .open = send_tftp_rr + struct tftphdr *tftph; + char *token,*value,*temp; + struct grub_net_application_transport_interface *app_interface = + (struct grub_net_application_transport_interface *) protstack->interface; + + app_interface->trans_prot->recv (inf,protstack->interface,nb); + + tftph = (struct tftphdr *) nb->data; + switch (tftph->opcode) + { + case TFTP_OACK: + /*process oack packet*/ + temp = (char *) tftph->u.oack.data; + while(get_tok_val(&token,&value,&temp,nb->tail)) + { + grub_printf("tok = <%s> val = <%s>\n",token,value); + process_option(token,value); + } + + //buff_clean + nb->data = nb->tail; + 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; + else + grub_netbuff_clear(nb); + break; + case TFTP_ERROR: + nb->data = nb->tail; + break; + } + return 0;// tftp_send_ack (inf,protstack,nb,tftph->u.data.block); + /*remove tftp header and return. + nb should now contain only the payload*/ +} + +static grub_err_t +tftp_send_ack (struct grub_net_network_layer_interface *inf __attribute((unused)), + struct grub_net_protocol_stack *protstack,struct grub_net_buff *nb) +{ + struct tftphdr *tftph; + struct grub_net_application_transport_interface *app_interface = (struct grub_net_application_transport_interface *) protstack->interface; + + 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; + + return app_interface->trans_prot->send (inf,protstack->interface,nb); +} + +static int tftp_file_size (struct grub_net_network_layer_interface* inf , + struct grub_net_protocol_stack *protocol_stack , struct grub_net_buff *nb ,char *filename ) +{ + + tftp_open (inf, protocol_stack,nb, filename); + return tftp_file.size; +} + +static grub_err_t +tftp_close (struct grub_net_network_layer_interface *inf __attribute((unused)), + struct grub_net_protocol_stack *protstack __attribute((unused)),struct grub_net_buff *nb __attribute((unused))) +{ + + return 0; +} + +static struct grub_net_application_transport_interface grub_net_tftp_app_trans_interf; +static struct grub_net_transport_network_interface grub_net_tftp_trans_net_interf; +static struct grub_net_network_link_interface grub_net_tftp_net_link_interf; +static struct grub_net_protocol_stack grub_net_tftp_stack = +{ + .name = "tftp", + .id = GRUB_NET_TFTP_ID, + .interface = (void *) &grub_net_tftp_app_trans_interf + }; +static struct grub_net_application_layer_protocol grub_tftp_protocol = +{ + .name = "tftp", + .id = GRUB_NET_TFTP_ID, + .open = tftp_open, + .recv = tftp_receive, + .send_ack = tftp_send_ack, + .get_file_size = tftp_file_size, + .close = tftp_close +}; + +static struct udp_interf tftp_udp_interf; + void tftp_ini(void) { - grub_protocol_register (&grub_tftp_protocol); + + ethernet_ini (); + ipv4_ini (); + udp_ini (); + grub_net_application_layer_protocol_register (&grub_tftp_protocol); + grub_net_stack_register (&grub_net_tftp_stack); + + grub_net_tftp_app_trans_interf.app_prot = &grub_tftp_protocol; + grub_net_tftp_app_trans_interf.trans_prot = grub_net_transport_layer_protocol_get (GRUB_NET_UDP_ID); + grub_net_tftp_app_trans_interf.inner_layer = &grub_net_tftp_trans_net_interf; + grub_net_tftp_app_trans_interf.data = &tftp_udp_interf; + + grub_net_tftp_trans_net_interf.trans_prot = grub_net_tftp_app_trans_interf.trans_prot; + grub_net_tftp_trans_net_interf.net_prot = grub_net_network_layer_protocol_get (GRUB_NET_IPV4_ID); + grub_net_tftp_trans_net_interf.inner_layer = &grub_net_tftp_net_link_interf; + + grub_net_tftp_net_link_interf.net_prot = grub_net_tftp_trans_net_interf.net_prot; + grub_net_tftp_net_link_interf.link_prot = grub_net_link_layer_protocol_get (GRUB_NET_ETHERNET_ID) ; + + } void tftp_fini(void) { - grub_protocol_unregister (&grub_tftp_protocol); + + + grub_net_application_layer_protocol_unregister (&grub_tftp_protocol); } /* int read_tftp_pckt (grub_uint16_t port, void *buffer, int &buff_len){ diff --git a/net/udp.c b/net/udp.c index 2a4a7690b..fb81aef93 100644 --- a/net/udp.c +++ b/net/udp.c @@ -4,41 +4,84 @@ #include #include #include -/*Assumes that there is allocated memory to the header before the buffer address. */ + static grub_err_t -send_udp_packet (struct grub_net_interface *inf, struct grub_net_protstack *protstack, struct grub_net_buff *nb) +send_udp_packet (struct grub_net_network_layer_interface *inf, + struct grub_net_application_transport_interface *app_trans_inf, struct grub_net_buff *nb) { struct udphdr *udph; - grub_err_t err; + struct udp_interf *udp_interf; - if((err = grub_netbuff_push (nb,sizeof(*udph)) ) != GRUB_ERR_NONE) - return err; + grub_netbuff_push (nb,sizeof(*udph)); udph = (struct udphdr *) nb->data; - udph->src = *((grub_uint16_t *) inf->card->tla->addr); - udph->dst = *((grub_uint16_t *) inf->tla->addr); + udp_interf = (struct udp_interf *) app_trans_inf->data; + udph->src = udp_interf->src; + udph->dst = udp_interf->dst; + /*no chksum*/ udph->chksum = 0; - udph->len = sizeof (sizeof (*udph)) + nb->end - nb->head; + udph->len = nb->tail - nb->data; - return protstack->next->prot->send(inf,protstack->next,nb); + return app_trans_inf->inner_layer->net_prot->send(inf,app_trans_inf->inner_layer,nb); } -static struct grub_net_protocol grub_udp_protocol = +static grub_err_t +receive_udp_packet (struct grub_net_network_layer_interface *inf, + struct grub_net_application_transport_interface *app_trans_inf, struct grub_net_buff *nb) +{ + + struct udphdr *udph; + struct udp_interf *udp_interf; + udp_interf = (struct udp_interf *) app_trans_inf->data; + + while(1) + { + app_trans_inf->inner_layer->net_prot->recv(inf,app_trans_inf->inner_layer,nb); + + udph = (struct udphdr *) nb->data; + // grub_printf("udph->dst %d\n",udph->dst); + // grub_printf("udp_interf->src %d\n",udp_interf->src); + if (udph->dst == udp_interf->src) + { + grub_netbuff_pull (nb,sizeof(*udph)); + + // udp_interf->src = udph->dst; + udp_interf->dst = udph->src; + + // grub_printf("udph->dst %d\n",udph->dst); + // grub_printf("udph->src %d\n",udph->src); + // grub_printf("udph->len %d\n",udph->len); + // grub_printf("udph->chksum %x\n",udph->chksum); + + /* - get udp header.. + - verify if is in the desired port + - if not. get another packet + - remove udp header*/ + + return 0; + } + } +} + + +static struct grub_net_transport_layer_protocol grub_udp_protocol = { .name = "udp", - .send = send_udp_packet + .id = GRUB_NET_UDP_ID, + .send = send_udp_packet, + .recv = receive_udp_packet }; void udp_ini(void) { - grub_protocol_register (&grub_udp_protocol); + grub_net_transport_layer_protocol_register (&grub_udp_protocol); } void udp_fini(void) { - grub_protocol_unregister (&grub_udp_protocol); + grub_net_transport_layer_protocol_unregister (&grub_udp_protocol); } /* From 8c599704a75bad68bd4d903fc1b111cba91bd354 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Mon, 21 Jun 2010 19:20:55 -0300 Subject: [PATCH 07/19] Network code specific for ieee1275 machines. Used to parse BOOTP packet from the server and use write/read on the network card. May be removed later. --- conf/powerpc-ieee1275.rmk | 3 +- include/grub/disk.h | 3 +- include/grub/ieee1275/ieee1275.h | 3 +- kern/ieee1275/init.c | 4 +- kern/ieee1275/openfw.c | 68 ++++++++++++++++-- kern/main.c | 8 +-- net/ieee1275/interface.c | 120 ++++++++++++++++++------------- 7 files changed, 144 insertions(+), 65 deletions(-) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 14d04f93e..ead6d4230 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -24,7 +24,8 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/generic/millisleep.c kern/time.c \ symlist.c kern/$(target_cpu)/cache.S net/ip.c net/tftp.c net/udp.c net/ethernet.c net/arp.c \ - net/ieee1275/interface.c net/interface.c net/protocol.c net/netbuff.c + net/ieee1275/interface.c net/interface.c net/protocol.c net/netbuff.c \ + fs/ieee1275/ofnet.c kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x200000,-Bstatic diff --git a/include/grub/disk.h b/include/grub/disk.h index e7f807e0e..1bdfb639b 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -42,7 +42,8 @@ enum grub_disk_dev_id GRUB_DISK_DEVICE_PXE_ID, GRUB_DISK_DEVICE_SCSI_ID, GRUB_DISK_DEVICE_FILE_ID, - GRUB_DISK_DEVICE_LUKS_ID + GRUB_DISK_DEVICE_LUKS_ID, + GRUB_DISK_DEVICE_OFNET_ID }; struct grub_disk; diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index b30909c68..f4c8b4edf 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -182,9 +182,8 @@ EXPORT_FUNC(grub_ieee1275_map) (grub_addr_t phys, grub_addr_t virt, char *EXPORT_FUNC(grub_ieee1275_encode_devname) (const char *path); char *EXPORT_FUNC(grub_ieee1275_get_filename) (const char *path); - int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook) (struct grub_ieee1275_devalias * alias)); - +char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path); #endif /* ! GRUB_IEEE1275_HEADER */ diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index b7e5c337e..1e108c920 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -32,6 +32,7 @@ #include #include #include +#include /* The minimal heap size we can live with. */ #define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024) @@ -223,13 +224,14 @@ grub_machine_init (void) grub_ssize_t actual; grub_ieee1275_init (); - + grub_console_init (); #ifdef __i386__ grub_get_extended_memory (); #endif grub_claim_heap (); grub_ofdisk_init (); + grub_ofnet_init(); /* Process commandline. */ if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args, diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index 5693f3be0..337fc4b7e 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -22,11 +22,13 @@ #include #include #include +#include enum grub_ieee1275_parse_type { GRUB_PARSE_FILENAME, GRUB_PARSE_PARTITION, + GRUB_PARSE_DEVICE }; /* Walk children of 'devpath', calling hook for each. */ @@ -366,12 +368,14 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) ret = grub_strndup (args, (grub_size_t)(comma - args)); } } - else + + else if (!grub_strcmp ("network", type)) + { + if (ptype == GRUB_PARSE_DEVICE) + ret = grub_strdup(device); + } + else { - /* XXX Handle net devices by configuring & registering a grub_net_dev - here, then return its name? - Example path: "net:,,,,,". */ grub_printf ("Unsupported type %s for device %s\n", type, device); } @@ -381,6 +385,12 @@ fail: return ret; } +char * +grub_ieee1275_get_aliasdevname (const char *path) +{ + return grub_ieee1275_parse_args (path, GRUB_PARSE_DEVICE); +} + char * grub_ieee1275_get_filename (const char *path) { @@ -432,3 +442,51 @@ grub_halt (void) grub_ieee1275_interpret ("power-off", 0); grub_ieee1275_interpret ("poweroff", 0); } + +static const struct +{ + char *name; + int offset; +} + +bootp_response_properties[] = +{ + { .name = "bootp-response", .offset = 0 }, + { .name = "dhcp-response", .offset = 0 }, + { .name = "bootpreply-packet", .offset = 0x2a }, +}; + +#define SIZE(X) ( sizeof (X) / sizeof(X[0])) + +grub_bootp_t +grub_getbootp( void ) +{ + grub_bootp_t packet = grub_malloc(sizeof *packet); + void *bootp_response = NULL; + grub_ssize_t size; + unsigned int i; + // grub_ieee1275_finddevice ("/chosen", &grub_ieee1275_chosen); + for ( i = 0; i < SIZE(bootp_response_properties); i++) + { + if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, + bootp_response_properties[i].name, &size)>=0) + break; + } + + if ( size <0 ) + { + grub_printf("Error to get bootp\n"); + return NULL; + } + + if (grub_ieee1275_get_property (grub_ieee1275_chosen, bootp_response_properties[i].name , bootp_response , + size, 0) < 0) + { + grub_printf("Error to get bootp\n"); + return NULL; + } + + packet = (void *) ((int)bootp_response + bootp_response_properties[i].offset); + return packet; +} + diff --git a/kern/main.c b/kern/main.c index 8b6c8a180..3320c4a68 100644 --- a/kern/main.c +++ b/kern/main.c @@ -95,14 +95,14 @@ grub_load_modules (void) grub_module_iterate (hook); } - +/* static void grub_load_config (void) { auto int hook (struct grub_module_header *); int hook (struct grub_module_header *header) { - /* Not an embedded config, skip. */ + / Not an embedded config, skip. / if (header->type != OBJ_TYPE_CONFIG) return 0; @@ -113,7 +113,7 @@ grub_load_config (void) grub_module_iterate (hook); } - +*/ /* Write hook for the environment variables of root. Remove surrounding parentheses, if any. */ static char * @@ -192,7 +192,7 @@ grub_main (void) grub_register_core_commands (); - grub_load_config (); + //grub_load_config (); grub_load_normal_mode (); grub_rescue_run (); } diff --git a/net/ieee1275/interface.c b/net/ieee1275/interface.c index 5a246ffa5..fbd887ad2 100644 --- a/net/ieee1275/interface.c +++ b/net/ieee1275/interface.c @@ -1,55 +1,21 @@ #include +#include #include - -grub_uint32_t get_server_ip (void) -{ - return bootp_pckt->siaddr; -} - -grub_uint32_t get_client_ip (void) -{ - return bootp_pckt->yiaddr; -} - -grub_uint8_t* get_server_mac (void) -{ - grub_uint8_t *mac; - - mac = grub_malloc (6 * sizeof(grub_uint8_t)); - mac[0] = 0x00 ; - mac[1] = 0x11 ; - mac[2] = 0x25 ; - mac[3] = 0xca ; - mac[4] = 0x1f ; - mac[5] = 0x01 ; - - return mac; - -} - -grub_uint8_t* get_client_mac (void) -{ - grub_uint8_t *mac; - - mac = grub_malloc (6 * sizeof (grub_uint8_t)); - mac[0] = 0x0a ; - mac[1] = 0x11 ; - mac[2] = 0xbd ; - mac[3] = 0xe3 ; - mac[4] = 0xe3 ; - mac[5] = 0x04 ; - - return mac; -} +#include +#include +#include +#include +#include static grub_ieee1275_ihandle_t handle; int card_open (void) { grub_ieee1275_open (grub_net->dev , &handle); - return 1;//error + return 0; } + int card_close (void) { @@ -59,22 +25,74 @@ int card_close (void) } -int send_card_buffer (void *buffer,int buff_len) +int send_card_buffer (struct grub_net_buff *pack) { - int actual; - - grub_ieee1275_write (handle,buffer,buff_len,&actual); + int actual; + //grub_printf("packet size transmited: %d\n",pack->tail - pack->data); + grub_ieee1275_write (handle,pack->data,pack->tail - pack->data,&actual); +// grub_printf("actual transmited %d\n",actual); return actual; } -int get_card_buffer (void *buffer,int buff_len) +int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) { - int actual; + int actual; + char *datap; + struct iphdr *iph; + struct etherhdr *eth; + struct arphdr *arph; + pack->data = pack->tail = pack->head; + datap = pack->data; + do + { + grub_ieee1275_read (handle,datap,sizeof (*eth),&actual); + // if (actual <= 0) + // grub_millisleep(10); - grub_ieee1275_read (handle,buffer,buff_len,&actual); - - return actual; + }while (actual <= 0); + eth = (struct etherhdr *) datap; + datap += sizeof(*eth); + + // grub_printf("ethernet eth->dst %x:%x:%x:%x:%x:%x\n",eth->dst[0], + // eth->dst[1],eth->dst[2],eth->dst[3],eth->dst[4],eth->dst[5]); + // grub_printf("ethernet eth->src %x:%x:%x:%x:%x:%x\n",eth->src[0],eth->src[1], + // eth->src[2],eth->src[3],eth->src[4],eth->src[5]); +// grub_printf ("eth.type 0x%x\n",eth->type); + + switch (eth->type) + { + case 0x806: + + grub_ieee1275_read (handle,datap,sizeof (*arph),&actual); + arph = (struct arphdr *) datap; + + grub_netbuff_put (pack,sizeof (*eth) + sizeof (*arph)); + break; + case 0x800: + grub_ieee1275_read (handle,datap,sizeof (*iph),&actual); + iph = (struct iphdr *) datap; + datap += sizeof(*iph); + + // grub_printf("ip.src 0x%x\n",iph->src); + // grub_printf("ip.dst 0x%x\n",iph->dest); + // grub_printf("ip.len 0x%x\n",iph->len); + // grub_printf("ip.protocol 0x%x\n",iph->protocol); + + grub_ieee1275_read (handle,datap,iph->len - sizeof (*iph),&actual); + + + grub_netbuff_put (pack,sizeof (*eth) + iph->len); + break; + case 0x86DD: + grub_printf("Ipv6 not yet implemented.\n"); + break; + default: + grub_printf("Unknow packet %x\n",eth->type); + break; + } +// grub_printf("packsize %d\n",pack->tail - pack->data); + return 0;// sizeof (eth) + iph.len; } From bf6d9eeb531e19d88c1705688468b89ea44c9031 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Wed, 23 Jun 2010 14:47:55 -0300 Subject: [PATCH 08/19] Abort transference when getting file size. --- net/tftp.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/net/tftp.c b/net/tftp.c index 1f04ef47e..8e89ed1f4 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -71,7 +71,6 @@ tftp_open (struct grub_net_network_layer_interface *inf __attribute((unused)), udp_interf = (struct udp_interf *) app_interface->data; udp_interf->src = TFTP_CLIENT_PORT + rrq_count++; - grub_printf("open tfpt udp_port = %d\n",udp_interf->src); udp_interf->dst = TFTP_SERVER_PORT; tftph = (struct tftphdr *) nb->data; @@ -135,16 +134,15 @@ tftp_receive (struct grub_net_network_layer_interface *inf __attribute((unused)) temp = (char *) tftph->u.oack.data; while(get_tok_val(&token,&value,&temp,nb->tail)) { - grub_printf("tok = <%s> val = <%s>\n",token,value); process_option(token,value); } //buff_clean nb->data = nb->tail; - 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"); + // 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: @@ -182,11 +180,39 @@ tftp_send_ack (struct grub_net_network_layer_interface *inf __attribute((unused) return app_interface->trans_prot->send (inf,protstack->interface,nb); } +static grub_err_t +tftp_send_err (struct grub_net_network_layer_interface *inf __attribute((unused)), + struct grub_net_protocol_stack *protstack,struct grub_net_buff *nb, char *errmsg, int errcode) +{ + + struct tftphdr *tftph; + struct grub_net_application_transport_interface *app_interface + = (struct grub_net_application_transport_interface *) protstack->interface; + int msglen = 0; + int hdrlen = 0; + nb->data = nb->tail = nb->end; + + grub_netbuff_push (nb,sizeof (*tftph)); + + tftph = (struct tftphdr *) nb->data; + tftph->opcode = TFTP_ERROR; + tftph->u.err.errcode = errcode; + + grub_strcpy ((char *)tftph->u.err.errmsg,errmsg); + msglen += grub_strlen (errmsg) + 1; + hdrlen = sizeof (tftph->opcode) + sizeof (tftph->u.err.errcode) + msglen; + grub_netbuff_unput (nb,nb->tail - (nb->data + hdrlen)); + + return app_interface->trans_prot->send (inf,protstack->interface,nb); +} + static int tftp_file_size (struct grub_net_network_layer_interface* inf , struct grub_net_protocol_stack *protocol_stack , struct grub_net_buff *nb ,char *filename ) { tftp_open (inf, protocol_stack,nb, filename); + tftp_send_err (inf, protocol_stack,nb,"Abort transference.",0); + return tftp_file.size; } From 1edb7287ff681aa6889e397ab4c891ea93246f2f Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Wed, 23 Jun 2010 14:49:46 -0300 Subject: [PATCH 09/19] Parse ipv6 header on incoming packets. --- conf/powerpc-ieee1275.rmk | 1 - fs/ieee1275/ofnet.c | 31 +++++++++++++++---------------- include/grub/net/ip.h | 12 ++++++++++++ net/ieee1275/interface.c | 14 ++++++++++++-- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index ead6d4230..f0faef489 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -3,7 +3,6 @@ # Images. -<<<<<<< TREE kernel_img_HEADERS += ieee1275/ieee1275.h \ command.h i18n.h env_private.h net/ip.h net/udp.h net/ethernet.h net/arp.h net/tftp.h\ net/ieee1275/interface.h net/type_net.h net.h net/interface.h net/protocol.h net/netbuff.h diff --git a/fs/ieee1275/ofnet.c b/fs/ieee1275/ofnet.c index 196aadcf2..3bbb5c227 100644 --- a/fs/ieee1275/ofnet.c +++ b/fs/ieee1275/ofnet.c @@ -145,7 +145,7 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) return 1; } - grub_printf("name = %s\n",name); + // grub_printf("name = %s\n",name); struct grub_net_protocol_stack *stack; struct grub_net_buff *pack; @@ -164,38 +164,37 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) for (found_addr = 0x800000; found_addr < + 2000 * 0x100000; found_addr += 0x100000) { - grub_printf("traing to claim %d bytes at 0x%x\n",file_size,found_addr); +// grub_printf("trying to claim %d bytes at 0x%x\n",file_size,found_addr); if (grub_claimmap (found_addr , file_size) != -1) break; } - grub_printf("Claimed %d bytes at 0x%x\n",file_size,found_addr); +// grub_printf("Claimed %d bytes at 0x%x\n",file_size,found_addr); file->data = (void *) found_addr; - grub_printf("file->data = 0x%x\n",(int)file->data); - grub_printf("file_size = %d\n",file_size); - grub_printf("OPEN\n"); +// grub_printf("file->data = 0x%x\n",(int)file->data); +// grub_printf("file_size = %d\n",file_size); +// grub_printf("OPEN\n"); grub_netbuff_clear(pack); grub_netbuff_reserve (pack,80*1024); app_interface->app_prot->open (NULL,stack,pack,(char *) name); do { //if (app_interface->app_prot->recv (NULL,stack,pack) == GRUB_ERR_NONE) - grub_printf("RECEIVE PACKET\n"); +// grub_printf("RECEIVE PACKET\n"); grub_netbuff_clear(pack); grub_netbuff_reserve (pack,80*1024); app_interface->app_prot->recv (NULL,stack,pack); if (grub_errno != GRUB_ERR_NONE) return grub_errno; - grub_printf("RECEIVED PACKET\n"); +// grub_printf("RECEIVED PACKET\n"); // { - grub_printf("payload_size= %d\n",pack->tail - pack->data); - grub_printf("amount= %d\n",amount); - grub_printf("file_size= %d\n",file_size); +// grub_printf("payload_size= %d\n",pack->tail - pack->data); +// grub_printf("amount= %d\n",amount); +// grub_printf("file_size= %d\n",file_size); datap = (char *)file->data + amount; amount += (pack->tail - pack->data); - grub_printf("datap = 0x%x\n",(int)datap ); - // amount += pack->tail - pack->data; +// grub_printf("datap = 0x%x\n",(int)datap ); grub_memcpy(datap, pack->data, pack->tail - pack->data); - grub_printf("SEND ACK\n"); +// grub_printf("SEND ACK\n"); grub_netbuff_clear(pack); grub_netbuff_reserve (pack,80*1024); @@ -204,12 +203,12 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) if (grub_errno != GRUB_ERR_NONE) return grub_errno; - grub_printf("SENT ACK\n"); +// grub_printf("SENT ACK\n"); //} // file->data = grub_realloc(file->data,amount); }while (amount < file_size); - grub_printf("transfer complete\n"); +// grub_printf("transfer complete\n"); file->size = file_size; // grub_netbuff_free(pack); diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h index e1f45dcfa..cb119ac6f 100644 --- a/include/grub/net/ip.h +++ b/include/grub/net/ip.h @@ -16,6 +16,18 @@ struct iphdr { grub_uint32_t dest; } __attribute__ ((packed)) ; +struct ip6hdr +{ + grub_uint8_t version:4, + priority:4; + grub_uint8_t flow_lbl[3]; + grub_uint16_t payload_len; + grub_uint8_t nexthdr; + grub_uint8_t hop_limit; + grub_uint8_t saddr[16]; + grub_uint8_t daddr[16]; +} __attribute__ ((packed)); + #define IP_UDP 17 /* UDP protocol */ #define IP_BROADCAST 0xFFFFFFFF diff --git a/net/ieee1275/interface.c b/net/ieee1275/interface.c index fbd887ad2..1100ee85d 100644 --- a/net/ieee1275/interface.c +++ b/net/ieee1275/interface.c @@ -44,6 +44,7 @@ int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) struct iphdr *iph; struct etherhdr *eth; struct arphdr *arph; + struct ip6hdr *ip6h; pack->data = pack->tail = pack->head; datap = pack->data; do @@ -86,11 +87,20 @@ int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) grub_netbuff_put (pack,sizeof (*eth) + iph->len); break; + case 0x86DD: - grub_printf("Ipv6 not yet implemented.\n"); + grub_printf("!!!!!!!!!!!!!!!!!IPV6 packet received!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + grub_ieee1275_read (handle,datap,sizeof (*ip6h),&actual); + ip6h = (struct ip6hdr *) datap; + grub_printf("ip6hdr->payload_len = %x\n",ip6h->payload_len); + grub_printf("ip6hdr->nexthdr = %x\n",ip6h->nexthdr); + + datap += sizeof(*ip6h); + grub_ieee1275_read (handle,datap,ip6h->payload_len - sizeof (*ip6h),&actual); break; + default: - grub_printf("Unknow packet %x\n",eth->type); + grub_printf("Unknow packet %x\n",eth->type); break; } // grub_printf("packsize %d\n",pack->tail - pack->data); From 3ec6213b179b3b82611e4caa35dae37a16fd2045 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Tue, 29 Jun 2010 06:50:15 -0300 Subject: [PATCH 10/19] Clean Debug messages --- fs/ieee1275/ofnet.c | 75 ++++++++++--------------------------- include/grub/net/type_net.h | 1 + net/ethernet.c | 6 +++ net/ieee1275/interface.c | 16 -------- net/ip.c | 7 ++++ net/netbuff.c | 7 +--- net/tftp.c | 6 ++- net/udp.c | 8 +++- 8 files changed, 46 insertions(+), 80 deletions(-) diff --git a/fs/ieee1275/ofnet.c b/fs/ieee1275/ofnet.c index 3bbb5c227..a9d16e7e0 100644 --- a/fs/ieee1275/ofnet.c +++ b/fs/ieee1275/ofnet.c @@ -56,7 +56,7 @@ grub_ofnet_open (const char *name, grub_disk_t disk) { - if (grub_strcmp (name, "network")) + if (grub_strcmp (name, "net")) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a net disk"); disk->total_sectors = U64MAXSIZE; @@ -109,7 +109,7 @@ grub_ofnetfs_dir (grub_device_t device , int (*hook) (const char *filename, const struct grub_dirhook_info *info) __attribute((unused))) { - if(grub_strcmp (device->disk->name,"network")) + if(grub_strcmp (device->disk->name,"net")) { return grub_error (GRUB_ERR_BAD_FS, "not an net filesystem"); } @@ -140,7 +140,7 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) //grub_addr_t addr; if (name[0] == '/') name++; - if(grub_strcmp (file->device->disk->name,"network")) + if(grub_strcmp (file->device->disk->name,"net")) { return 1; @@ -161,80 +161,43 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) grub_netbuff_reserve (pack,80*1024); file_size = app_interface->app_prot->get_file_size(NULL,stack,pack,(char *) name); - for (found_addr = 0x800000; found_addr < + 2000 * 0x100000; found_addr += 0x100000) { -// grub_printf("trying to claim %d bytes at 0x%x\n",file_size,found_addr); if (grub_claimmap (found_addr , file_size) != -1) break; } -// grub_printf("Claimed %d bytes at 0x%x\n",file_size,found_addr); file->data = (void *) found_addr; -// grub_printf("file->data = 0x%x\n",(int)file->data); -// grub_printf("file_size = %d\n",file_size); -// grub_printf("OPEN\n"); + grub_netbuff_clear(pack); grub_netbuff_reserve (pack,80*1024); app_interface->app_prot->open (NULL,stack,pack,(char *) name); - do { - //if (app_interface->app_prot->recv (NULL,stack,pack) == GRUB_ERR_NONE) -// grub_printf("RECEIVE PACKET\n"); + do + { grub_netbuff_clear(pack); grub_netbuff_reserve (pack,80*1024); app_interface->app_prot->recv (NULL,stack,pack); if (grub_errno != GRUB_ERR_NONE) - return grub_errno; -// grub_printf("RECEIVED PACKET\n"); - // { -// grub_printf("payload_size= %d\n",pack->tail - pack->data); -// grub_printf("amount= %d\n",amount); -// grub_printf("file_size= %d\n",file_size); - datap = (char *)file->data + amount; - amount += (pack->tail - pack->data); -// grub_printf("datap = 0x%x\n",(int)datap ); - grub_memcpy(datap, pack->data, pack->tail - pack->data); -// grub_printf("SEND ACK\n"); - + goto error; + if ((pack->tail - pack->data)) + { + // file->data = grub_realloc(file->data,amount + pack->tail - pack->data); + datap = (char *)file->data + amount; + amount += (pack->tail - pack->data); + grub_memcpy(datap , pack->data, pack->tail - pack->data); + } grub_netbuff_clear(pack); grub_netbuff_reserve (pack,80*1024); app_interface->app_prot->send_ack (NULL,stack,pack); if (grub_errno != GRUB_ERR_NONE) - return grub_errno; - -// grub_printf("SENT ACK\n"); - //} - // file->data = grub_realloc(file->data,amount); + goto error; }while (amount < file_size); -// grub_printf("transfer complete\n"); - file->size = file_size; - -// grub_netbuff_free(pack); - /*Start ARP header*/ - // arp.arpr.hwtype = 0x1; /* hardware type (must be ARPHRD_ETHER) */ - // arp.arpr.protocol = 0x0800; /* protocol type (must be ETH_P_IP) */ - // arp.arpr.hwlen = 0x6; /* hardware address length (must be 6) */ - // arp.arpr.protolen = 0x4; /* protocol address length (must be 4) */ - // arp.arpr.opcode = 0x1; /* ARP opcode */ - - - /*arp.arpr.shwaddr[0] =0x0a ; - arp.arpr.shwaddr[1] =0x11 ; - arp.arpr.shwaddr[2] =0xbd ; - arp.arpr.shwaddr[3] =0xe3 ; - arp.arpr.shwaddr[4] =0xe3 ; - arp.arpr.shwaddr[5] =0x04 ; - arp.arpr.sipaddr = dhcp_pckt -> yiaddr; */ /* sender's IP address */ - /*arp.arpr.thwaddr[0] =0; - arp.arpr.thwaddr[1] =0; - arp.arpr.thwaddr[2] =0; - arp.arpr.thwaddr[3] =0; - arp.arpr.thwaddr[4] =0; - arp.arpr.thwaddr[5] =0; - arp.arpr.tipaddr = dhcp_pckt -> siaddr; */ /* target's IP address */ - /*END ARP header */ + file->size = file_size; + + error: + grub_netbuff_free(pack); return grub_errno; } diff --git a/include/grub/net/type_net.h b/include/grub/net/type_net.h index 276c50bf9..a1717d6a7 100644 --- a/include/grub/net/type_net.h +++ b/include/grub/net/type_net.h @@ -5,6 +5,7 @@ #define UDP_PCKT 0x11 #define IP_PCKT 0x0800 +#define TIMEOUT_TIME_MS 3*1000 typedef enum { GRUB_NET_TFTP_ID, diff --git a/net/ethernet.c b/net/ethernet.c index a4bdbff5b..2bcb8107d 100644 --- a/net/ethernet.c +++ b/net/ethernet.c @@ -7,6 +7,7 @@ #include #include #include +#include static grub_err_t send_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ ((unused)), @@ -42,6 +43,8 @@ recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb) { struct etherhdr *eth; + grub_uint64_t start_time, current_time; + start_time = grub_get_time_ms(); while (1) { get_card_packet (nb); @@ -59,6 +62,9 @@ recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ grub_netbuff_pull(nb,sizeof(*eth)); return 0; } + current_time = grub_get_time_ms(); + if (current_time - start_time > TIMEOUT_TIME_MS) + return grub_error (GRUB_ERR_TIMEOUT, "Time out."); } /* - get ethernet header - verify if the next layer is the desired one. diff --git a/net/ieee1275/interface.c b/net/ieee1275/interface.c index 1100ee85d..be9810fb2 100644 --- a/net/ieee1275/interface.c +++ b/net/ieee1275/interface.c @@ -29,9 +29,7 @@ int send_card_buffer (struct grub_net_buff *pack) { int actual; - //grub_printf("packet size transmited: %d\n",pack->tail - pack->data); grub_ieee1275_write (handle,pack->data,pack->tail - pack->data,&actual); -// grub_printf("actual transmited %d\n",actual); return actual; } @@ -50,18 +48,11 @@ int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) do { grub_ieee1275_read (handle,datap,sizeof (*eth),&actual); - // if (actual <= 0) - // grub_millisleep(10); }while (actual <= 0); eth = (struct etherhdr *) datap; datap += sizeof(*eth); - // grub_printf("ethernet eth->dst %x:%x:%x:%x:%x:%x\n",eth->dst[0], - // eth->dst[1],eth->dst[2],eth->dst[3],eth->dst[4],eth->dst[5]); - // grub_printf("ethernet eth->src %x:%x:%x:%x:%x:%x\n",eth->src[0],eth->src[1], - // eth->src[2],eth->src[3],eth->src[4],eth->src[5]); -// grub_printf ("eth.type 0x%x\n",eth->type); switch (eth->type) { @@ -77,10 +68,6 @@ int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) iph = (struct iphdr *) datap; datap += sizeof(*iph); - // grub_printf("ip.src 0x%x\n",iph->src); - // grub_printf("ip.dst 0x%x\n",iph->dest); - // grub_printf("ip.len 0x%x\n",iph->len); - // grub_printf("ip.protocol 0x%x\n",iph->protocol); grub_ieee1275_read (handle,datap,iph->len - sizeof (*iph),&actual); @@ -89,11 +76,8 @@ int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) break; case 0x86DD: - grub_printf("!!!!!!!!!!!!!!!!!IPV6 packet received!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); grub_ieee1275_read (handle,datap,sizeof (*ip6h),&actual); ip6h = (struct ip6hdr *) datap; - grub_printf("ip6hdr->payload_len = %x\n",ip6h->payload_len); - grub_printf("ip6hdr->nexthdr = %x\n",ip6h->nexthdr); datap += sizeof(*ip6h); grub_ieee1275_read (handle,datap,ip6h->payload_len - sizeof (*ip6h),&actual); diff --git a/net/ip.c b/net/ip.c index 5eaa74f90..044cfde6b 100644 --- a/net/ip.c +++ b/net/ip.c @@ -7,6 +7,7 @@ #include #include #include +#include struct grub_net_protocol *grub_ipv4_prot; @@ -65,6 +66,8 @@ recv_ip_packet (struct grub_net_network_layer_interface *inf, { struct iphdr *iph; + grub_uint64_t start_time, current_time; + start_time = grub_get_time_ms(); while (1) { trans_net_inf->inner_layer->link_prot->recv(inf,trans_net_inf->inner_layer,nb); @@ -74,6 +77,10 @@ recv_ip_packet (struct grub_net_network_layer_interface *inf, grub_netbuff_pull(nb,sizeof(*iph)); return 0; } + + current_time = grub_get_time_ms(); + if (current_time - start_time > TIMEOUT_TIME_MS) + return grub_error (GRUB_ERR_TIMEOUT, "Time out."); } /* grub_printf("ip.src 0x%x\n",iph->src); grub_printf("ip.dst 0x%x\n",iph->dest); diff --git a/net/netbuff.c b/net/netbuff.c index 136d55bc4..ce52233b6 100644 --- a/net/netbuff.c +++ b/net/netbuff.c @@ -41,11 +41,6 @@ grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff ,grub_size_t len) grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len) { net_buff->data -= len; -/* grub_printf("push len =%d\n",len); - grub_printf("pack->head =%x\n",(unsigned int)net_buff->head); - grub_printf("pack->data =%x\n",(unsigned int)net_buff->data); - grub_printf("pack->tail =%x\n",(unsigned int)net_buff->tail); - grub_printf("pack->end =%x\n",(unsigned int)net_buff->end);*/ if (net_buff->data < net_buff->head) return grub_error (GRUB_ERR_OUT_OF_RANGE, "push out of the packet range."); return GRUB_ERR_NONE; @@ -87,7 +82,7 @@ struct grub_net_buff *grub_netbuff_alloc ( grub_size_t len ) grub_err_t grub_netbuff_free (struct grub_net_buff *net_buff) { - grub_free (net_buff); + grub_free (net_buff->head); return 0; } diff --git a/net/tftp.c b/net/tftp.c index 8e89ed1f4..dff0f134c 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -70,7 +70,7 @@ tftp_open (struct grub_net_network_layer_interface *inf __attribute((unused)), grub_netbuff_push (nb,sizeof (*tftph)); udp_interf = (struct udp_interf *) app_interface->data; - udp_interf->src = TFTP_CLIENT_PORT + rrq_count++; + udp_interf->src = TFTP_CLIENT_PORT;// + rrq_count++; udp_interf->dst = TFTP_SERVER_PORT; tftph = (struct tftphdr *) nb->data; @@ -112,6 +112,8 @@ tftp_open (struct grub_net_network_layer_interface *inf __attribute((unused)), app_interface->trans_prot->send (inf,protstack->interface,nb); /*Receive OACK*/ + grub_netbuff_clear (nb); + grub_netbuff_reserve (nb,80*1024); return app_interface->app_prot->recv(inf,protstack,nb); } @@ -211,6 +213,8 @@ static int tftp_file_size (struct grub_net_network_layer_interface* inf , { tftp_open (inf, protocol_stack,nb, filename); + grub_netbuff_clear (nb); + grub_netbuff_reserve (nb,80*1024); tftp_send_err (inf, protocol_stack,nb,"Abort transference.",0); return tftp_file.size; diff --git a/net/udp.c b/net/udp.c index fb81aef93..0321fd58a 100644 --- a/net/udp.c +++ b/net/udp.c @@ -4,6 +4,7 @@ #include #include #include +#include static grub_err_t send_udp_packet (struct grub_net_network_layer_interface *inf, @@ -35,7 +36,8 @@ receive_udp_packet (struct grub_net_network_layer_interface *inf, struct udphdr *udph; struct udp_interf *udp_interf; udp_interf = (struct udp_interf *) app_trans_inf->data; - + grub_uint64_t start_time, current_time; + start_time = grub_get_time_ms(); while(1) { app_trans_inf->inner_layer->net_prot->recv(inf,app_trans_inf->inner_layer,nb); @@ -62,6 +64,10 @@ receive_udp_packet (struct grub_net_network_layer_interface *inf, return 0; } + current_time = grub_get_time_ms(); + if (current_time - start_time > TIMEOUT_TIME_MS) + return grub_error (GRUB_ERR_TIMEOUT, "Time out."); + } } From f8795693f1c3caa557b8658ac3d8661b1f84b739 Mon Sep 17 00:00:00 2001 From: Paulo de Rezende Pinatti Date: Tue, 13 Jul 2010 11:22:35 -0300 Subject: [PATCH 11/19] Added support to netdisk specified in the form (net,protocol,server_ip,username,password) an to list its information with command ls. * fs/ieee1275/ofnet.c (grub_ofnet_open): parse parameters to determine netdisk data * fs/ieee1275/ofnet.c (grub_ofnet_close): dealloc netdisk data * include/grub/disk.h: added struct grub_netdisk_data * include/grub/ieee1275/ofnet.h: added newline * kern/disk.c (grub_disk_open): ignore partition check for netdisk * normal/misc.c (grub_normal_print_device_info): added support to list netdisk information --- fs/ieee1275/ofnet.c | 159 ++++++++++++++++++++++++++++++++-- include/grub/disk.h | 17 ++++ include/grub/ieee1275/ofnet.h | 1 + kern/disk.c | 4 +- normal/misc.c | 39 +++++++++ 5 files changed, 213 insertions(+), 7 deletions(-) diff --git a/fs/ieee1275/ofnet.c b/fs/ieee1275/ofnet.c index a9d16e7e0..9010317ba 100644 --- a/fs/ieee1275/ofnet.c +++ b/fs/ieee1275/ofnet.c @@ -42,6 +42,85 @@ //static grub_ieee1275_ihandle_t handle = 0; +static const char * +find_sep (const char *name) +{ + const char *p = name; + char c = *p; + + if (c == '\0') + return NULL; + + do + { + if (c == '\\' && *p == ',') + p++; + else if (c == ',') + return p - 1; + } while ((c = *p++) != '\0'); + return p - 1; +} + +static grub_err_t +retrieve_field(const char *src, char **field, const char **rest) +{ + const char *p; + grub_size_t len; + + p = find_sep(src); + if (! p) + { + *field = NULL; + *rest = src; + return 0; + } + + len = p - src; + *field = grub_malloc (len + 1); + if (! *field) + { + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory"); + } + + grub_memcpy (*field, src, len); + (*field)[len] = '\0'; + + if (*p == '\0') + *rest = p; + else + *rest = p + 1; + return 0; +} + +static grub_err_t +parse_ip (const char *val, grub_uint32_t *ip, const char **rest) +{ + grub_uint32_t newip = 0; + unsigned long t; + int i; + const char *ptr = val; + + for (i = 0; i < 4; i++) + { + t = grub_strtoul (ptr, (char **) &ptr, 0); + if (grub_errno) + return grub_errno; + if (t & ~0xff) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); + newip >>= 8; + newip |= (t << 24); + if (i != 3 && *ptr != '.') + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); + ptr++; + } + ptr = ptr - 1; + if ( *ptr != '\0' && *ptr != ',') + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); + *ip = newip; + if (rest) + *rest = ptr; + return 0; +} static int grub_ofnet_iterate (int (*hook) (const char *name)) @@ -54,23 +133,93 @@ grub_ofnet_iterate (int (*hook) (const char *name)) static grub_err_t grub_ofnet_open (const char *name, grub_disk_t disk) { - + grub_err_t err; + const char *p1, *p2; + char *user = NULL, *pwd = NULL; + grub_netdisk_data_t data; + grub_netdisk_protocol_t proto; + grub_uint32_t server_ip = 0; if (grub_strcmp (name, "net")) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a net disk"); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a net disk"); - disk->total_sectors = U64MAXSIZE; + p1 = find_sep(disk->name); + if (! p1 || *p1 == '\0') + return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments missing"); + p1++; + + // parse protocol + p2 = find_sep(p1); + if (! p2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no protocol specified"); + if ((p2 - p1 == 4) && (! grub_strncasecmp(p1, "tftp", p2 - p1))) + proto = GRUB_NETDISK_PROTOCOL_TFTP; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid protocol specified"); + + // parse server ip + if ( *p2 == '\0') + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no server ip specified"); + p1 = p2 + 1; + err = parse_ip(p1, &server_ip, &p2); + if (err) + return err; + + // parse username (optional) + if ( *p2 == ',') + p2++; + err = retrieve_field(p2, &user, &p1); + if (err) + return err; + if (user) + { + // parse password (optional) + err = retrieve_field(p1, &pwd, &p2); + if (err) + { + grub_free(user); + return err; + } + } + + if (! disk->data) + { + data = grub_malloc (sizeof(*data)); + disk->data = data; + } + else + { + data = disk->data; + if (data->username) + grub_free(data->username); + if (data->password) + grub_free(data->password); + } + data->protocol = proto; + data->server_ip = server_ip; + data->username = user; + data->password = pwd; + + disk->total_sectors = 0; disk->id = (unsigned long) "net"; disk->has_partitions = 0; - disk->data = 0; return GRUB_ERR_NONE; } static void -grub_ofnet_close (grub_disk_t disk __attribute((unused))) +grub_ofnet_close (grub_disk_t disk) { + grub_netdisk_data_t data = disk->data; + if (data) + { + if (data->username) + grub_free(data->username); + if (data->password) + grub_free(data->password); + grub_free(data); + } } static grub_err_t diff --git a/include/grub/disk.h b/include/grub/disk.h index 1bdfb639b..dc8bc5018 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -119,6 +119,23 @@ struct grub_disk }; typedef struct grub_disk *grub_disk_t; +/* Net Disk */ +enum grub_netdisk_protocol +{ + GRUB_NETDISK_PROTOCOL_TFTP +}; +typedef enum grub_netdisk_protocol grub_netdisk_protocol_t; + +struct grub_netdisk_data +{ + grub_netdisk_protocol_t protocol; + grub_uint32_t server_ip; + grub_uint32_t port; + char *username; + char *password; +}; +typedef struct grub_netdisk_data *grub_netdisk_data_t; + #ifdef GRUB_UTIL struct grub_disk_memberlist { diff --git a/include/grub/ieee1275/ofnet.h b/include/grub/ieee1275/ofnet.h index 7daadf61d..a26c22235 100644 --- a/include/grub/ieee1275/ofnet.h +++ b/include/grub/ieee1275/ofnet.h @@ -25,6 +25,7 @@ extern void grub_ofnet_init(void); extern void grub_ofnet_fini(void); + /* struct grub_net; diff --git a/kern/disk.c b/kern/disk.c index ccd5f200f..051e59aca 100644 --- a/kern/disk.c +++ b/kern/disk.c @@ -281,7 +281,7 @@ grub_disk_open (const char *name) goto fail; } - if (p && ! disk->has_partitions) + if (p && ! disk->has_partitions && grub_strcmp (raw, "net")) { grub_error (GRUB_ERR_BAD_DEVICE, "no partition on this disk"); goto fail; @@ -289,7 +289,7 @@ grub_disk_open (const char *name) disk->dev = dev; - if (p) + if (p && grub_strcmp (raw, "net")) { disk->partition = grub_partition_probe (disk, p + 1); if (! disk->partition) diff --git a/normal/misc.c b/normal/misc.c index 17ba372ce..d53fe711c 100644 --- a/normal/misc.c +++ b/normal/misc.c @@ -32,8 +32,47 @@ grub_err_t grub_normal_print_device_info (const char *name) { grub_device_t dev; + grub_netdisk_data_t data; char *p; + if ((! grub_strcmp(name, "net")) || (! grub_strncmp(name, "net,", 4))) + { + grub_printf_ (N_("Device network:")); + grub_putchar (' '); + + dev = grub_device_open (name); + if (! dev || ! dev->disk || ! dev->disk->data) + grub_printf ("%s", _("Network information not available")); + else + { + data = dev->disk->data; + grub_putchar ('\n'); + grub_putchar ('\t'); + if (data->protocol == GRUB_NETDISK_PROTOCOL_TFTP) + grub_printf_(N_("Protocol: %s"), "TFTP"); + else + grub_printf_(N_("Protocol: %s"), "Unknown"); + grub_putchar ('\n'); + 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); + if (data->username) + { + grub_putchar ('\n'); + grub_putchar ('\t'); + grub_printf_(N_("Username: %s"), data->username); + if (data->password) + { + grub_putchar ('\n'); + grub_putchar ('\t'); + grub_printf_(N_("Password: %s"), data->password); + } + } + } + grub_putchar ('\n'); + + return GRUB_ERR_NONE; + } + p = grub_strchr (name, ','); if (p) { From 818a356eb196a2c2ca5af7d580b9920c8564ebcc Mon Sep 17 00:00:00 2001 From: Paulo de Rezende Pinatti Date: Thu, 29 Jul 2010 16:36:17 -0300 Subject: [PATCH 12/19] Fixed get_card_packet to correctly read data from network card into buffer. * net/ieee1275/interface.c (get_card_packet): read data regardless of ethernet header --- net/ieee1275/interface.c | 54 +++------------------------------------- 1 file changed, 4 insertions(+), 50 deletions(-) diff --git a/net/ieee1275/interface.c b/net/ieee1275/interface.c index be9810fb2..342044041 100644 --- a/net/ieee1275/interface.c +++ b/net/ieee1275/interface.c @@ -1,9 +1,4 @@ #include -#include -#include -#include -#include -#include #include #include @@ -37,56 +32,15 @@ int send_card_buffer (struct grub_net_buff *pack) int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) { - int actual; - char *datap; - struct iphdr *iph; - struct etherhdr *eth; - struct arphdr *arph; - struct ip6hdr *ip6h; + int actual, rc; pack->data = pack->tail = pack->head; - datap = pack->data; do { - grub_ieee1275_read (handle,datap,sizeof (*eth),&actual); + rc = grub_ieee1275_read (handle,pack->data,1500,&actual); - }while (actual <= 0); - eth = (struct etherhdr *) datap; - datap += sizeof(*eth); - + }while (actual <= 0 || rc < 0); + grub_netbuff_put (pack, actual); - switch (eth->type) - { - case 0x806: - - grub_ieee1275_read (handle,datap,sizeof (*arph),&actual); - arph = (struct arphdr *) datap; - - grub_netbuff_put (pack,sizeof (*eth) + sizeof (*arph)); - break; - case 0x800: - grub_ieee1275_read (handle,datap,sizeof (*iph),&actual); - iph = (struct iphdr *) datap; - datap += sizeof(*iph); - - - grub_ieee1275_read (handle,datap,iph->len - sizeof (*iph),&actual); - - - grub_netbuff_put (pack,sizeof (*eth) + iph->len); - break; - - case 0x86DD: - grub_ieee1275_read (handle,datap,sizeof (*ip6h),&actual); - ip6h = (struct ip6hdr *) datap; - - datap += sizeof(*ip6h); - grub_ieee1275_read (handle,datap,ip6h->payload_len - sizeof (*ip6h),&actual); - break; - - default: - grub_printf("Unknow packet %x\n",eth->type); - break; - } // grub_printf("packsize %d\n",pack->tail - pack->data); return 0;// sizeof (eth) + iph.len; } From 11d1ea5df607d8d2e6463f482f24e92c9cb609be Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Thu, 29 Jul 2010 17:52:54 -0300 Subject: [PATCH 13/19] Use server and client IP from the bootp packet. --- net/ip.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/net/ip.c b/net/ip.c index 044cfde6b..65b0f2b70 100644 --- a/net/ip.c +++ b/net/ip.c @@ -72,7 +72,9 @@ recv_ip_packet (struct grub_net_network_layer_interface *inf, { trans_net_inf->inner_layer->link_prot->recv(inf,trans_net_inf->inner_layer,nb); iph = (struct iphdr *) nb->data; - if (iph->dest == 0x0908eaaa && iph->src == 0x0908ea92 && iph->protocol == 0x11) + if (iph->protocol == 0x11 && + iph->dest == (grub_uint32_t) bootp_pckt -> yiaddr && + iph->src == (grub_uint32_t) bootp_pckt -> siaddr ) { grub_netbuff_pull(nb,sizeof(*iph)); return 0; @@ -82,11 +84,11 @@ recv_ip_packet (struct grub_net_network_layer_interface *inf, if (current_time - start_time > TIMEOUT_TIME_MS) return grub_error (GRUB_ERR_TIMEOUT, "Time out."); } -/* grub_printf("ip.src 0x%x\n",iph->src); - grub_printf("ip.dst 0x%x\n",iph->dest); - grub_printf("ip.len 0x%x\n",iph->len); - grub_printf("ip.protocol 0x%x\n",iph->protocol); - */ +// grub_printf("ip.src 0x%x\n",iph->src); +// grub_printf("ip.dst 0x%x\n",iph->dest); +// grub_printf("ip.len 0x%x\n",iph->len); +// grub_printf("ip.protocol 0x%x\n",iph->protocol); + /* - get ip header - verify if is the next layer is correct -*/ From f89661762a82b0784965ca27d88473e704648cf2 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Thu, 29 Jul 2010 18:07:09 -0300 Subject: [PATCH 14/19] Only open the card in netboot. --- fs/ieee1275/ofnet.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/fs/ieee1275/ofnet.c b/fs/ieee1275/ofnet.c index 9010317ba..82b5235cc 100644 --- a/fs/ieee1275/ofnet.c +++ b/fs/ieee1275/ofnet.c @@ -141,6 +141,7 @@ grub_ofnet_open (const char *name, grub_disk_t disk) grub_uint32_t server_ip = 0; if (grub_strcmp (name, "net")) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a net disk"); p1 = find_sep(disk->name); @@ -258,7 +259,7 @@ grub_ofnetfs_dir (grub_device_t device , int (*hook) (const char *filename, const struct grub_dirhook_info *info) __attribute((unused))) { - if(grub_strcmp (device->disk->name,"net")) + if(grub_strncmp (device->disk->name,"net",3)) { return grub_error (GRUB_ERR_BAD_FS, "not an net filesystem"); } @@ -287,9 +288,10 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) { //void *buffer; //grub_addr_t addr; + if (name[0] == '/') name++; - if(grub_strcmp (file->device->disk->name,"net")) + if(grub_strncmp (file->device->disk->name,"net",3)) { return 1; @@ -311,15 +313,17 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) file_size = app_interface->app_prot->get_file_size(NULL,stack,pack,(char *) name); for (found_addr = 0x800000; found_addr < + 2000 * 0x100000; found_addr += 0x100000) - { - if (grub_claimmap (found_addr , file_size) != -1) - break; - } + { + if (grub_claimmap (found_addr , file_size) != -1) + break; + } file->data = (void *) found_addr; grub_netbuff_clear(pack); grub_netbuff_reserve (pack,80*1024); app_interface->app_prot->open (NULL,stack,pack,(char *) name); + if (grub_errno != GRUB_ERR_NONE) + goto error; do { @@ -401,7 +405,7 @@ grub_ofnet_detect (void) } devalias = grub_ieee1275_get_aliasdevname (bootpath); - if (grub_strcmp(devalias ,"network")) + if (grub_strncmp(devalias ,"net",3)) return 0; grub_net = grub_malloc (sizeof *grub_net ); @@ -455,8 +459,8 @@ grub_ofnet_init(void) grub_get_netinfo (grub_net, bootp_pckt ); grub_disk_dev_register (&grub_ofnet_dev); grub_fs_register (&grub_ofnetfs_fs); + card_open (); } - card_open (); } void grub_ofnet_fini(void) From 17ef14c91669b1c7a8c32f106148c142a488a9c4 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Thu, 29 Jul 2010 18:13:00 -0300 Subject: [PATCH 15/19] Process errot packets in TFTP reply. --- net/tftp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/tftp.c b/net/tftp.c index dff0f134c..0fb43105d 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -140,7 +140,7 @@ tftp_receive (struct grub_net_network_layer_interface *inf __attribute((unused)) } //buff_clean - nb->data = nb->tail; + 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); @@ -155,7 +155,8 @@ tftp_receive (struct grub_net_network_layer_interface *inf __attribute((unused)) grub_netbuff_clear(nb); break; case TFTP_ERROR: - nb->data = nb->tail; + grub_netbuff_clear (nb); + return grub_error (GRUB_ERR_ACCESS_DENIED, (char *)tftph->u.err.errmsg); break; } From 7c978f06900fc81e185bc0c8977f935c0185927c Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Thu, 29 Jul 2010 18:17:01 -0300 Subject: [PATCH 16/19] Implement the size field. --- include/grub/net/ethernet.h | 24 ++++++++++++-- net/ethernet.c | 65 ++++++++++++++++++++----------------- 2 files changed, 58 insertions(+), 31 deletions(-) diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h index 46aa04f60..9043a5f02 100644 --- a/include/grub/net/ethernet.h +++ b/include/grub/net/ethernet.h @@ -1,11 +1,31 @@ #ifndef GRUB_NET_ETHERNET_HEADER #define GRUB_NET_ETHERNET_HEADER 1 #include -struct etherhdr { +#define LLCADDRMASK 0x7f + +struct etherhdr +{ grub_uint8_t dst[6]; grub_uint8_t src[6]; grub_uint16_t type; -} __attribute__ ((packed)) ; +} __attribute__ ((packed)); + +#define PCP (x) x & 0xe000 +#define CFI (x) x & 0x1000 +#define VID (x) x & 0x0fff + +struct llchdr +{ +grub_uint8_t dsap; +grub_uint8_t ssap; +grub_uint8_t ctrl; +} __attribute__ ((packed)); + +struct snaphdr +{ +grub_uint8_t oui[3]; +grub_uint16_t type; +} __attribute__ ((packed)); void ethernet_ini(void); void ethernet_fini(void); diff --git a/net/ethernet.c b/net/ethernet.c index 2bcb8107d..ab5992133 100644 --- a/net/ethernet.c +++ b/net/ethernet.c @@ -18,19 +18,13 @@ send_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ grub_netbuff_push (nb,sizeof(*eth)); eth = (struct etherhdr *) nb->data; - eth->dst[0] =0x00; - eth->dst[1] =0x11; - eth->dst[2] =0x25; - eth->dst[3] =0xca; - eth->dst[4] =0x1f; - eth->dst[5] =0x01; - eth->src[0] =0x0a; - eth->src[1] =0x11; - eth->src[2] =0xbd; - eth->src[3] =0xe3; - eth->src[4] =0xe3; - eth->src[5] =0x04; - + eth->dst[0] = 0x00; + eth->dst[1] = 0x11; + eth->dst[2] = 0x25; + 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); @@ -44,25 +38,38 @@ recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ { struct etherhdr *eth; grub_uint64_t start_time, current_time; + struct llchdr *llch; + struct snaphdr *snaph; + grub_uint16_t type; start_time = grub_get_time_ms(); - while (1) - { - get_card_packet (nb); - eth = (struct etherhdr *) nb->data; + while (1) + { + get_card_packet (nb); + eth = (struct etherhdr *) nb->data; + type = eth->type; + grub_netbuff_pull(nb,sizeof (*eth)); + // grub_printf("ethernet type 58 %x\n",type); + // grub_printf("ethernet eth->type 58 %x\n",type); + if (eth->type <=1500) + { + llch = (struct llchdr *) nb->data; + type = llch->dsap & LLCADDRMASK; + + if (llch->dsap == 0xaa && llch->ssap == 0xaa && llch->ctrl == 0x3) + { + grub_netbuff_pull (nb,sizeof(*llch)); + snaph = (struct snaphdr *) nb->data; + type = snaph->type; + } + } + /*change for grub_memcmp*/ - if( eth->src[0] == 0x00 && eth->src[1] == 0x11 && eth->src[2] == 0x25 && - eth->src[3] == 0xca && eth->src[4] == 0x1f && eth->src[5] == 0x01 && eth->type == 0x800) - { - //grub_printf("ethernet eth->dst %x:%x:%x:%x:%x:%x\n",eth->dst[0], - // eth->dst[1],eth->dst[2],eth->dst[3],eth->dst[4],eth->dst[5]); - // grub_printf("ethernet eth->src %x:%x:%x:%x:%x:%x\n",eth->src[0],eth->src[1], - // eth->src[2],eth->src[3],eth->src[4],eth->src[5]); - //grub_printf("ethernet eth->type 0x%x\n",eth->type); - //grub_printf("out from ethernet\n"); - grub_netbuff_pull(nb,sizeof(*eth)); + //if( eth->src[0] == 0x00 && eth->src[1] == 0x11 && eth->src[2] == 0x25 && + // eth->src[3] == 0xca && eth->src[4] == 0x1f && eth->src[5] == 0x01 && type == 0x800) + if(type == 0x800) return 0; - } - current_time = grub_get_time_ms(); + + current_time = grub_get_time_ms (); if (current_time - start_time > TIMEOUT_TIME_MS) return grub_error (GRUB_ERR_TIMEOUT, "Time out."); } From 10830203a09d8afdb8f10ab322042bbcdecece16 Mon Sep 17 00:00:00 2001 From: Paulo de Rezende Pinatti Date: Fri, 13 Aug 2010 14:42:16 -0300 Subject: [PATCH 17/19] 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 --- fs/ieee1275/ofnet.c | 48 +++++--- include/grub/net/arp.h | 49 +++++++-- include/grub/net/interface.h | 2 +- include/grub/net/ip.h | 1 + include/grub/net/protocol.h | 10 +- net/arp.c | 207 +++++++++++++++++++++++++++++++++++ net/ethernet.c | 38 ++++--- net/interface.c | 1 - net/ip.c | 27 ++++- net/netbuff.c | 2 +- net/tftp.c | 4 +- normal/misc.c | 2 +- 12 files changed, 335 insertions(+), 56 deletions(-) diff --git a/fs/ieee1275/ofnet.c b/fs/ieee1275/ofnet.c index 82b5235cc..cf7eeb5b2 100644 --- a/fs/ieee1275/ofnet.c +++ b/fs/ieee1275/ofnet.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -95,7 +96,7 @@ retrieve_field(const char *src, char **field, const char **rest) static grub_err_t 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; int i; const char *ptr = val; @@ -107,8 +108,7 @@ parse_ip (const char *val, grub_uint32_t *ip, const char **rest) return grub_errno; if (t & ~0xff) return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); - newip >>= 8; - newip |= (t << 24); + p[i] = (grub_uint8_t) t; if (i != 3 && *ptr != '.') return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); ptr++; @@ -116,7 +116,6 @@ parse_ip (const char *val, grub_uint32_t *ip, const char **rest) ptr = ptr - 1; if ( *ptr != '\0' && *ptr != ',') return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); - *ip = newip; if (rest) *rest = ptr; return 0; @@ -305,12 +304,33 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) char *datap; int amount = 0; 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; - pack = grub_netbuff_alloc (80*1024); - grub_netbuff_reserve (pack,80*1024); - file_size = app_interface->app_prot->get_file_size(NULL,stack,pack,(char *) name); + app_interface->inner_layer->data = (void *) &(netdisk_data->server_ip); + pack = grub_netbuff_alloc (2048); + 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) { @@ -320,16 +340,16 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) file->data = (void *) found_addr; grub_netbuff_clear(pack); - grub_netbuff_reserve (pack,80*1024); - app_interface->app_prot->open (NULL,stack,pack,(char *) name); + grub_netbuff_reserve (pack,2048); + app_interface->app_prot->open (&net_interface,stack,pack,(char *) name); if (grub_errno != GRUB_ERR_NONE) goto error; do { grub_netbuff_clear(pack); - grub_netbuff_reserve (pack,80*1024); - app_interface->app_prot->recv (NULL,stack,pack); + grub_netbuff_reserve (pack,2048); + app_interface->app_prot->recv (&net_interface,stack,pack); if (grub_errno != GRUB_ERR_NONE) goto error; 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_netbuff_clear(pack); - grub_netbuff_reserve (pack,80*1024); - app_interface->app_prot->send_ack (NULL,stack,pack); + grub_netbuff_reserve (pack,2048); + app_interface->app_prot->send_ack (&net_interface,stack,pack); if (grub_errno != GRUB_ERR_NONE) goto error; diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h index 86ae2deea..75260aeb3 100644 --- a/include/grub/net/arp.h +++ b/include/grub/net/arp.h @@ -1,17 +1,42 @@ #ifndef GRUB_NET_ARP_HEADER #define GRUB_NET_ARP_HEADER 1 +#include +#include +#include -#include -struct arphdr{ - grub_int16_t hwtype; /* hardware type (must be ARPHRD_ETHER) */ - grub_int16_t protocol; /* protocol type (must be ETH_P_IP) */ - grub_int8_t hwlen; /* hardware address length (must be 6) */ - grub_int8_t protolen; /* protocol address length (must be 4) */ - grub_uint16_t opcode; /* ARP opcode */ - grub_uint8_t shwaddr[6]; /* sender's hardware address */ - grub_uint32_t sipaddr; /* sender's IP address */ - grub_uint8_t thwaddr[6]; /* target's hardware address */ - grub_uint32_t tipaddr; /* target's IP address */ -}__attribute__ ((packed)); +/* 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 + +/* ARP header operation codes */ +#define ARP_REQUEST 1 +#define ARP_REPLY 2 + +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 diff --git a/include/grub/net/interface.h b/include/grub/net/interface.h index 4d100fd75..cf24dd22e 100644 --- a/include/grub/net/interface.h +++ b/include/grub/net/interface.h @@ -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 grub_net_stack_register (struct grub_net_protocol_stack *stack) { diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h index cb119ac6f..5baacd439 100644 --- a/include/grub/net/ip.h +++ b/include/grub/net/ip.h @@ -2,6 +2,7 @@ #define GRUB_NET_IP_HEADER 1 #include +#define IP_ETHERTYPE 0x800 /* IANA Ethertype */ struct iphdr { grub_uint8_t verhdrlen; diff --git a/include/grub/net/protocol.h b/include/grub/net/protocol.h index b7a3e5d3b..ffc3dd719 100644 --- a/include/grub/net/protocol.h +++ b/include/grub/net/protocol.h @@ -8,7 +8,7 @@ struct grub_net_protocol; struct grub_net_protocol_stack; struct grub_net_network_layer_interface; - +struct grub_net_addr; typedef enum grub_network_layer_protocol_id { @@ -57,6 +57,7 @@ struct grub_net_network_layer_protocol struct grub_net_network_layer_protocol *next; char *name; grub_net_protocol_id_t id; + grub_uint16_t type; /* IANA Ethertype */ //grub_network_layer_protocol_id_t id; grub_err_t (*ntoa) (char *name, grub_net_network_layer_address_t *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; char *name; + grub_uint16_t type; /* ARP hardware type */ grub_net_protocol_id_t id; 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 , - 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; diff --git a/net/arp.c b/net/arp.c index e69de29bb..c02ea011d 100644 --- a/net/arp.c +++ b/net/arp.c @@ -0,0 +1,207 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/net/ethernet.c b/net/ethernet.c index ab5992133..14bc41c5b 100644 --- a/net/ethernet.c +++ b/net/ethernet.c @@ -8,24 +8,21 @@ #include #include #include +#include static grub_err_t 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; grub_netbuff_push (nb,sizeof(*eth)); eth = (struct etherhdr *) nb->data; - eth->dst[0] = 0x00; - eth->dst[1] = 0x11; - eth->dst[2] = 0x25; - eth->dst[3] = 0xca; - eth->dst[4] = 0x1f; - eth->dst[5] = 0x01; - grub_memcpy (eth->src, bootp_pckt -> chaddr,6); - eth->type = 0x0800; + grub_memcpy(eth->dst, target_addr.addr, target_addr.len); + grub_memcpy(eth->src, bootp_pckt->chaddr, 6); + eth->type = ethertype; return send_card_buffer(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 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; grub_uint64_t start_time, current_time; @@ -63,12 +61,17 @@ recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ } } - /*change for grub_memcmp*/ - //if( eth->src[0] == 0x00 && eth->src[1] == 0x11 && eth->src[2] == 0x25 && - // eth->src[3] == 0xca && eth->src[4] == 0x1f && eth->src[5] == 0x01 && type == 0x800) - if(type == 0x800) - return 0; - + /* ARP packet */ + if (type == ARP_ETHERTYPE) + { + arp_receive(inf, net_link_inf, nb); + 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 (); if (current_time - start_time > TIMEOUT_TIME_MS) return grub_error (GRUB_ERR_TIMEOUT, "Time out."); @@ -77,7 +80,7 @@ recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ - verify if the next layer is the desired one. - if not. get another packet. - 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", .id = GRUB_NET_ETHERNET_ID, + .type = ARPHRD_ETHERNET, .send = send_ethernet_packet, .recv = recv_ethernet_packet }; diff --git a/net/interface.c b/net/interface.c index bacabf4cb..f17b3e66b 100644 --- a/net/interface.c +++ b/net/interface.c @@ -22,7 +22,6 @@ INTERFACE_REGISTER_FUNCTIONS("link");*/ #include #include -struct grub_net_protocol_stack *grub_net_protocol_stacks; struct grub_net_protocol_stack *grub_net_protocol_stack_get (char *name) { diff --git a/net/ip.c b/net/ip.c index 65b0f2b70..142f33e70 100644 --- a/net/ip.c +++ b/net/ip.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,8 @@ send_ip_packet (struct grub_net_network_layer_interface *inf, struct iphdr *iph; static int id = 0x2400; + struct grub_net_addr nl_target_addr, ll_target_addr; + grub_err_t rc; grub_netbuff_push(nb,sizeof(*iph)); iph = (struct iphdr *) nb->data; @@ -51,12 +54,26 @@ send_ip_packet (struct grub_net_network_layer_interface *inf, iph->ttl = 0xff; iph->protocol = 0x11; 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 = 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); } @@ -70,11 +87,12 @@ recv_ip_packet (struct grub_net_network_layer_interface *inf, start_time = grub_get_time_ms(); 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; if (iph->protocol == 0x11 && 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)); return 0; @@ -99,6 +117,7 @@ static struct grub_net_network_layer_protocol grub_ipv4_protocol = { .name = "ipv4", .id = GRUB_NET_IPV4_ID, + .type = IP_ETHERTYPE, .send = send_ip_packet, .recv = recv_ip_packet }; diff --git a/net/netbuff.c b/net/netbuff.c index ce52233b6..4f6a1da84 100644 --- a/net/netbuff.c +++ b/net/netbuff.c @@ -72,7 +72,7 @@ struct grub_net_buff *grub_netbuff_alloc ( grub_size_t len ) len = NETBUFFMINLEN; 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->head = nb->data = nb->tail = data; nb->end = (char *) nb; diff --git a/net/tftp.c b/net/tftp.c index 0fb43105d..2aeae38e9 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -113,7 +113,7 @@ tftp_open (struct grub_net_network_layer_interface *inf __attribute((unused)), app_interface->trans_prot->send (inf,protstack->interface,nb); /*Receive OACK*/ grub_netbuff_clear (nb); - grub_netbuff_reserve (nb,80*1024); + grub_netbuff_reserve (nb,2048); 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); 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); return tftp_file.size; diff --git a/normal/misc.c b/normal/misc.c index d53fe711c..30967e174 100644 --- a/normal/misc.c +++ b/normal/misc.c @@ -54,7 +54,7 @@ grub_normal_print_device_info (const char *name) grub_printf_(N_("Protocol: %s"), "Unknown"); grub_putchar ('\n'); 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) { grub_putchar ('\n'); From 9a9cee4e4347c0480fb9e19ce2732a2132c4e3f9 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Wed, 15 Sep 2010 13:00:51 -0300 Subject: [PATCH 18/19] Use the correct address types in net.c. implement ntoa ipv4 function. --- commands/net.c | 40 +++++++++++++++++++++++++++---------- include/grub/net.h | 29 +++++++++++++++++++++++---- include/grub/net/protocol.h | 5 +++-- include/grub/net/type_net.h | 8 ++++---- net/ip.c | 38 +++++++++++++++++++++++++++++++++-- 5 files changed, 97 insertions(+), 23 deletions(-) diff --git a/commands/net.c b/commands/net.c index b8ceb36f4..2558a309b 100644 --- a/commands/net.c +++ b/commands/net.c @@ -22,11 +22,8 @@ #include #include -struct grub_net_route *grub_net_routes = NULL; -struct grub_net_network_layer_interface *grub_net_network_layer_interfaces = NULL; -struct grub_net_card *grub_net_cards = NULL; -struct grub_net_network_layer_protocol *grub_net_network_layer_protocols = NULL; +/*Find which protocol understands the given address*/ grub_err_t grub_net_resolve_address (struct grub_net_network_layer_protocol **prot, char *name, @@ -102,7 +99,7 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); FOR_NET_NETWORK_LEVEL_INTERFACES (inter) - if (grub_strcmp (inter->name, args[1])) + if ( !grub_strcmp (inter->name, args[1])) break; if (inter == NULL) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found")); @@ -124,21 +121,36 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), grub_err_t err; grub_net_network_layer_address_t addr; struct grub_net_network_layer_interface *inter; + grub_printf("Enter add addr function.\n"); + + grub_printf("card list address in net.c = %x\n", (int) grub_net_cards); if (argc != 4) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("four arguments expected")); FOR_NET_CARDS (card) - if (grub_strcmp (card->name, args[1])) + { + grub_printf("card address = %x\n", (int) card); + grub_printf("card->name = %s\n",card->name); + grub_printf("args[1] = %s\n",args[1]); + if ( !grub_strcmp (card->name, args[1])) break; + } + + grub_printf("Out of the loop.\n"); + grub_printf("card address = %x\n", (int) card); + if (card == NULL) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("card not found")); + grub_printf("protocols loop.\n"); FOR_NET_NETWORK_LEVEL_PROTOCOLS (prot) - if (grub_strcmp (prot->name, args[2])) + if ( !grub_strcmp (prot->name, args[2])) break; - if (card == NULL) + grub_printf("end protocols loop.\n"); + + if (prot == NULL) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("protocol not found")); err = grub_net_resolve_address_in_protocol (prot, args[3], &addr); @@ -163,6 +175,12 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), } grub_net_network_layer_interface_register (inter); + FOR_NET_NETWORK_LEVEL_INTERFACES (inter) + { + grub_printf("inter->name = %s\n",inter->name); + grub_printf("inter->address = %x\n",(int) (inter->address.ipv4)); + + } return GRUB_ERR_NONE; } @@ -178,7 +196,7 @@ grub_cmd_delroute (struct grub_command *cmd __attribute__ ((unused)), for (prev = &grub_net_routes, route = *prev; route; prev = &((*prev)->next), route = *prev) - if (grub_strcmp (route->name, args[0]) == 0) + if ( !grub_strcmp (route->name, args[0]) == 0) { *prev = route->next; grub_free (route->name); @@ -232,7 +250,7 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), N_("Unrecognised address %s"), args[1]); } - if (grub_strcmp (args[2], "gw") == 0 && argc >= 4) + if ( !grub_strcmp (args[2], "gw") == 0 && argc >= 4) { grub_err_t err; route->is_gateway = 1; @@ -251,7 +269,7 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), route->is_gateway = 0; FOR_NET_NETWORK_LEVEL_INTERFACES (inter) - if (grub_strcmp (inter->name, args[2])) + if ( !grub_strcmp (inter->name, args[2])) break; if (!inter) diff --git a/include/grub/net.h b/include/grub/net.h index abb8a3167..18779dabe 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -31,6 +31,8 @@ struct grub_net_card; struct grub_net_card_driver { + struct grub_net_card_driver *next; + 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 *nb); @@ -66,7 +68,7 @@ struct grub_net_network_layer_interface /* Underlying protocol. */ struct grub_net_network_layer_protocol *protocol; struct grub_net_card *card; - union grub_net_network_layer_address address; + grub_net_network_layer_address_t address; void *data; }; @@ -121,7 +123,7 @@ grub_net_session_recv (struct grub_net_session *session, void *buf, return session->protocol->recv (session, buf, size); } -struct grub_net_network_layer_interface *grub_net_network_layer_interfaces; +extern struct grub_net_network_layer_interface *EXPORT_VAR(grub_net_network_layer_interfaces); static inline void grub_net_network_layer_interface_register (struct grub_net_network_layer_interface *inter) @@ -139,7 +141,7 @@ grub_net_network_layer_interface_unregister (struct grub_net_network_layer_inter #define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_layer_interfaces; var; var = var->next) -extern struct grub_net_route *grub_net_routes; +extern struct grub_net_route *EXPORT_VAR(grub_net_routes); static inline void grub_net_route_register (struct grub_net_route *route) @@ -157,7 +159,7 @@ grub_net_route_unregister (struct grub_net_route *route) #define FOR_NET_ROUTES(var) for (var = grub_net_routes; var; var = var->next) -extern struct grub_net_card *grub_net_cards; +extern struct grub_net_card *EXPORT_VAR(grub_net_cards); static inline void grub_net_card_register (struct grub_net_card *card) @@ -174,7 +176,26 @@ grub_net_card_unregister (struct grub_net_card *card) } #define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next) +struct grub_net_card_driver *grub_net_card_drivers; +static inline void +grub_net_card_driver_register (struct grub_net_card_driver *driver) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_card_drivers), + GRUB_AS_LIST (driver)); +} + +static inline void +grub_net_card_driver_unregister (struct grub_net_card_driver *driver) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_card_drivers), + GRUB_AS_LIST (driver)); +} + +void ofdriver_ini(void); +void ofdriver_fini(void); + +#define FOR_NET_CARD_DRIVERS(var) for (var = grub_net_card_drivers; var; var = var->next) #define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_layer_protocols; (var); (var) = (var)->next) diff --git a/include/grub/net/protocol.h b/include/grub/net/protocol.h index ffc3dd719..ce37404bc 100644 --- a/include/grub/net/protocol.h +++ b/include/grub/net/protocol.h @@ -1,6 +1,7 @@ #ifndef GRUB_PROTOCOL_HEADER #define GRUB_PROTOCOL_HEADER #include +#include #include #include #include @@ -60,7 +61,7 @@ struct grub_net_network_layer_protocol grub_uint16_t type; /* IANA Ethertype */ //grub_network_layer_protocol_id_t id; grub_err_t (*ntoa) (char *name, grub_net_network_layer_address_t *addr); - char * (*aton) (union grub_net_network_layer_address addr); + char * (*aton) (grub_net_network_layer_address_t addr); grub_err_t (*net_ntoa) (char *name, grub_net_network_layer_netaddress_t *addr); char * (*net_aton) (grub_net_network_layer_netaddress_t addr); @@ -87,7 +88,7 @@ struct grub_net_link_layer_protocol grub_uint16_t ethertype); }; -extern struct grub_net_network_layer_protocol *grub_net_network_layer_protocols; +extern struct grub_net_network_layer_protocol *EXPORT_VAR(grub_net_network_layer_protocols); typedef struct grub_net_protocol *grub_net_protocol_t; void grub_net_application_layer_protocol_register (struct grub_net_application_layer_protocol *prot); diff --git a/include/grub/net/type_net.h b/include/grub/net/type_net.h index a1717d6a7..f159b1de0 100644 --- a/include/grub/net/type_net.h +++ b/include/grub/net/type_net.h @@ -18,16 +18,16 @@ typedef enum }grub_net_protocol_id_t; -typedef union grub_net_network_layer_address +typedef union grub_net_network_layer_netaddress { grub_uint32_t ipv4; -} grub_net_network_layer_netaddress_t; +} grub_net_network_layer_address_t; -typedef union grub_net_network_layer_netaddress +typedef union grub_net_network_layer_address { struct { grub_uint32_t base; int masksize; } ipv4; -} grub_net_network_layer_address_t; +} grub_net_network_layer_netaddress_t; #endif diff --git a/net/ip.c b/net/ip.c index 142f33e70..8237603f2 100644 --- a/net/ip.c +++ b/net/ip.c @@ -68,8 +68,10 @@ send_ip_packet (struct grub_net_network_layer_interface *inf, 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) + if (rc != GRUB_ERR_NONE){ + grub_printf("Error in the ARP resolve.\n"); 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); @@ -113,13 +115,45 @@ recv_ip_packet (struct grub_net_network_layer_interface *inf, return 0; } + +static grub_err_t +ipv4_ntoa (char *val, grub_net_network_layer_address_t *addr ) +{ + grub_uint8_t *p = (grub_uint8_t *) addr; + unsigned long t; + int i; + + for (i = 0; i < 4; i++) + { + t = grub_strtoul (val, (char **) &val, 0); + if (grub_errno) + return grub_errno; + + if (t & ~0xff) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); + + p[i] = (grub_uint8_t) t; + if (i != 3 && *val != '.') + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); + + val++; + } + + val = val - 1; + if (*val != '\0') + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); + + return GRUB_ERR_NONE; +} + static struct grub_net_network_layer_protocol grub_ipv4_protocol = { .name = "ipv4", .id = GRUB_NET_IPV4_ID, .type = IP_ETHERTYPE, .send = send_ip_packet, - .recv = recv_ip_packet + .recv = recv_ip_packet, + .ntoa = ipv4_ntoa }; void ipv4_ini(void) From 87fdc7e8d28f20f355240219ea7e7a580e0f7303 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Wed, 15 Sep 2010 13:23:23 -0300 Subject: [PATCH 19/19] Create Open firmware pseudo driver. Change ofnet.c to disknet.c and remove almost all ieee1275 specific code. Create grub_net_malloc to handle iee1275 memory issues in a temporary solution. --- conf/powerpc-ieee1275.rmk | 6 +- fs/{ieee1275/ofnet.c => netdisk.c} | 142 ++++++++------------------ include/grub/ieee1275/ieee1275.h | 10 +- include/grub/ieee1275/ofnet.h | 29 +----- include/grub/net/disknet.h | 5 + include/grub/net/ethernet.h | 15 ++- include/grub/net/ieee1275/interface.h | 9 -- include/grub/net/mem.h | 9 ++ kern/ieee1275/openfw.c | 64 ++++++++++++ net/drivers/ieee1275/ofdriver.c | 74 ++++++++++++++ net/ethernet.c | 9 +- net/i386/mem.c | 10 ++ net/ieee1275/interface.c | 46 --------- net/ieee1275/mem.c | 32 ++++++ net/protocol.c | 2 + 15 files changed, 272 insertions(+), 190 deletions(-) rename fs/{ieee1275/ofnet.c => netdisk.c} (77%) create mode 100644 include/grub/net/disknet.h create mode 100644 include/grub/net/mem.h create mode 100644 net/drivers/ieee1275/ofdriver.c create mode 100644 net/i386/mem.c delete mode 100644 net/ieee1275/interface.c create mode 100644 net/ieee1275/mem.c diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index f0faef489..a70a1e962 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -5,7 +5,7 @@ kernel_img_HEADERS += ieee1275/ieee1275.h \ command.h i18n.h env_private.h net/ip.h net/udp.h net/ethernet.h net/arp.h net/tftp.h\ - net/ieee1275/interface.h net/type_net.h net.h net/interface.h net/protocol.h net/netbuff.h + net/ieee1275/interface.h net/type_net.h net.h net/interface.h net/protocol.h net/netbuff.h net/mem.h # Programs pkglib_PROGRAMS = kernel.img @@ -23,8 +23,8 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/generic/millisleep.c kern/time.c \ symlist.c kern/$(target_cpu)/cache.S net/ip.c net/tftp.c net/udp.c net/ethernet.c net/arp.c \ - net/ieee1275/interface.c net/interface.c net/protocol.c net/netbuff.c \ - fs/ieee1275/ofnet.c + net/drivers/ieee1275/ofdriver.c net/interface.c net/protocol.c net/netbuff.c \ + fs/netdisk.c net/ieee1275/mem.c kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x200000,-Bstatic diff --git a/fs/ieee1275/ofnet.c b/fs/netdisk.c similarity index 77% rename from fs/ieee1275/ofnet.c rename to fs/netdisk.c index cf7eeb5b2..2f6e97d52 100644 --- a/fs/ieee1275/ofnet.c +++ b/fs/netdisk.c @@ -23,26 +23,25 @@ #include #include #include -#include -#include -#include #include #include #include #include #include -#include #include #include #include +#include +#include + +struct grub_net_card *grub_net_cards = NULL; +struct grub_net_network_layer_interface *grub_net_network_layer_interfaces = NULL; +struct grub_net_route *grub_net_routes = NULL; #define BUFFERADDR 0X00000000 #define BUFFERSIZE 0x02000000 #define U64MAXSIZE 18446744073709551615ULL - -//static grub_ieee1275_ihandle_t handle = 0; - static const char * find_sep (const char *name) { @@ -295,29 +294,45 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) return 1; } - // grub_printf("name = %s\n",name); +/*TESt*/ + // grub_printf("name = %s\n",name); + struct grub_net_card *card; + struct grub_ofnetcard_data *ofdata; + FOR_NET_CARDS(card) + { + grub_printf("card address = %x\n", (int) card); + grub_printf ("card name = %s\n", card->name); + ofdata = card->data; + grub_printf("card path = %s\n", (char *) ofdata->path); + grub_printf("card handle = %d\n", ofdata->handle); + } + grub_printf("card list address in disknet.c = %x\n",(int) grub_net_cards); + card = grub_net_cards; + grub_printf("card address = %x\n", (int) card); +/*TESt*/ + struct grub_net_protocol_stack *stack; struct grub_net_buff *pack; struct grub_net_application_transport_interface *app_interface; int file_size; char *datap; int amount = 0; - 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.addr = (grub_uint8_t *) & (bootp_pckt->yiaddr); ila.len = 4; - lla.addr = (grub_uint8_t *) &(bootp_pckt->chaddr); + 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 + card->ila = &ila; + card->lla = &lla; + net_interface.card = card; + if(! netdisk_data) return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments missing"); @@ -328,37 +343,35 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) app_interface = (struct grub_net_application_transport_interface *) stack->interface; app_interface->inner_layer->data = (void *) &(netdisk_data->server_ip); + pack = grub_netbuff_alloc (2048); 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) - { - if (grub_claimmap (found_addr , file_size) != -1) - break; - } - file->data = (void *) found_addr; + file->data = grub_net_malloc (file_size); grub_netbuff_clear(pack); grub_netbuff_reserve (pack,2048); + app_interface->app_prot->open (&net_interface,stack,pack,(char *) name); if (grub_errno != GRUB_ERR_NONE) goto error; do { - grub_netbuff_clear(pack); - grub_netbuff_reserve (pack,2048); app_interface->app_prot->recv (&net_interface,stack,pack); + if (grub_errno != GRUB_ERR_NONE) goto error; + if ((pack->tail - pack->data)) { - // file->data = grub_realloc(file->data,amount + pack->tail - pack->data); datap = (char *)file->data + amount; amount += (pack->tail - pack->data); - grub_memcpy(datap , pack->data, pack->tail - pack->data); + grub_memcpy (datap , pack->data, pack->tail - pack->data); } + grub_netbuff_clear(pack); grub_netbuff_reserve (pack,2048); app_interface->app_prot->send_ack (&net_interface,stack,pack); @@ -394,54 +407,6 @@ static struct grub_fs grub_ofnetfs_fs = .next = 0 }; -static char * -grub_ieee1275_get_devargs (const char *path) -{ - int len; - char *colon = grub_strchr (path, ':'); - len = colon - path; - if (! colon) - return 0; - - return grub_strndup (path,len); -} - -static int -grub_ofnet_detect (void) -{ - - char *devalias; - char bootpath[64]; /* XXX check length */ - grub_ieee1275_phandle_t root; - grub_uint32_t net_type; - - grub_ieee1275_finddevice ("/chosen", &grub_ieee1275_chosen); - if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath, - sizeof (bootpath), 0)) - { - /* Should never happen. */ - grub_printf ("/chosen/bootpath property missing!\n"); - return 0; - } - devalias = grub_ieee1275_get_aliasdevname (bootpath); - - if (grub_strncmp(devalias ,"net",3)) - return 0; - - grub_net = grub_malloc (sizeof *grub_net ); - grub_net->name = "net"; - grub_net->dev = grub_ieee1275_get_devargs (bootpath); - grub_ieee1275_finddevice ("/", &root); - grub_ieee1275_get_integer_property (root, "ibm,fw-net-compatibility", - &net_type, sizeof net_type, 0); - grub_printf("root = %d\n",root); - grub_printf("net_type= %d\n",net_type); - grub_net->type = net_type; - - return 1; -} - - #define IPMASK 0x000000FF #define IPSIZE 16 #define IPTEMPLATE "%d.%d.%d.%d" @@ -456,34 +421,17 @@ grub_ip2str (grub_uint32_t ip) return str_ip; } + void -grub_get_netinfo (grub_ofnet_t netinfo,grub_bootp_t packet) +grub_disknet_init(void) { - netinfo->sip = grub_ip2str(packet->siaddr); - netinfo->cip = grub_ip2str(packet->yiaddr); - netinfo->gat = grub_ip2str(packet->giaddr); - grub_printf("packet->siaddr = %x\n",packet->siaddr); - grub_printf("netinfo-> = %s\n",netinfo->sip); - grub_printf("packet->yiaddr = %x\n",packet->yiaddr); - grub_printf("netinfo-> = %s\n",netinfo->cip); - grub_printf("packet->giaddr = %x\n",packet->giaddr); - grub_printf("netinfo-> = %s\n",netinfo->gat); + + grub_disk_dev_register (&grub_ofnet_dev); + grub_fs_register (&grub_ofnetfs_fs); } + void -grub_ofnet_init(void) -{ - tftp_ini (); - bootp_pckt = grub_getbootp (); - if(grub_ofnet_detect ()) - { - grub_get_netinfo (grub_net, bootp_pckt ); - grub_disk_dev_register (&grub_ofnet_dev); - grub_fs_register (&grub_ofnetfs_fs); - card_open (); - } -} -void -grub_ofnet_fini(void) +grub_disknet_fini(void) { grub_fs_unregister (&grub_ofnetfs_fs); grub_disk_dev_unregister (&grub_ofnet_dev); diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index f4c8b4edf..8fb558fa7 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -24,7 +24,6 @@ #include #include -/* Maps a device alias to a pathname. */ struct grub_ieee1275_devalias { char *name; @@ -65,6 +64,13 @@ struct grub_ieee1275_common_hdr typedef grub_uint32_t grub_ieee1275_ihandle_t; typedef grub_uint32_t grub_ieee1275_phandle_t; +struct grub_ofnetcard_data +{ + char *path; + grub_ieee1275_ihandle_t handle; +}; + +/* Maps a device alias to a pathname. */ extern grub_ieee1275_phandle_t EXPORT_VAR(grub_ieee1275_chosen); extern grub_ieee1275_ihandle_t EXPORT_VAR(grub_ieee1275_mmu); extern int (* EXPORT_VAR(grub_ieee1275_entry_fn)) (void *); @@ -186,4 +192,6 @@ int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook) (struct grub_ieee1275_devalias * alias)); char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path); +void EXPORT_FUNC(grub_ofnet_findcards) (void); +void EXPORT_FUNC(grub_ofnet_probecards) (void); #endif /* ! GRUB_IEEE1275_HEADER */ diff --git a/include/grub/ieee1275/ofnet.h b/include/grub/ieee1275/ofnet.h index a26c22235..ba4c62630 100644 --- a/include/grub/ieee1275/ofnet.h +++ b/include/grub/ieee1275/ofnet.h @@ -23,32 +23,9 @@ #include #include -extern void grub_ofnet_init(void); -extern void grub_ofnet_fini(void); +void grub_ofnet_init(void); +void grub_ofnet_fini(void); -/* -struct grub_net; - -struct grub_net_dev -{ - / The device name. / - const char *name; - - / FIXME: Just a template. / - int (*probe) (struct grub_net *net, const void *addr); - void (*reset) (struct grub_net *net); - int (*poll) (struct grub_net *net); - void (*transmit) (struct grub_net *net, const void *destip, - unsigned srcsock, unsigned destsock, const void *packet); - void (*disable) (struct grub_net *net); - - / The next net device. / - struct grub_net_dev *next; -}; -typedef struct grub_net_dev *grub_net_dev_t; - -struct grub_fs; -*/ struct grub_ofnet { /* The net name. */ @@ -85,7 +62,7 @@ struct grub_bootp { char file [128]; /* Boot filename */ // grub_uint32_t filesize ; /*File size (testing)*/ unsigned char vend [64]; -}; +}; typedef struct grub_bootp* grub_bootp_t; diff --git a/include/grub/net/disknet.h b/include/grub/net/disknet.h new file mode 100644 index 000000000..59aa2a320 --- /dev/null +++ b/include/grub/net/disknet.h @@ -0,0 +1,5 @@ +#ifndef GRUB_DISKNET_HEADER +#define GRUB_DISKNET_HEADER 1 + void grub_disknet_init(void); + void grub_disknet_fini(void); +#endif /* ! GRUB_NET_HEADER */ diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h index 9043a5f02..f4a6c22cf 100644 --- a/include/grub/net/ethernet.h +++ b/include/grub/net/ethernet.h @@ -10,9 +10,18 @@ struct etherhdr grub_uint16_t type; } __attribute__ ((packed)); -#define PCP (x) x & 0xe000 -#define CFI (x) x & 0x1000 -#define VID (x) x & 0x0fff +#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 { diff --git a/include/grub/net/ieee1275/interface.h b/include/grub/net/ieee1275/interface.h index 16f624c05..c369e35a6 100644 --- a/include/grub/net/ieee1275/interface.h +++ b/include/grub/net/ieee1275/interface.h @@ -6,14 +6,5 @@ #include #include - -grub_ofnet_t grub_net; - grub_bootp_t bootp_pckt; - -int send_card_buffer (struct grub_net_buff *pack); -int get_card_packet (struct grub_net_buff *pack); -int card_open (void); -int card_close (void); - #endif diff --git a/include/grub/net/mem.h b/include/grub/net/mem.h new file mode 100644 index 000000000..bbdac512b --- /dev/null +++ b/include/grub/net/mem.h @@ -0,0 +1,9 @@ +#ifndef GRUB_NETMM_H +#define GRUB_NETMM_H 1 + +#include +#include + +void *EXPORT_FUNC(grub_net_malloc) (grub_size_t size); + +#endif /* ! GRUB_MM_H */ diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index 337fc4b7e..2650ff3d4 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -23,6 +23,10 @@ #include #include #include +#include +#include +#include +#include enum grub_ieee1275_parse_type { @@ -490,3 +494,63 @@ grub_getbootp( void ) return packet; } +void grub_ofnet_findcards (void) +{ + struct grub_net_card *card; + int i = 0; + + auto int search_net_devices (struct grub_ieee1275_devalias *alias); + + int search_net_devices (struct grub_ieee1275_devalias *alias) + { + if ( !grub_strcmp (alias->type,"network") ) + { + + card = grub_malloc (sizeof (struct grub_net_card)); + struct grub_ofnetcard_data *ofdata = grub_malloc (sizeof (struct grub_ofnetcard_data)); + ofdata->path = grub_strdup (alias->path); + card->data = ofdata; + card->name = grub_xasprintf("eth%d",i++); // grub_strdup (alias->name); + grub_net_card_register (card); + } + return 0; + } + + /*Look at all nodes for devices of the type network*/ + grub_ieee1275_devices_iterate (search_net_devices); + +} + +void grub_ofnet_probecards (void) +{ + struct grub_net_card *card; + struct grub_net_card_driver *driver; + + /*Assign correspondent driver for each device. */ + FOR_NET_CARDS (card) + { + FOR_NET_CARD_DRIVERS (driver) + { + if (driver->init(card) == GRUB_ERR_NONE) + { + card->driver = driver; + continue; + } + } + } +} + +void +grub_ofnet_init(void) +{ + + ofdriver_ini(); + grub_ofnet_findcards(); + grub_ofnet_probecards(); + + /*init tftp stack - will be handled by module subsystem in the future*/ + tftp_ini (); + /*get bootp packet - won't be needed in the future*/ + bootp_pckt = grub_getbootp (); + grub_disknet_init(); +} diff --git a/net/drivers/ieee1275/ofdriver.c b/net/drivers/ieee1275/ofdriver.c new file mode 100644 index 000000000..5f6c3c2f6 --- /dev/null +++ b/net/drivers/ieee1275/ofdriver.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include + +static +grub_err_t card_open (struct grub_net_card *dev) +{ + + struct grub_ofnetcard_data *data = dev->data; + return grub_ieee1275_open (data->path,&(data->handle)); +} + +static +grub_err_t card_close (struct grub_net_card *dev) +{ + + struct grub_ofnetcard_data *data = dev->data; + + if (data->handle) + grub_ieee1275_close (data->handle); + return GRUB_ERR_NONE; +} + +static +grub_err_t send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) +{ + + int actual; + struct grub_ofnetcard_data *data = dev->data; + + return grub_ieee1275_write (data->handle,pack->data,pack->tail - pack->data,&actual); +} + +static +grub_err_t get_card_packet (struct grub_net_card *dev, struct grub_net_buff *pack) +{ + + int actual, rc; + struct grub_ofnetcard_data *data = dev->data; + grub_netbuff_clear(pack); + + do + { + rc = grub_ieee1275_read (data->handle,pack->data,1500,&actual); + + }while (actual <= 0 || rc < 0); + grub_netbuff_put (pack, actual); + + return GRUB_ERR_NONE; +} + +static struct grub_net_card_driver ofdriver = +{ + .name = "ofnet", + .init = card_open, + .fini = card_close, + .send = send_card_buffer, + .recv = get_card_packet + +}; + +void ofdriver_ini(void) +{ + grub_net_card_driver_register (&ofdriver); +} + +void ofdriver_fini(void) +{ + grub_net_card_driver_unregister (&ofdriver); +} + + + diff --git a/net/ethernet.c b/net/ethernet.c index 14bc41c5b..7b578abab 100644 --- a/net/ethernet.c +++ b/net/ethernet.c @@ -22,10 +22,10 @@ struct grub_net_addr target_addr, grub_uint16_t ethertype) eth = (struct etherhdr *) nb->data; grub_memcpy(eth->dst, target_addr.addr, target_addr.len); grub_memcpy(eth->src, bootp_pckt->chaddr, 6); + eth->type = ethertype; - return send_card_buffer(nb); -// return inf->card->driver->send(inf->card,nb); + return inf->card->driver->send (inf->card,nb); } @@ -42,12 +42,11 @@ grub_uint16_t ethertype) start_time = grub_get_time_ms(); while (1) { - get_card_packet (nb); + inf->card->driver->recv (inf->card,nb); eth = (struct etherhdr *) nb->data; type = eth->type; grub_netbuff_pull(nb,sizeof (*eth)); - // grub_printf("ethernet type 58 %x\n",type); - // grub_printf("ethernet eth->type 58 %x\n",type); + if (eth->type <=1500) { llch = (struct llchdr *) nb->data; diff --git a/net/i386/mem.c b/net/i386/mem.c new file mode 100644 index 000000000..d6c98ea80 --- /dev/null +++ b/net/i386/mem.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include + + +void *grub_net_malloc (grub_size_t size) +{ + return grub_malloc (size); +} diff --git a/net/ieee1275/interface.c b/net/ieee1275/interface.c deleted file mode 100644 index 342044041..000000000 --- a/net/ieee1275/interface.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include - -static grub_ieee1275_ihandle_t handle; -int card_open (void) -{ - - grub_ieee1275_open (grub_net->dev , &handle); - return 0; - -} - -int card_close (void) -{ - - if (handle) - grub_ieee1275_close (handle); - return 0; -} - - -int send_card_buffer (struct grub_net_buff *pack) -{ - - int actual; - grub_ieee1275_write (handle,pack->data,pack->tail - pack->data,&actual); - - return actual; -} - -int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) -{ - - int actual, rc; - pack->data = pack->tail = pack->head; - do - { - rc = grub_ieee1275_read (handle,pack->data,1500,&actual); - - }while (actual <= 0 || rc < 0); - grub_netbuff_put (pack, actual); - -// grub_printf("packsize %d\n",pack->tail - pack->data); - return 0;// sizeof (eth) + iph.len; -} diff --git a/net/ieee1275/mem.c b/net/ieee1275/mem.c new file mode 100644 index 000000000..416a04253 --- /dev/null +++ b/net/ieee1275/mem.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include +#include +#define TRASHOLD_SIZE 5 * 1024 * 1024 + +void *grub_net_malloc (grub_size_t size) +{ + + int found = 0; + grub_addr_t found_addr; + + if (size <= TRASHOLD_SIZE) + return grub_malloc (size); + + for (found_addr = 0x800000; found_addr < + 2000 * 0x100000; found_addr += 0x100000) + { + if (grub_claimmap (found_addr , size) != -1) + { + found = 1; + break; + } + } + + if (!found) + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); + + return found?(void *) found_addr:NULL; + +} diff --git a/net/protocol.c b/net/protocol.c index 05d4471d2..bdd7f3671 100644 --- a/net/protocol.c +++ b/net/protocol.c @@ -2,6 +2,8 @@ #include #include +struct grub_net_network_layer_protocol *grub_net_network_layer_protocols = NULL; + #define PROTOCOL_REGISTER_FUNCTIONS(layername) \ struct grub_net_##layername##_layer_protocol *grub_net_##layername##_layer_protocols;\ \