grub_err_t grub_net_send_udp_packet (const grub_net_socket_t socket, struct grub_net_buff *nb) { struct udphdr *udph; grub_err_t err; err = grub_netbuff_push (nb, sizeof (*udph)); if (err) return err; udph = (struct udphdr *) nb->data; udph->src = grub_cpu_to_be16 (socket->x_in_port); udph->dst = grub_cpu_to_be16 (socket->x_out_port); /* No chechksum. */ udph->chksum = 0; udph->len = grub_cpu_to_be16 (nb->tail - nb->data); return grub_net_send_ip_packet (socket->x_inf, &(socket->x_out_nla), nb); }
grub_err_t grub_net_recv_icmp_packet (struct grub_net_buff *nb, struct grub_net_network_level_interface *inf, const grub_net_link_level_address_t *ll_src, const grub_net_network_level_address_t *src) { struct icmp_header *icmph; grub_err_t err; grub_uint16_t checksum; /* Ignore broadcast. */ if (!inf) { grub_netbuff_free (nb); return GRUB_ERR_NONE; } icmph = (struct icmp_header *) nb->data; if (nb->tail - nb->data < (grub_ssize_t) sizeof (*icmph)) { grub_netbuff_free (nb); return GRUB_ERR_NONE; } checksum = icmph->checksum; icmph->checksum = 0; if (checksum != grub_net_ip_chksum (nb->data, nb->tail - nb->data)) { icmph->checksum = checksum; return GRUB_ERR_NONE; } icmph->checksum = checksum; err = grub_netbuff_pull (nb, sizeof (*icmph)); if (err) return err; switch (icmph->type) { case ICMP_ECHO: { struct grub_net_buff *nb_reply; struct icmp_header *icmphr; if (icmph->code) break; nb_reply = grub_netbuff_make_pkt (nb->tail - nb->data + sizeof (*icmphr)); if (!nb_reply) { grub_netbuff_free (nb); return grub_errno; } grub_memcpy (nb_reply->data + sizeof (*icmphr), nb->data, nb->tail - nb->data); icmphr = (struct icmp_header *) nb_reply->data; icmphr->type = ICMP_ECHO_REPLY; icmphr->code = 0; 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, ll_src, nb_reply, GRUB_NET_IP_ICMP); grub_netbuff_free (nb); grub_netbuff_free (nb_reply); return err; } }; grub_netbuff_free (nb); return GRUB_ERR_NONE; }