]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
IPv6. Apparently working. At least I could retrieve a file with http6
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Wed, 12 Oct 2011 23:22:56 +0000 (01:22 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Wed, 12 Oct 2011 23:22:56 +0000 (01:22 +0200)
grub-core/net/arp.c
grub-core/net/bootp.c
grub-core/net/icmp.c
grub-core/net/icmp6.c
grub-core/net/ip.c
grub-core/net/net.c
grub-core/net/tcp.c
grub-core/net/udp.c
include/grub/net.h
include/grub/net/ip.h
include/grub/net/netbuff.h

index b4c10531bb611fced503d500c9be241b7dc5801d..c9a7cb21e87426c2311d308a8b2baf4829e69117 100644 (file)
@@ -58,6 +58,7 @@ grub_net_arp_send_request (struct grub_net_network_level_interface *inf,
   int i;
   grub_size_t addrlen;
   grub_uint16_t etherpro;
+  grub_uint8_t *nbd;
 
   if (proto_addr->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4)
     {
@@ -99,6 +100,7 @@ grub_net_arp_send_request (struct grub_net_network_level_interface *inf,
   grub_memcpy (aux, &proto_addr->ipv4, 4);
   grub_memset (&target_hw_addr.mac, 0xff, 6);
 
+  nbd = nb.data;
   send_ethernet_packet (inf, &nb, target_hw_addr, GRUB_NET_ETHERTYPE_ARP);
   for (i = 0; i < GRUB_NET_TRIES; i++)
     {
@@ -107,6 +109,7 @@ grub_net_arp_send_request (struct grub_net_network_level_interface *inf,
       grub_net_poll_cards (GRUB_NET_INTERVAL);
       if (grub_net_link_layer_resolve_check (inf, proto_addr))
        return GRUB_ERR_NONE;
+      nb.data = nbd;
       send_ethernet_packet (inf, &nb, target_hw_addr, GRUB_NET_ETHERTYPE_ARP);
     }
 
@@ -142,7 +145,7 @@ grub_net_arp_receive (struct grub_net_buff *nb,
     return GRUB_ERR_NONE;
 
   sender_hw_addr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
-  grub_memcpy (sender_hw_addr.mac, &sender_hardware_address,
+  grub_memcpy (sender_hw_addr.mac, sender_hardware_address,
               sizeof (sender_hw_addr.mac));
   grub_net_link_layer_add_address (card, &sender_addr, &sender_hw_addr, 1);
 
index 1b852725539d90071532a13aa55f6f96621c477a..be79463ce46114f6bfbb368f571a1f0fd0eb7f0c 100644 (file)
@@ -493,7 +493,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)),
                                                         &ifaces[j].address,
                                                         &target);
 
-         err = grub_net_send_ip_packet (&ifaces[j], &target, nb,
+         err = grub_net_send_ip_packet (&ifaces[j], &target, NULL, nb,
                                         GRUB_NET_IP_UDP);
          grub_netbuff_free (nb);
          if (err)
index 88132b142e3c86ebdaa4e394bd357f5d2fa6cf00..9e6bc5c6fe1c31fc9b04085f04d91de580a3fe01 100644 (file)
@@ -106,7 +106,9 @@ grub_net_recv_icmp_packet (struct grub_net_buff *nb,
        icmphr->checksum = 0;
        icmphr->checksum = grub_net_ip_chksum ((void *) nb_reply->data,
                                               nb_reply->tail - nb_reply->data);
-       err = grub_net_send_ip_packet (inf, src, nb_reply, GRUB_NET_IP_ICMP);
+       /* FIXME: gateway pings.  */
+       err = grub_net_send_ip_packet (inf, src, NULL,
+                                      nb_reply, GRUB_NET_IP_ICMP);
 
       ping_fail:
        grub_netbuff_free (nb);
index 1f9278910c89bb56053ecd0975fd4b0a124c8043..b231f17e90cd0917251b721504bac95f9feea996 100644 (file)
@@ -182,7 +182,8 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
                                                           GRUB_NET_IP_ICMPV6,
                                                           &inf->address,
                                                           source);
-       err = grub_net_send_ip_packet (inf, source, nb_reply,
+       /* FIXME: gateway pings.  */
+       err = grub_net_send_ip_packet (inf, source, NULL, nb_reply,
                                       GRUB_NET_IP_ICMPV6);
 
       ping_fail:
@@ -288,7 +289,7 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
                                                           GRUB_NET_IP_ICMPV6,
                                                           &inf->address,
                                                           source);
-       err = grub_net_send_ip_packet (inf, source, nb_reply,
+       err = grub_net_send_ip_packet (inf, source, NULL, nb_reply,
                                       GRUB_NET_IP_ICMPV6);
 
       ndp_fail:
@@ -384,12 +385,19 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
                for (slaac = card->slaac_list; slaac; slaac = slaac->next)
                  {
                    grub_net_network_level_address_t addr;
+                   grub_net_network_level_netaddress_t netaddr;
+
                    if (slaac->address.type
                        != GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET)
                      continue;
                    addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
                    addr.ipv6[0] = opt->prefix[0];
                    addr.ipv6[1] = grub_net_ipv6_get_id (&slaac->address);
+                   netaddr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
+                   netaddr.ipv6.base[0] = opt->prefix[0];
+                   netaddr.ipv6.base[1] = 0;
+                   netaddr.ipv6.masksize = 64;
+
                    FOR_NET_NETWORK_LEVEL_INTERFACES (inf)
                    {
                      if (inf->card == card
@@ -408,9 +416,10 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
                                + sizeof (":XXXXXXXXXXXXXXXXXXXX")];
                      grub_snprintf (name, sizeof (name), "%s:%d",
                                     slaac->name, slaac->slaac_counter++);
-                     grub_net_add_addr (name, 
-                                        card, &addr,
-                                        &slaac->address, 0);
+                     inf = grub_net_add_addr (name, 
+                                              card, &addr,
+                                              &slaac->address, 0);
+                     grub_net_add_route (name, netaddr, inf);
                    }
                  }
              }
@@ -435,7 +444,7 @@ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf,
   struct neighbour_solicit *sol;
   struct icmp_header *icmphr;
   grub_net_network_level_address_t multicast;
-
+  grub_uint8_t *nbd;
   multicast.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
   multicast.ipv6[0] = grub_be_to_cpu64_compile_time (0xff02ULL << 48);
   multicast.ipv6[1] = (grub_be_to_cpu64_compile_time (0x01ff000000ULL)
@@ -467,7 +476,7 @@ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf,
     goto fail;
 
   ohdr = (struct option_header *) nb->data;
-  ohdr->type = OPTION_TARGET_LINK_LAYER_ADDRESS;
+  ohdr->type = OPTION_SOURCE_LINK_LAYER_ADDRESS;
   ohdr->len = 1;
   err = grub_netbuff_push (nb, sizeof (*sol));  
   if (err)
@@ -482,14 +491,15 @@ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf,
     goto fail;
 
   icmphr = (struct icmp_header *) nb->data;
-  icmphr->type = ICMP6_NEIGHBOUR_ADVERTISE;
+  icmphr->type = ICMP6_NEIGHBOUR_SOLICIT;
   icmphr->code = 0;
   icmphr->checksum = 0;
   icmphr->checksum = grub_net_ip_transport_checksum (nb,
                                                     GRUB_NET_IP_ICMPV6,
                                                     &inf->address,
                                                     &multicast);
-  err = grub_net_send_ip_packet (inf, &multicast, nb,
+  nbd = nb->data;
+  err = grub_net_send_ip_packet (inf, &multicast, NULL, nb,
                                 GRUB_NET_IP_ICMPV6);
   if (err)
     goto fail;
@@ -501,7 +511,8 @@ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf,
       grub_net_poll_cards (GRUB_NET_INTERVAL);
       if (grub_net_link_layer_resolve_check (inf, proto_addr))
        break;
-      err = grub_net_send_ip_packet (inf, &multicast, nb,
+      nb->data = nbd;
+      err = grub_net_send_ip_packet (inf, &multicast, NULL, nb,
                                     GRUB_NET_IP_ICMPV6);
       if (err)
        break;
index 27b8221fbf002069f0e64338543f5000d33d5741..19e12ddac17159f3d429ed9df82500d018bde2e8 100644 (file)
@@ -181,9 +181,10 @@ send_fragmented (struct grub_net_network_level_interface * inf,
 }
 
 static grub_err_t
-grub_net_send_ip4_packet (struct grub_net_network_level_interface * inf,
-                         const grub_net_network_level_address_t * target,
-                         struct grub_net_buff * nb,
+grub_net_send_ip4_packet (struct grub_net_network_level_interface *inf,
+                         const grub_net_network_level_address_t *target,
+                         const grub_net_network_level_address_t *gw,
+                         struct grub_net_buff *nb,
                          grub_net_ip_protocol_t proto)
 {
   struct iphdr *iph;
@@ -193,7 +194,7 @@ grub_net_send_ip4_packet (struct grub_net_network_level_interface * inf,
   COMPILE_TIME_ASSERT (GRUB_NET_OUR_IPV4_HEADER_SIZE == sizeof (*iph));
 
   /* Determine link layer target address via ARP.  */
-  err = grub_net_link_layer_resolve (inf, target, &ll_target_addr);
+  err = grub_net_link_layer_resolve (inf, gw ? : target, &ll_target_addr);
   if (err)
     return err;
 
@@ -578,9 +579,10 @@ grub_net_recv_ip4_packets (struct grub_net_buff * nb,
 }
 
 static grub_err_t
-grub_net_send_ip6_packet (struct grub_net_network_level_interface * inf,
-                         const grub_net_network_level_address_t * target,
-                         struct grub_net_buff * nb,
+grub_net_send_ip6_packet (struct grub_net_network_level_interface *inf,
+                         const grub_net_network_level_address_t *target,
+                         const grub_net_network_level_address_t *gw,
+                         struct grub_net_buff *nb,
                          grub_net_ip_protocol_t proto)
 {
   struct ip6hdr *iph;
@@ -590,7 +592,7 @@ grub_net_send_ip6_packet (struct grub_net_network_level_interface * inf,
   COMPILE_TIME_ASSERT (GRUB_NET_OUR_IPV6_HEADER_SIZE == sizeof (*iph));
 
   /* Determine link layer target address via ARP.  */
-  err = grub_net_link_layer_resolve (inf, target, &ll_target_addr);
+  err = grub_net_link_layer_resolve (inf, gw ? : target, &ll_target_addr);
   if (err)
     return err;
 
@@ -612,17 +614,18 @@ grub_net_send_ip6_packet (struct grub_net_network_level_interface * inf,
 }
 
 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,
+                        const grub_net_network_level_address_t *gw,
+                        struct grub_net_buff *nb,
                         grub_net_ip_protocol_t proto)
 {
   switch (target->type)
     {
     case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4:
-      return grub_net_send_ip4_packet (inf, target, nb, proto);
+      return grub_net_send_ip4_packet (inf, target, gw, nb, proto);
     case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6:
-      return grub_net_send_ip6_packet (inf, target, nb, proto);
+      return grub_net_send_ip6_packet (inf, target, gw, nb, proto);
     default:
       return grub_error (GRUB_ERR_BAD_ARGUMENT, "not an IP");
     }
index 1134223b2cb4d426cd4c7091a91d5a615a128feb..2e8d9678ed7e7e46f867a55729d3d433ab9b8dd5 100644 (file)
@@ -160,8 +160,6 @@ grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf,
       return GRUB_ERR_NONE;
     }
 
-
-
   /* Check cache table.  */
   entry = link_layer_find_entry (proto_addr, inf->card);
   if (entry)
@@ -378,18 +376,23 @@ static int
 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++)
     {
+      unsigned long t;
       t = grub_strtoul (ptr, (char **) &ptr, 0);
       if (grub_errno)
        {
          grub_errno = GRUB_ERR_NONE;
          return 0;
        }
+      if (*ptr != '.' && i == 0)
+       {
+         newip = t;
+         break;
+       }
       if (t & ~0xff)
        return 0;
       newip >>= 8;
@@ -400,7 +403,56 @@ parse_ip (const char *val, grub_uint32_t *ip, const char **rest)
     }
   *ip = grub_cpu_to_le32 (newip);
   if (rest)
-    *rest = ptr - 1;
+    *rest = (ptr - 1);
+  return 1;
+}
+
+static int
+parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest)
+{
+  grub_uint16_t newip[8];
+  const char *ptr = val;
+  int word, quaddot = -1;
+
+  if (ptr[0] == ':' && ptr[1] != ':')
+    return 0;
+  if (ptr[0] == ':')
+    ptr++;
+
+  for (word = 0; word < 8; word++)
+    {
+      unsigned long t;
+      if (*ptr == ':')
+       {
+         quaddot = word;
+         word--;
+         ptr++;
+         continue;
+       }
+      t = grub_strtoul (ptr, (char **) &ptr, 16);
+      if (grub_errno)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         break;
+       }
+      if (t & ~0xffff)
+       return 0;
+      newip[word] = grub_cpu_to_be16 (t);
+      if (*ptr != ':')
+       break;
+      ptr++;
+    }
+  if (quaddot == -1 && word < 7)
+    return 0;
+  if (quaddot != -1)
+    {
+      grub_memmove (&newip[quaddot + 7 - word], &newip[quaddot],
+                   (word - quaddot + 1) * sizeof (newip[0]));
+      grub_memset (&newip[quaddot], 0, (7 - word) * sizeof (newip[0]));
+    }
+  grub_memcpy (ip, newip, 16);
+  if (rest)
+    *rest = ptr;
   return 1;
 }
 
@@ -422,16 +474,21 @@ match_net (const grub_net_network_level_netaddress_t *net,
       }
     case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6:
       {
-       grub_int64_t mask[2];
-       mask[1] = 0xffffffffffffffffULL << (128 - net->ipv6.masksize);
-       if (net->ipv6.masksize < 64)
-         mask[0] = 0xffffffffffffffffULL;
+       grub_uint64_t mask[2];
+       if (net->ipv6.masksize <= 64)
+         {
+           mask[0] = 0xffffffffffffffffULL << (64 - net->ipv6.masksize);
+           mask[1] = 0;
+         }
        else 
-         mask[0] = 0xffffffffffffffffULL << (64 - net->ipv6.masksize);
+         {
+           mask[0] = 0xffffffffffffffffULL;
+           mask[1] = 0xffffffffffffffffULL << (128 - net->ipv6.masksize);
+         }
        return (((grub_be_to_cpu64 (net->ipv6.base[0]) & mask[0])
-               == (grub_be_to_cpu32 (addr->ipv6[0]) & mask[0]))
+               == (grub_be_to_cpu64 (addr->ipv6[0]) & mask[0]))
                && ((grub_be_to_cpu64 (net->ipv6.base[1]) & mask[1])
-                   == (grub_be_to_cpu32 (addr->ipv6[1]) & mask[1])));
+                   == (grub_be_to_cpu64 (addr->ipv6[1]) & mask[1])));
       }
     }
   return 0;
@@ -441,11 +498,17 @@ grub_err_t
 grub_net_resolve_address (const char *name,
                          grub_net_network_level_address_t *addr)
 {
-  if (parse_ip (name, &addr->ipv4, NULL))
+  const char *rest;
+  if (parse_ip (name, &addr->ipv4, &rest) && *rest == 0)
     {
       addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
       return GRUB_ERR_NONE;
     }
+  if (parse_ip6 (name, addr->ipv6, &rest) && *rest == 0)
+    {
+      addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
+      return GRUB_ERR_NONE;
+    }
   return grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("unrecognised address %s"),
                     name);
 }
@@ -460,12 +523,32 @@ grub_net_resolve_net_address (const char *name,
       addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
       if (*rest == '/')
        {
-         addr->ipv4.masksize = grub_strtoul (rest + 1, NULL, 0);
-         if (!grub_errno)
-           return GRUB_ERR_NONE;           
+         addr->ipv4.masksize = grub_strtoul (rest + 1, (char **) &rest, 0);
+         if (!grub_errno && *rest == 0)
+           return GRUB_ERR_NONE;
+         grub_errno = GRUB_ERR_NONE;
+       }
+      else if (*rest == 0)
+       {
+         addr->ipv4.masksize = 32;
+         return GRUB_ERR_NONE;
+       }
+    }
+  if (parse_ip6 (name, addr->ipv6.base, &rest))
+    {
+      addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
+      if (*rest == '/')
+       {
+         addr->ipv6.masksize = grub_strtoul (rest + 1, (char **) &rest, 0);
+         if (!grub_errno && *rest == 0)
+           return GRUB_ERR_NONE;
+         grub_errno = GRUB_ERR_NONE;
+       }
+      else if (*rest == 0)
+       {
+         addr->ipv6.masksize = 128;
+         return GRUB_ERR_NONE;
        }
-      addr->ipv4.masksize = 32;
-      return GRUB_ERR_NONE;
     }
   return grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("unrecognised address %s"),
                     name);
index 72ee8a239d2f8c0bcc8e3ac910d15ba42a6e8fc9..ae1dc57edabf91ef76062dc69814b5b924a75e99 100644 (file)
@@ -69,7 +69,7 @@ struct grub_net_tcp_socket
                           void *recv);
   void (*error_hook) (grub_net_tcp_socket_t sock, void *recv);
   void *hook_data;
-  grub_net_network_level_address_t out_nla;
+  grub_net_network_level_address_t out_nla, gw;
   struct grub_net_network_level_interface *inf;
   grub_net_packets_t packs;
   grub_priority_queue_t pq;
@@ -216,8 +216,8 @@ tcp_send (struct grub_net_buff *nb, grub_net_tcp_socket_t socket)
        socket->unack_last->next = unack;
     }
 
-  err = grub_net_send_ip_packet (socket->inf, &(socket->out_nla), nb,
-                                GRUB_NET_IP_TCP);
+  err = grub_net_send_ip_packet (socket->inf, &(socket->out_nla),
+                                &(socket->gw),nb, GRUB_NET_IP_TCP);
   if (err)
     return err;
   nb->data = nbd;
@@ -240,11 +240,11 @@ grub_net_tcp_close (grub_net_tcp_socket_t sock,
     sock->recv_hook = NULL;
 
   nb_fin = grub_netbuff_alloc (sizeof (*tcph_fin)
-                              + GRUB_NET_OUR_IPV4_HEADER_SIZE
+                              + GRUB_NET_OUR_MAX_IP_HEADER_SIZE
                               + GRUB_NET_MAX_LINK_HEADER_SIZE);
   if (!nb_fin)
     return;
-  err = grub_netbuff_reserve (nb_fin, GRUB_NET_OUR_IPV4_HEADER_SIZE
+  err = grub_netbuff_reserve (nb_fin, GRUB_NET_OUR_MAX_IP_HEADER_SIZE
                               + GRUB_NET_MAX_LINK_HEADER_SIZE);
   if (err)
     {
@@ -368,7 +368,8 @@ grub_net_tcp_retransmit (void)
        unack->try_count++;
        unack->last_try = ctime;
        nbd = unack->nb->data;
-       err = grub_net_send_ip_packet (sock->inf, &(sock->out_nla), unack->nb,
+       err = grub_net_send_ip_packet (sock->inf, &(sock->out_nla),
+                                      &(sock->gw), unack->nb,
                                       GRUB_NET_IP_TCP);
        unack->nb->data = nbd;
        if (err)
@@ -468,11 +469,11 @@ grub_net_tcp_accept (grub_net_tcp_socket_t sock,
   sock->error_hook = error_hook;
   sock->hook_data = hook_data;
   nb_ack = grub_netbuff_alloc (sizeof (*tcph)
-                              + GRUB_NET_OUR_IPV4_HEADER_SIZE
+                              + GRUB_NET_OUR_MAX_IP_HEADER_SIZE
                               + GRUB_NET_MAX_LINK_HEADER_SIZE);
   if (!nb_ack)
     return grub_errno;
-  err = grub_netbuff_reserve (nb_ack, GRUB_NET_OUR_IPV4_HEADER_SIZE
+  err = grub_netbuff_reserve (nb_ack, GRUB_NET_OUR_MAX_IP_HEADER_SIZE
                              + GRUB_NET_MAX_LINK_HEADER_SIZE);
   if (err)
     {
@@ -525,9 +526,10 @@ grub_net_tcp_open (char *server,
   if (err)
     return NULL;
 
-  if (addr.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4)
+  if (addr.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
+      && addr.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6)
     {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "not a IPv4 address");
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "not an IP address");
       return NULL;
     }
  
@@ -542,6 +544,7 @@ grub_net_tcp_open (char *server,
   socket->out_port = out_port;
   socket->inf = inf;
   socket->out_nla = addr;
+  socket->gw = gateway;
   socket->in_port = in_port++;
   socket->recv_hook = recv_hook;
   socket->error_hook = error_hook;
@@ -593,7 +596,8 @@ grub_net_tcp_open (char *server,
     {
       int j;
       nb->data = nbd;
-      err = grub_net_send_ip_packet (socket->inf, &(socket->out_nla), nb,
+      err = grub_net_send_ip_packet (socket->inf, &(socket->out_nla), 
+                                    &(socket->gw), nb,
                                     GRUB_NET_IP_TCP);
       if (err)
        {
@@ -636,20 +640,23 @@ grub_net_send_tcp_packet (const grub_net_tcp_socket_t socket,
   grub_err_t err;
   grub_ssize_t fraglen;
   COMPILE_TIME_ASSERT (sizeof (struct tcphdr) == GRUB_NET_TCP_HEADER_SIZE);
-  fraglen = (socket->inf->card->mtu - GRUB_NET_OUR_IPV4_HEADER_SIZE
-            - sizeof (*tcph));
+  if (socket->out_nla.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4)
+    fraglen = (socket->inf->card->mtu - GRUB_NET_OUR_IPV4_HEADER_SIZE
+              - sizeof (*tcph));
+  else
+    fraglen = 1280 - GRUB_NET_OUR_IPV6_HEADER_SIZE;
 
   while (nb->tail - nb->data > fraglen)
     {
       struct grub_net_buff *nb2;
 
       nb2 = grub_netbuff_alloc (fraglen + sizeof (*tcph)
-                               + GRUB_NET_OUR_IPV4_HEADER_SIZE
+                               + GRUB_NET_OUR_MAX_IP_HEADER_SIZE
                                + GRUB_NET_MAX_LINK_HEADER_SIZE);
       if (!nb2)
        return grub_errno;
       err = grub_netbuff_reserve (nb2, GRUB_NET_MAX_LINK_HEADER_SIZE
-                                 + GRUB_NET_OUR_IPV4_HEADER_SIZE);
+                                 + GRUB_NET_OUR_MAX_IP_HEADER_SIZE);
       if (err)
        return err;
       err = grub_netbuff_put (nb2, sizeof (*tcph));
@@ -724,8 +731,7 @@ grub_net_recv_tcp_packet (struct grub_net_buff *nb,
     if (!(grub_be_to_cpu16 (tcph->dst) == sock->in_port
          && grub_be_to_cpu16 (tcph->src) == sock->out_port
          && inf == sock->inf
-         && source->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
-         && source->ipv4 == sock->out_nla.ipv4))
+         && grub_net_addr_cmp (source, &sock->out_nla) == 0))
       continue;
     if (tcph->checksum)
       {
index a2315dd3fb64a475e13d433a654cc2de5e653f81..2284d8f6c2947995ad552d0fd6cfb6f877a0196d 100644 (file)
@@ -34,7 +34,7 @@ struct grub_net_udp_socket
   grub_err_t (*recv_hook) (grub_net_udp_socket_t sock, struct grub_net_buff *nb,
                           void *recv);
   void *recv_hook_data;
-  grub_net_network_level_address_t out_nla;
+  grub_net_network_level_address_t out_nla, gw;
   struct grub_net_network_level_interface *inf;
 };
 
@@ -76,9 +76,10 @@ grub_net_udp_open (char *server,
   if (err)
     return NULL;
 
-  if (addr.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4)
+  if (addr.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
+      && addr.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6)
     {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "not a IPv4 address");
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "not an IP address");
       return NULL;
     }
  
@@ -93,6 +94,7 @@ grub_net_udp_open (char *server,
   socket->out_port = out_port;
   socket->inf = inf;
   socket->out_nla = addr;
+  socket->gw = gateway;
   socket->in_port = in_port++;
   socket->status = GRUB_NET_SOCKET_START;
   socket->recv_hook = recv_hook;
@@ -127,8 +129,8 @@ grub_net_send_udp_packet (const grub_net_udp_socket_t socket,
                                                 &socket->inf->address,
                                                 &socket->out_nla);
 
-  return grub_net_send_ip_packet (socket->inf, &(socket->out_nla), nb,
-                                 GRUB_NET_IP_UDP);
+  return grub_net_send_ip_packet (socket->inf, &(socket->out_nla),
+                                 &(socket->gw), nb, GRUB_NET_IP_UDP);
 }
 
 grub_err_t
@@ -160,8 +162,7 @@ grub_net_recv_udp_packet (struct grub_net_buff *nb,
   {
     if (grub_be_to_cpu16 (udph->dst) == sock->in_port
        && inf == sock->inf
-       && source->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
-       && source->ipv4 == sock->out_nla.ipv4
+       && grub_net_addr_cmp (source, &sock->out_nla) == 0
        && (sock->status == GRUB_NET_SOCKET_START
            || grub_be_to_cpu16 (udph->src) == sock->out_port))
       {
index e3f7525be909ebedc47b16d0a7ced70e3c2b8670..b3adb74f9137b0323a1176a917eaba966fbab999 100644 (file)
@@ -34,6 +34,7 @@ enum
     GRUB_NET_TCP_HEADER_SIZE = 20,
     GRUB_NET_OUR_IPV4_HEADER_SIZE = 20,
     GRUB_NET_OUR_IPV6_HEADER_SIZE = 40,
+    GRUB_NET_OUR_MAX_IP_HEADER_SIZE = 40,
     GRUB_NET_TCP_RESERVE_SIZE = GRUB_NET_TCP_HEADER_SIZE 
     + GRUB_NET_OUR_IPV4_HEADER_SIZE
     + GRUB_NET_MAX_LINK_HEADER_SIZE
index 78053de60bdc25d6688f81519063e11aa09c7ef6..1b3c0893a98d135a2a0e5f779ee64e53c953b3bd 100644 (file)
@@ -52,6 +52,7 @@ grub_net_recv_ip_packets (struct grub_net_buff *nb,
 grub_err_t
 grub_net_send_ip_packet (struct grub_net_network_level_interface *inf,
                         const grub_net_network_level_address_t *target,
+                        const grub_net_network_level_address_t *gw,
                         struct grub_net_buff *nb,
                         grub_net_ip_protocol_t proto);
 
index 5fafd89f6baa35f69a283254e8182823be34cac0..c745d51d706883fdbaffcdd37a2dd1d3a03595a6 100644 (file)
@@ -18,13 +18,13 @@ struct grub_net_buff
   grub_uint8_t *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);
+grub_err_t grub_netbuff_put (struct grub_net_buff *net_buffgrub_size_t len);
+grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buffgrub_size_t len);
+grub_err_t grub_netbuff_push (struct grub_net_buff *net_buffgrub_size_t len);
+grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buffgrub_size_t len);
+grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buffgrub_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 );
+struct grub_net_buff * grub_netbuff_alloc (grub_size_t len);
 grub_err_t grub_netbuff_free (struct grub_net_buff *net_buff);
 
 #endif