]> git.ipfire.org Git - people/ms/suricata.git/blame - src/app-layer-tftp.c
detect-geoip: add info for list keywords
[people/ms/suricata.git] / src / app-layer-tftp.c
CommitLineData
b9cf49e9
CG
1/* Copyright (C) 2017 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
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 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 *
17 */
18
19/**
20 * \file
21 *
22 * \author Clément Galland <clement.galland@epita.fr>
23 *
24 * Parser for NTP application layer running on UDP port 69.
25 */
26
27
28#include "suricata-common.h"
29#include "stream.h"
30#include "conf.h"
31
32#include "util-unittest.h"
33
34#include "app-layer-detect-proto.h"
35#include "app-layer-parser.h"
36
37#include "app-layer-tftp.h"
38
b9cf49e9
CG
39#include "rust-tftp-tftp-gen.h"
40
41/* The default port to probe if not provided in the configuration file. */
42#define TFTP_DEFAULT_PORT "69"
43
44/* The minimum size for an message. For some protocols this might
45 * be the size of a header. */
46#define TFTP_MIN_FRAME_LEN 4
47
b9cf49e9
CG
48static void *TFTPStateAlloc(void)
49{
50 return rs_tftp_state_alloc();
51}
52
53static void TFTPStateFree(void *state)
54{
55 rs_tftp_state_free(state);
56}
57
58/**
59 * \brief Callback from the application layer to have a transaction freed.
60 *
61 * \param state a void pointer to the TFTPState object.
62 * \param tx_id the transaction ID to free.
63 */
64static void TFTPStateTxFree(void *state, uint64_t tx_id)
65{
66 rs_tftp_state_tx_free(state, tx_id);
67}
68
69static int TFTPStateGetEventInfo(const char *event_name, int *event_id,
70 AppLayerEventType *event_type)
71{
72 return -1;
73}
74
d568e7fa 75static AppLayerDecoderEvents *TFTPGetEvents(void *tx)
b9cf49e9
CG
76{
77 return NULL;
78}
79
b9cf49e9
CG
80/**
81 * \brief Probe the input to see if it looks like echo.
82 *
83 * \retval ALPROTO_TFTP if it looks like echo, otherwise
84 * ALPROTO_UNKNOWN.
85 */
422e4892
VJ
86static AppProto TFTPProbingParser(Flow *f, uint8_t direction,
87 uint8_t *input, uint32_t input_len, uint8_t *rdir)
b9cf49e9 88{
80f2fbac 89 /* Very simple test - if there is input, this is tftp.
b9cf49e9
CG
90 * Also check if it's starting by a zero */
91 if (input_len >= TFTP_MIN_FRAME_LEN && *input == 0) {
92 SCLogDebug("Detected as ALPROTO_TFTP.");
93 return ALPROTO_TFTP;
94 }
95
96 SCLogDebug("Protocol not detected as ALPROTO_TFTP.");
97 return ALPROTO_UNKNOWN;
98}
99
100static int TFTPParseRequest(Flow *f, void *state,
101 AppLayerParserState *pstate, uint8_t *input, uint32_t input_len,
7bc3c3ac 102 void *local_data, const uint8_t flags)
b9cf49e9
CG
103{
104 SCLogDebug("Parsing echo request: len=%"PRIu32, input_len);
105
106 /* Likely connection closed, we can just return here. */
107 if ((input == NULL || input_len == 0) &&
108 AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
109 return 0;
110 }
111
112 /* Probably don't want to create a transaction in this case
113 * either. */
114 if (input == NULL || input_len == 0) {
115 return 0;
116 }
117
118 return rs_tftp_request(state, input, input_len);
119}
120
121/**
122 * \brief Response parsing is not implemented
123 */
124static int TFTPParseResponse(Flow *f, void *state, AppLayerParserState *pstate,
7bc3c3ac
VJ
125 uint8_t *input, uint32_t input_len, void *local_data,
126 const uint8_t flags)
b9cf49e9
CG
127{
128 return 0;
129}
130
131static uint64_t TFTPGetTxCnt(void *state)
132{
133 return rs_tftp_get_tx_cnt(state);
134}
135
136static void *TFTPGetTx(void *state, uint64_t tx_id)
137{
138 return rs_tftp_get_tx(state, tx_id);
139}
140
141static void TFTPSetTxLogged(void *state, void *vtx, uint32_t logger)
142{
143 rs_tftp_set_tx_logged(state, vtx, logger);
144}
145
80f2fbac 146static LoggerId TFTPGetTxLogged(void *state, void *vtx)
b9cf49e9 147{
80f2fbac 148 return rs_tftp_get_tx_logged(state, vtx);
b9cf49e9
CG
149}
150
151/**
152 * \brief Called by the application layer.
153 *
154 * In most cases 1 can be returned here.
155 */
156static int TFTPGetAlstateProgressCompletionStatus(uint8_t direction) {
157 return 1;
158}
159
160/**
161 * \brief Return the state of a transaction in a given direction.
162 *
163 * In the case of the echo protocol, the existence of a transaction
164 * means that the request is done. However, some protocols that may
165 * need multiple chunks of data to complete the request may need more
166 * than just the existence of a transaction for the request to be
167 * considered complete.
168 *
169 * For the response to be considered done, the response for a request
170 * needs to be seen. The response_done flag is set on response for
171 * checking here.
172 */
173static int TFTPGetStateProgress(void *tx, uint8_t direction)
174{
175 return 1;
176}
177
178static DetectEngineState *TFTPGetTxDetectState(void *vtx)
179{
180 return NULL;
181}
182
7548944b 183static int TFTPSetTxDetectState(void *vtx,
b9cf49e9
CG
184 DetectEngineState *s)
185{
186 return 0;
187}
188
189void RegisterTFTPParsers(void)
190{
191 const char *proto_name = "tftp";
192
193 /* Check if TFTP UDP detection is enabled. If it does not exist in
194 * the configuration file then it will be enabled by default. */
195 if (AppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name)) {
196
197 SCLogDebug("TFTP UDP protocol detection enabled.");
198
199 AppLayerProtoDetectRegisterProtocol(ALPROTO_TFTP, proto_name);
200
201 if (RunmodeIsUnittests()) {
202 SCLogDebug("Unittest mode, registeringd default configuration.");
203 AppLayerProtoDetectPPRegister(IPPROTO_UDP, TFTP_DEFAULT_PORT,
204 ALPROTO_TFTP, 0, TFTP_MIN_FRAME_LEN,
205 STREAM_TOSERVER, TFTPProbingParser,
206 NULL);
207 } else {
208 if (!AppLayerProtoDetectPPParseConfPorts("udp", IPPROTO_UDP,
209 proto_name, ALPROTO_TFTP,
210 0, TFTP_MIN_FRAME_LEN,
211 TFTPProbingParser, NULL)) {
212 SCLogDebug("No echo app-layer configuration, enabling echo"
213 " detection UDP detection on port %s.",
214 TFTP_DEFAULT_PORT);
215 AppLayerProtoDetectPPRegister(IPPROTO_UDP,
216 TFTP_DEFAULT_PORT, ALPROTO_TFTP,
217 0, TFTP_MIN_FRAME_LEN,
218 STREAM_TOSERVER,TFTPProbingParser,
219 NULL);
220 }
221 }
222 } else {
223 SCLogDebug("Protocol detecter and parser disabled for TFTP.");
224 return;
225 }
226
227 if (AppLayerParserConfParserEnabled("udp", proto_name)) {
228
229 SCLogDebug("Registering TFTP protocol parser.");
230
231 /* Register functions for state allocation and freeing. A
232 * state is allocated for every new TFTP flow. */
233 AppLayerParserRegisterStateFuncs(IPPROTO_UDP, ALPROTO_TFTP,
234 TFTPStateAlloc, TFTPStateFree);
235
236 /* Register request parser for parsing frame from server to client. */
237 AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_TFTP,
238 STREAM_TOSERVER, TFTPParseRequest);
239
240 /* Register response parser for parsing frames from server to client. */
241 AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_TFTP,
242 STREAM_TOCLIENT, TFTPParseResponse);
243
244 /* Register a function to be called by the application layer
245 * when a transaction is to be freed. */
246 AppLayerParserRegisterTxFreeFunc(IPPROTO_UDP, ALPROTO_TFTP,
247 TFTPStateTxFree);
248
249 AppLayerParserRegisterLoggerFuncs(IPPROTO_UDP, ALPROTO_TFTP,
250 TFTPGetTxLogged, TFTPSetTxLogged);
251
252 /* Register a function to return the current transaction count. */
253 AppLayerParserRegisterGetTxCnt(IPPROTO_UDP, ALPROTO_TFTP,
254 TFTPGetTxCnt);
255
256 /* Transaction handling. */
257 AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_TFTP,
258 TFTPGetAlstateProgressCompletionStatus);
259 AppLayerParserRegisterGetStateProgressFunc(IPPROTO_UDP,
260 ALPROTO_TFTP,
261 TFTPGetStateProgress);
262 AppLayerParserRegisterGetTx(IPPROTO_UDP, ALPROTO_TFTP,
263 TFTPGetTx);
264
b9cf49e9
CG
265 /* What is this being registered for? */
266 AppLayerParserRegisterDetectStateFuncs(IPPROTO_UDP, ALPROTO_TFTP,
7548944b 267 TFTPGetTxDetectState,
b9cf49e9
CG
268 TFTPSetTxDetectState);
269
270 AppLayerParserRegisterGetEventInfo(IPPROTO_UDP, ALPROTO_TFTP,
271 TFTPStateGetEventInfo);
272 AppLayerParserRegisterGetEventsFunc(IPPROTO_UDP, ALPROTO_TFTP,
273 TFTPGetEvents);
274 }
275 else {
276 SCLogDebug("TFTP protocol parsing disabled.");
277 }
b9cf49e9 278}