aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-smtp.c
diff options
context:
space:
mode:
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>2008-09-06 23:58:23 +0000
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>2008-09-06 23:58:23 +0000
commitf8cbd0d7941f6c8ef86ee8c89a5cc4fa58e38d48 (patch)
tree0b14d75e8f9dab38f519d5a358342cd4593eabbf /epan/dissectors/packet-smtp.c
parentfb0ccccdf2cd0b00b0d528b913b038c7c0d93c8d (diff)
Have a line_is_smtp_command() routine to check whether a line is an SMTP
command, and use that in the parsing loop (that means we don't have to treat 4-character commands and non-4-character commands separately). git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@26155 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-smtp.c')
-rw-r--r--epan/dissectors/packet-smtp.c89
1 files changed, 69 insertions, 20 deletions
diff --git a/epan/dissectors/packet-smtp.c b/epan/dissectors/packet-smtp.c
index 82cc6f9d7f..42eba2a02a 100644
--- a/epan/dissectors/packet-smtp.c
+++ b/epan/dissectors/packet-smtp.c
@@ -126,6 +126,59 @@ struct smtp_request_val {
gboolean msg_last; /* Is this the last BDAT chunk */
};
+/*
+ * See
+ *
+ * http://support.microsoft.com/default.aspx?scid=kb;[LN];812455
+ *
+ * for the Exchange extensions.
+ */
+static const struct {
+ const char *command;
+ int len;
+} commands[] = {
+ { "STARTTLS", 8 }, /* RFC 2487 */
+ { "X-EXPS", 6 }, /* Microsoft Exchange */
+ { "X-LINK2STATE", 12 }, /* Microsoft Exchange */
+ { "XEXCH50", 7 } /* Microsoft Exchange */
+};
+
+#define NCOMMANDS (sizeof commands / sizeof commands[0])
+
+static gboolean
+line_is_smtp_command(const guchar *command, int commandlen)
+{
+ size_t i;
+
+ /*
+ * To quote RFC 821, "Command codes are four alphabetic
+ * characters". (We treat only A-Z and a-z as alphabetic.)
+ *
+ * However, there are some SMTP extensions that involve commands
+ * longer than 4 characters and/or that contain non-alphabetic
+ * characters; we treat them specially.
+ *
+ * XXX - should we just have a table of known commands? Or would
+ * that fail to catch some extensions we don't know about?
+ */
+#define ISALPHA(c) (((c) >= 'A' && (c) <= 'Z') || \
+ ((c) >= 'a' && (c) <= 'z'))
+ if (commandlen == 4 && ISALPHA(command[0]) && ISALPHA(command[1]) &&
+ ISALPHA(command[2]) && ISALPHA(command[3])) {
+ /* standard 4-alphabetic command */
+ return TRUE;
+ }
+
+ /*
+ * Check the list of non-4-alphabetic commands.
+ */
+ for (i = 0; i < NCOMMANDS; i++) {
+ if (commandlen == commands[i].len &&
+ g_ascii_strncasecmp(command, commands[i].command, commands[i].len) == 0)
+ return TRUE;
+ }
+ return FALSE;
+}
static void dissect_smtp_data(tvbuff_t *tvb, int offset, proto_tree *smtp_tree)
{
@@ -165,7 +218,8 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
int request = 0;
conversation_t *conversation;
struct smtp_request_val *request_val;
- const guchar *line;
+ const guchar *line, *linep, *lineend;
+ guchar c;
guint32 code;
int linelen = 0;
gint length_remaining;
@@ -388,17 +442,17 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/*
* This is commands - unless the capture started in the
* middle of a session, and we're in the middle of data.
- * To quote RFC 821, "Command codes are four alphabetic
- * characters"; if we don't see four alphabetic characters
- * and, if there's anything else in the line, a space, we
- * assume it's not a command.
- * (We treat only A-Z and a-z as alphabetic.)
+ *
+ * Commands are not necessarily 4 characters; look
+ * for a space or the end of the line to see where
+ * the putative command ends.
*/
-#define ISALPHA(c) (((c) >= 'A' && (c) <= 'Z') || \
- ((c) >= 'a' && (c) <= 'z'))
- if (linelen >= 4 && ISALPHA(line[0]) && ISALPHA(line[1]) &&
- ISALPHA(line[2]) && ISALPHA(line[3]) &&
- (linelen == 4 || line[4] == ' ')) {
+ linep = line;
+ lineend = line + linelen;
+ while (linep < lineend && (c = *linep) != ' ')
+ linep++;
+ cmdlen = linep - line;
+ if (line_is_smtp_command(line, cmdlen)) {
if (g_ascii_strncasecmp(line, "DATA", 4) == 0) {
/*
@@ -458,17 +512,12 @@ dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
} else {
- if ((linelen >= 7) && line[0] == 'X' && ( (g_ascii_strncasecmp(line, "X-EXPS ", 7) == 0) ||
- ((linelen >=13) && (g_ascii_strncasecmp(line, "X-LINK2STATE ", 13) == 0)) ||
- ((linelen >= 8) && (g_ascii_strncasecmp(line, "XEXCH50 ", 8) == 0)) ))
- frame_data->pdu_type = SMTP_PDU_CMD;
- else
- /*
- * Assume it's message data.
- */
+ /*
+ * Assume it's message data.
+ */
- frame_data->pdu_type = request_val->data_seen ? SMTP_PDU_MESSAGE : SMTP_PDU_CMD;
+ frame_data->pdu_type = request_val->data_seen ? SMTP_PDU_MESSAGE : SMTP_PDU_CMD;
}
}