]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
bootp support
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 24 Jun 2011 18:35:25 +0000 (20:35 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 24 Jun 2011 18:35:25 +0000 (20:35 +0200)
12 files changed:
grub-core/net/arp.c
grub-core/net/drivers/emu/emunet.c
grub-core/net/ethernet.c
grub-core/net/ip.c
grub-core/net/net.c
grub-core/net/tftp.c
grub-core/net/udp.c
include/grub/emu/export.h [new file with mode: 0644]
include/grub/net.h
include/grub/net/ethernet.h
include/grub/net/netbuff.h
include/grub/net/udp.h

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