ehlo           = "EHLO" SP ( Domain / address-literal ) CRLF

helo           = "HELO" SP Domain CRLF

ehlo-ok-rsp    = ( "250" SP Domain [ SP ehlo-greet ] CRLF )
                 / ( "250-" Domain [ SP ehlo-greet ] CRLF
                 *( "250-" ehlo-line CRLF )
                 "250" SP ehlo-line CRLF )

ehlo-greet     = 1*(%d0-9 / %d11-12 / %d14-127)
                 ; string of any characters other than CR or LF

ehlo-line      = ehlo-keyword *( SP ehlo-param )

ehlo-keyword   = (ALPHA / DIGIT) *(ALPHA / DIGIT / "-")
                 ; additional syntax of ehlo-params depends on
                 ; ehlo-keyword

ehlo-param     = 1*(%d33-126)
                 ; any CHAR excluding <SP> and all
                 ; control characters (US-ASCII 0-31 and 127
                 ; inclusive)

mail = "MAIL FROM:" Reverse-path
                                    [SP Mail-parameters] CRLF

rcpt = "RCPT TO:" ( "<Postmaster@" Domain ">" / "<Postmaster>" /
            Forward-path ) [SP Rcpt-parameters] CRLF

data = "DATA" CRLF

rset = "RSET" CRLF

vrfy = "VRFY" SP String CRLF

expn = "EXPN" SP String CRLF

help = "HELP" [ SP String ] CRLF

noop = "NOOP" [ SP String ] CRLF

quit = "QUIT" CRLF

Reverse-path   = Path / "<>"

Forward-path   = Path

Path           = "<" [ A-d-l ":" ] Mailbox ">"

A-d-l          = At-domain *( "," At-domain )
               ; Note that this form, the so-called "source
               ; route", MUST BE accepted, SHOULD NOT be
               ; generated, and SHOULD be ignored.

At-domain      = "@" Domain

Mail-parameters  = esmtp-param *(SP esmtp-param)

Rcpt-parameters  = esmtp-param *(SP esmtp-param)

esmtp-param    = esmtp-keyword ["=" esmtp-value]

esmtp-keyword  = (ALPHA / DIGIT) *(ALPHA / DIGIT / "-")

esmtp-value    = 1*(%d33-60 / %d62-126)
               ; any CHAR excluding "=", SP, and control
               ; characters.  If this string is an email address,
               ; i.e., a Mailbox, then the "xtext" syntax [32]
               ; SHOULD be used.

Keyword        = Ldh-str

Argument       = Atom

Domain         = sub-domain *("." sub-domain)

sub-domain     = Let-dig [Ldh-str]

Let-dig        = ALPHA / DIGIT

Ldh-str        = *( ALPHA / DIGIT / "-" ) Let-dig

address-literal  = "[" ( IPv4-address-literal /
                 IPv6-address-literal /
                 General-address-literal ) "]"
                 ; See Section 4.1.3

Mailbox        = Local-part "@" ( Domain / address-literal )

Local-part     = Dot-string / Quoted-string
               ; MAY be case-sensitive


Dot-string     = Atom *("."  Atom)

Atom           = 1*atext

Quoted-string  = DQUOTE *QcontentSMTP DQUOTE

QcontentSMTP   = qtextSMTP / quoted-pairSMTP

quoted-pairSMTP  = %d92 %d32-126
                 ; i.e., backslash followed by any ASCII
                 ; graphic (including itself) or SPace

qtextSMTP      = %d32-33 / %d35-91 / %d93-126
               ; i.e., within a quoted string, any
               ; ASCII graphic or space is permitted
               ; without blackslash-quoting except
               ; double-quote and the backslash itself.

String         = Atom / Quoted-string

IPv4-address-literal  = Snum 3("."  Snum)

IPv6-address-literal  = "IPv6:" IPv6-addr

General-address-literal  = Standardized-tag ":" 1*dcontent

Standardized-tag  = Ldh-str
                  ; Standardized-tag MUST be specified in a
                  ; Standards-Track RFC and registered with IANA

dcontent       = %d33-90 / ; Printable US-ASCII
               %d94-126 ; excl. "[", "\", "]"

Snum           = 1*3DIGIT
               ; representing a decimal integer
               ; value in the range 0 through 255

IPv6-addr      = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp

IPv6-hex       = 1*4HEXDIG

IPv6-full      = IPv6-hex 7(":" IPv6-hex)

IPv6-comp      = [IPv6-hex *5(":" IPv6-hex)] "::"
               [IPv6-hex *5(":" IPv6-hex)]
               ; The "::" represents at least 2 16-bit groups of
               ; zeros.  No more than 6 groups in addition to the
               ; "::" may be present.

IPv6v4-full    = IPv6-hex 5(":" IPv6-hex) ":" IPv4-address-literal

IPv6v4-comp    = [IPv6-hex *3(":" IPv6-hex)] "::"
               [IPv6-hex *3(":" IPv6-hex) ":"]
               IPv4-address-literal
               ; The "::" represents at least 2 16-bit groups of
               ; zeros.  No more than 4 groups in addition to the
               ; "::" and IPv4-address-literal may be present.

Greeting       = ( "220 " (Domain / address-literal)
               [ SP textstring ] CRLF ) /
               ( "220-" (Domain / address-literal)
               [ SP textstring ] CRLF
               *( "220-" [ textstring ] CRLF )
               "220" [ SP textstring ] CRLF )

textstring     = 1*(%d09 / %d32-126) ; HT, SP, Printable US-ASCII

Reply-line     = *( Reply-code "-" [ textstring ] CRLF )
               Reply-code [ SP textstring ] CRLF

Reply-code     = %x32-35 %x30-35 %x30-39

Return-path-line  = "Return-Path:" FWS Reverse-path CRLF

Time-stamp-line  = "Received:" FWS Stamp CRLF

Stamp          = From-domain By-domain Opt-info [CFWS] ";"
               FWS date-time
               ; where "date-time" is as defined in RFC 5322 [4]
               ; but the "obs-" forms, especially two-digit
               ; years, are prohibited in SMTP and MUST NOT be used.

From-domain    = "FROM" FWS Extended-Domain

By-domain      = CFWS "BY" FWS Extended-Domain

Extended-Domain  = Domain /
                 ( Domain FWS "(" TCP-info ")" ) /
                 ( address-literal FWS "(" TCP-info ")" )

TCP-info       = address-literal / ( Domain FWS address-literal )
               ; Information derived by server from TCP connection
               ; not client EHLO.

Opt-info       = [Via] [With] [ID] [For]
               [Additional-Registered-Clauses]

Via            = CFWS "VIA" FWS Link

With           = CFWS "WITH" FWS Protocol

ID             = CFWS "ID" FWS ( Atom / msg-id )
               ; msg-id is defined in RFC 5322 [4]

For            = CFWS "FOR" FWS ( Path / Mailbox )

Additional-Registered-Clauses  = CFWS Atom FWS String
                               ; Additional standard clauses may be
                               ; added in this
                               ; location by future standards and
                               ; registration with
                               ; IANA.  SMTP servers SHOULD NOT use
                               ; unregistered
                               ; names.  See Section 8.

Link           = "TCP" / Addtl-Link

Addtl-Link     = Atom
               ; Additional standard names for links are
               ; registered with the Internet Assigned Numbers
               ; Authority (IANA).  "Via" is primarily of value
               ; with non-Internet transports.  SMTP servers
               ; SHOULD NOT use unregistered names.

Protocol       = "ESMTP" / "SMTP" / Attdl-Protocol

Attdl-Protocol = Atom
               ; Additional standard names for protocols are
               ; registered with the Internet Assigned Numbers
               ; Authority (IANA) in the "mail parameters"
               ; registry [9].  SMTP servers SHOULD NOT
               ; use unregistered names.
