Syntax Details

This section is normative, and any discrepancies with the ABNF fragments in the preceding text are to be resolved in favor of this grammar.

See [RFC2234] for ABNF notation.  Please note that as per this ABNF definition, literal text strings (those in quotes) are case-insensitive.  Hence, "ip4" matches "ip4", "IP4", "iP4" and "Ip4".

Example Records - folding white space added for readability

svc=S1:A,M2:A,H1+:B  dmn=QR1,SPF1+5,DK2

S1=dnsbl.spamcop.net

QR1=ip4:?170(24.30.23;24.28.200;24.28.204;24.30.18;24.93.47;24.25.9),
  +4(65.24.5.120;24.94.166.28;24.29.109.84;66.75.162.68;24.24.2.12)

SPF1="mx include:s._spf.ebay.com include:m._spf.ebay.com

  include:p._spf.ebay.com include:c._spf.ebay.com ~all"

DK2=dk:MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhAKJ2lzDLZ8XlVambQfMXn3LRGKOD5

  o6lMIgulclWjZwP56LRqdg5ZX15bhc/GsvW8xW/R5Sh1NnkJNyL/cqY1a+GzzL47t7

  EXzVc+nRLWT1kwTvFNGIoAUsFUq+J6+OprwIDAQAB

svc=dnsbl.spamcop.net:A,M2:A,H1+:B  dmn=QR1,SPF1+5,DK2

dmn=SPF1:"v=spf1 redirect:mydomain.com"

 

Collected ABNF

record          =  name-value-pair  *( ( 1*WSP / CRLF ) name-value-pair )

name-value-pair =  name [WSP] "=" [FWS] ( string / quoted-string )

name            =  1*( ALPHA / DIGIT / "." )

string          =  1*( stext ) *( FWS 1*( stext ) )

stext           =  %d33 /     ; Any character except controls,  

                   %d35-91 /  ;   SP, and specials.

                   %d93-126        

specials        =  "\" / DQUOTE

quoted-string   =  DQUOTE *([anyspace] qcontent) [anyspace] DQUOTE

                   ; anything but " and \

anyspace        =  ( WSP / FWS / NBFWS )

qcontent        =  qtext / quoted-pair

qtext           =  NO-WS-CTL /     ; Non white space controls

                   stext

quoted-pair     =  ("\" text)

text            =  %d1-9   /       ; All characters

                   %d11-12 /       ;   excluding CR and LF

                   %d14-127

 

list            =  item  *( "," [anyspace] item )

item            =  name [ "+" [number]] [ ":"  [anyspace] string ]

 

QR1-block       =  "QR1="  blockspec  *( SP  blockspec )

                   ; after removal of FWS

blockspec       =  ( "ip4" / "ip6" ) ":"  blocklist  *( ","  blocklist )

blocklist       =  prefix  number  "("  block-starts ")"

prefix          =  "+" / "-" / "?"

block-starts    =  start  *( ";"  start  )

start           =  ip4-address / ip6-address

 

ip4-address     =  ; as per conventional dotted quad notation,

                   ; e.g. 192.0.2.0

ip6-address     =  ; as per [RFC 3513], section 2.2,

                   ; e.g. 2001:DB8::CD30

 

FWS             =  ( *WSP CRLF 1*WSP )    ; Folding White Space

                   ; In a string FWS is semantically invisible.  In a

                   ; quoted-string, or between name-value pairs, it is

                   ; equivalent to SP.

NBFWS           =  ( "\" CRLF 1*WSP )     ; No Break FWS

                   ; Semantically invisible in either type of string

WSP             =  SP / HTAB

SP              =  %d9

HTAB            =  %d32

CRLF            =  CR LF

CR              =  %d13

LF              =  %d10

NO-WS-CTL       =  %d1-8 /         ; US-ASCII control characters

                   %d11-12 /       ;  that do not include the

                   %d14-31 /       ;  carriage return, line feed,

                   %d127           ;  and white space characters

number          =  1*( DIGIT )

 

Problem:  How to handle folding white space in a quoted string with a long word that must be split.

Ideal Solution:  Redesign the method that needs such a monstrosity.

Possible Solution:  The default is to leave one space in place of each removed FWS.  To over-ride that default,  use a \ at the end of the line.  See NBFWS above.

XYZ:"ip4:207.171.160.32/28 ip4:207.171.164.32/28
  ip4:207.171.180.176/28 dk:o6lMIgulclWjZwP56LRqdg5ZX1\
  5bhc/GsvW8xW/R5Sh1NnkJNyL/cqY1a+GzzL47t7   ~all"

Note on Block Sizes

We chose to use a decimal number instead of the conventional CIDR blocksize notation for two reasons.  1)  It is advantageous to specify blocks of the exact size needed, not just 2**n.  2)  Many blocks of the same size can be grouped, saving space in a tight DNS record.

Semantics

Strings following the svc and dmn names are interpreted as lists.  Other strings have whatever interpretation is needed by their methods.  The string following QR1 is delivered verbatim to the QR1 routines (minus the FWS).  The string following SPF1 is delivered verbatim with FWS converted to a single space.

List items for svc and dmn must have unique names, and the names must match any related DNS records ( less the leading underscore).

Parameters for each list item can be provided in strings immediately after the item, later in the record, or in separate records.  All three are semantically equivalent.

+<number> in a list item means separate records are available, and no more than <number> DNS queries will be necessary to complete the processing of this item.  The first record is found by a TXT query to _<name>.<domain>  Subsequent records are found as specified by the method. (e.g. SPF1 uses commands like redirect. )

QR1 Semantics

Blocks are processed left to right.  The initial presumption is FAIL.  If the tested IP address is within one of the blocks, the result is NEUTRAL or PASS, depending on the ? or + in front of the block.  NEUTRAL over-rides FAIL, and PASS over-rides NEUTRAL  An explicit FAIL ( "-" in front of a block ) terminates the QR1 test without looking at any remaining blocks.

A PASS or FAIL from QR1 is conclusive.  No further testing is necessary.  A NEUTRAL can be over-ridden by a PASS or FAIL from a later test.

 

===  End of File  4/21/05   ===