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,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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/net/ethernet.h>
|
||||
|
@ -8,6 +26,28 @@
|
|||
#include <grub/time.h>
|
||||
#include <grub/net/arp.h>
|
||||
|
||||
#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,
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/net/ip.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/net/arp.h>
|
||||
|
@ -7,8 +25,32 @@
|
|||
#include <grub/net/netbuff.h>
|
||||
#include <grub/mm.h>
|
||||
|
||||
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);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <grub/net/udp.h>
|
||||
#include <grub/net.h>
|
||||
#include <grub/net/netbuff.h>
|
||||
#include <grub/net/ip.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/i18n.h>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 <grub/efi/api.h>
|
||||
#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);
|
||||
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRUB_NET_ETHERNET_HEADER
|
||||
#define GRUB_NET_ETHERNET_HEADER 1
|
||||
#include <grub/types.h>
|
||||
#include <grub/net.h>
|
||||
|
||||
#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,
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRUB_NET_IP_HEADER
|
||||
#define GRUB_NET_IP_HEADER 1
|
||||
#include <grub/misc.h>
|
||||
#include <grub/net.h>
|
||||
|
||||
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
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
#ifndef GRUB_NET_TFTP_HEADER
|
||||
#define GRUB_NET_TFTP_HEADER 1
|
||||
|
||||
#include <grub/misc.h>
|
||||
#include <grub/net/ethernet.h>
|
||||
#include <grub/net/udp.h>
|
||||
|
||||
/* 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
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue