diff --git a/ChangeLog b/ChangeLog index 75331f9f1..d08e5251b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-10-15 Vladimir Serbinenko + + Split emunet into platform-dependent and GRUB-binding parts. Keep + platform-dependent part in kernel for easy access to OS functions. + 2013-10-15 Vladimir Serbinenko * grub-core/tests/video_checksum.c: Use grub_util_fd_* rather than diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist index 666efc604..c8413da22 100644 --- a/conf/Makefile.extra-dist +++ b/conf/Makefile.extra-dist @@ -85,7 +85,6 @@ EXTRA_DIST += grub-core/osdep/hurd/getroot.c EXTRA_DIST += grub-core/osdep/linux/getroot.c EXTRA_DIST += grub-core/osdep/sun/getroot.c -EXTRA_DIST += grub-core/osdep/basic/emunet.c EXTRA_DIST += grub-core/osdep/basic/random.c EXTRA_DIST += grub-core/osdep/basic/ofpath.c @@ -93,7 +92,6 @@ EXTRA_DIST += grub-core/osdep/unix/password.c EXTRA_DIST += grub-core/osdep/unix/random.c EXTRA_DIST += grub-core/osdep/unix/sleep.c -EXTRA_DIST += grub-core/osdep/linux/emunet.c EXTRA_DIST += grub-core/osdep/linux/ofpath.c EXTRA_DIST += grub-core/osdep/windows/password.c diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index d9ec7ca31..630b866ee 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -218,6 +218,7 @@ if COND_emu KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/export.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/net.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostdisk.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h if COND_GRUB_EMU_SDL diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index d9645f3cf..710fa6b2c 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -257,6 +257,9 @@ kernel = { extra_dist = osdep/windows/emuconsole.c; emu = osdep/sleep.c; emu = osdep/init.c; + emu = osdep/emunet.c; + extra_dist = osdep/linux/emunet.c; + extra_dist = osdep/basic/emunet.c; videoinkernel = term/gfxterm.c; videoinkernel = font/font.c; @@ -1978,7 +1981,7 @@ module = { module = { name = emunet; - emu = osdep/emunet.c; + emu = net/drivers/emu/emunet.c; enable = emu; }; diff --git a/grub-core/net/drivers/emu/emunet.c b/grub-core/net/drivers/emu/emunet.c new file mode 100644 index 000000000..7c977cd52 --- /dev/null +++ b/grub-core/net/drivers/emu/emunet.c @@ -0,0 +1,116 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,2011,2012,2013 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 + +GRUB_MOD_LICENSE ("GPLv3+"); + +static grub_err_t +send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)), + struct grub_net_buff *pack); + +static struct grub_net_buff * +get_card_packet (struct grub_net_card *dev __attribute__ ((unused))); + +static struct grub_net_card_driver emudriver = + { + .name = "emu", + .send = send_card_buffer, + .recv = get_card_packet + }; + +static struct grub_net_card emucard = + { + .name = "emu0", + .driver = &emudriver, + .mtu = 1500, + .default_address = { + .type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET, + {.mac = {0, 1, 2, 3, 4, 5}} + }, + .flags = 0 + }; + +static grub_err_t +send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)), + struct grub_net_buff *pack) +{ + grub_ssize_t actual; + + actual = grub_emunet_send (pack->data, pack->tail - pack->data); + if (actual < 0) + return grub_error (GRUB_ERR_IO, N_("couldn't send network packet")); + + return GRUB_ERR_NONE; +} + +static struct grub_net_buff * +get_card_packet (struct grub_net_card *dev __attribute__ ((unused))) +{ + grub_ssize_t actual; + struct grub_net_buff *nb; + + nb = grub_netbuff_alloc (emucard.mtu + 36 + 2); + if (!nb) + return NULL; + + /* Reserve 2 bytes so that 2 + 14/18 bytes of ethernet header is divisible + by 4. So that IP header is aligned on 4 bytes. */ + grub_netbuff_reserve (nb, 2); + if (!nb) + { + grub_netbuff_free (nb); + return NULL; + } + + actual = grub_emunet_receive (nb->data, emucard.mtu + 36); + if (actual < 0) + { + grub_netbuff_free (nb); + return NULL; + } + grub_netbuff_put (nb, actual); + + return nb; +} + +static int registered = 0; + +GRUB_MOD_INIT(emunet) +{ + if (grub_emunet_create (&emucard.mtu)) + { + grub_net_card_register (&emucard); + registered = 1; + } +} + +GRUB_MOD_FINI(emunet) +{ + if (registered) + { + grub_emunet_close (); + grub_net_card_unregister (&emucard); + registered = 0; + } +} diff --git a/grub-core/osdep/basic/emunet.c b/grub-core/osdep/basic/emunet.c index e7989341c..6362e5cfb 100644 --- a/grub-core/osdep/basic/emunet.c +++ b/grub-core/osdep/basic/emunet.c @@ -16,6 +16,35 @@ * along with GRUB. If not, see . */ -#include +#include +#include -GRUB_MOD_LICENSE ("GPLv3+"); +#include +#include + +grub_ssize_t +grub_emunet_send (const void *packet __attribute__ ((unused)), + grub_size_t sz __attribute__ ((unused))) +{ + return -1; +} + +grub_ssize_t +grub_emunet_receive (void *packet __attribute__ ((unused)), + grub_size_t sz __attribute__ ((unused))) +{ + return -1; +} + +int +grub_emunet_create (grub_size_t *mtu) +{ + *mtu = 1500; + return -1; +} + +void +grub_emunet_close (void) +{ + return; +} diff --git a/grub-core/osdep/linux/emunet.c b/grub-core/osdep/linux/emunet.c index 9b502c73d..19b188f09 100644 --- a/grub-core/osdep/linux/emunet.c +++ b/grub-core/osdep/linux/emunet.c @@ -16,107 +16,59 @@ * along with GRUB. If not, see . */ -#include -#include +#include +#include + #include -#include #include #include #include +#include #include #include -#include -#include -#include +#include -GRUB_MOD_LICENSE ("GPLv3+"); +#include static int fd; -static grub_err_t -send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)), - struct grub_net_buff *pack) +grub_ssize_t +grub_emunet_send (const void *packet, grub_size_t sz) { - ssize_t actual; - - actual = write (fd, pack->data, pack->tail - pack->data); - if (actual < 0) - return grub_error (GRUB_ERR_IO, N_("couldn't send network packet")); - - return GRUB_ERR_NONE; + return write (fd, packet, sz); } -static struct grub_net_buff * -get_card_packet (struct grub_net_card *dev __attribute__ ((unused))) +grub_ssize_t +grub_emunet_receive (void *packet, grub_size_t sz) { - ssize_t actual; - struct grub_net_buff *nb; - - nb = grub_netbuff_alloc (1536 + 2); - if (!nb) - return NULL; - - /* Reserve 2 bytes so that 2 + 14/18 bytes of ethernet header is divisible - by 4. So that IP header is aligned on 4 bytes. */ - grub_netbuff_reserve (nb, 2); - if (!nb) - { - grub_netbuff_free (nb); - return NULL; - } - - actual = read (fd, nb->data, 1536); - if (actual < 0) - { - grub_netbuff_free (nb); - return NULL; - } - grub_netbuff_put (nb, actual); - - return nb; + return read (fd, packet, sz); } -static struct grub_net_card_driver emudriver = - { - .name = "emu", - .send = send_card_buffer, - .recv = get_card_packet - }; - -static struct grub_net_card emucard = - { - .name = "emu0", - .driver = &emudriver, - .mtu = 1500, - .default_address = { - .type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET, - {.mac = {0, 1, 2, 3, 4, 5}} - }, - .flags = 0 - }; - -GRUB_MOD_INIT(emunet) +int +grub_emunet_create (grub_size_t *mtu) { struct ifreq ifr; + *mtu = 1500; fd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK); if (fd < 0) - return; - grub_memset (&ifr, 0, sizeof (ifr)); + return -1; + memset (&ifr, 0, sizeof (ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; if (ioctl (fd, TUNSETIFF, &ifr) < 0) { close (fd); fd = -1; - return; + return -1; } - grub_net_card_register (&emucard); + return 0; } -GRUB_MOD_FINI(emunet) +void +grub_emunet_close (void) { - if (fd >= 0) - { - close (fd); - grub_net_card_unregister (&emucard); - } + if (fd < 0) + return; + + close (fd); + fd = -1; } diff --git a/include/grub/emu/export.h b/include/grub/emu/export.h index 03fea2c91..bdeb10f9d 100644 --- a/include/grub/emu/export.h +++ b/include/grub/emu/export.h @@ -1,20 +1,7 @@ #ifdef GRUB_SYMBOL_GENERATOR -void EXPORT_FUNC (open64) (void); -void EXPORT_FUNC (close) (void); -void EXPORT_FUNC (read) (void); -void EXPORT_FUNC (write) (void); -void EXPORT_FUNC (ioctl) (void); -void EXPORT_FUNC (__errno_location) (void); -void EXPORT_FUNC (strerror) (void); void EXPORT_FUNC (sysconf) (void); void EXPORT_FUNC (times) (void); #else -#include -#include -#include #include -#include #include -#include -#include #endif diff --git a/include/grub/emu/net.h b/include/grub/emu/net.h new file mode 100644 index 000000000..a5d4fcbe4 --- /dev/null +++ b/include/grub/emu/net.h @@ -0,0 +1,37 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 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_EMUNET_HEADER +#define GRUB_EMUNET_HEADER 1 + +#include +#include + +grub_ssize_t +EXPORT_FUNC(grub_emunet_send) (const void *packet, grub_size_t sz); + +grub_ssize_t +EXPORT_FUNC(grub_emunet_receive) (void *packet, grub_size_t sz); + +int +EXPORT_FUNC(grub_emunet_create) (grub_size_t *mtu); + +void +EXPORT_FUNC(grub_emunet_close) (void); + +#endif