//回答フィールドへの追加 //これを下記のように変更し、OneRRのコンストラクタを使用するようにする public void AddRr(RrKind rrKind, OneRr oneRr) { //名前の圧縮は、最後のgetBytes()で処理する var i = (int)rrKind; _ar[i].Add(oneRr); try{ var count = _dnsHeader.GetCount(i); _dnsHeader.SetCount(i, ++count); } catch (IOException) { Util.RuntimeException("PacketDns.addRR()"); } }
//パケット解釈のためのコンストラクタ public PacketDns(byte[] buffer) { Init(); //ヘッダの解釈 _dnsHeader = new PacketDnsHeader(buffer, 0); var offset = _dnsHeader.Length(); // オペコード 0:標準 1:逆 2:サーバ状態 //var c = (short)(Util.htons(_headerDns.Flags) & 0x7800); //var opcode = (ushort)(c >> 11); var flags = _dnsHeader.Flags; var opcode = flags & 0x7800; if (opcode != 0){ // 標準問い合せ以外は対応していない throw new IOException(string.Format("OPCODE not 0 [CPCODE={0}]", opcode)); } //**************************************** //質問/回答/権限/追加フィールド取得 //**************************************** for (var rr = 0; rr < 4; rr++){ //ushort max = Util.htons(_headerDns.Count[rr]);//対象フィールドのデータ数 var max = _dnsHeader.GetCount(rr); if (rr == 0 && max != 1){ //質問エントリーが1でないパケットは処理できません。 throw new IOException(string.Format("QD Entry !=0 [count={0}]", max)); } for (var n = 0; n < max; n++){ //名前の取得 //offsetの移動 名前のサイズが一定ではないので、そのサイズ分だけ進める var u0 = new UnCompress(buffer, offset); offset = u0.OffSet; var name = u0.HostName; //名前以降のリソースレコードを取得 var packetRr = new PacketRr(buffer, offset); var dnsType = packetRr.DnsType; if (rr == 0){ //質問フィールド[QD]の場合は、TTL, DLEN , DATAは無い _ar[rr].Add(new RrQuery(name, dnsType)); //offsetの移動 名前以降の分だけ進める offset += 4; continue; } var ttl = packetRr.Ttl; var dlen = packetRr.DLen; var data = packetRr.Data; //TypeによってはNameが含まれている場合があるが、Nameは圧縮されている可能性があるので、 //いったん、string 戻してから、改めてリソース用に組み直したDataを作成する OneRr oneRr = null; if (dnsType == DnsType.A){ oneRr = new RrA(name, ttl, data); } else if (dnsType == DnsType.Aaaa){ oneRr = new RrAaaa(name, ttl, data); } else if (dnsType == DnsType.Cname || dnsType == DnsType.Ptr || dnsType == DnsType.Ns){ var u1 = new UnCompress(buffer, offset + 10); switch (dnsType){ case DnsType.Cname: oneRr = new RrCname(name, ttl, u1.HostName); break; case DnsType.Ptr: oneRr = new RrPtr(name, ttl, u1.HostName); break; case DnsType.Ns: oneRr = new RrNs(name, ttl, u1.HostName); break; default: Util.RuntimeException(string.Format("DnsPacket() not implement dnsType={0}", dnsType)); break; } } else if (dnsType == DnsType.Mx){ var preference = Conv.GetUShort(buffer, offset + 10); var u2 = new UnCompress(buffer, offset + 12); oneRr = new RrMx(name, ttl, preference, u2.HostName); } else if (dnsType == DnsType.Soa){ var u3 = new UnCompress(buffer, offset + 10); var u4 = new UnCompress(buffer, u3.OffSet); var p = u4.OffSet; var serial = Conv.GetUInt(buffer, p); p += 4; var refresh = Conv.GetUInt(buffer, p); p += 4; var retry = Conv.GetUInt(buffer, p); p += 4; var expire = Conv.GetUInt(buffer, p); p += 4; var minimum = Conv.GetUInt(buffer, p); oneRr = new RrSoa(name, ttl, u3.HostName, u4.HostName, serial, refresh, retry, expire, minimum); } if (oneRr != null){ //A NS MX SOA PTR CNAMEの6種類以外は、処理(追加)しない _ar[rr].Add(oneRr); } offset += 10 + dlen; } //ヘッダ内のRRレコードのエントリー数を設定する _dnsHeader.SetCount(rr, (ushort) _ar[rr].Count); } }
public void setCountの確認() { //setUp PacketDnsHeader sut = new PacketDnsHeader(); var expected = (ushort)0xf1f1; sut.SetCount(3, expected); //exercise ushort actual = sut.GetCount(3); //verify Assert.That(actual, Is.EqualTo(expected)); }
//パケット解釈のためのコンストラクタ public PacketDns(byte[] buffer) { Init(); //ヘッダの解釈 _dnsHeader = new PacketDnsHeader(buffer, 0); var offset = _dnsHeader.Length(); // オペコード 0:標準 1:逆 2:サーバ状態 //var c = (short)(Util.htons(_headerDns.Flags) & 0x7800); //var opcode = (ushort)(c >> 11); var flags = _dnsHeader.Flags; var opcode = flags & 0x7800; if (opcode != 0) { // 標準問い合せ以外は対応していない throw new IOException(string.Format("OPCODE not 0 [CPCODE={0}]", opcode)); } //**************************************** //質問/回答/権限/追加フィールド取得 //**************************************** for (var rr = 0; rr < 4; rr++) { //ushort max = Util.htons(_headerDns.Count[rr]);//対象フィールドのデータ数 var max = _dnsHeader.GetCount(rr); if (rr == 0 && max != 1) { //質問エントリーが1でないパケットは処理できません。 throw new IOException(string.Format("QD Entry !=0 [count={0}]", max)); } for (var n = 0; n < max; n++) { //名前の取得 //offsetの移動 名前のサイズが一定ではないので、そのサイズ分だけ進める var u0 = new UnCompress(buffer, offset); offset = u0.OffSet; var name = u0.HostName; //名前以降のリソースレコードを取得 var packetRr = new PacketRr(buffer, offset); var dnsType = packetRr.DnsType; if (rr == 0) { //質問フィールド[QD]の場合は、TTL, DLEN , DATAは無い _ar[rr].Add(new RrQuery(name, dnsType)); //offsetの移動 名前以降の分だけ進める offset += 4; continue; } var ttl = packetRr.Ttl; var dlen = packetRr.DLen; var data = packetRr.Data; //TypeによってはNameが含まれている場合があるが、Nameは圧縮されている可能性があるので、 //いったん、string 戻してから、改めてリソース用に組み直したDataを作成する OneRr oneRr = null; if (dnsType == DnsType.A) { oneRr = new RrA(name, ttl, data); } else if (dnsType == DnsType.Aaaa) { oneRr = new RrAaaa(name, ttl, data); } else if (dnsType == DnsType.Cname || dnsType == DnsType.Ptr || dnsType == DnsType.Ns) { var u1 = new UnCompress(buffer, offset + 10); switch (dnsType) { case DnsType.Cname: oneRr = new RrCname(name, ttl, u1.HostName); break; case DnsType.Ptr: oneRr = new RrPtr(name, ttl, u1.HostName); break; case DnsType.Ns: oneRr = new RrNs(name, ttl, u1.HostName); break; default: Util.RuntimeException(string.Format("DnsPacket() not implement dnsType={0}", dnsType)); break; } } else if (dnsType == DnsType.Mx) { var preference = Conv.GetUShort(buffer, offset + 10); var u2 = new UnCompress(buffer, offset + 12); oneRr = new RrMx(name, ttl, preference, u2.HostName); } else if (dnsType == DnsType.Soa) { var u3 = new UnCompress(buffer, offset + 10); var u4 = new UnCompress(buffer, u3.OffSet); var p = u4.OffSet; var serial = Conv.GetUInt(buffer, p); p += 4; var refresh = Conv.GetUInt(buffer, p); p += 4; var retry = Conv.GetUInt(buffer, p); p += 4; var expire = Conv.GetUInt(buffer, p); p += 4; var minimum = Conv.GetUInt(buffer, p); oneRr = new RrSoa(name, ttl, u3.HostName, u4.HostName, serial, refresh, retry, expire, minimum); } if (oneRr != null) { //A NS MX SOA PTR CNAMEの6種類以外は、処理(追加)しない _ar[rr].Add(oneRr); } offset += 10 + dlen; } //ヘッダ内のRRレコードのエントリー数を設定する _dnsHeader.SetCount(rr, (ushort)_ar[rr].Count); } }