IPv6. Apparently working. At least I could retrieve a file with http6
This commit is contained in:
		
							parent
							
								
									7c006811f8
								
							
						
					
					
						commit
						da1b289afc
					
				
					 11 changed files with 184 additions and 73 deletions
				
			
		|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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"); | ||||
|     } | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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) | ||||
|       { | ||||
|  |  | |||
|  | @ -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)) | ||||
|       { | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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_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_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 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue