From b975df6348fdf7bb02d107dd4fff92965e5f9182 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 12:53:37 +0200 Subject: [PATCH] Send TFTP_ERROR on tftp premature close. Several cleanups --- grub-core/net/ethernet.c | 40 ++++++++++++ grub-core/net/ip.c | 46 +++++++++++++- grub-core/net/net.c | 1 + grub-core/net/tftp.c | 118 +++++++++++++++++++++++++++++++++++- include/grub/net.h | 34 +++-------- include/grub/net/device.h | 0 include/grub/net/ethernet.h | 41 ++++++------- include/grub/net/ip.h | 63 ++++++++++--------- include/grub/net/tftp.h | 68 --------------------- include/grub/net/udp.h | 4 +- 10 files changed, 262 insertions(+), 153 deletions(-) delete mode 100644 include/grub/net/device.h delete mode 100644 include/grub/net/tftp.h diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index 3006c9d93..acd33bcf6 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -1,3 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + #include #include #include @@ -8,6 +26,28 @@ #include #include +#define LLCADDRMASK 0x7f + +struct etherhdr +{ + grub_uint8_t dst[6]; + grub_uint8_t src[6]; + grub_uint16_t type; +} __attribute__ ((packed)); + +struct llchdr +{ + grub_uint8_t dsap; + grub_uint8_t ssap; + grub_uint8_t ctrl; +} __attribute__ ((packed)); + +struct snaphdr +{ + grub_uint8_t oui[3]; + grub_uint16_t type; +} __attribute__ ((packed)); + grub_err_t send_ethernet_packet (struct grub_net_network_level_interface *inf, struct grub_net_buff *nb, diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c index 8b06f7d11..642a67f18 100644 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@ -1,3 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + #include #include #include @@ -7,8 +25,32 @@ #include #include +struct iphdr { + grub_uint8_t verhdrlen; + grub_uint8_t service; + grub_uint16_t len; + grub_uint16_t ident; + grub_uint16_t frags; + grub_uint8_t ttl; + grub_uint8_t protocol; + grub_uint16_t chksum; + grub_uint32_t src; + grub_uint32_t dest; +} __attribute__ ((packed)) ; + +struct ip6hdr +{ + grub_uint8_t version:4, priority:4; + grub_uint8_t flow_lbl[3]; + grub_uint16_t payload_len; + grub_uint8_t nexthdr; + grub_uint8_t hop_limit; + grub_uint8_t saddr[16]; + grub_uint8_t daddr[16]; +} __attribute__ ((packed)); + grub_uint16_t -ipchksum (void *ipv, int len) +grub_net_ip_chksum (void *ipv, int len) { grub_uint16_t *ip = (grub_uint16_t *) ipv; grub_uint32_t sum = 0; @@ -48,7 +90,7 @@ grub_net_send_ip_packet (struct grub_net_network_level_interface * inf, iph->dest = target->ipv4; iph->chksum = 0; - iph->chksum = ipchksum ((void *) nb->data, sizeof (*iph)); + iph->chksum = grub_net_ip_chksum ((void *) nb->data, sizeof (*iph)); /* Determine link layer target address via ARP. */ err = grub_net_arp_resolve (inf, target, &ll_target_addr); diff --git a/grub-core/net/net.c b/grub-core/net/net.c index a3b76cae0..0d664d9b5 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 6ffe27669..be1534021 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -1,5 +1,22 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + #include -#include #include #include #include @@ -11,6 +28,74 @@ GRUB_MOD_LICENSE ("GPLv3+"); +/* IP port for the MTFTP server used for Intel's PXE */ +enum + { + MTFTP_SERVER_PORT = 75, + MTFTP_CLIENT_PORT = 76, + /* IP port for the TFTP server */ + TFTP_SERVER_PORT = 69 + }; + +enum + { + TFTP_DEFAULTSIZE_PACKET = 512, + TFTP_MAX_PACKET = 1432 + }; + +enum + { + TFTP_CODE_EOF = 1, + TFTP_CODE_MORE = 2, + TFTP_CODE_ERROR = 3, + TFTP_CODE_BOOT = 4, + TFTP_CODE_CFG = 5 + }; + +enum + { + TFTP_RRQ = 1, + TFTP_WRQ = 2, + TFTP_DATA = 3, + TFTP_ACK = 4, + TFTP_ERROR = 5, + TFTP_OACK = 6 + }; + +enum + { + TFTP_EUNDEF = 0, /* not defined */ + TFTP_ENOTFOUND = 1, /* file not found */ + TFTP_EACCESS = 2, /* access violation */ + TFTP_ENOSPACE = 3, /* disk full or allocation exceeded */ + TFTP_EBADOP = 4, /* illegal TFTP operation */ + TFTP_EBADID = 5, /* unknown transfer ID */ + TFTP_EEXISTS = 6, /* file already exists */ + TFTP_ENOUSER = 7 /* no such user */ + }; + +struct tftphdr { + grub_uint16_t opcode; + union { + grub_int8_t rrq[TFTP_DEFAULTSIZE_PACKET]; + struct { + grub_uint16_t block; + grub_int8_t download[TFTP_MAX_PACKET]; + } data; + struct { + grub_uint16_t block; + } ack; + struct { + grub_uint16_t errcode; + grub_int8_t errmsg[TFTP_DEFAULTSIZE_PACKET]; + } err; + struct { + grub_int8_t data[TFTP_DEFAULTSIZE_PACKET+2]; + } oack; + } u; +} __attribute__ ((packed)) ; + + typedef struct tftp_data { grub_uint64_t file_size; @@ -40,7 +125,7 @@ tftp_receive (grub_net_socket_t sock __attribute__ ((unused)), switch (grub_be_to_cpu16 (tftph->opcode)) { case TFTP_OACK: - data->block_size = 512; + data->block_size = TFTP_DEFAULTSIZE_PACKET; data->have_oack = 1; for (ptr = nb->data + sizeof (tftph->opcode); ptr < nb->tail;) { @@ -224,8 +309,35 @@ static grub_err_t tftp_close (struct grub_file *file) { tftp_data_t data = file->data; + if (data->sock) - grub_net_udp_close (data->sock); + { + char nbdata[512]; + grub_err_t err; + struct grub_net_buff nb_err; + struct tftphdr *tftph; + + nb_err.head = nbdata; + nb_err.end = nbdata + sizeof (nbdata); + + grub_netbuff_clear (&nb_err); + grub_netbuff_reserve (&nb_err, 512); + err = grub_netbuff_push (&nb_err, sizeof (tftph->opcode) + + sizeof (tftph->u.err.errcode) + + sizeof ("closed")); + if (!err) + { + tftph = (struct tftphdr *) nb_err.data; + tftph->opcode = grub_cpu_to_be16 (TFTP_ERROR); + tftph->u.err.errcode = grub_cpu_to_be16 (TFTP_EUNDEF); + grub_memcpy (tftph->u.err.errmsg, "closed", sizeof ("closed")); + + err = grub_net_send_udp_packet (data->sock, &nb_err); + } + if (err) + grub_print_error (); + grub_net_udp_close (data->sock); + } grub_free (data); return GRUB_ERR_NONE; } diff --git a/include/grub/net.h b/include/grub/net.h index 85fdef365..0ac0838cf 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010 Free Software Foundation, Inc. + * Copyright (C) 2010,2011 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -82,6 +82,10 @@ typedef struct grub_net_packets grub_net_packet_t *last; } grub_net_packets_t; +#ifdef GRUB_MACHINE_EFI +#include +#endif + struct grub_net_card { struct grub_net_card *next; @@ -93,11 +97,13 @@ struct grub_net_card int opened; union { +#ifdef GRUB_MACHINE_EFI struct { struct grub_efi_simple_network *efi_net; - void *efi_handle; + grub_efi_handle_t efi_handle; }; +#endif void *data; int data_num; }; @@ -420,30 +426,6 @@ extern struct grub_net_network_level_interface *grub_net_network_level_interface #define FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE(var,next) for (var = grub_net_network_level_interfaces, next = var->next; var; var = next, next = var->next) -grub_err_t grub_net_send_link_layer (struct grub_net_network_level_interface *inf, - struct grub_net_buff *nb, - grub_net_link_level_address_t *target); - -typedef int -(*grub_net_packet_handler_t) (struct grub_net_buff *nb, - struct grub_net_network_level_interface *inf); - -grub_err_t grub_net_recv_link_layer (struct grub_net_network_level_interface *inf, - grub_net_packet_handler_t handler); - - -grub_err_t -grub_net_recv_ip_packets (struct grub_net_buff *nb, - const struct grub_net_card *card, - const grub_net_link_level_address_t *hwaddress); - -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); - -#define FOR_NET_NL_PACKETS(inf, var) FOR_PACKETS(inf->nl_pending, var) - void grub_net_poll_cards (unsigned time); diff --git a/include/grub/net/device.h b/include/grub/net/device.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h index a841dc12c..a68aafd96 100644 --- a/include/grub/net/ethernet.h +++ b/include/grub/net/ethernet.h @@ -1,30 +1,26 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + #ifndef GRUB_NET_ETHERNET_HEADER #define GRUB_NET_ETHERNET_HEADER 1 #include #include -#define LLCADDRMASK 0x7f - -struct etherhdr -{ - grub_uint8_t dst[6]; - grub_uint8_t src[6]; - grub_uint16_t type; -} __attribute__ ((packed)); - -struct llchdr -{ - grub_uint8_t dsap; - grub_uint8_t ssap; - grub_uint8_t ctrl; -} __attribute__ ((packed)); - -struct snaphdr -{ - grub_uint8_t oui[3]; - grub_uint16_t type; -} __attribute__ ((packed)); - /* IANA Ethertype */ enum { @@ -32,7 +28,6 @@ enum GRUB_NET_ETHERTYPE_ARP = 0x0806 }; - grub_err_t send_ethernet_packet (struct grub_net_network_level_interface *inf, struct grub_net_buff *nb, diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h index cb8481a7d..9bed1e19c 100644 --- a/include/grub/net/ip.h +++ b/include/grub/net/ip.h @@ -1,35 +1,42 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + #ifndef GRUB_NET_IP_HEADER #define GRUB_NET_IP_HEADER 1 #include +#include -struct iphdr { - grub_uint8_t verhdrlen; - grub_uint8_t service; - grub_uint16_t len; - grub_uint16_t ident; - grub_uint16_t frags; - grub_uint8_t ttl; - grub_uint8_t protocol; - grub_uint16_t chksum; - grub_uint32_t src; - grub_uint32_t dest; -} __attribute__ ((packed)) ; - -struct ip6hdr -{ - grub_uint8_t version:4, priority:4; - grub_uint8_t flow_lbl[3]; - grub_uint16_t payload_len; - grub_uint8_t nexthdr; - grub_uint8_t hop_limit; - grub_uint8_t saddr[16]; - grub_uint8_t daddr[16]; -} __attribute__ ((packed)); - -#define IP_UDP 0x11 /* UDP protocol */ +enum + { + IP_UDP = 0x11 /* UDP protocol */ + }; #define IP_BROADCAST 0xFFFFFFFF -grub_uint16_t ipchksum(void *ipv, int len); -void ipv4_ini(void); -void ipv4_fini(void); +grub_uint16_t grub_net_ip_chksum(void *ipv, int len); + +grub_err_t +grub_net_recv_ip_packets (struct grub_net_buff *nb, + const struct grub_net_card *card, + const grub_net_link_level_address_t *hwaddress); + +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); + #endif diff --git a/include/grub/net/tftp.h b/include/grub/net/tftp.h deleted file mode 100644 index 0d8cbd1de..000000000 --- a/include/grub/net/tftp.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef GRUB_NET_TFTP_HEADER -#define GRUB_NET_TFTP_HEADER 1 - -#include -#include -#include - -/* IP port for the MTFTP server used for Intel's PXE */ -#define MTFTP_SERVER_PORT 75 -#define MTFTP_CLIENT_PORT 76 - -#define TFTP_DEFAULTSIZE_PACKET 512 -#define TFTP_MAX_PACKET 1432 - -/* IP port for the TFTP server */ -#define TFTP_SERVER_PORT 69 - - -/* We define these based on what's in arpa/tftp.h. We just like our - * names better, cause they're clearer */ -#define TFTP_RRQ 1 -#define TFTP_WRQ 2 -#define TFTP_DATA 3 -#define TFTP_ACK 4 -#define TFTP_ERROR 5 -#define TFTP_OACK 6 - -#define TFTP_CODE_EOF 1 -#define TFTP_CODE_MORE 2 -#define TFTP_CODE_ERROR 3 -#define TFTP_CODE_BOOT 4 -#define TFTP_CODE_CFG 5 - -#define TFTP_EUNDEF 0 /* not defined */ -#define TFTP_ENOTFOUND 1 /* file not found */ -#define TFTP_EACCESS 2 /* access violation */ -#define TFTP_ENOSPACE 3 /* disk full or allocation exceeded */ -#define TFTP_EBADOP 4 /* illegal TFTP operation */ -#define TFTP_EBADID 5 /* unknown transfer ID */ -#define TFTP_EEXISTS 6 /* file already exists */ -#define TFTP_ENOUSER 7 /* no such user */ - - /* * own here because this is cleaner, and maps to the same data layout. - * */ - - -struct tftphdr { - grub_uint16_t opcode; - union { - grub_int8_t rrq[TFTP_DEFAULTSIZE_PACKET]; - struct { - grub_uint16_t block; - grub_int8_t download[TFTP_MAX_PACKET]; - } data; - struct { - grub_uint16_t block; - } ack; - struct { - grub_uint16_t errcode; - grub_int8_t errmsg[TFTP_DEFAULTSIZE_PACKET]; - } err; - struct { - grub_int8_t data[TFTP_DEFAULTSIZE_PACKET+2]; - } oack; - } u; -} __attribute__ ((packed)) ; - -#endif diff --git a/include/grub/net/udp.h b/include/grub/net/udp.h index 272612299..5aacf8abb 100644 --- a/include/grub/net/udp.h +++ b/include/grub/net/udp.h @@ -28,13 +28,11 @@ grub_net_udp_close (grub_net_socket_t sock) } grub_err_t -grub_net_send_udp_packet (const grub_net_socket_t socket , struct grub_net_buff *nb); +grub_net_send_udp_packet (const grub_net_socket_t socket, struct grub_net_buff *nb); grub_err_t grub_net_recv_udp_packet (struct grub_net_buff *nb, struct grub_net_network_level_interface *inf); -#define FOR_NET_UDP_PACKETS(inf, var) FOR_PACKETS(inf->udp_pending, var) - #endif