Send TFTP_ERROR on tftp premature close. Several cleanups
This commit is contained in:
parent
72b9ad936a
commit
b975df6348
10 changed files with 262 additions and 153 deletions
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/misc.h>
|
||||
#include <grub/net/tftp.h>
|
||||
#include <grub/net/udp.h>
|
||||
#include <grub/net/ip.h>
|
||||
#include <grub/net/ethernet.h>
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue