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…
Reference in a new issue