Coverage Report

Created: 2025-10-10 07:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/src/FtpLayer.cpp
Line
Count
Source
1
#define LOG_MODULE PacketLogModuleFtpLayer
2
3
#include "FtpLayer.h"
4
5
namespace pcpp
6
{
7
8
  // ----------------- Class FtpRequestLayer -----------------
9
  bool FtpRequestLayer::setCommand(FtpCommand code)
10
0
  {
11
0
    return setCommandInternal(getCommandAsString(code));
12
0
  }
13
14
  FtpRequestLayer::FtpCommand FtpRequestLayer::getCommand() const
15
0
  {
16
0
    size_t val = 0;
17
0
    std::string field = getCommandString();
18
19
0
    for (size_t idx = 0; idx < field.size(); ++idx)
20
0
    {
21
0
      val |= static_cast<size_t>(field.c_str()[idx]) << (idx * 8);
22
0
    }
23
24
0
    return static_cast<FtpCommand>(val);
25
0
  }
26
27
  std::string FtpRequestLayer::getCommandString() const
28
0
  {
29
0
    return getCommandInternal();
30
0
  }
31
32
  bool FtpRequestLayer::setCommandOption(const std::string& value)
33
0
  {
34
0
    return setCommandOptionInternal(value);
35
0
  }
36
37
  std::string FtpRequestLayer::getCommandOption(bool removeEscapeCharacters) const
38
0
  {
39
0
    if (removeEscapeCharacters)
40
0
    {
41
0
      std::stringstream ss;
42
0
      std::string field = getCommandOptionInternal();
43
0
      for (size_t idx = 0; idx < field.size(); ++idx)
44
0
      {
45
0
        if (int(field.c_str()[idx]) < 127 && int(field.c_str()[idx]) > 31)  // From SPACE to ~
46
0
          ss << field.c_str()[idx];
47
0
      }
48
0
      return ss.str();
49
0
    }
50
0
    return getCommandOptionInternal();
51
0
  }
52
53
  std::string FtpRequestLayer::getCommandInfo(FtpCommand code)
54
0
  {
55
0
    switch (code)
56
0
    {
57
0
    case FtpCommand::ABOR:
58
0
      return "Abort an active file transfer";
59
0
    case FtpCommand::ACCT:
60
0
      return "Account information";
61
0
    case FtpCommand::ADAT:
62
0
      return "Authentication/Security Data";
63
0
    case FtpCommand::ALLO:
64
0
      return "Allocate sufficient disk space to receive a file";
65
0
    case FtpCommand::APPE:
66
0
      return "Append (with create)";
67
0
    case FtpCommand::AUTH:
68
0
      return "Authentication/Security Mechanism";
69
0
    case FtpCommand::AVBL:
70
0
      return "Get the available space";
71
0
    case FtpCommand::CCC:
72
0
      return "Clear Command Channel";
73
0
    case FtpCommand::CDUP:
74
0
      return "Change to Parent Directory";
75
0
    case FtpCommand::CONF:
76
0
      return "Confidentiality Protection Command";
77
0
    case FtpCommand::CSID:
78
0
      return "Client / Server Identification";
79
0
    case FtpCommand::CWD:
80
0
      return "Change working directory";
81
0
    case FtpCommand::DELE:
82
0
      return "Delete file";
83
0
    case FtpCommand::DSIZ:
84
0
      return "Get the directory size";
85
0
    case FtpCommand::ENC:
86
0
      return "Privacy Protected Channel";
87
0
    case FtpCommand::EPRT:
88
0
      return "Specifies an extended address and port to which the server should connect";
89
0
    case FtpCommand::EPSV:
90
0
      return "Enter extended passive mode";
91
0
    case FtpCommand::FEAT:
92
0
      return "Get the feature list implemented by the server";
93
0
    case FtpCommand::HELP:
94
0
      return "Returns usage documentation on a command if specified, else a general help document is returned";
95
0
    case FtpCommand::HOST:
96
0
      return "Identify desired virtual host on server, by name";
97
0
    case FtpCommand::LANG:
98
0
      return "Language Negotiation";
99
0
    case FtpCommand::LIST:
100
0
      return "Returns information of a file or directory if specified, else information of the current working directory is returned";
101
0
    case FtpCommand::LPRT:
102
0
      return "Specifies a long address and port to which the server should connect";
103
0
    case FtpCommand::LPSV:
104
0
      return "Enter long passive mode";
105
0
    case FtpCommand::MDTM:
106
0
      return "Return the last-modified time of a specified file";
107
0
    case FtpCommand::MFCT:
108
0
      return "Modify the creation time of a file";
109
0
    case FtpCommand::MFF:
110
0
      return "Modify fact (the last modification time, creation time, UNIX group/owner/mode of a file)";
111
0
    case FtpCommand::MFMT:
112
0
      return "Modify the last modification time of a file";
113
0
    case FtpCommand::MIC:
114
0
      return "Integrity Protected Command";
115
0
    case FtpCommand::MKD:
116
0
      return "Make directory";
117
0
    case FtpCommand::MLSD:
118
0
      return "Lists the contents of a directory in a standardized machine-readable format";
119
0
    case FtpCommand::MLST:
120
0
      return "Provides data about exactly the object named on its command line in a standardized machine-readable format";
121
0
    case FtpCommand::MODE:
122
0
      return "Sets the transfer mode (Stream, Block, or Compressed)";
123
0
    case FtpCommand::NLST:
124
0
      return "Returns a list of file names in a specified directory";
125
0
    case FtpCommand::NOOP:
126
0
      return "No operation (dummy packet; used mostly on keepalives)";
127
0
    case FtpCommand::OPTS:
128
0
      return "Select options for a feature (for example OPTS UTF8 ON)";
129
0
    case FtpCommand::PASS:
130
0
      return "Authentication password";
131
0
    case FtpCommand::PASV:
132
0
      return "Enter passive mode";
133
0
    case FtpCommand::PBSZ:
134
0
      return "Protection Buffer Size";
135
0
    case FtpCommand::PORT:
136
0
      return "Specifies an address and port to which the server should connect";
137
0
    case FtpCommand::PROT:
138
0
      return "Data Channel Protection Level";
139
0
    case FtpCommand::PWD:
140
0
      return "Print working directory. Returns the current directory of the host";
141
0
    case FtpCommand::QUIT:
142
0
      return "Disconnect";
143
0
    case FtpCommand::REIN:
144
0
      return "Re initializes the connection";
145
0
    case FtpCommand::REST:
146
0
      return "Restart transfer from the specified point";
147
0
    case FtpCommand::RETR:
148
0
      return "Retrieve a copy of the file";
149
0
    case FtpCommand::RMD:
150
0
      return "Remove a directory";
151
0
    case FtpCommand::RMDA:
152
0
      return "Remove a directory tree";
153
0
    case FtpCommand::RNFR:
154
0
      return "Rename from";
155
0
    case FtpCommand::RNTO:
156
0
      return "Rename to";
157
0
    case FtpCommand::SITE:
158
0
      return "Sends site specific commands to remote server (like SITE IDLE 60 or SITE UMASK 002). Inspect SITE HELP output for complete list of supported commands";
159
0
    case FtpCommand::SIZE:
160
0
      return "Return the size of a file";
161
0
    case FtpCommand::SMNT:
162
0
      return "Mount file structure";
163
0
    case FtpCommand::SPSV:
164
0
      return "Use single port passive mode (only one TCP port number for both control connections and passive-mode data connections)";
165
0
    case FtpCommand::STAT:
166
0
      return "Returns information on the server status, including the status of the current connection";
167
0
    case FtpCommand::STOR:
168
0
      return "Accept the data and to store the data as a file at the server site";
169
0
    case FtpCommand::STOU:
170
0
      return "Store file uniquely";
171
0
    case FtpCommand::STRU:
172
0
      return "Set file transfer structure";
173
0
    case FtpCommand::SYST:
174
0
      return "Return system type";
175
0
    case FtpCommand::THMB:
176
0
      return "Get a thumbnail of a remote image file";
177
0
    case FtpCommand::TYPE:
178
0
      return "Sets the transfer mode (ASCII/Binary)";
179
0
    case FtpCommand::USER:
180
0
      return "Authentication username";
181
0
    case FtpCommand::XCUP:
182
0
      return "Change to the parent of the current working directory";
183
0
    case FtpCommand::XMKD:
184
0
      return "Make a directory";
185
0
    case FtpCommand::XPWD:
186
0
      return "Print the current working directory";
187
0
    case FtpCommand::XRCP:
188
0
      return "";
189
0
    case FtpCommand::XRMD:
190
0
      return "Remove the directory";
191
0
    case FtpCommand::XRSQ:
192
0
      return "";
193
0
    case FtpCommand::XSEM:
194
0
      return "Send, mail if cannot";
195
0
    case FtpCommand::XSEN:
196
0
      return "Send to terminal";
197
0
    default:
198
0
      return "Unknown command";
199
0
    }
200
0
  }
201
202
  std::string FtpRequestLayer::getCommandAsString(FtpCommand code)
203
0
  {
204
0
    std::stringstream oss;
205
0
    for (size_t idx = 0; idx < 4; ++idx)
206
0
    {
207
0
      char val = (uint64_t(code) >> (8 * idx)) & UINT8_MAX;
208
0
      if (val)  // Dont push if it is a null character
209
0
      {
210
0
        oss << val;
211
0
      }
212
0
    }
213
0
    return oss.str();
214
0
  }
215
216
  std::string FtpRequestLayer::toString() const
217
0
  {
218
0
    return "FTP Request: " + getCommandString();
219
0
  }
220
221
  // ----------------- Class FtpResponseLayer -----------------
222
  bool FtpResponseLayer::setStatusCode(FtpStatusCode code)
223
0
  {
224
0
    std::ostringstream oss;
225
0
    oss << int(code);
226
0
    return setCommandInternal(oss.str());
227
0
  }
228
229
  FtpResponseLayer::FtpStatusCode FtpResponseLayer::getStatusCode() const
230
439
  {
231
439
    return static_cast<FtpStatusCode>(atoi(getCommandInternal().c_str()));
232
439
  }
233
234
  std::string FtpResponseLayer::getStatusCodeString() const
235
878
  {
236
878
    return getCommandInternal();
237
878
  }
238
239
  bool FtpResponseLayer::setStatusOption(const std::string& value)
240
0
  {
241
0
    return setCommandOptionInternal(value);
242
0
  }
243
244
  std::string FtpResponseLayer::getStatusOption(bool removeEscapeCharacters) const
245
878
  {
246
878
    if (removeEscapeCharacters)
247
439
    {
248
439
      std::stringstream ss;
249
439
      std::string field = getCommandOptionInternal();
250
5.68k
      for (size_t idx = 0; idx < field.size(); ++idx)
251
5.24k
      {
252
5.24k
        if (int(field.c_str()[idx]) < 127 && int(field.c_str()[idx]) > 31)  // From SPACE to ~
253
4.60k
          ss << field.c_str()[idx];
254
5.24k
      }
255
439
      return ss.str();
256
439
    }
257
439
    return getCommandOptionInternal();
258
878
  }
259
260
  std::string FtpResponseLayer::getStatusCodeAsString(FtpStatusCode code)
261
0
  {
262
0
    switch (code)
263
0
    {
264
0
    case FtpStatusCode::RESTART_MARKER:
265
0
      return "Restart marker reply";
266
0
    case FtpStatusCode::SERVICE_READY_IN_MIN:
267
0
      return "Service ready in nnn minutes";
268
0
    case FtpStatusCode::DATA_ALREADY_OPEN_START_TRANSFER:
269
0
      return "Data connection already open; transfer starting";
270
0
    case FtpStatusCode::FILE_OK:
271
0
      return "File status okay; about to open data connection";
272
0
    case FtpStatusCode::COMMAND_OK:
273
0
      return "Command okay";
274
0
    case FtpStatusCode::COMMAND_NOT_IMPLEMENTED_SUPERFLUOUS:
275
0
      return "Command not implemented, superfluous at this site";
276
0
    case FtpStatusCode::SYSTEM_STATUS:
277
0
      return "System status, or system help reply";
278
0
    case FtpStatusCode::DIR_STATUS:
279
0
      return "Directory status";
280
0
    case FtpStatusCode::FILE_STATUS:
281
0
      return "File status";
282
0
    case FtpStatusCode::HELP_MESSAGE:
283
0
      return "Help message";
284
0
    case FtpStatusCode::NAME_SYSTEM_TYPE:
285
0
      return "NAME system type";
286
0
    case FtpStatusCode::SERVICE_READY_FOR_USER:
287
0
      return "Service ready for new user";
288
0
    case FtpStatusCode::SERVICE_CLOSING_CONTROL:
289
0
      return "Service closing control connection";
290
0
    case FtpStatusCode::DATA_OPEN_NO_TRANSFER:
291
0
      return "Data connection open; no transfer in progress";
292
0
    case FtpStatusCode::CLOSING_DATA:
293
0
      return "Closing data connection";
294
0
    case FtpStatusCode::ENTERING_PASSIVE:
295
0
      return "Entering Passive Mode";
296
0
    case FtpStatusCode::ENTERING_EXTENDED_PASSIVE:
297
0
      return "Entering Extended Passive Mode";
298
0
    case FtpStatusCode::USER_LOG_IN_PROCEED:
299
0
      return "User logged in, proceed";
300
0
    case FtpStatusCode::USER_LOG_IN_AUTHORIZED:
301
0
      return "User logged in, authorized by security data exchange";
302
0
    case FtpStatusCode::SEC_DATA_EXCHANGE_COMPLETE:
303
0
      return "Security data exchange complete";
304
0
    case FtpStatusCode::SEC_DATA_EXCHANGE_COMPLETE_SUCCESS:
305
0
      return "Security data exchange completed successfully";
306
0
    case FtpStatusCode::REQ_FILE_OK_COMPLETE:
307
0
      return "Requested file action okay, completed";
308
0
    case FtpStatusCode::PATHNAME_CREATED:
309
0
      return "PATHNAME created";
310
0
    case FtpStatusCode::USER_OK_NEED_PASSWORD:
311
0
      return "User name okay, need password";
312
0
    case FtpStatusCode::NEED_ACCOUNT:
313
0
      return "Need account for login";
314
0
    case FtpStatusCode::REQ_SEC_MECHANISM_OK:
315
0
      return "Requested security mechanism is ok";
316
0
    case FtpStatusCode::SEC_IS_ACCEPTABLE:
317
0
      return "Security data is acceptable, more is required";
318
0
    case FtpStatusCode::USER_OK_NEED_PASS_CHALLENGE:
319
0
      return "Username okay, need password. Challenge is ...";
320
0
    case FtpStatusCode::FILE_PENDING_ACTION:
321
0
      return "Requested file action pending further information";
322
0
    case FtpStatusCode::SERVICE_NOT_AVAILABLE:
323
0
      return "Service not available, closing control connection";
324
0
    case FtpStatusCode::CANT_OPEN_DATA_CONNECTION:
325
0
      return "Can't open data connection";
326
0
    case FtpStatusCode::CONNECTION_CLOSED:
327
0
      return "Connection closed; transfer aborted";
328
0
    case FtpStatusCode::NEED_UNAVAILABLE_RESOURCE_TO_SEC:
329
0
      return "Need some unavailable resource to process security";
330
0
    case FtpStatusCode::REQ_FILE_ACTION_NOT_TAKEN:
331
0
      return "Requested file action not taken";
332
0
    case FtpStatusCode::REQ_ACTION_ABORTED:
333
0
      return "Requested action aborted: local error in processing";
334
0
    case FtpStatusCode::REQ_ACTION_NOT_TAKEN:
335
0
      return "Requested action not taken. Insufficient storage space in system";
336
0
    case FtpStatusCode::SYNTAX_ERROR_COMMAND_UNRECOGNIZED:
337
0
      return "Syntax error, command unrecognized";
338
0
    case FtpStatusCode::SYNTAX_ERROR_PARAMETER_OR_ARGUMENT:
339
0
      return "Syntax error in parameters or arguments";
340
0
    case FtpStatusCode::COMMAND_NOT_IMPLEMENTED:
341
0
      return "Command not implemented";
342
0
    case FtpStatusCode::BAD_SEQUENCE_COMMANDS:
343
0
      return "Bad sequence of commands";
344
0
    case FtpStatusCode::COMMAND_NOT_IMPLEMENTED_FOR_PARAMETER:
345
0
      return "Command not implemented for that parameter";
346
0
    case FtpStatusCode::NETWORK_PROTOCOL_NOT_SUPPORTED:
347
0
      return "Network protocol not supported";
348
0
    case FtpStatusCode::NOT_LOGGED_IN:
349
0
      return "Not logged in";
350
0
    case FtpStatusCode::NEED_ACCOUNT_FOR_STORE_FILE:
351
0
      return "Need account for storing files";
352
0
    case FtpStatusCode::COMMAND_PROTECTION_DENIED:
353
0
      return "Command protection level denied for policy reasons";
354
0
    case FtpStatusCode::REQUEST_DENIED:
355
0
      return "Request denied for policy reasons";
356
0
    case FtpStatusCode::FAILED_SEC_CHECK:
357
0
      return "Failed security check (hash, sequence, etc)";
358
0
    case FtpStatusCode::REQ_PROT_LEVEL_NOT_SUPPORTED:
359
0
      return "Requested PROT level not supported by mechanism";
360
0
    case FtpStatusCode::COMMAND_PROTECTION_LEVEL_NOT_SUPPORTED:
361
0
      return "Command protection level not supported by security mechanism";
362
0
    case FtpStatusCode::FILE_UNAVAILABLE:
363
0
      return "Requested action not taken: File unavailable";
364
0
    case FtpStatusCode::PAGE_TYPE_UNKNOWN:
365
0
      return "Requested action aborted: page type unknown";
366
0
    case FtpStatusCode::EXCEED_STORAGE_ALLOCATION:
367
0
      return "Requested file action aborted: Exceeded storage allocation";
368
0
    case FtpStatusCode::FILENAME_NOT_ALLOWED:
369
0
      return "Requested action not taken: File name not allowed";
370
0
    case FtpStatusCode::INTEGRITY_PROTECTED:
371
0
      return "Integrity protected reply";
372
0
    case FtpStatusCode::CONFIDENTIALITY_AND_INTEGRITY_PROTECTED:
373
0
      return "Confidentiality and integrity protected reply";
374
0
    case FtpStatusCode::CONFIDENTIALITY_PROTECTED:
375
0
      return "Confidentiality protected reply";
376
0
    default:
377
0
      return "Unknown Status Code";
378
0
    }
379
0
  }
380
381
  std::string FtpResponseLayer::toString() const
382
878
  {
383
878
    return "FTP Response: " + getStatusCodeString();
384
878
  }
385
386
  std::string FtpDataLayer::toString() const
387
862
  {
388
862
    return "FTP Data";
389
862
  }
390
391
}  // namespace pcpp