Coverage Report

Created: 2026-05-11 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeradius-server/src/protocols/tftp/base.c
Line
Count
Source
1
/*
2
 *   This program is free software; you can redistribute it and/or modify
3
 *   it under the terms of the GNU General Public License as published by
4
 *   the Free Software Foundation; either version 2 of the License, or
5
 *   (at your option) any later version.
6
 *
7
 *   This program is distributed in the hope that it will be useful,
8
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 *   GNU General Public License for more details.
11
 *
12
 *   You should have received a copy of the GNU General Public License
13
 *   along with this program; if not, write to the Free Software
14
 *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15
 */
16
17
/**
18
 * $Id: b3dbef62dea1cdc90674fb27119128effa4a7c12 $
19
 * @file src/protocols/tftp/base.c
20
 * @brief TFTP protocol.
21
 * @author Jorge Pereira <jpereira@freeradius.org>
22
 *
23
 * @copyright 2021 The FreeRADIUS server project.
24
 * @copyright 2021 Network RADIUS SAS (legal@networkradius.com)
25
 */
26
27
RCSID("$Id: b3dbef62dea1cdc90674fb27119128effa4a7c12 $")
28
29
#include <freeradius-devel/util/pair.h>
30
31
#include "tftp.h"
32
#include "attrs.h"
33
34
static uint32_t instance_count = 0;
35
36
fr_dict_t const *dict_tftp;
37
38
extern fr_dict_autoload_t libfreeradius_tftp[];
39
fr_dict_autoload_t libfreeradius_tftp[] = {
40
  { .out = &dict_tftp, .proto = "tftp" },
41
  DICT_AUTOLOAD_TERMINATOR
42
};
43
44
fr_dict_attr_t const *attr_tftp_block;
45
fr_dict_attr_t const *attr_tftp_block_size;
46
fr_dict_attr_t const *attr_tftp_data;
47
fr_dict_attr_t const *attr_tftp_error_code;
48
fr_dict_attr_t const *attr_tftp_error_message;
49
fr_dict_attr_t const *attr_tftp_filename;
50
fr_dict_attr_t const *attr_tftp_opcode;
51
fr_dict_attr_t const *attr_tftp_mode;
52
53
fr_dict_attr_t const *attr_packet_type;
54
55
extern fr_dict_attr_autoload_t libfreeradius_tftp_dict_attr[];
56
fr_dict_attr_autoload_t libfreeradius_tftp_dict_attr[] = {
57
  { .out = &attr_tftp_block, .name = "Block", .type = FR_TYPE_UINT16, .dict = &dict_tftp },
58
  { .out = &attr_tftp_block_size, .name = "Block-Size", .type = FR_TYPE_UINT16, .dict = &dict_tftp },
59
  { .out = &attr_tftp_data, .name = "Data", .type = FR_TYPE_OCTETS, .dict = &dict_tftp },
60
  { .out = &attr_tftp_error_code, .name = "Error-Code", .type = FR_TYPE_UINT16, .dict = &dict_tftp },
61
  { .out = &attr_tftp_error_message, .name = "Error-Message", .type = FR_TYPE_STRING, .dict = &dict_tftp },
62
  { .out = &attr_tftp_filename, .name = "Filename", .type = FR_TYPE_STRING, .dict = &dict_tftp },
63
  { .out = &attr_tftp_opcode, .name = "Opcode", .type = FR_TYPE_UINT16, .dict = &dict_tftp },
64
  { .out = &attr_tftp_mode, .name = "Mode", .type = FR_TYPE_UINT8, .dict = &dict_tftp },
65
66
  { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_tftp },
67
68
  DICT_AUTOLOAD_TERMINATOR
69
};
70
71
char const *fr_tftp_codes[FR_TFTP_MAX_CODE] = {
72
  [FR_PACKET_TYPE_VALUE_READ_REQUEST] = "Read-Request",
73
  [FR_PACKET_TYPE_VALUE_WRITE_REQUEST] = "Write-Request",
74
  [FR_PACKET_TYPE_VALUE_DATA] = "Data",
75
  [FR_PACKET_TYPE_VALUE_ACKNOWLEDGEMENT] = "Acknowledgement",
76
  [FR_PACKET_TYPE_VALUE_ERROR] = "Error",
77
  [FR_PACKET_TYPE_VALUE_DO_NOT_RESPOND] = "Do-Not-Respond"
78
};
79
80
char const *fr_tftp_error_codes[FR_TFTP_MAX_ERROR_CODE] = {
81
  [FR_ERROR_CODE_VALUE_FILE_NOT_FOUND] = "File not found",
82
  [FR_ERROR_CODE_VALUE_ACCESS_VIOLATION] = "Access violation",
83
  [FR_ERROR_CODE_VALUE_DISK_FULL] = "Disk Full",
84
  [FR_ERROR_CODE_VALUE_ILLEGAL_OPERATION] = "Illegal TFTP operation",
85
  [FR_ERROR_CODE_VALUE_UNKNOWN_TRANSFER_ID] = "Unknown transfer ID",
86
  [FR_ERROR_CODE_VALUE_FILE_ALREADY_EXISTS] = "File already exists",
87
  [FR_ERROR_CODE_VALUE_NO_SUCH_USER] = "No such user"
88
};
89
90
int fr_tftp_global_init(void)
91
700
{
92
700
  if (instance_count > 0) {
93
350
    instance_count++;
94
350
    return 0;
95
350
  }
96
97
350
  instance_count++;
98
99
350
  if (fr_dict_autoload(libfreeradius_tftp) < 0) {
100
0
  fail:
101
0
    instance_count--;
102
0
    return -1;
103
0
  }
104
105
350
  if (fr_dict_attr_autoload(libfreeradius_tftp_dict_attr) < 0) {
106
0
    fr_dict_autofree(libfreeradius_tftp);
107
0
    goto fail;
108
0
  }
109
110
111
350
  return 0;
112
350
}
113
114
void fr_tftp_global_free(void)
115
700
{
116
700
  fr_assert(instance_count > 0);
117
118
700
  if (--instance_count > 0) return;
119
120
350
  fr_dict_autofree(libfreeradius_tftp);
121
350
}