From 7ddb5feb69af64af149f2962725a70b261129263 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Thu, 12 Jan 2012 21:10:29 +0100 Subject: [PATCH] RawRdlength seems to work; --- msg.go | 15 ++++++++++---- rawmsg.go | 62 +++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/msg.go b/msg.go index a8baed5d..0553a8ae 100644 --- a/msg.go +++ b/msg.go @@ -179,7 +179,7 @@ func PackDomainName(s string, msg []byte, off int, compression map[string]int, c // Add trailing dot to canonicalize name. lenmsg := len(msg) if n := len(s); n == 0 || s[n-1] != '.' { - //println("hier? s", s) + //println("hier? s", s) //return lenmsg, false // This is an error, should be fqdn s += "." } @@ -579,8 +579,8 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok boo off += net.IPv6len case "OPT": // EDNS if off+2 > lenmsg { - // This is an ENDNS0 (OPT Record) with no rdata - // We can savely return here. + // This is an ENDNS0 (OPT Record) with no rdata + // We can savely return here. break } opt := make([]Option, 1) @@ -880,7 +880,7 @@ func packRR(rr RR, msg []byte, off int, compression map[string]int, compress boo if !ok { return len(msg), false } - RawSetRdLength(msg, off, off1) + RawSetRdlength(msg, off, off1) return off1, true } @@ -892,7 +892,14 @@ func unpackRR(msg []byte, off int) (rr RR, off1 int, ok bool) { if off, ok = unpackStruct(&h, msg, off); !ok { return nil, len(msg), false } + rrtype, rdlength, off4 := RawTypeRdlength(msg, off0) + if rrtype == 0 { + return nil, len(msg), false + } end := off + int(h.Rdlength) + println(h.Rdlength, "me l", rdlength) + println(h.Rrtype, "me t", rrtype) + println(end, "me tl", off4+int(rdlength)) // make an rr of that type and re-unpack. // again inefficient but doesn't need to be fast. TODO speed diff --git a/rawmsg.go b/rawmsg.go index a49ff66e..1eecd07b 100644 --- a/rawmsg.go +++ b/rawmsg.go @@ -14,13 +14,12 @@ func RawSetId(msg []byte, off int, id uint16) bool { return true } -// RawSetRdLength sets the rdlength in the header of +// RawSetRdlength sets the rdlength in the header of // the RR. The offset 'off' must be positioned at the -// start of the header of the RR. -func RawSetRdLength(msg []byte, off, end int) bool { - // We are at the start of the header, walk the - // domainname (might be compressed), and set the - // length +// start of the header of the RR, 'end' must be the +// end of the RR. +func RawSetRdlength(msg []byte, off, end int) bool { + // We are at the start of the header, walk the domainname (might be compressed) Loop: for { if off > len(msg) { @@ -35,21 +34,52 @@ Loop: break Loop } + case 0xC0: + // pointer, next byte included, ends domainname + off++ + break Loop + } + } + // 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. + off += 2 + 2 + 4 + if off+1 > len(msg) { + return false + } + //off+1 is the end of the header, 'end' is the end of the rr + //so 'end' - 'off+2' is the lenght of the rdata + msg[off], msg[off+1] = packUint16(uint16(end - (off + 2))) + return true +} + +// RawSetRdlength return the type and length as found +// in the RR header. +func RawTypeRdlength(msg []byte, off int) (uint16, uint16, int) { +Loop: + for { + if off > len(msg) { + return 0, 0, off + } + c := int(msg[off]) + off++ + switch c & 0xC00 { + case 0x00: + if c == 0x00 { + // End of the domainname + break Loop + } + case 0xC0: // pointer, next byte included, ends domainnames off++ break Loop } } - // 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 - off += 2 + 2 + 4 - if off+1 > len(msg) { - return false + off-- + if off+8 > len(msg) { + return 0, 0, off } - //off+1 is the end of the header, 'end' is the end of the rr - //so 'end' - 'off+2' is the lenght of the rdata - msg[off], msg[off+1] = packUint16(uint16(end - (off+2))) - return true + t, off := unpackUint16(msg, off) // type + l, off := unpackUint16(msg, off+6) // length + return t, l, off }