support routed pings

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-10-13 20:53:22 +02:00
parent bd40efbf0b
commit 0cb9503b70
8 changed files with 79 additions and 57 deletions

View file

@ -458,6 +458,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)),
struct grub_net_buff *nb; struct grub_net_buff *nb;
struct udphdr *udph; struct udphdr *udph;
grub_net_network_level_address_t target; grub_net_network_level_address_t target;
grub_net_link_level_address_t ll_target;
if (!ifaces[j].prev) if (!ifaces[j].prev)
continue; continue;
@ -505,11 +506,15 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)),
udph->len = grub_cpu_to_be16 (nb->tail - nb->data); udph->len = grub_cpu_to_be16 (nb->tail - nb->data);
target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
target.ipv4 = 0xffffffff; target.ipv4 = 0xffffffff;
err = grub_net_link_layer_resolve (&ifaces[j], &target, &ll_target);
if (err)
return err;
udph->chksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP, udph->chksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP,
&ifaces[j].address, &ifaces[j].address,
&target); &target);
err = grub_net_send_ip_packet (&ifaces[j], &target, NULL, nb, err = grub_net_send_ip_packet (&ifaces[j], &target, &ll_target, nb,
GRUB_NET_IP_UDP); GRUB_NET_IP_UDP);
grub_netbuff_free (nb); grub_netbuff_free (nb);
if (err) if (err)

View file

@ -88,6 +88,7 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb,
struct snaphdr *snaph; struct snaphdr *snaph;
grub_net_ethertype_t type; grub_net_ethertype_t type;
grub_net_link_level_address_t hwaddress; grub_net_link_level_address_t hwaddress;
grub_net_link_level_address_t src_hwaddress;
grub_err_t err; grub_err_t err;
eth = (struct etherhdr *) nb->data; eth = (struct etherhdr *) nb->data;
@ -113,6 +114,8 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb,
hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
grub_memcpy (hwaddress.mac, eth->dst, sizeof (hwaddress.mac)); grub_memcpy (hwaddress.mac, eth->dst, sizeof (hwaddress.mac));
src_hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
grub_memcpy (src_hwaddress.mac, eth->src, sizeof (src_hwaddress.mac));
switch (type) switch (type)
{ {
@ -124,7 +127,7 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb,
/* IP packet. */ /* IP packet. */
case GRUB_NET_ETHERTYPE_IP: case GRUB_NET_ETHERTYPE_IP:
case GRUB_NET_ETHERTYPE_IP6: case GRUB_NET_ETHERTYPE_IP6:
return grub_net_recv_ip_packets (nb, card, &hwaddress); return grub_net_recv_ip_packets (nb, card, &hwaddress, &src_hwaddress);
} }
grub_netbuff_free (nb); grub_netbuff_free (nb);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;

View file

@ -42,6 +42,7 @@ enum
grub_err_t grub_err_t
grub_net_recv_icmp_packet (struct grub_net_buff *nb, grub_net_recv_icmp_packet (struct grub_net_buff *nb,
struct grub_net_network_level_interface *inf, struct grub_net_network_level_interface *inf,
const grub_net_link_level_address_t *ll_src,
const grub_net_network_level_address_t *src) const grub_net_network_level_address_t *src)
{ {
struct icmp_header *icmph; struct icmp_header *icmph;
@ -106,8 +107,7 @@ grub_net_recv_icmp_packet (struct grub_net_buff *nb,
icmphr->checksum = 0; icmphr->checksum = 0;
icmphr->checksum = grub_net_ip_chksum ((void *) nb_reply->data, icmphr->checksum = grub_net_ip_chksum ((void *) nb_reply->data,
nb_reply->tail - nb_reply->data); nb_reply->tail - nb_reply->data);
/* FIXME: gateway pings. */ err = grub_net_send_ip_packet (inf, src, ll_src,
err = grub_net_send_ip_packet (inf, src, NULL,
nb_reply, GRUB_NET_IP_ICMP); nb_reply, GRUB_NET_IP_ICMP);
ping_fail: ping_fail:

View file

@ -103,6 +103,7 @@ grub_err_t
grub_net_recv_icmp6_packet (struct grub_net_buff *nb, grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
struct grub_net_card *card, struct grub_net_card *card,
struct grub_net_network_level_interface *inf, struct grub_net_network_level_interface *inf,
const grub_net_link_level_address_t *ll_src,
const grub_net_network_level_address_t *source, const grub_net_network_level_address_t *source,
const grub_net_network_level_address_t *dest, const grub_net_network_level_address_t *dest,
grub_uint8_t ttl) grub_uint8_t ttl)
@ -182,8 +183,7 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
GRUB_NET_IP_ICMPV6, GRUB_NET_IP_ICMPV6,
&inf->address, &inf->address,
source); source);
/* FIXME: gateway pings. */ err = grub_net_send_ip_packet (inf, source, ll_src, nb_reply,
err = grub_net_send_ip_packet (inf, source, NULL, nb_reply,
GRUB_NET_IP_ICMPV6); GRUB_NET_IP_ICMPV6);
ping_fail: ping_fail:
@ -289,7 +289,7 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
GRUB_NET_IP_ICMPV6, GRUB_NET_IP_ICMPV6,
&inf->address, &inf->address,
source); source);
err = grub_net_send_ip_packet (inf, source, NULL, nb_reply, err = grub_net_send_ip_packet (inf, source, ll_src, nb_reply,
GRUB_NET_IP_ICMPV6); GRUB_NET_IP_ICMPV6);
ndp_fail: ndp_fail:
@ -444,6 +444,7 @@ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf,
struct neighbour_solicit *sol; struct neighbour_solicit *sol;
struct icmp_header *icmphr; struct icmp_header *icmphr;
grub_net_network_level_address_t multicast; grub_net_network_level_address_t multicast;
grub_net_link_level_address_t ll_multicast;
grub_uint8_t *nbd; grub_uint8_t *nbd;
multicast.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; multicast.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
multicast.ipv6[0] = grub_be_to_cpu64_compile_time (0xff02ULL << 48); multicast.ipv6[0] = grub_be_to_cpu64_compile_time (0xff02ULL << 48);
@ -451,6 +452,10 @@ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf,
| (proto_addr->ipv6[1] | (proto_addr->ipv6[1]
& grub_be_to_cpu64_compile_time (0xffffff))); & grub_be_to_cpu64_compile_time (0xffffff)));
err = grub_net_link_layer_resolve (inf, &multicast, &ll_multicast);
if (err)
return err;
nb = grub_netbuff_alloc (sizeof (struct neighbour_solicit) nb = grub_netbuff_alloc (sizeof (struct neighbour_solicit)
+ sizeof (struct option_header) + sizeof (struct option_header)
+ 6 + 6
@ -499,7 +504,7 @@ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf,
&inf->address, &inf->address,
&multicast); &multicast);
nbd = nb->data; nbd = nb->data;
err = grub_net_send_ip_packet (inf, &multicast, NULL, nb, err = grub_net_send_ip_packet (inf, &multicast, &ll_multicast, nb,
GRUB_NET_IP_ICMPV6); GRUB_NET_IP_ICMPV6);
if (err) if (err)
goto fail; goto fail;
@ -512,7 +517,7 @@ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf,
if (grub_net_link_layer_resolve_check (inf, proto_addr)) if (grub_net_link_layer_resolve_check (inf, proto_addr))
break; break;
nb->data = nbd; nb->data = nbd;
err = grub_net_send_ip_packet (inf, &multicast, NULL, nb, err = grub_net_send_ip_packet (inf, &multicast, &ll_multicast, nb,
GRUB_NET_IP_ICMPV6); GRUB_NET_IP_ICMPV6);
if (err) if (err)
break; break;

View file

@ -183,23 +183,16 @@ send_fragmented (struct grub_net_network_level_interface * inf,
static grub_err_t static grub_err_t
grub_net_send_ip4_packet (struct grub_net_network_level_interface *inf, 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 *target,
const grub_net_network_level_address_t *gw, const grub_net_link_level_address_t *ll_target_addr,
struct grub_net_buff *nb, struct grub_net_buff *nb,
grub_net_ip_protocol_t proto) grub_net_ip_protocol_t proto)
{ {
struct iphdr *iph; struct iphdr *iph;
grub_net_link_level_address_t ll_target_addr;
grub_err_t err;
COMPILE_TIME_ASSERT (GRUB_NET_OUR_IPV4_HEADER_SIZE == sizeof (*iph)); 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, gw ? : target, &ll_target_addr);
if (err)
return err;
if (nb->tail - nb->data + sizeof (struct iphdr) > inf->card->mtu) if (nb->tail - nb->data + sizeof (struct iphdr) > inf->card->mtu)
return send_fragmented (inf, target, nb, proto, ll_target_addr); return send_fragmented (inf, target, nb, proto, *ll_target_addr);
grub_netbuff_push (nb, sizeof (*iph)); grub_netbuff_push (nb, sizeof (*iph));
iph = (struct iphdr *) nb->data; iph = (struct iphdr *) nb->data;
@ -217,13 +210,14 @@ grub_net_send_ip4_packet (struct grub_net_network_level_interface *inf,
iph->chksum = 0; iph->chksum = 0;
iph->chksum = grub_net_ip_chksum ((void *) nb->data, sizeof (*iph)); iph->chksum = grub_net_ip_chksum ((void *) nb->data, sizeof (*iph));
return send_ethernet_packet (inf, nb, ll_target_addr, return send_ethernet_packet (inf, nb, *ll_target_addr,
GRUB_NET_ETHERTYPE_IP); GRUB_NET_ETHERTYPE_IP);
} }
static grub_err_t static grub_err_t
handle_dgram (struct grub_net_buff *nb, handle_dgram (struct grub_net_buff *nb,
struct grub_net_card *card, struct grub_net_card *card,
const grub_net_link_level_address_t *source_hwaddress,
const grub_net_link_level_address_t *hwaddress, const grub_net_link_level_address_t *hwaddress,
grub_net_ip_protocol_t proto, grub_net_ip_protocol_t proto,
const grub_net_network_level_address_t *source, const grub_net_network_level_address_t *source,
@ -325,9 +319,10 @@ handle_dgram (struct grub_net_buff *nb,
case GRUB_NET_IP_TCP: case GRUB_NET_IP_TCP:
return grub_net_recv_tcp_packet (nb, inf, source); return grub_net_recv_tcp_packet (nb, inf, source);
case GRUB_NET_IP_ICMP: case GRUB_NET_IP_ICMP:
return grub_net_recv_icmp_packet (nb, inf, source); return grub_net_recv_icmp_packet (nb, inf, source_hwaddress, source);
case GRUB_NET_IP_ICMPV6: case GRUB_NET_IP_ICMPV6:
return grub_net_recv_icmp6_packet (nb, card, inf, source, dest, ttl); return grub_net_recv_icmp6_packet (nb, card, inf, source_hwaddress,
source, dest, ttl);
default: default:
grub_netbuff_free (nb); grub_netbuff_free (nb);
break; break;
@ -365,7 +360,8 @@ free_old_fragments (void)
static grub_err_t static grub_err_t
grub_net_recv_ip4_packets (struct grub_net_buff *nb, grub_net_recv_ip4_packets (struct grub_net_buff *nb,
struct grub_net_card *card, struct grub_net_card *card,
const grub_net_link_level_address_t * hwaddress) const grub_net_link_level_address_t *hwaddress,
const grub_net_link_level_address_t *src_hwaddress)
{ {
struct iphdr *iph = (struct iphdr *) nb->data; struct iphdr *iph = (struct iphdr *) nb->data;
grub_err_t err; grub_err_t err;
@ -439,7 +435,7 @@ grub_net_recv_ip4_packets (struct grub_net_buff * nb,
dest.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; dest.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
dest.ipv4 = iph->dest; dest.ipv4 = iph->dest;
return handle_dgram (nb, card, hwaddress, iph->protocol, return handle_dgram (nb, card, src_hwaddress, hwaddress, iph->protocol,
&source, &dest, iph->ttl); &source, &dest, iph->ttl);
} }
@ -571,7 +567,8 @@ grub_net_recv_ip4_packets (struct grub_net_buff * nb,
dest.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; dest.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
dest.ipv4 = dst; dest.ipv4 = dst;
return handle_dgram (ret, card, hwaddress, proto, &source, &dest, return handle_dgram (ret, card, src_hwaddress,
hwaddress, proto, &source, &dest,
ttl); ttl);
} }
@ -581,21 +578,14 @@ grub_net_recv_ip4_packets (struct grub_net_buff * nb,
static grub_err_t static grub_err_t
grub_net_send_ip6_packet (struct grub_net_network_level_interface *inf, 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 *target,
const grub_net_network_level_address_t *gw, const grub_net_link_level_address_t *ll_target_addr,
struct grub_net_buff *nb, struct grub_net_buff *nb,
grub_net_ip_protocol_t proto) grub_net_ip_protocol_t proto)
{ {
struct ip6hdr *iph; struct ip6hdr *iph;
grub_net_link_level_address_t ll_target_addr;
grub_err_t err;
COMPILE_TIME_ASSERT (GRUB_NET_OUR_IPV6_HEADER_SIZE == sizeof (*iph)); 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, gw ? : target, &ll_target_addr);
if (err)
return err;
if (nb->tail - nb->data + sizeof (struct iphdr) > inf->card->mtu) if (nb->tail - nb->data + sizeof (struct iphdr) > inf->card->mtu)
return grub_error (GRUB_ERR_NET_PACKET_TOO_BIG, "packet too big"); return grub_error (GRUB_ERR_NET_PACKET_TOO_BIG, "packet too big");
@ -609,23 +599,23 @@ grub_net_send_ip6_packet (struct grub_net_network_level_interface *inf,
grub_memcpy (&iph->src, inf->address.ipv6, sizeof (iph->src)); grub_memcpy (&iph->src, inf->address.ipv6, sizeof (iph->src));
grub_memcpy (&iph->dest, target->ipv6, sizeof (iph->dest)); grub_memcpy (&iph->dest, target->ipv6, sizeof (iph->dest));
return send_ethernet_packet (inf, nb, ll_target_addr, return send_ethernet_packet (inf, nb, *ll_target_addr,
GRUB_NET_ETHERTYPE_IP6); GRUB_NET_ETHERTYPE_IP6);
} }
grub_err_t grub_err_t
grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, 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 *target,
const grub_net_network_level_address_t *gw, const grub_net_link_level_address_t *ll_target_addr,
struct grub_net_buff *nb, struct grub_net_buff *nb,
grub_net_ip_protocol_t proto) grub_net_ip_protocol_t proto)
{ {
switch (target->type) switch (target->type)
{ {
case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4:
return grub_net_send_ip4_packet (inf, target, gw, nb, proto); return grub_net_send_ip4_packet (inf, target, ll_target_addr, nb, proto);
case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6: case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6:
return grub_net_send_ip6_packet (inf, target, gw, nb, proto); return grub_net_send_ip6_packet (inf, target, ll_target_addr, nb, proto);
default: default:
return grub_error (GRUB_ERR_BAD_ARGUMENT, "not an IP"); return grub_error (GRUB_ERR_BAD_ARGUMENT, "not an IP");
} }
@ -634,7 +624,8 @@ grub_net_send_ip_packet (struct grub_net_network_level_interface *inf,
static grub_err_t static grub_err_t
grub_net_recv_ip6_packets (struct grub_net_buff *nb, grub_net_recv_ip6_packets (struct grub_net_buff *nb,
struct grub_net_card *card, struct grub_net_card *card,
const grub_net_link_level_address_t * hwaddress) const grub_net_link_level_address_t *hwaddress,
const grub_net_link_level_address_t *src_hwaddress)
{ {
struct ip6hdr *iph = (struct ip6hdr *) nb->data; struct ip6hdr *iph = (struct ip6hdr *) nb->data;
grub_err_t err; grub_err_t err;
@ -684,21 +675,22 @@ grub_net_recv_ip6_packets (struct grub_net_buff * nb,
grub_memcpy (source.ipv6, &iph->src, sizeof (source.ipv6)); grub_memcpy (source.ipv6, &iph->src, sizeof (source.ipv6));
grub_memcpy (dest.ipv6, &iph->dest, sizeof (dest.ipv6)); grub_memcpy (dest.ipv6, &iph->dest, sizeof (dest.ipv6));
return handle_dgram (nb, card, hwaddress, iph->protocol, return handle_dgram (nb, card, src_hwaddress, hwaddress, iph->protocol,
&source, &dest, iph->ttl); &source, &dest, iph->ttl);
} }
grub_err_t grub_err_t
grub_net_recv_ip_packets (struct grub_net_buff *nb, grub_net_recv_ip_packets (struct grub_net_buff *nb,
struct grub_net_card *card, struct grub_net_card *card,
const grub_net_link_level_address_t * hwaddress) const grub_net_link_level_address_t *hwaddress,
const grub_net_link_level_address_t *src_hwaddress)
{ {
struct iphdr *iph = (struct iphdr *) nb->data; struct iphdr *iph = (struct iphdr *) nb->data;
if ((iph->verhdrlen >> 4) == 4) if ((iph->verhdrlen >> 4) == 4)
return grub_net_recv_ip4_packets (nb, card, hwaddress); return grub_net_recv_ip4_packets (nb, card, hwaddress, src_hwaddress);
if ((iph->verhdrlen >> 4) == 6) if ((iph->verhdrlen >> 4) == 6)
return grub_net_recv_ip6_packets (nb, card, hwaddress); return grub_net_recv_ip6_packets (nb, card, hwaddress, src_hwaddress);
grub_dprintf ("net", "Bad IP version: %d\n", (iph->verhdrlen >> 4)); grub_dprintf ("net", "Bad IP version: %d\n", (iph->verhdrlen >> 4));
grub_netbuff_free (nb); grub_netbuff_free (nb);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;

View file

@ -70,7 +70,8 @@ struct grub_net_tcp_socket
void (*error_hook) (grub_net_tcp_socket_t sock, void *recv); void (*error_hook) (grub_net_tcp_socket_t sock, void *recv);
void (*fin_hook) (grub_net_tcp_socket_t sock, void *recv); void (*fin_hook) (grub_net_tcp_socket_t sock, void *recv);
void *hook_data; void *hook_data;
grub_net_network_level_address_t out_nla, gw; grub_net_network_level_address_t out_nla;
grub_net_link_level_address_t ll_target_addr;
struct grub_net_network_level_interface *inf; struct grub_net_network_level_interface *inf;
grub_net_packets_t packs; grub_net_packets_t packs;
grub_priority_queue_t pq; grub_priority_queue_t pq;
@ -218,7 +219,8 @@ tcp_send (struct grub_net_buff *nb, grub_net_tcp_socket_t socket)
} }
err = grub_net_send_ip_packet (socket->inf, &(socket->out_nla), err = grub_net_send_ip_packet (socket->inf, &(socket->out_nla),
&(socket->gw),nb, GRUB_NET_IP_TCP); &(socket->ll_target_addr), nb,
GRUB_NET_IP_TCP);
if (err) if (err)
return err; return err;
nb->data = nbd; nb->data = nbd;
@ -392,7 +394,7 @@ grub_net_tcp_retransmit (void)
} }
err = grub_net_send_ip_packet (sock->inf, &(sock->out_nla), err = grub_net_send_ip_packet (sock->inf, &(sock->out_nla),
&(sock->gw), unack->nb, &(sock->ll_target_addr), unack->nb,
GRUB_NET_IP_TCP); GRUB_NET_IP_TCP);
unack->nb->data = nbd; unack->nb->data = nbd;
if (err) if (err)
@ -552,6 +554,7 @@ grub_net_tcp_open (char *server,
struct tcphdr *tcph; struct tcphdr *tcph;
int i; int i;
grub_uint8_t *nbd; grub_uint8_t *nbd;
grub_net_link_level_address_t ll_target_addr;
err = grub_net_resolve_address (server, &addr); err = grub_net_resolve_address (server, &addr);
if (err) if (err)
@ -568,6 +571,10 @@ grub_net_tcp_open (char *server,
if (err) if (err)
return NULL; return NULL;
err = grub_net_link_layer_resolve (inf, &gateway, &ll_target_addr);
if (err)
return NULL;
socket = grub_zalloc (sizeof (*socket)); socket = grub_zalloc (sizeof (*socket));
if (socket == NULL) if (socket == NULL)
return NULL; return NULL;
@ -575,7 +582,7 @@ grub_net_tcp_open (char *server,
socket->out_port = out_port; socket->out_port = out_port;
socket->inf = inf; socket->inf = inf;
socket->out_nla = addr; socket->out_nla = addr;
socket->gw = gateway; socket->ll_target_addr = ll_target_addr;
socket->in_port = in_port++; socket->in_port = in_port++;
socket->recv_hook = recv_hook; socket->recv_hook = recv_hook;
socket->error_hook = error_hook; socket->error_hook = error_hook;
@ -629,7 +636,7 @@ grub_net_tcp_open (char *server,
int j; int j;
nb->data = nbd; nb->data = nbd;
err = grub_net_send_ip_packet (socket->inf, &(socket->out_nla), err = grub_net_send_ip_packet (socket->inf, &(socket->out_nla),
&(socket->gw), nb, &(socket->ll_target_addr), nb,
GRUB_NET_IP_TCP); GRUB_NET_IP_TCP);
if (err) if (err)
{ {

View file

@ -34,7 +34,8 @@ struct grub_net_udp_socket
grub_err_t (*recv_hook) (grub_net_udp_socket_t sock, struct grub_net_buff *nb, grub_err_t (*recv_hook) (grub_net_udp_socket_t sock, struct grub_net_buff *nb,
void *recv); void *recv);
void *recv_hook_data; void *recv_hook_data;
grub_net_network_level_address_t out_nla, gw; grub_net_network_level_address_t out_nla;
grub_net_link_level_address_t ll_target_addr;
struct grub_net_network_level_interface *inf; struct grub_net_network_level_interface *inf;
}; };
@ -71,6 +72,7 @@ grub_net_udp_open (char *server,
grub_net_network_level_address_t gateway; grub_net_network_level_address_t gateway;
grub_net_udp_socket_t socket; grub_net_udp_socket_t socket;
static int in_port = 25300; static int in_port = 25300;
grub_net_link_level_address_t ll_target_addr;
err = grub_net_resolve_address (server, &addr); err = grub_net_resolve_address (server, &addr);
if (err) if (err)
@ -87,6 +89,10 @@ grub_net_udp_open (char *server,
if (err) if (err)
return NULL; return NULL;
err = grub_net_link_layer_resolve (inf, &gateway, &ll_target_addr);
if (err)
return NULL;
socket = grub_zalloc (sizeof (*socket)); socket = grub_zalloc (sizeof (*socket));
if (socket == NULL) if (socket == NULL)
return NULL; return NULL;
@ -94,7 +100,7 @@ grub_net_udp_open (char *server,
socket->out_port = out_port; socket->out_port = out_port;
socket->inf = inf; socket->inf = inf;
socket->out_nla = addr; socket->out_nla = addr;
socket->gw = gateway; socket->ll_target_addr = ll_target_addr;
socket->in_port = in_port++; socket->in_port = in_port++;
socket->status = GRUB_NET_SOCKET_START; socket->status = GRUB_NET_SOCKET_START;
socket->recv_hook = recv_hook; socket->recv_hook = recv_hook;
@ -130,7 +136,8 @@ grub_net_send_udp_packet (const grub_net_udp_socket_t socket,
&socket->out_nla); &socket->out_nla);
return grub_net_send_ip_packet (socket->inf, &(socket->out_nla), return grub_net_send_ip_packet (socket->inf, &(socket->out_nla),
&(socket->gw), nb, GRUB_NET_IP_UDP); &(socket->ll_target_addr), nb,
GRUB_NET_IP_UDP);
} }
grub_err_t grub_err_t

View file

@ -47,23 +47,26 @@ grub_uint16_t grub_net_ip_chksum(void *ipv, grub_size_t len);
grub_err_t grub_err_t
grub_net_recv_ip_packets (struct grub_net_buff *nb, grub_net_recv_ip_packets (struct grub_net_buff *nb,
struct grub_net_card *card, struct grub_net_card *card,
const grub_net_link_level_address_t *hwaddress); const grub_net_link_level_address_t *hwaddress,
const grub_net_link_level_address_t *src_hwaddress);
grub_err_t grub_err_t
grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, 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 *target,
const grub_net_network_level_address_t *gw, const grub_net_link_level_address_t *ll_target_addr,
struct grub_net_buff *nb, struct grub_net_buff *nb,
grub_net_ip_protocol_t proto); grub_net_ip_protocol_t proto);
grub_err_t grub_err_t
grub_net_recv_icmp_packet (struct grub_net_buff *nb, grub_net_recv_icmp_packet (struct grub_net_buff *nb,
struct grub_net_network_level_interface *inf, struct grub_net_network_level_interface *inf,
const grub_net_link_level_address_t *ll_src,
const grub_net_network_level_address_t *src); const grub_net_network_level_address_t *src);
grub_err_t grub_err_t
grub_net_recv_icmp6_packet (struct grub_net_buff *nb, grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
struct grub_net_card *card, struct grub_net_card *card,
struct grub_net_network_level_interface *inf, struct grub_net_network_level_interface *inf,
const grub_net_link_level_address_t *ll_src,
const grub_net_network_level_address_t *source, const grub_net_network_level_address_t *source,
const grub_net_network_level_address_t *dest, const grub_net_network_level_address_t *dest,
grub_uint8_t ttl); grub_uint8_t ttl);