scan.go 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331
  1. package dns
  2. import (
  3. "bufio"
  4. "fmt"
  5. "io"
  6. "os"
  7. "path/filepath"
  8. "strconv"
  9. "strings"
  10. )
  11. const maxTok = 2048 // Largest token we can return.
  12. // The maximum depth of $INCLUDE directives supported by the
  13. // ZoneParser API.
  14. const maxIncludeDepth = 7
  15. // Tokinize a RFC 1035 zone file. The tokenizer will normalize it:
  16. // * Add ownernames if they are left blank;
  17. // * Suppress sequences of spaces;
  18. // * Make each RR fit on one line (_NEWLINE is send as last)
  19. // * Handle comments: ;
  20. // * Handle braces - anywhere.
  21. const (
  22. // Zonefile
  23. zEOF = iota
  24. zString
  25. zBlank
  26. zQuote
  27. zNewline
  28. zRrtpe
  29. zOwner
  30. zClass
  31. zDirOrigin // $ORIGIN
  32. zDirTTL // $TTL
  33. zDirInclude // $INCLUDE
  34. zDirGenerate // $GENERATE
  35. // Privatekey file
  36. zValue
  37. zKey
  38. zExpectOwnerDir // Ownername
  39. zExpectOwnerBl // Whitespace after the ownername
  40. zExpectAny // Expect rrtype, ttl or class
  41. zExpectAnyNoClass // Expect rrtype or ttl
  42. zExpectAnyNoClassBl // The whitespace after _EXPECT_ANY_NOCLASS
  43. zExpectAnyNoTTL // Expect rrtype or class
  44. zExpectAnyNoTTLBl // Whitespace after _EXPECT_ANY_NOTTL
  45. zExpectRrtype // Expect rrtype
  46. zExpectRrtypeBl // Whitespace BEFORE rrtype
  47. zExpectRdata // The first element of the rdata
  48. zExpectDirTTLBl // Space after directive $TTL
  49. zExpectDirTTL // Directive $TTL
  50. zExpectDirOriginBl // Space after directive $ORIGIN
  51. zExpectDirOrigin // Directive $ORIGIN
  52. zExpectDirIncludeBl // Space after directive $INCLUDE
  53. zExpectDirInclude // Directive $INCLUDE
  54. zExpectDirGenerate // Directive $GENERATE
  55. zExpectDirGenerateBl // Space after directive $GENERATE
  56. )
  57. // ParseError is a parsing error. It contains the parse error and the location in the io.Reader
  58. // where the error occurred.
  59. type ParseError struct {
  60. file string
  61. err string
  62. lex lex
  63. }
  64. func (e *ParseError) Error() (s string) {
  65. if e.file != "" {
  66. s = e.file + ": "
  67. }
  68. s += "dns: " + e.err + ": " + strconv.QuoteToASCII(e.lex.token) + " at line: " +
  69. strconv.Itoa(e.lex.line) + ":" + strconv.Itoa(e.lex.column)
  70. return
  71. }
  72. type lex struct {
  73. token string // text of the token
  74. err bool // when true, token text has lexer error
  75. value uint8 // value: zString, _BLANK, etc.
  76. torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar
  77. line int // line in the file
  78. column int // column in the file
  79. }
  80. // ttlState describes the state necessary to fill in an omitted RR TTL
  81. type ttlState struct {
  82. ttl uint32 // ttl is the current default TTL
  83. isByDirective bool // isByDirective indicates whether ttl was set by a $TTL directive
  84. }
  85. // NewRR reads the RR contained in the string s. Only the first RR is returned.
  86. // If s contains no records, NewRR will return nil with no error.
  87. //
  88. // The class defaults to IN and TTL defaults to 3600. The full zone file syntax
  89. // like $TTL, $ORIGIN, etc. is supported. All fields of the returned RR are
  90. // set, except RR.Header().Rdlength which is set to 0.
  91. func NewRR(s string) (RR, error) {
  92. if len(s) > 0 && s[len(s)-1] != '\n' { // We need a closing newline
  93. return ReadRR(strings.NewReader(s+"\n"), "")
  94. }
  95. return ReadRR(strings.NewReader(s), "")
  96. }
  97. // ReadRR reads the RR contained in r.
  98. //
  99. // The string file is used in error reporting and to resolve relative
  100. // $INCLUDE directives.
  101. //
  102. // See NewRR for more documentation.
  103. func ReadRR(r io.Reader, file string) (RR, error) {
  104. zp := NewZoneParser(r, ".", file)
  105. zp.SetDefaultTTL(defaultTtl)
  106. zp.SetIncludeAllowed(true)
  107. rr, _ := zp.Next()
  108. return rr, zp.Err()
  109. }
  110. // ZoneParser is a parser for an RFC 1035 style zonefile.
  111. //
  112. // Each parsed RR in the zone is returned sequentially from Next. An
  113. // optional comment can be retrieved with Comment.
  114. //
  115. // The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are all
  116. // supported. Although $INCLUDE is disabled by default.
  117. // Note that $GENERATE's range support up to a maximum of 65535 steps.
  118. //
  119. // Basic usage pattern when reading from a string (z) containing the
  120. // zone data:
  121. //
  122. // zp := NewZoneParser(strings.NewReader(z), "", "")
  123. //
  124. // for rr, ok := zp.Next(); ok; rr, ok = zp.Next() {
  125. // // Do something with rr
  126. // }
  127. //
  128. // if err := zp.Err(); err != nil {
  129. // // log.Println(err)
  130. // }
  131. //
  132. // Comments specified after an RR (and on the same line!) are
  133. // returned too:
  134. //
  135. // foo. IN A 10.0.0.1 ; this is a comment
  136. //
  137. // The text "; this is comment" is returned from Comment. Comments inside
  138. // the RR are returned concatenated along with the RR. Comments on a line
  139. // by themselves are discarded.
  140. type ZoneParser struct {
  141. c *zlexer
  142. parseErr *ParseError
  143. origin string
  144. file string
  145. defttl *ttlState
  146. h RR_Header
  147. // sub is used to parse $INCLUDE files and $GENERATE directives.
  148. // Next, by calling subNext, forwards the resulting RRs from this
  149. // sub parser to the calling code.
  150. sub *ZoneParser
  151. osFile *os.File
  152. includeDepth uint8
  153. includeAllowed bool
  154. generateDisallowed bool
  155. }
  156. // NewZoneParser returns an RFC 1035 style zonefile parser that reads
  157. // from r.
  158. //
  159. // The string file is used in error reporting and to resolve relative
  160. // $INCLUDE directives. The string origin is used as the initial
  161. // origin, as if the file would start with an $ORIGIN directive.
  162. func NewZoneParser(r io.Reader, origin, file string) *ZoneParser {
  163. var pe *ParseError
  164. if origin != "" {
  165. origin = Fqdn(origin)
  166. if _, ok := IsDomainName(origin); !ok {
  167. pe = &ParseError{file, "bad initial origin name", lex{}}
  168. }
  169. }
  170. return &ZoneParser{
  171. c: newZLexer(r),
  172. parseErr: pe,
  173. origin: origin,
  174. file: file,
  175. }
  176. }
  177. // SetDefaultTTL sets the parsers default TTL to ttl.
  178. func (zp *ZoneParser) SetDefaultTTL(ttl uint32) {
  179. zp.defttl = &ttlState{ttl, false}
  180. }
  181. // SetIncludeAllowed controls whether $INCLUDE directives are
  182. // allowed. $INCLUDE directives are not supported by default.
  183. //
  184. // The $INCLUDE directive will open and read from a user controlled
  185. // file on the system. Even if the file is not a valid zonefile, the
  186. // contents of the file may be revealed in error messages, such as:
  187. //
  188. // /etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31
  189. // /etc/shadow: dns: not a TTL: "root:$6$<redacted>::0:99999:7:::" at line: 1:125
  190. func (zp *ZoneParser) SetIncludeAllowed(v bool) {
  191. zp.includeAllowed = v
  192. }
  193. // Err returns the first non-EOF error that was encountered by the
  194. // ZoneParser.
  195. func (zp *ZoneParser) Err() error {
  196. if zp.parseErr != nil {
  197. return zp.parseErr
  198. }
  199. if zp.sub != nil {
  200. if err := zp.sub.Err(); err != nil {
  201. return err
  202. }
  203. }
  204. return zp.c.Err()
  205. }
  206. func (zp *ZoneParser) setParseError(err string, l lex) (RR, bool) {
  207. zp.parseErr = &ParseError{zp.file, err, l}
  208. return nil, false
  209. }
  210. // Comment returns an optional text comment that occurred alongside
  211. // the RR.
  212. func (zp *ZoneParser) Comment() string {
  213. if zp.parseErr != nil {
  214. return ""
  215. }
  216. if zp.sub != nil {
  217. return zp.sub.Comment()
  218. }
  219. return zp.c.Comment()
  220. }
  221. func (zp *ZoneParser) subNext() (RR, bool) {
  222. if rr, ok := zp.sub.Next(); ok {
  223. return rr, true
  224. }
  225. if zp.sub.osFile != nil {
  226. zp.sub.osFile.Close()
  227. zp.sub.osFile = nil
  228. }
  229. if zp.sub.Err() != nil {
  230. // We have errors to surface.
  231. return nil, false
  232. }
  233. zp.sub = nil
  234. return zp.Next()
  235. }
  236. // Next advances the parser to the next RR in the zonefile and
  237. // returns the (RR, true). It will return (nil, false) when the
  238. // parsing stops, either by reaching the end of the input or an
  239. // error. After Next returns (nil, false), the Err method will return
  240. // any error that occurred during parsing.
  241. func (zp *ZoneParser) Next() (RR, bool) {
  242. if zp.parseErr != nil {
  243. return nil, false
  244. }
  245. if zp.sub != nil {
  246. return zp.subNext()
  247. }
  248. // 6 possible beginnings of a line (_ is a space):
  249. //
  250. // 0. zRRTYPE -> all omitted until the rrtype
  251. // 1. zOwner _ zRrtype -> class/ttl omitted
  252. // 2. zOwner _ zString _ zRrtype -> class omitted
  253. // 3. zOwner _ zString _ zClass _ zRrtype -> ttl/class
  254. // 4. zOwner _ zClass _ zRrtype -> ttl omitted
  255. // 5. zOwner _ zClass _ zString _ zRrtype -> class/ttl (reversed)
  256. //
  257. // After detecting these, we know the zRrtype so we can jump to functions
  258. // handling the rdata for each of these types.
  259. st := zExpectOwnerDir // initial state
  260. h := &zp.h
  261. for l, ok := zp.c.Next(); ok; l, ok = zp.c.Next() {
  262. // zlexer spotted an error already
  263. if l.err {
  264. return zp.setParseError(l.token, l)
  265. }
  266. switch st {
  267. case zExpectOwnerDir:
  268. // We can also expect a directive, like $TTL or $ORIGIN
  269. if zp.defttl != nil {
  270. h.Ttl = zp.defttl.ttl
  271. }
  272. h.Class = ClassINET
  273. switch l.value {
  274. case zNewline:
  275. st = zExpectOwnerDir
  276. case zOwner:
  277. name, ok := toAbsoluteName(l.token, zp.origin)
  278. if !ok {
  279. return zp.setParseError("bad owner name", l)
  280. }
  281. h.Name = name
  282. st = zExpectOwnerBl
  283. case zDirTTL:
  284. st = zExpectDirTTLBl
  285. case zDirOrigin:
  286. st = zExpectDirOriginBl
  287. case zDirInclude:
  288. st = zExpectDirIncludeBl
  289. case zDirGenerate:
  290. st = zExpectDirGenerateBl
  291. case zRrtpe:
  292. h.Rrtype = l.torc
  293. st = zExpectRdata
  294. case zClass:
  295. h.Class = l.torc
  296. st = zExpectAnyNoClassBl
  297. case zBlank:
  298. // Discard, can happen when there is nothing on the
  299. // line except the RR type
  300. case zString:
  301. ttl, ok := stringToTTL(l.token)
  302. if !ok {
  303. return zp.setParseError("not a TTL", l)
  304. }
  305. h.Ttl = ttl
  306. if zp.defttl == nil || !zp.defttl.isByDirective {
  307. zp.defttl = &ttlState{ttl, false}
  308. }
  309. st = zExpectAnyNoTTLBl
  310. default:
  311. return zp.setParseError("syntax error at beginning", l)
  312. }
  313. case zExpectDirIncludeBl:
  314. if l.value != zBlank {
  315. return zp.setParseError("no blank after $INCLUDE-directive", l)
  316. }
  317. st = zExpectDirInclude
  318. case zExpectDirInclude:
  319. if l.value != zString {
  320. return zp.setParseError("expecting $INCLUDE value, not this...", l)
  321. }
  322. neworigin := zp.origin // There may be optionally a new origin set after the filename, if not use current one
  323. switch l, _ := zp.c.Next(); l.value {
  324. case zBlank:
  325. l, _ := zp.c.Next()
  326. if l.value == zString {
  327. name, ok := toAbsoluteName(l.token, zp.origin)
  328. if !ok {
  329. return zp.setParseError("bad origin name", l)
  330. }
  331. neworigin = name
  332. }
  333. case zNewline, zEOF:
  334. // Ok
  335. default:
  336. return zp.setParseError("garbage after $INCLUDE", l)
  337. }
  338. if !zp.includeAllowed {
  339. return zp.setParseError("$INCLUDE directive not allowed", l)
  340. }
  341. if zp.includeDepth >= maxIncludeDepth {
  342. return zp.setParseError("too deeply nested $INCLUDE", l)
  343. }
  344. // Start with the new file
  345. includePath := l.token
  346. if !filepath.IsAbs(includePath) {
  347. includePath = filepath.Join(filepath.Dir(zp.file), includePath)
  348. }
  349. r1, e1 := os.Open(includePath)
  350. if e1 != nil {
  351. var as string
  352. if !filepath.IsAbs(l.token) {
  353. as = fmt.Sprintf(" as `%s'", includePath)
  354. }
  355. msg := fmt.Sprintf("failed to open `%s'%s: %v", l.token, as, e1)
  356. return zp.setParseError(msg, l)
  357. }
  358. zp.sub = NewZoneParser(r1, neworigin, includePath)
  359. zp.sub.defttl, zp.sub.includeDepth, zp.sub.osFile = zp.defttl, zp.includeDepth+1, r1
  360. zp.sub.SetIncludeAllowed(true)
  361. return zp.subNext()
  362. case zExpectDirTTLBl:
  363. if l.value != zBlank {
  364. return zp.setParseError("no blank after $TTL-directive", l)
  365. }
  366. st = zExpectDirTTL
  367. case zExpectDirTTL:
  368. if l.value != zString {
  369. return zp.setParseError("expecting $TTL value, not this...", l)
  370. }
  371. if err := slurpRemainder(zp.c); err != nil {
  372. return zp.setParseError(err.err, err.lex)
  373. }
  374. ttl, ok := stringToTTL(l.token)
  375. if !ok {
  376. return zp.setParseError("expecting $TTL value, not this...", l)
  377. }
  378. zp.defttl = &ttlState{ttl, true}
  379. st = zExpectOwnerDir
  380. case zExpectDirOriginBl:
  381. if l.value != zBlank {
  382. return zp.setParseError("no blank after $ORIGIN-directive", l)
  383. }
  384. st = zExpectDirOrigin
  385. case zExpectDirOrigin:
  386. if l.value != zString {
  387. return zp.setParseError("expecting $ORIGIN value, not this...", l)
  388. }
  389. if err := slurpRemainder(zp.c); err != nil {
  390. return zp.setParseError(err.err, err.lex)
  391. }
  392. name, ok := toAbsoluteName(l.token, zp.origin)
  393. if !ok {
  394. return zp.setParseError("bad origin name", l)
  395. }
  396. zp.origin = name
  397. st = zExpectOwnerDir
  398. case zExpectDirGenerateBl:
  399. if l.value != zBlank {
  400. return zp.setParseError("no blank after $GENERATE-directive", l)
  401. }
  402. st = zExpectDirGenerate
  403. case zExpectDirGenerate:
  404. if zp.generateDisallowed {
  405. return zp.setParseError("nested $GENERATE directive not allowed", l)
  406. }
  407. if l.value != zString {
  408. return zp.setParseError("expecting $GENERATE value, not this...", l)
  409. }
  410. return zp.generate(l)
  411. case zExpectOwnerBl:
  412. if l.value != zBlank {
  413. return zp.setParseError("no blank after owner", l)
  414. }
  415. st = zExpectAny
  416. case zExpectAny:
  417. switch l.value {
  418. case zRrtpe:
  419. if zp.defttl == nil {
  420. return zp.setParseError("missing TTL with no previous value", l)
  421. }
  422. h.Rrtype = l.torc
  423. st = zExpectRdata
  424. case zClass:
  425. h.Class = l.torc
  426. st = zExpectAnyNoClassBl
  427. case zString:
  428. ttl, ok := stringToTTL(l.token)
  429. if !ok {
  430. return zp.setParseError("not a TTL", l)
  431. }
  432. h.Ttl = ttl
  433. if zp.defttl == nil || !zp.defttl.isByDirective {
  434. zp.defttl = &ttlState{ttl, false}
  435. }
  436. st = zExpectAnyNoTTLBl
  437. default:
  438. return zp.setParseError("expecting RR type, TTL or class, not this...", l)
  439. }
  440. case zExpectAnyNoClassBl:
  441. if l.value != zBlank {
  442. return zp.setParseError("no blank before class", l)
  443. }
  444. st = zExpectAnyNoClass
  445. case zExpectAnyNoTTLBl:
  446. if l.value != zBlank {
  447. return zp.setParseError("no blank before TTL", l)
  448. }
  449. st = zExpectAnyNoTTL
  450. case zExpectAnyNoTTL:
  451. switch l.value {
  452. case zClass:
  453. h.Class = l.torc
  454. st = zExpectRrtypeBl
  455. case zRrtpe:
  456. h.Rrtype = l.torc
  457. st = zExpectRdata
  458. default:
  459. return zp.setParseError("expecting RR type or class, not this...", l)
  460. }
  461. case zExpectAnyNoClass:
  462. switch l.value {
  463. case zString:
  464. ttl, ok := stringToTTL(l.token)
  465. if !ok {
  466. return zp.setParseError("not a TTL", l)
  467. }
  468. h.Ttl = ttl
  469. if zp.defttl == nil || !zp.defttl.isByDirective {
  470. zp.defttl = &ttlState{ttl, false}
  471. }
  472. st = zExpectRrtypeBl
  473. case zRrtpe:
  474. h.Rrtype = l.torc
  475. st = zExpectRdata
  476. default:
  477. return zp.setParseError("expecting RR type or TTL, not this...", l)
  478. }
  479. case zExpectRrtypeBl:
  480. if l.value != zBlank {
  481. return zp.setParseError("no blank before RR type", l)
  482. }
  483. st = zExpectRrtype
  484. case zExpectRrtype:
  485. if l.value != zRrtpe {
  486. return zp.setParseError("unknown RR type", l)
  487. }
  488. h.Rrtype = l.torc
  489. st = zExpectRdata
  490. case zExpectRdata:
  491. var rr RR
  492. if newFn, ok := TypeToRR[h.Rrtype]; ok && canParseAsRR(h.Rrtype) {
  493. rr = newFn()
  494. *rr.Header() = *h
  495. } else {
  496. rr = &RFC3597{Hdr: *h}
  497. }
  498. _, isPrivate := rr.(*PrivateRR)
  499. if !isPrivate && zp.c.Peek().token == "" {
  500. // This is a dynamic update rr.
  501. // TODO(tmthrgd): Previously slurpRemainder was only called
  502. // for certain RR types, which may have been important.
  503. if err := slurpRemainder(zp.c); err != nil {
  504. return zp.setParseError(err.err, err.lex)
  505. }
  506. return rr, true
  507. } else if l.value == zNewline {
  508. return zp.setParseError("unexpected newline", l)
  509. }
  510. if err := rr.parse(zp.c, zp.origin); err != nil {
  511. // err is a concrete *ParseError without the file field set.
  512. // The setParseError call below will construct a new
  513. // *ParseError with file set to zp.file.
  514. // If err.lex is nil than we have encounter an unknown RR type
  515. // in that case we substitute our current lex token.
  516. if err.lex == (lex{}) {
  517. return zp.setParseError(err.err, l)
  518. }
  519. return zp.setParseError(err.err, err.lex)
  520. }
  521. return rr, true
  522. }
  523. }
  524. // If we get here, we and the h.Rrtype is still zero, we haven't parsed anything, this
  525. // is not an error, because an empty zone file is still a zone file.
  526. return nil, false
  527. }
  528. // canParseAsRR returns true if the record type can be parsed as a
  529. // concrete RR. It blacklists certain record types that must be parsed
  530. // according to RFC 3597 because they lack a presentation format.
  531. func canParseAsRR(rrtype uint16) bool {
  532. switch rrtype {
  533. case TypeANY, TypeNULL, TypeOPT, TypeTSIG:
  534. return false
  535. default:
  536. return true
  537. }
  538. }
  539. type zlexer struct {
  540. br io.ByteReader
  541. readErr error
  542. line int
  543. column int
  544. comBuf string
  545. comment string
  546. l lex
  547. cachedL *lex
  548. brace int
  549. quote bool
  550. space bool
  551. commt bool
  552. rrtype bool
  553. owner bool
  554. nextL bool
  555. eol bool // end-of-line
  556. }
  557. func newZLexer(r io.Reader) *zlexer {
  558. br, ok := r.(io.ByteReader)
  559. if !ok {
  560. br = bufio.NewReaderSize(r, 1024)
  561. }
  562. return &zlexer{
  563. br: br,
  564. line: 1,
  565. owner: true,
  566. }
  567. }
  568. func (zl *zlexer) Err() error {
  569. if zl.readErr == io.EOF {
  570. return nil
  571. }
  572. return zl.readErr
  573. }
  574. // readByte returns the next byte from the input
  575. func (zl *zlexer) readByte() (byte, bool) {
  576. if zl.readErr != nil {
  577. return 0, false
  578. }
  579. c, err := zl.br.ReadByte()
  580. if err != nil {
  581. zl.readErr = err
  582. return 0, false
  583. }
  584. // delay the newline handling until the next token is delivered,
  585. // fixes off-by-one errors when reporting a parse error.
  586. if zl.eol {
  587. zl.line++
  588. zl.column = 0
  589. zl.eol = false
  590. }
  591. if c == '\n' {
  592. zl.eol = true
  593. } else {
  594. zl.column++
  595. }
  596. return c, true
  597. }
  598. func (zl *zlexer) Peek() lex {
  599. if zl.nextL {
  600. return zl.l
  601. }
  602. l, ok := zl.Next()
  603. if !ok {
  604. return l
  605. }
  606. if zl.nextL {
  607. // Cache l. Next returns zl.cachedL then zl.l.
  608. zl.cachedL = &l
  609. } else {
  610. // In this case l == zl.l, so we just tell Next to return zl.l.
  611. zl.nextL = true
  612. }
  613. return l
  614. }
  615. func (zl *zlexer) Next() (lex, bool) {
  616. l := &zl.l
  617. switch {
  618. case zl.cachedL != nil:
  619. l, zl.cachedL = zl.cachedL, nil
  620. return *l, true
  621. case zl.nextL:
  622. zl.nextL = false
  623. return *l, true
  624. case l.err:
  625. // Parsing errors should be sticky.
  626. return lex{value: zEOF}, false
  627. }
  628. var (
  629. str [maxTok]byte // Hold string text
  630. com [maxTok]byte // Hold comment text
  631. stri int // Offset in str (0 means empty)
  632. comi int // Offset in com (0 means empty)
  633. escape bool
  634. )
  635. if zl.comBuf != "" {
  636. comi = copy(com[:], zl.comBuf)
  637. zl.comBuf = ""
  638. }
  639. zl.comment = ""
  640. for x, ok := zl.readByte(); ok; x, ok = zl.readByte() {
  641. l.line, l.column = zl.line, zl.column
  642. if stri >= len(str) {
  643. l.token = "token length insufficient for parsing"
  644. l.err = true
  645. return *l, true
  646. }
  647. if comi >= len(com) {
  648. l.token = "comment length insufficient for parsing"
  649. l.err = true
  650. return *l, true
  651. }
  652. switch x {
  653. case ' ', '\t':
  654. if escape || zl.quote {
  655. // Inside quotes or escaped this is legal.
  656. str[stri] = x
  657. stri++
  658. escape = false
  659. break
  660. }
  661. if zl.commt {
  662. com[comi] = x
  663. comi++
  664. break
  665. }
  666. var retL lex
  667. if stri == 0 {
  668. // Space directly in the beginning, handled in the grammar
  669. } else if zl.owner {
  670. // If we have a string and its the first, make it an owner
  671. l.value = zOwner
  672. l.token = string(str[:stri])
  673. // escape $... start with a \ not a $, so this will work
  674. switch strings.ToUpper(l.token) {
  675. case "$TTL":
  676. l.value = zDirTTL
  677. case "$ORIGIN":
  678. l.value = zDirOrigin
  679. case "$INCLUDE":
  680. l.value = zDirInclude
  681. case "$GENERATE":
  682. l.value = zDirGenerate
  683. }
  684. retL = *l
  685. } else {
  686. l.value = zString
  687. l.token = string(str[:stri])
  688. if !zl.rrtype {
  689. tokenUpper := strings.ToUpper(l.token)
  690. if t, ok := StringToType[tokenUpper]; ok {
  691. l.value = zRrtpe
  692. l.torc = t
  693. zl.rrtype = true
  694. } else if strings.HasPrefix(tokenUpper, "TYPE") {
  695. t, ok := typeToInt(l.token)
  696. if !ok {
  697. l.token = "unknown RR type"
  698. l.err = true
  699. return *l, true
  700. }
  701. l.value = zRrtpe
  702. l.torc = t
  703. zl.rrtype = true
  704. }
  705. if t, ok := StringToClass[tokenUpper]; ok {
  706. l.value = zClass
  707. l.torc = t
  708. } else if strings.HasPrefix(tokenUpper, "CLASS") {
  709. t, ok := classToInt(l.token)
  710. if !ok {
  711. l.token = "unknown class"
  712. l.err = true
  713. return *l, true
  714. }
  715. l.value = zClass
  716. l.torc = t
  717. }
  718. }
  719. retL = *l
  720. }
  721. zl.owner = false
  722. if !zl.space {
  723. zl.space = true
  724. l.value = zBlank
  725. l.token = " "
  726. if retL == (lex{}) {
  727. return *l, true
  728. }
  729. zl.nextL = true
  730. }
  731. if retL != (lex{}) {
  732. return retL, true
  733. }
  734. case ';':
  735. if escape || zl.quote {
  736. // Inside quotes or escaped this is legal.
  737. str[stri] = x
  738. stri++
  739. escape = false
  740. break
  741. }
  742. zl.commt = true
  743. zl.comBuf = ""
  744. if comi > 1 {
  745. // A newline was previously seen inside a comment that
  746. // was inside braces and we delayed adding it until now.
  747. com[comi] = ' ' // convert newline to space
  748. comi++
  749. if comi >= len(com) {
  750. l.token = "comment length insufficient for parsing"
  751. l.err = true
  752. return *l, true
  753. }
  754. }
  755. com[comi] = ';'
  756. comi++
  757. if stri > 0 {
  758. zl.comBuf = string(com[:comi])
  759. l.value = zString
  760. l.token = string(str[:stri])
  761. return *l, true
  762. }
  763. case '\r':
  764. escape = false
  765. if zl.quote {
  766. str[stri] = x
  767. stri++
  768. }
  769. // discard if outside of quotes
  770. case '\n':
  771. escape = false
  772. // Escaped newline
  773. if zl.quote {
  774. str[stri] = x
  775. stri++
  776. break
  777. }
  778. if zl.commt {
  779. // Reset a comment
  780. zl.commt = false
  781. zl.rrtype = false
  782. // If not in a brace this ends the comment AND the RR
  783. if zl.brace == 0 {
  784. zl.owner = true
  785. l.value = zNewline
  786. l.token = "\n"
  787. zl.comment = string(com[:comi])
  788. return *l, true
  789. }
  790. zl.comBuf = string(com[:comi])
  791. break
  792. }
  793. if zl.brace == 0 {
  794. // If there is previous text, we should output it here
  795. var retL lex
  796. if stri != 0 {
  797. l.value = zString
  798. l.token = string(str[:stri])
  799. if !zl.rrtype {
  800. tokenUpper := strings.ToUpper(l.token)
  801. if t, ok := StringToType[tokenUpper]; ok {
  802. zl.rrtype = true
  803. l.value = zRrtpe
  804. l.torc = t
  805. }
  806. }
  807. retL = *l
  808. }
  809. l.value = zNewline
  810. l.token = "\n"
  811. zl.comment = zl.comBuf
  812. zl.comBuf = ""
  813. zl.rrtype = false
  814. zl.owner = true
  815. if retL != (lex{}) {
  816. zl.nextL = true
  817. return retL, true
  818. }
  819. return *l, true
  820. }
  821. case '\\':
  822. // comments do not get escaped chars, everything is copied
  823. if zl.commt {
  824. com[comi] = x
  825. comi++
  826. break
  827. }
  828. // something already escaped must be in string
  829. if escape {
  830. str[stri] = x
  831. stri++
  832. escape = false
  833. break
  834. }
  835. // something escaped outside of string gets added to string
  836. str[stri] = x
  837. stri++
  838. escape = true
  839. case '"':
  840. if zl.commt {
  841. com[comi] = x
  842. comi++
  843. break
  844. }
  845. if escape {
  846. str[stri] = x
  847. stri++
  848. escape = false
  849. break
  850. }
  851. zl.space = false
  852. // send previous gathered text and the quote
  853. var retL lex
  854. if stri != 0 {
  855. l.value = zString
  856. l.token = string(str[:stri])
  857. retL = *l
  858. }
  859. // send quote itself as separate token
  860. l.value = zQuote
  861. l.token = "\""
  862. zl.quote = !zl.quote
  863. if retL != (lex{}) {
  864. zl.nextL = true
  865. return retL, true
  866. }
  867. return *l, true
  868. case '(', ')':
  869. if zl.commt {
  870. com[comi] = x
  871. comi++
  872. break
  873. }
  874. if escape || zl.quote {
  875. // Inside quotes or escaped this is legal.
  876. str[stri] = x
  877. stri++
  878. escape = false
  879. break
  880. }
  881. switch x {
  882. case ')':
  883. zl.brace--
  884. if zl.brace < 0 {
  885. l.token = "extra closing brace"
  886. l.err = true
  887. return *l, true
  888. }
  889. case '(':
  890. zl.brace++
  891. }
  892. default:
  893. escape = false
  894. if zl.commt {
  895. com[comi] = x
  896. comi++
  897. break
  898. }
  899. str[stri] = x
  900. stri++
  901. zl.space = false
  902. }
  903. }
  904. if zl.readErr != nil && zl.readErr != io.EOF {
  905. // Don't return any tokens after a read error occurs.
  906. return lex{value: zEOF}, false
  907. }
  908. var retL lex
  909. if stri > 0 {
  910. // Send remainder of str
  911. l.value = zString
  912. l.token = string(str[:stri])
  913. retL = *l
  914. if comi <= 0 {
  915. return retL, true
  916. }
  917. }
  918. if comi > 0 {
  919. // Send remainder of com
  920. l.value = zNewline
  921. l.token = "\n"
  922. zl.comment = string(com[:comi])
  923. if retL != (lex{}) {
  924. zl.nextL = true
  925. return retL, true
  926. }
  927. return *l, true
  928. }
  929. if zl.brace != 0 {
  930. l.token = "unbalanced brace"
  931. l.err = true
  932. return *l, true
  933. }
  934. return lex{value: zEOF}, false
  935. }
  936. func (zl *zlexer) Comment() string {
  937. if zl.l.err {
  938. return ""
  939. }
  940. return zl.comment
  941. }
  942. // Extract the class number from CLASSxx
  943. func classToInt(token string) (uint16, bool) {
  944. offset := 5
  945. if len(token) < offset+1 {
  946. return 0, false
  947. }
  948. class, err := strconv.ParseUint(token[offset:], 10, 16)
  949. if err != nil {
  950. return 0, false
  951. }
  952. return uint16(class), true
  953. }
  954. // Extract the rr number from TYPExxx
  955. func typeToInt(token string) (uint16, bool) {
  956. offset := 4
  957. if len(token) < offset+1 {
  958. return 0, false
  959. }
  960. typ, err := strconv.ParseUint(token[offset:], 10, 16)
  961. if err != nil {
  962. return 0, false
  963. }
  964. return uint16(typ), true
  965. }
  966. // stringToTTL parses things like 2w, 2m, etc, and returns the time in seconds.
  967. func stringToTTL(token string) (uint32, bool) {
  968. var s, i uint32
  969. for _, c := range token {
  970. switch c {
  971. case 's', 'S':
  972. s += i
  973. i = 0
  974. case 'm', 'M':
  975. s += i * 60
  976. i = 0
  977. case 'h', 'H':
  978. s += i * 60 * 60
  979. i = 0
  980. case 'd', 'D':
  981. s += i * 60 * 60 * 24
  982. i = 0
  983. case 'w', 'W':
  984. s += i * 60 * 60 * 24 * 7
  985. i = 0
  986. case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  987. i *= 10
  988. i += uint32(c) - '0'
  989. default:
  990. return 0, false
  991. }
  992. }
  993. return s + i, true
  994. }
  995. // Parse LOC records' <digits>[.<digits>][mM] into a
  996. // mantissa exponent format. Token should contain the entire
  997. // string (i.e. no spaces allowed)
  998. func stringToCm(token string) (e, m uint8, ok bool) {
  999. if token[len(token)-1] == 'M' || token[len(token)-1] == 'm' {
  1000. token = token[0 : len(token)-1]
  1001. }
  1002. s := strings.SplitN(token, ".", 2)
  1003. var meters, cmeters, val int
  1004. var err error
  1005. switch len(s) {
  1006. case 2:
  1007. if cmeters, err = strconv.Atoi(s[1]); err != nil {
  1008. return
  1009. }
  1010. fallthrough
  1011. case 1:
  1012. if meters, err = strconv.Atoi(s[0]); err != nil {
  1013. return
  1014. }
  1015. case 0:
  1016. // huh?
  1017. return 0, 0, false
  1018. }
  1019. ok = true
  1020. if meters > 0 {
  1021. e = 2
  1022. val = meters
  1023. } else {
  1024. e = 0
  1025. val = cmeters
  1026. }
  1027. for val > 10 {
  1028. e++
  1029. val /= 10
  1030. }
  1031. if e > 9 {
  1032. ok = false
  1033. }
  1034. m = uint8(val)
  1035. return
  1036. }
  1037. func toAbsoluteName(name, origin string) (absolute string, ok bool) {
  1038. // check for an explicit origin reference
  1039. if name == "@" {
  1040. // require a nonempty origin
  1041. if origin == "" {
  1042. return "", false
  1043. }
  1044. return origin, true
  1045. }
  1046. // require a valid domain name
  1047. _, ok = IsDomainName(name)
  1048. if !ok || name == "" {
  1049. return "", false
  1050. }
  1051. // check if name is already absolute
  1052. if IsFqdn(name) {
  1053. return name, true
  1054. }
  1055. // require a nonempty origin
  1056. if origin == "" {
  1057. return "", false
  1058. }
  1059. return appendOrigin(name, origin), true
  1060. }
  1061. func appendOrigin(name, origin string) string {
  1062. if origin == "." {
  1063. return name + origin
  1064. }
  1065. return name + "." + origin
  1066. }
  1067. // LOC record helper function
  1068. func locCheckNorth(token string, latitude uint32) (uint32, bool) {
  1069. switch token {
  1070. case "n", "N":
  1071. return LOC_EQUATOR + latitude, true
  1072. case "s", "S":
  1073. return LOC_EQUATOR - latitude, true
  1074. }
  1075. return latitude, false
  1076. }
  1077. // LOC record helper function
  1078. func locCheckEast(token string, longitude uint32) (uint32, bool) {
  1079. switch token {
  1080. case "e", "E":
  1081. return LOC_EQUATOR + longitude, true
  1082. case "w", "W":
  1083. return LOC_EQUATOR - longitude, true
  1084. }
  1085. return longitude, false
  1086. }
  1087. // "Eat" the rest of the "line"
  1088. func slurpRemainder(c *zlexer) *ParseError {
  1089. l, _ := c.Next()
  1090. switch l.value {
  1091. case zBlank:
  1092. l, _ = c.Next()
  1093. if l.value != zNewline && l.value != zEOF {
  1094. return &ParseError{"", "garbage after rdata", l}
  1095. }
  1096. case zNewline:
  1097. case zEOF:
  1098. default:
  1099. return &ParseError{"", "garbage after rdata", l}
  1100. }
  1101. return nil
  1102. }
  1103. // Parse a 64 bit-like ipv6 address: "0014:4fff:ff20:ee64"
  1104. // Used for NID and L64 record.
  1105. func stringToNodeID(l lex) (uint64, *ParseError) {
  1106. if len(l.token) < 19 {
  1107. return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
  1108. }
  1109. // There must be three colons at fixes postitions, if not its a parse error
  1110. if l.token[4] != ':' && l.token[9] != ':' && l.token[14] != ':' {
  1111. return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
  1112. }
  1113. s := l.token[0:4] + l.token[5:9] + l.token[10:14] + l.token[15:19]
  1114. u, err := strconv.ParseUint(s, 16, 64)
  1115. if err != nil {
  1116. return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
  1117. }
  1118. return u, nil
  1119. }