msg_helpers.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. package dns
  2. import (
  3. "encoding/base32"
  4. "encoding/base64"
  5. "encoding/binary"
  6. "encoding/hex"
  7. "net"
  8. "strconv"
  9. )
  10. // helper functions called from the generated zmsg.go
  11. // These function are named after the tag to help pack/unpack, if there is no tag it is the name
  12. // of the type they pack/unpack (string, int, etc). We prefix all with unpackData or packData, so packDataA or
  13. // packDataDomainName.
  14. func unpackDataA(msg []byte, off int) (net.IP, int, error) {
  15. if off+net.IPv4len > len(msg) {
  16. return nil, len(msg), &Error{err: "overflow unpacking a"}
  17. }
  18. a := append(make(net.IP, 0, net.IPv4len), msg[off:off+net.IPv4len]...)
  19. off += net.IPv4len
  20. return a, off, nil
  21. }
  22. func packDataA(a net.IP, msg []byte, off int) (int, error) {
  23. // It must be a slice of 4, even if it is 16, we encode only the first 4
  24. if off+net.IPv4len > len(msg) {
  25. return len(msg), &Error{err: "overflow packing a"}
  26. }
  27. switch len(a) {
  28. case net.IPv4len, net.IPv6len:
  29. copy(msg[off:], a.To4())
  30. off += net.IPv4len
  31. case 0:
  32. // Allowed, for dynamic updates.
  33. default:
  34. return len(msg), &Error{err: "overflow packing a"}
  35. }
  36. return off, nil
  37. }
  38. func unpackDataAAAA(msg []byte, off int) (net.IP, int, error) {
  39. if off+net.IPv6len > len(msg) {
  40. return nil, len(msg), &Error{err: "overflow unpacking aaaa"}
  41. }
  42. aaaa := append(make(net.IP, 0, net.IPv6len), msg[off:off+net.IPv6len]...)
  43. off += net.IPv6len
  44. return aaaa, off, nil
  45. }
  46. func packDataAAAA(aaaa net.IP, msg []byte, off int) (int, error) {
  47. if off+net.IPv6len > len(msg) {
  48. return len(msg), &Error{err: "overflow packing aaaa"}
  49. }
  50. switch len(aaaa) {
  51. case net.IPv6len:
  52. copy(msg[off:], aaaa)
  53. off += net.IPv6len
  54. case 0:
  55. // Allowed, dynamic updates.
  56. default:
  57. return len(msg), &Error{err: "overflow packing aaaa"}
  58. }
  59. return off, nil
  60. }
  61. // unpackHeader unpacks an RR header, returning the offset to the end of the header and a
  62. // re-sliced msg according to the expected length of the RR.
  63. func unpackHeader(msg []byte, off int) (rr RR_Header, off1 int, truncmsg []byte, err error) {
  64. hdr := RR_Header{}
  65. if off == len(msg) {
  66. return hdr, off, msg, nil
  67. }
  68. hdr.Name, off, err = UnpackDomainName(msg, off)
  69. if err != nil {
  70. return hdr, len(msg), msg, err
  71. }
  72. hdr.Rrtype, off, err = unpackUint16(msg, off)
  73. if err != nil {
  74. return hdr, len(msg), msg, err
  75. }
  76. hdr.Class, off, err = unpackUint16(msg, off)
  77. if err != nil {
  78. return hdr, len(msg), msg, err
  79. }
  80. hdr.Ttl, off, err = unpackUint32(msg, off)
  81. if err != nil {
  82. return hdr, len(msg), msg, err
  83. }
  84. hdr.Rdlength, off, err = unpackUint16(msg, off)
  85. if err != nil {
  86. return hdr, len(msg), msg, err
  87. }
  88. msg, err = truncateMsgFromRdlength(msg, off, hdr.Rdlength)
  89. return hdr, off, msg, err
  90. }
  91. // pack packs an RR header, returning the offset to the end of the header.
  92. // See PackDomainName for documentation about the compression.
  93. func (hdr RR_Header) pack(msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) {
  94. if off == len(msg) {
  95. return off, nil
  96. }
  97. off, err = PackDomainName(hdr.Name, msg, off, compression, compress)
  98. if err != nil {
  99. return len(msg), err
  100. }
  101. off, err = packUint16(hdr.Rrtype, msg, off)
  102. if err != nil {
  103. return len(msg), err
  104. }
  105. off, err = packUint16(hdr.Class, msg, off)
  106. if err != nil {
  107. return len(msg), err
  108. }
  109. off, err = packUint32(hdr.Ttl, msg, off)
  110. if err != nil {
  111. return len(msg), err
  112. }
  113. off, err = packUint16(hdr.Rdlength, msg, off)
  114. if err != nil {
  115. return len(msg), err
  116. }
  117. return off, nil
  118. }
  119. // helper helper functions.
  120. // truncateMsgFromRdLength truncates msg to match the expected length of the RR.
  121. // Returns an error if msg is smaller than the expected size.
  122. func truncateMsgFromRdlength(msg []byte, off int, rdlength uint16) (truncmsg []byte, err error) {
  123. lenrd := off + int(rdlength)
  124. if lenrd > len(msg) {
  125. return msg, &Error{err: "overflowing header size"}
  126. }
  127. return msg[:lenrd], nil
  128. }
  129. func fromBase32(s []byte) (buf []byte, err error) {
  130. for i, b := range s {
  131. if b >= 'a' && b <= 'z' {
  132. s[i] = b - 32
  133. }
  134. }
  135. buflen := base32.HexEncoding.DecodedLen(len(s))
  136. buf = make([]byte, buflen)
  137. n, err := base32.HexEncoding.Decode(buf, s)
  138. buf = buf[:n]
  139. return
  140. }
  141. func toBase32(b []byte) string { return base32.HexEncoding.EncodeToString(b) }
  142. func fromBase64(s []byte) (buf []byte, err error) {
  143. buflen := base64.StdEncoding.DecodedLen(len(s))
  144. buf = make([]byte, buflen)
  145. n, err := base64.StdEncoding.Decode(buf, s)
  146. buf = buf[:n]
  147. return
  148. }
  149. func toBase64(b []byte) string { return base64.StdEncoding.EncodeToString(b) }
  150. // dynamicUpdate returns true if the Rdlength is zero.
  151. func noRdata(h RR_Header) bool { return h.Rdlength == 0 }
  152. func unpackUint8(msg []byte, off int) (i uint8, off1 int, err error) {
  153. if off+1 > len(msg) {
  154. return 0, len(msg), &Error{err: "overflow unpacking uint8"}
  155. }
  156. return uint8(msg[off]), off + 1, nil
  157. }
  158. func packUint8(i uint8, msg []byte, off int) (off1 int, err error) {
  159. if off+1 > len(msg) {
  160. return len(msg), &Error{err: "overflow packing uint8"}
  161. }
  162. msg[off] = byte(i)
  163. return off + 1, nil
  164. }
  165. func unpackUint16(msg []byte, off int) (i uint16, off1 int, err error) {
  166. if off+2 > len(msg) {
  167. return 0, len(msg), &Error{err: "overflow unpacking uint16"}
  168. }
  169. return binary.BigEndian.Uint16(msg[off:]), off + 2, nil
  170. }
  171. func packUint16(i uint16, msg []byte, off int) (off1 int, err error) {
  172. if off+2 > len(msg) {
  173. return len(msg), &Error{err: "overflow packing uint16"}
  174. }
  175. binary.BigEndian.PutUint16(msg[off:], i)
  176. return off + 2, nil
  177. }
  178. func unpackUint32(msg []byte, off int) (i uint32, off1 int, err error) {
  179. if off+4 > len(msg) {
  180. return 0, len(msg), &Error{err: "overflow unpacking uint32"}
  181. }
  182. return binary.BigEndian.Uint32(msg[off:]), off + 4, nil
  183. }
  184. func packUint32(i uint32, msg []byte, off int) (off1 int, err error) {
  185. if off+4 > len(msg) {
  186. return len(msg), &Error{err: "overflow packing uint32"}
  187. }
  188. binary.BigEndian.PutUint32(msg[off:], i)
  189. return off + 4, nil
  190. }
  191. func unpackUint48(msg []byte, off int) (i uint64, off1 int, err error) {
  192. if off+6 > len(msg) {
  193. return 0, len(msg), &Error{err: "overflow unpacking uint64 as uint48"}
  194. }
  195. // Used in TSIG where the last 48 bits are occupied, so for now, assume a uint48 (6 bytes)
  196. i = (uint64(uint64(msg[off])<<40 | uint64(msg[off+1])<<32 | uint64(msg[off+2])<<24 | uint64(msg[off+3])<<16 |
  197. uint64(msg[off+4])<<8 | uint64(msg[off+5])))
  198. off += 6
  199. return i, off, nil
  200. }
  201. func packUint48(i uint64, msg []byte, off int) (off1 int, err error) {
  202. if off+6 > len(msg) {
  203. return len(msg), &Error{err: "overflow packing uint64 as uint48"}
  204. }
  205. msg[off] = byte(i >> 40)
  206. msg[off+1] = byte(i >> 32)
  207. msg[off+2] = byte(i >> 24)
  208. msg[off+3] = byte(i >> 16)
  209. msg[off+4] = byte(i >> 8)
  210. msg[off+5] = byte(i)
  211. off += 6
  212. return off, nil
  213. }
  214. func unpackUint64(msg []byte, off int) (i uint64, off1 int, err error) {
  215. if off+8 > len(msg) {
  216. return 0, len(msg), &Error{err: "overflow unpacking uint64"}
  217. }
  218. return binary.BigEndian.Uint64(msg[off:]), off + 8, nil
  219. }
  220. func packUint64(i uint64, msg []byte, off int) (off1 int, err error) {
  221. if off+8 > len(msg) {
  222. return len(msg), &Error{err: "overflow packing uint64"}
  223. }
  224. binary.BigEndian.PutUint64(msg[off:], i)
  225. off += 8
  226. return off, nil
  227. }
  228. func unpackString(msg []byte, off int) (string, int, error) {
  229. if off+1 > len(msg) {
  230. return "", off, &Error{err: "overflow unpacking txt"}
  231. }
  232. l := int(msg[off])
  233. if off+l+1 > len(msg) {
  234. return "", off, &Error{err: "overflow unpacking txt"}
  235. }
  236. s := make([]byte, 0, l)
  237. for _, b := range msg[off+1 : off+1+l] {
  238. switch b {
  239. case '"', '\\':
  240. s = append(s, '\\', b)
  241. default:
  242. if b < 32 || b > 127 { // unprintable
  243. var buf [3]byte
  244. bufs := strconv.AppendInt(buf[:0], int64(b), 10)
  245. s = append(s, '\\')
  246. for i := 0; i < 3-len(bufs); i++ {
  247. s = append(s, '0')
  248. }
  249. for _, r := range bufs {
  250. s = append(s, r)
  251. }
  252. } else {
  253. s = append(s, b)
  254. }
  255. }
  256. }
  257. off += 1 + l
  258. return string(s), off, nil
  259. }
  260. func packString(s string, msg []byte, off int) (int, error) {
  261. txtTmp := make([]byte, 256*4+1)
  262. off, err := packTxtString(s, msg, off, txtTmp)
  263. if err != nil {
  264. return len(msg), err
  265. }
  266. return off, nil
  267. }
  268. func unpackStringBase32(msg []byte, off, end int) (string, int, error) {
  269. if end > len(msg) {
  270. return "", len(msg), &Error{err: "overflow unpacking base32"}
  271. }
  272. s := toBase32(msg[off:end])
  273. return s, end, nil
  274. }
  275. func packStringBase32(s string, msg []byte, off int) (int, error) {
  276. b32, err := fromBase32([]byte(s))
  277. if err != nil {
  278. return len(msg), err
  279. }
  280. if off+len(b32) > len(msg) {
  281. return len(msg), &Error{err: "overflow packing base32"}
  282. }
  283. copy(msg[off:off+len(b32)], b32)
  284. off += len(b32)
  285. return off, nil
  286. }
  287. func unpackStringBase64(msg []byte, off, end int) (string, int, error) {
  288. // Rest of the RR is base64 encoded value, so we don't need an explicit length
  289. // to be set. Thus far all RR's that have base64 encoded fields have those as their
  290. // last one. What we do need is the end of the RR!
  291. if end > len(msg) {
  292. return "", len(msg), &Error{err: "overflow unpacking base64"}
  293. }
  294. s := toBase64(msg[off:end])
  295. return s, end, nil
  296. }
  297. func packStringBase64(s string, msg []byte, off int) (int, error) {
  298. b64, err := fromBase64([]byte(s))
  299. if err != nil {
  300. return len(msg), err
  301. }
  302. if off+len(b64) > len(msg) {
  303. return len(msg), &Error{err: "overflow packing base64"}
  304. }
  305. copy(msg[off:off+len(b64)], b64)
  306. off += len(b64)
  307. return off, nil
  308. }
  309. func unpackStringHex(msg []byte, off, end int) (string, int, error) {
  310. // Rest of the RR is hex encoded value, so we don't need an explicit length
  311. // to be set. NSEC and TSIG have hex fields with a length field.
  312. // What we do need is the end of the RR!
  313. if end > len(msg) {
  314. return "", len(msg), &Error{err: "overflow unpacking hex"}
  315. }
  316. s := hex.EncodeToString(msg[off:end])
  317. return s, end, nil
  318. }
  319. func packStringHex(s string, msg []byte, off int) (int, error) {
  320. h, err := hex.DecodeString(s)
  321. if err != nil {
  322. return len(msg), err
  323. }
  324. if off+(len(h)) > len(msg) {
  325. return len(msg), &Error{err: "overflow packing hex"}
  326. }
  327. copy(msg[off:off+len(h)], h)
  328. off += len(h)
  329. return off, nil
  330. }
  331. func unpackStringTxt(msg []byte, off int) ([]string, int, error) {
  332. txt, off, err := unpackTxt(msg, off)
  333. if err != nil {
  334. return nil, len(msg), err
  335. }
  336. return txt, off, nil
  337. }
  338. func packStringTxt(s []string, msg []byte, off int) (int, error) {
  339. txtTmp := make([]byte, 256*4+1) // If the whole string consists out of \DDD we need this many.
  340. off, err := packTxt(s, msg, off, txtTmp)
  341. if err != nil {
  342. return len(msg), err
  343. }
  344. return off, nil
  345. }
  346. func unpackDataOpt(msg []byte, off int) ([]EDNS0, int, error) {
  347. var edns []EDNS0
  348. Option:
  349. code := uint16(0)
  350. if off+4 > len(msg) {
  351. return nil, len(msg), &Error{err: "overflow unpacking opt"}
  352. }
  353. code = binary.BigEndian.Uint16(msg[off:])
  354. off += 2
  355. optlen := binary.BigEndian.Uint16(msg[off:])
  356. off += 2
  357. if off+int(optlen) > len(msg) {
  358. return nil, len(msg), &Error{err: "overflow unpacking opt"}
  359. }
  360. switch code {
  361. case EDNS0NSID:
  362. e := new(EDNS0_NSID)
  363. if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
  364. return nil, len(msg), err
  365. }
  366. edns = append(edns, e)
  367. off += int(optlen)
  368. case EDNS0SUBNET:
  369. e := new(EDNS0_SUBNET)
  370. if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
  371. return nil, len(msg), err
  372. }
  373. edns = append(edns, e)
  374. off += int(optlen)
  375. case EDNS0COOKIE:
  376. e := new(EDNS0_COOKIE)
  377. if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
  378. return nil, len(msg), err
  379. }
  380. edns = append(edns, e)
  381. off += int(optlen)
  382. case EDNS0UL:
  383. e := new(EDNS0_UL)
  384. if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
  385. return nil, len(msg), err
  386. }
  387. edns = append(edns, e)
  388. off += int(optlen)
  389. case EDNS0LLQ:
  390. e := new(EDNS0_LLQ)
  391. if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
  392. return nil, len(msg), err
  393. }
  394. edns = append(edns, e)
  395. off += int(optlen)
  396. case EDNS0DAU:
  397. e := new(EDNS0_DAU)
  398. if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
  399. return nil, len(msg), err
  400. }
  401. edns = append(edns, e)
  402. off += int(optlen)
  403. case EDNS0DHU:
  404. e := new(EDNS0_DHU)
  405. if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
  406. return nil, len(msg), err
  407. }
  408. edns = append(edns, e)
  409. off += int(optlen)
  410. case EDNS0N3U:
  411. e := new(EDNS0_N3U)
  412. if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
  413. return nil, len(msg), err
  414. }
  415. edns = append(edns, e)
  416. off += int(optlen)
  417. case EDNS0PADDING:
  418. e := new(EDNS0_PADDING)
  419. if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
  420. return nil, len(msg), err
  421. }
  422. edns = append(edns, e)
  423. off += int(optlen)
  424. default:
  425. e := new(EDNS0_LOCAL)
  426. e.Code = code
  427. if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
  428. return nil, len(msg), err
  429. }
  430. edns = append(edns, e)
  431. off += int(optlen)
  432. }
  433. if off < len(msg) {
  434. goto Option
  435. }
  436. return edns, off, nil
  437. }
  438. func packDataOpt(options []EDNS0, msg []byte, off int) (int, error) {
  439. for _, el := range options {
  440. b, err := el.pack()
  441. if err != nil || off+3 > len(msg) {
  442. return len(msg), &Error{err: "overflow packing opt"}
  443. }
  444. binary.BigEndian.PutUint16(msg[off:], el.Option()) // Option code
  445. binary.BigEndian.PutUint16(msg[off+2:], uint16(len(b))) // Length
  446. off += 4
  447. if off+len(b) > len(msg) {
  448. copy(msg[off:], b)
  449. off = len(msg)
  450. continue
  451. }
  452. // Actual data
  453. copy(msg[off:off+len(b)], b)
  454. off += len(b)
  455. }
  456. return off, nil
  457. }
  458. func unpackStringOctet(msg []byte, off int) (string, int, error) {
  459. s := string(msg[off:])
  460. return s, len(msg), nil
  461. }
  462. func packStringOctet(s string, msg []byte, off int) (int, error) {
  463. txtTmp := make([]byte, 256*4+1)
  464. off, err := packOctetString(s, msg, off, txtTmp)
  465. if err != nil {
  466. return len(msg), err
  467. }
  468. return off, nil
  469. }
  470. func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) {
  471. var nsec []uint16
  472. length, window, lastwindow := 0, 0, -1
  473. for off < len(msg) {
  474. if off+2 > len(msg) {
  475. return nsec, len(msg), &Error{err: "overflow unpacking nsecx"}
  476. }
  477. window = int(msg[off])
  478. length = int(msg[off+1])
  479. off += 2
  480. if window <= lastwindow {
  481. // RFC 4034: Blocks are present in the NSEC RR RDATA in
  482. // increasing numerical order.
  483. return nsec, len(msg), &Error{err: "out of order NSEC block"}
  484. }
  485. if length == 0 {
  486. // RFC 4034: Blocks with no types present MUST NOT be included.
  487. return nsec, len(msg), &Error{err: "empty NSEC block"}
  488. }
  489. if length > 32 {
  490. return nsec, len(msg), &Error{err: "NSEC block too long"}
  491. }
  492. if off+length > len(msg) {
  493. return nsec, len(msg), &Error{err: "overflowing NSEC block"}
  494. }
  495. // Walk the bytes in the window and extract the type bits
  496. for j := 0; j < length; j++ {
  497. b := msg[off+j]
  498. // Check the bits one by one, and set the type
  499. if b&0x80 == 0x80 {
  500. nsec = append(nsec, uint16(window*256+j*8+0))
  501. }
  502. if b&0x40 == 0x40 {
  503. nsec = append(nsec, uint16(window*256+j*8+1))
  504. }
  505. if b&0x20 == 0x20 {
  506. nsec = append(nsec, uint16(window*256+j*8+2))
  507. }
  508. if b&0x10 == 0x10 {
  509. nsec = append(nsec, uint16(window*256+j*8+3))
  510. }
  511. if b&0x8 == 0x8 {
  512. nsec = append(nsec, uint16(window*256+j*8+4))
  513. }
  514. if b&0x4 == 0x4 {
  515. nsec = append(nsec, uint16(window*256+j*8+5))
  516. }
  517. if b&0x2 == 0x2 {
  518. nsec = append(nsec, uint16(window*256+j*8+6))
  519. }
  520. if b&0x1 == 0x1 {
  521. nsec = append(nsec, uint16(window*256+j*8+7))
  522. }
  523. }
  524. off += length
  525. lastwindow = window
  526. }
  527. return nsec, off, nil
  528. }
  529. func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) {
  530. if len(bitmap) == 0 {
  531. return off, nil
  532. }
  533. var lastwindow, lastlength uint16
  534. for j := 0; j < len(bitmap); j++ {
  535. t := bitmap[j]
  536. window := t / 256
  537. length := (t-window*256)/8 + 1
  538. if window > lastwindow && lastlength != 0 { // New window, jump to the new offset
  539. off += int(lastlength) + 2
  540. lastlength = 0
  541. }
  542. if window < lastwindow || length < lastlength {
  543. return len(msg), &Error{err: "nsec bits out of order"}
  544. }
  545. if off+2+int(length) > len(msg) {
  546. return len(msg), &Error{err: "overflow packing nsec"}
  547. }
  548. // Setting the window #
  549. msg[off] = byte(window)
  550. // Setting the octets length
  551. msg[off+1] = byte(length)
  552. // Setting the bit value for the type in the right octet
  553. msg[off+1+int(length)] |= byte(1 << (7 - (t % 8)))
  554. lastwindow, lastlength = window, length
  555. }
  556. off += int(lastlength) + 2
  557. return off, nil
  558. }
  559. func unpackDataDomainNames(msg []byte, off, end int) ([]string, int, error) {
  560. var (
  561. servers []string
  562. s string
  563. err error
  564. )
  565. if end > len(msg) {
  566. return nil, len(msg), &Error{err: "overflow unpacking domain names"}
  567. }
  568. for off < end {
  569. s, off, err = UnpackDomainName(msg, off)
  570. if err != nil {
  571. return servers, len(msg), err
  572. }
  573. servers = append(servers, s)
  574. }
  575. return servers, off, nil
  576. }
  577. func packDataDomainNames(names []string, msg []byte, off int, compression map[string]int, compress bool) (int, error) {
  578. var err error
  579. for j := 0; j < len(names); j++ {
  580. off, err = PackDomainName(names[j], msg, off, compression, false && compress)
  581. if err != nil {
  582. return len(msg), err
  583. }
  584. }
  585. return off, nil
  586. }