dns/rawmsg.go

96 lines
2.1 KiB
Go
Raw Normal View History

2011-08-08 12:09:05 +00:00
package dns
2012-08-24 13:06:15 +00:00
// These raw* functions do not use reflection, they directly set the values
2012-05-03 06:53:38 +00:00
// in the buffer. There are faster than their reflection counterparts.
2012-03-18 21:41:29 +00:00
// RawSetId sets the message id in buf.
2012-08-31 19:03:03 +00:00
func rawSetId(msg []byte, i uint16) bool {
if len(msg) < 2 {
return false
}
msg[0], msg[1] = packUint16(i)
2012-08-31 19:03:03 +00:00
return true
}
2013-04-07 21:05:48 +00:00
// rawSetQuestionLen sets the length of the question section.
2012-08-31 19:03:31 +00:00
func rawSetQuestionLen(msg []byte, i uint16) bool {
2012-08-31 19:03:03 +00:00
if len(msg) < 6 {
return false
}
msg[4], msg[5] = packUint16(i)
2012-08-31 19:03:03 +00:00
return true
}
2012-08-24 10:42:41 +00:00
// rawSetAnswerLen sets the lenght of the answer section.
2012-08-31 19:03:31 +00:00
func rawSetAnswerLen(msg []byte, i uint16) bool {
2012-08-31 19:03:03 +00:00
if len(msg) < 8 {
return false
}
msg[6], msg[7] = packUint16(i)
2012-08-31 19:03:03 +00:00
return true
}
2012-08-24 10:42:41 +00:00
// rawSetsNsLen sets the lenght of the authority section.
2012-08-31 19:03:31 +00:00
func rawSetNsLen(msg []byte, i uint16) bool {
2012-08-31 19:03:03 +00:00
if len(msg) < 10 {
return false
}
msg[8], msg[9] = packUint16(i)
2012-08-31 19:03:03 +00:00
return true
}
2012-08-24 10:42:41 +00:00
// rawSetExtraLen sets the lenght of the additional section.
2012-08-31 19:03:31 +00:00
func rawSetExtraLen(msg []byte, i uint16) bool {
2012-08-31 19:03:03 +00:00
if len(msg) < 12 {
return false
}
msg[10], msg[11] = packUint16(i)
2012-08-31 19:03:03 +00:00
return true
2011-08-08 14:29:13 +00:00
}
2012-01-11 15:02:05 +00:00
2012-08-24 10:42:41 +00:00
// rawSetRdlength sets the rdlength in the header of
2012-01-12 09:50:01 +00:00
// the RR. The offset 'off' must be positioned at the
2012-01-12 20:10:29 +00:00
// start of the header of the RR, 'end' must be the
// end of the RR.
func rawSetRdlength(msg []byte, off, end int) bool {
l := len(msg)
2012-01-11 15:02:05 +00:00
Loop:
for {
if off+1 > l {
return false
}
2012-01-11 15:02:05 +00:00
c := int(msg[off])
off++
switch c & 0xC0 {
2012-01-11 15:02:05 +00:00
case 0x00:
if c == 0x00 {
// End of the domainname
break Loop
}
2013-06-14 18:42:55 +00:00
if off+c > l {
return false
}
2013-06-14 18:42:55 +00:00
off += c
2012-01-11 15:02:05 +00:00
case 0xC0:
2012-01-12 20:10:29 +00:00
// pointer, next byte included, ends domainname
2012-01-11 15:02:05 +00:00
off++
break Loop
}
}
2012-01-12 20:10:29 +00:00
// The domainname has been seen, we at the start of the fixed part in the header.
// Type is 2 bytes, class is 2 bytes, ttl 4 and then 2 bytes for the length.
2012-01-11 15:02:05 +00:00
off += 2 + 2 + 4
if off+2 > l {
return false
}
2012-01-12 20:10:29 +00:00
//off+1 is the end of the header, 'end' is the end of the rr
//so 'end' - 'off+2' is the length of the rdata
rdatalen := end - (off + 2)
if rdatalen > 0xFFFF {
return false
}
msg[off], msg[off+1] = packUint16(uint16(rdatalen))
return true
2012-01-11 15:02:05 +00:00
}