Upgraded GRUB2 to 2.00 release.
[AROS.git] / arch / all-pc / boot / grub2-aros / grub-core / net / icmp.c
blobe55a0d86a52a3ab4248ad4eab89dbea4b11f0358
1 /*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2010,2011 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19 #include <grub/net.h>
20 #include <grub/net/ip.h>
21 #include <grub/net/netbuff.h>
23 struct icmp_header
25 grub_uint8_t type;
26 grub_uint8_t code;
27 grub_uint16_t checksum;
28 } __attribute__ ((packed));
30 struct ping_header
32 grub_uint16_t id;
33 grub_uint16_t seq;
34 } __attribute__ ((packed));
36 enum
38 ICMP_ECHO_REPLY = 0,
39 ICMP_ECHO = 8,
42 grub_err_t
43 grub_net_recv_icmp_packet (struct grub_net_buff *nb,
44 struct grub_net_network_level_interface *inf,
45 const grub_net_link_level_address_t *ll_src,
46 const grub_net_network_level_address_t *src)
48 struct icmp_header *icmph;
49 grub_err_t err;
50 grub_uint16_t checksum;
52 /* Ignore broadcast. */
53 if (!inf)
55 grub_netbuff_free (nb);
56 return GRUB_ERR_NONE;
59 icmph = (struct icmp_header *) nb->data;
61 if (nb->tail - nb->data < (grub_ssize_t) sizeof (*icmph))
63 grub_netbuff_free (nb);
64 return GRUB_ERR_NONE;
67 checksum = icmph->checksum;
68 icmph->checksum = 0;
69 if (checksum != grub_net_ip_chksum (nb->data, nb->tail - nb->data))
71 icmph->checksum = checksum;
72 return GRUB_ERR_NONE;
74 icmph->checksum = checksum;
76 err = grub_netbuff_pull (nb, sizeof (*icmph));
77 if (err)
78 return err;
80 switch (icmph->type)
82 case ICMP_ECHO:
84 struct grub_net_buff *nb_reply;
85 struct icmp_header *icmphr;
86 if (icmph->code)
87 break;
88 nb_reply = grub_netbuff_alloc (nb->tail - nb->data + 512);
89 if (!nb_reply)
91 grub_netbuff_free (nb);
92 return grub_errno;
94 err = grub_netbuff_reserve (nb_reply, nb->tail - nb->data + 512);
95 if (err)
96 goto ping_fail;
97 err = grub_netbuff_push (nb_reply, nb->tail - nb->data);
98 if (err)
99 goto ping_fail;
100 grub_memcpy (nb_reply->data, nb->data, nb->tail - nb->data);
101 err = grub_netbuff_push (nb_reply, sizeof (*icmphr));
102 if (err)
103 goto ping_fail;
104 icmphr = (struct icmp_header *) nb_reply->data;
105 icmphr->type = ICMP_ECHO_REPLY;
106 icmphr->code = 0;
107 icmphr->checksum = 0;
108 icmphr->checksum = grub_net_ip_chksum ((void *) nb_reply->data,
109 nb_reply->tail - nb_reply->data);
110 err = grub_net_send_ip_packet (inf, src, ll_src,
111 nb_reply, GRUB_NET_IP_ICMP);
113 ping_fail:
114 grub_netbuff_free (nb);
115 grub_netbuff_free (nb_reply);
116 return err;
120 grub_netbuff_free (nb);
121 return GRUB_ERR_NONE;