DoboWiki
Top
> .NETプログラミング研究/114 をテンプレートにして作成
.NETプログラミング研究/114 をテンプレートにして作成
開始行:
#title(DNSサーバーと直接やり取りして、情報を取得する)
#navi(.NETプログラミング研究)
#contents
*DNSサーバーと直接やり取りして、情報を取得する [#g8a63083]
.NET Frameworkでは、「[[ホスト名からIPアドレス、IPアドレ...
もしこのようなDNSクライアントの機能が必要であれば、サード...
-[[C# .NET DNS query component>http://www.codeproject.com...
-[[DNS.NET Resolver>http://www.codeproject.com/Articles/2...
-[[DNS Client Library for .NET>http://www.simpledns.com/d...
-[[OpenDNS.NET>http://sourceforge.net/projects/opendnsnet...
-[[ARSoft.Tools.Net - C#/.Net DNS client/server, SPF and ...
-[[DnDns and PocketDnDns - A .NET DNS Client Resolver Lib...
しかしここでは、あえてSocket(サンプルでは、UdpClientクラ...
**具体例 [#j39108b4]
本来なら、RFC((RFC1034、RFC1035、RFC1885、RFC2915等))に書...
このサンプルはコンソールアプリケーションで、指定されたDNS...
このサンプルは、Aレコードの他、NS、CNAME、PTR、MXにも対応...
このサンプルでは、DNSサーバーとして「[[Google Public DNS>...
このサンプルを作成するにあたり、以下の記事を参考にさせて...
-[[RFC 1035>http://www.faqs.org/rfcs/rfc1035.html]]
-[[DNS クライアントを作ってみよう (2)>http://x68000.q-e-d...
-[[c# - How to get mx records for a dns name with System....
#code(vbnet){{
Imports System.Net
Imports System.Text
Imports System.Collections.Generic
Class Program
'エントリポイント
Public Shared Sub Main(args As String())
'DNSのIPアドレスまたはホスト名
Dim dns As String = "8.8.8.8"
'DNSのポート番号
Dim dnsPort As Integer = 53
'検索するホスト名またはIPv4アドレス
Dim domainOrAddress As String = "microsoft.com"
'Dim domainOrAddress As String = "134.170.185.46"
'レコード種別
'A=1 NS=2 CNAME=5 PTR=12 MX=15 のみに対応
Dim qType As Byte = 1
'送信するデータを作成する
Dim req As Byte() = CreateRequestMessage(domainOr...
Console.WriteLine(BitConverter.ToString(req))
Dim res As Byte() = Nothing
Using udpc As New System.Net.Sockets.UdpClient(dn...
'UDPでリクエストメッセージを送信する
udpc.Send(req, req.Length)
'レスポンスを受信する
Dim ep As IPEndPoint = Nothing
res = udpc.Receive(ep)
End Using
Console.WriteLine(BitConverter.ToString(res))
'受信したデータから回答を取り出す
Dim answers As String() = GetAnswersFromResponse(...
'回答を表示する
Console.WriteLine("回答:")
For Each s As String In answers
Console.WriteLine(s)
Next
Console.ReadLine()
End Sub
'リクエストメッセージを作成する
Private Shared Function CreateRequestMessage( _
qName As String, qType As Byte) As Byte()
qName = qName.TrimEnd("."c)
Using ms As New System.IO.MemoryStream()
'Header section
'ID
ms.WriteByte(0)
ms.WriteByte(0)
'QR、Opcode、AA、TC、RD(RDのみ1)
ms.WriteByte(1)
'RA、Z、RCODE
ms.WriteByte(0)
'QDCOUNT(質問数)
ms.WriteByte(0)
ms.WriteByte(1)
'ANCOUNT(回答数)
ms.WriteByte(0)
ms.WriteByte(0)
'NSCOUNT
ms.WriteByte(0)
ms.WriteByte(0)
'ADCOUNT
ms.WriteByte(0)
ms.WriteByte(0)
'Question section
'QNAME を作成
Dim buf1 As String() = qName.Split("."c)
If qType = 12 Then
'PTRの時は、IPアドレスを逆に並べて、.in-a...
buf1 = New String() _
{buf1(3), buf1(2), buf1(1), buf1(0), ...
End If
For Each s As String In buf1
'文字列をバイト配列に変換
Dim bs1 As Byte() = Encoding.ASCII.GetByt...
'長さと文字列データを書き込む
ms.WriteByte(CByte(bs1.Length))
ms.Write(bs1, 0, bs1.Length)
Next
ms.WriteByte(0)
'QTYPE
ms.WriteByte(0)
ms.WriteByte(qType)
'QCLASS(Internetは1)
ms.WriteByte(0)
ms.WriteByte(1)
Return ms.ToArray()
End Using
End Function
'レスポンスメッセージから回答を取得する
Private Shared Function GetAnswersFromResponse( _
data As Byte(), startPos As Integer) As Strin...
'データの読み込み位置
Dim pos As Integer = 0
'RCODE (0=No error condition)
Dim resCode As Integer = data(3) And &HF
Console.WriteLine("Response Code:{0}", resCode)
'ANCOUNT(回答数)
pos = 6
Dim anCount As Integer = ConvertToShort(data, pos)
Console.WriteLine("Answers Count:{0}", anCount)
'NSCOUNT
Dim nsCount As Integer = ConvertToShort(data, pos)
'ARCOUNT
Dim arCount As Integer = ConvertToShort(data, pos)
'Questionを飛ばす
pos = startPos
Dim list As New List(Of String)()
'回答数だけ繰り返す
For i As Integer = 0 To anCount - 1
'ドメイン名を取り出す
Dim domainName As String = GetDomainName(data...
Console.WriteLine("Domain:{0}", domainName)
'TYPE
Dim ppType As Short = ConvertToShort(data, pos)
'CLASS、TTLを飛ばす
pos += 6
'RDLENGTH
Dim rdLength As Short = ConvertToShort(data, ...
Dim str As String = "???"
Select Case ppType
Case 1
'A
'IPアドレスを抜き出す
str = GetIPv4Address(data, pos)
list.Add(str)
Exit Select
Case 2, 5, 12
PTR:
'NS
'CNAME
'PTR
'ドメイン名を抜き出す
str = GetDomainName(data, pos)
list.Add(str)
Exit Select
Case 15
'MX
'Preference
Dim preference As Short = ConvertToSh...
Console.WriteLine("Preference:{0}", p...
'ドメイン名を取得する
GoTo PTR
End Select
Console.WriteLine(str)
Next
Return list.ToArray()
End Function
'データの指定位置からDomain名を取得する
Private Shared Function GetDomainName( _
data As Byte(), ByRef pos As Integer) As String
Dim sb As New StringBuilder()
While pos < data.Length
'labelの長さを取得
Dim len As Integer = data(pos)
pos += 1
'長さが0の時、終了
If len = 0 Then
Exit While
End If
If (len And &HC0) = &HC0 Then
'Message compressionの時
'新たな位置を取得
Dim newpos As Integer = _
ConvertToShort(CByte(len And &H3F), d...
pos += 1
'新たな位置から取得したDomainを追加
If sb.Length > 0 Then
sb.Append("."c)
End If
sb.Append(GetDomainName(data, newpos))
Exit While
End If
'byteを文字列に変換して、labelを取得し、追加...
If sb.Length > 0 Then
sb.Append("."c)
End If
sb.Append(Encoding.ASCII.GetString(data, pos,...
pos += len
End While
Return sb.ToString()
End Function
'データの指定位置からIPアドレスを取得する
Private Shared Function GetIPv4Address( _
data As Byte(), ByRef pos As Integer) As String
pos += 4
Return String.Format("{0}.{1}.{2}.{3}", _
data(pos - 4), data(pos - 3), data(pos - 2), ...
End Function
'2つのバイトからInt16を作成
Private Shared Function ConvertToShort(b1 As Byte, b2...
Return CShort(b1 << 8 Or b2)
End Function
Private Shared Function ConvertToShort( _
data As Byte(), ByRef pos As Integer) As Short
pos += 2
Return ConvertToShort(data(pos - 2), data(pos - 1))
End Function
End Class
}}
#code(csharp){{
using System;
using System.Net;
using System.Text;
using System.Collections.Generic;
class Program
{
//エントリポイント
public static void Main(string[] args)
{
//DNSのIPアドレスまたはホスト名
string dns = "8.8.8.8";
//DNSのポート番号
int dnsPort = 53;
//検索するホスト名またはIPv4アドレス
string domainOrAddress = "microsoft.com";
//string domainOrAddress = "134.170.185.46";
//レコード種別
//A=1 NS=2 CNAME=5 PTR=12 MX=15 のみに対応
byte qType = 1;
//送信するデータを作成する
byte[] req = CreateRequestMessage(domainOrAddress...
Console.WriteLine(BitConverter.ToString(req));
byte[] res = null;
using (System.Net.Sockets.UdpClient udpc =
new System.Net.Sockets.UdpClient(dns, dnsPort))
{
//UDPでリクエストメッセージを送信する
udpc.Send(req, req.Length);
//レスポンスを受信する
IPEndPoint ep = null;
res = udpc.Receive(ref ep);
}
Console.WriteLine(BitConverter.ToString(res));
//受信したデータから回答を取り出す
string[] answers = GetAnswersFromResponse(res, re...
//結果を表示する
Console.WriteLine("結果:");
foreach (string s in answers)
{
Console.WriteLine(s);
}
Console.ReadLine();
}
//リクエストメッセージを作成する
private static byte[] CreateRequestMessage(string qNa...
{
qName = qName.TrimEnd('.');
using (System.IO.MemoryStream ms = new System.IO....
{
//Header section
//ID
ms.WriteByte(0);
ms.WriteByte(0);
//QR、Opcode、AA、TC、RD(RDのみ1)
ms.WriteByte(1);
//RA、Z、RCODE
ms.WriteByte(0);
//QDCOUNT(質問数)
ms.WriteByte(0);
ms.WriteByte(1);
//ANCOUNT(回答数)
ms.WriteByte(0);
ms.WriteByte(0);
//NSCOUNT
ms.WriteByte(0);
ms.WriteByte(0);
//ADCOUNT
ms.WriteByte(0);
ms.WriteByte(0);
//Question section
//QNAME を作成
string[] buf1 = qName.Split('.');
if (qType == 12)
{
//PTRの時は、IPアドレスを逆に並べて、.in-...
buf1 = new string[] {
buf1[3], buf1[2], buf1[1], buf1[0], "...
}
foreach (string s in buf1)
{
//文字列をバイト配列に変換
byte[] bs1 = System.Text.Encoding.ASCII.G...
//長さと文字列データを書き込む
ms.WriteByte((byte)bs1.Length);
ms.Write(bs1, 0, bs1.Length);
}
ms.WriteByte(0);
//QTYPE
ms.WriteByte(0);
ms.WriteByte(qType);
//QCLASS(Internetは1)
ms.WriteByte(0);
ms.WriteByte(1);
return ms.ToArray();
}
}
//レスポンスメッセージから回答を取得する
private static string[] GetAnswersFromResponse(byte[]...
{
//データの読み込み位置
int pos = 0;
//RCODE (0=No error condition)
int resCode = data[3] & 0xF;
Console.WriteLine("Response Code:{0}", resCode);
//ANCOUNT(回答数)
pos = 6;
int anCount = ConvertToShort(data, ref pos);
Console.WriteLine("Answers Count:{0}", anCount);
//NSCOUNT
int nsCount = ConvertToShort(data, ref pos);
//ARCOUNT
int arCount = ConvertToShort(data, ref pos);
//Questionを飛ばす
pos = startPos;
List<string> list = new List<string>();
//回答数だけ繰り返す
for (int i = 0; i < anCount; i++)
{
//ドメイン名を取り出す
string domainName = GetDomainName(data, ref p...
Console.WriteLine("Domain:{0}", domainName);
//TYPE
short ppType = ConvertToShort(data, ref pos);
//CLASS、TTLを飛ばす
pos += 6;
//RDLENGTH
short rdLength = ConvertToShort(data, ref pos);
string str = "???";
switch (ppType)
{
case 1:
//A
//IPアドレスを抜き出す
str = GetIPv4Address(data, ref pos);
list.Add(str);
break;
case 2:
//NS
case 5:
//CNAME
case 12:
//PTR
//ドメイン名を抜き出す
str = GetDomainName(data, ref pos);
list.Add(str);
break;
case 15:
//MX
//Preference
short preference = ConvertToShort(dat...
Console.WriteLine("Preference:{0}", p...
//ドメイン名を取得する
goto case 2;
}
Console.WriteLine(str);
}
return list.ToArray();
}
//データの指定位置からDomain名を取得する
private static string GetDomainName(byte[] data, ref ...
{
StringBuilder sb = new StringBuilder();
while (pos < data.Length)
{
//labelの長さを取得
int len = data[pos++];
//長さが0の時、終了
if (len == 0) { break; }
if ((len & 0xC0) == 0xC0)
{
//Message compressionの時
//新たな位置を取得
int newpos = ConvertToShort((byte)(len & ...
pos++;
//新たな位置から取得したDomainを追加
if (sb.Length > 0) { sb.Append('.'); }
sb.Append(GetDomainName(data, ref newpos));
break;
}
//byteを文字列に変換して、labelを取得し、追加...
if (sb.Length > 0) { sb.Append('.'); }
sb.Append(Encoding.ASCII.GetString(data, pos,...
pos += len;
}
return sb.ToString();
}
//データの指定位置からIPアドレスを取得する
private static string GetIPv4Address(byte[] data, ref...
{
return string.Format("{0}.{1}.{2}.{3}",
data[pos++], data[pos++], data[pos++], data[p...
}
//2つのバイトからInt16を作成
private static short ConvertToShort(byte b1, byte b2)
{
return (short)(b1 << 8 | b2);
}
private static short ConvertToShort(byte[] data, ref ...
{
return ConvertToShort(data[pos++], data[pos++]);
}
}
}}
**補足説明 [#n4fbbed6]
上記サンプルについて、少し補足の説明をします。
CreateRequestMessageメソッドで、DNSサーバーに送信するデー...
GetAnswersFromResponseメソッドで、DNSサーバーから受信した...
Answer部分の解析は、NAME(ドメイン名)、TYPE(レコード種...
ConvertToShortメソッドでは、2つのバイト値から1つのInt16値...
**最後に [#hbed5db1]
皆様のおかげで、今年も一年無事に過ごすことができました。...
**コメント [#l631ec6a]
#comment
//これより下は編集しないでください
#pageinfo([[:Category/.NET]] [[:Category/ASP.NET]],2014-1...
終了行:
#title(DNSサーバーと直接やり取りして、情報を取得する)
#navi(.NETプログラミング研究)
#contents
*DNSサーバーと直接やり取りして、情報を取得する [#g8a63083]
.NET Frameworkでは、「[[ホスト名からIPアドレス、IPアドレ...
もしこのようなDNSクライアントの機能が必要であれば、サード...
-[[C# .NET DNS query component>http://www.codeproject.com...
-[[DNS.NET Resolver>http://www.codeproject.com/Articles/2...
-[[DNS Client Library for .NET>http://www.simpledns.com/d...
-[[OpenDNS.NET>http://sourceforge.net/projects/opendnsnet...
-[[ARSoft.Tools.Net - C#/.Net DNS client/server, SPF and ...
-[[DnDns and PocketDnDns - A .NET DNS Client Resolver Lib...
しかしここでは、あえてSocket(サンプルでは、UdpClientクラ...
**具体例 [#j39108b4]
本来なら、RFC((RFC1034、RFC1035、RFC1885、RFC2915等))に書...
このサンプルはコンソールアプリケーションで、指定されたDNS...
このサンプルは、Aレコードの他、NS、CNAME、PTR、MXにも対応...
このサンプルでは、DNSサーバーとして「[[Google Public DNS>...
このサンプルを作成するにあたり、以下の記事を参考にさせて...
-[[RFC 1035>http://www.faqs.org/rfcs/rfc1035.html]]
-[[DNS クライアントを作ってみよう (2)>http://x68000.q-e-d...
-[[c# - How to get mx records for a dns name with System....
#code(vbnet){{
Imports System.Net
Imports System.Text
Imports System.Collections.Generic
Class Program
'エントリポイント
Public Shared Sub Main(args As String())
'DNSのIPアドレスまたはホスト名
Dim dns As String = "8.8.8.8"
'DNSのポート番号
Dim dnsPort As Integer = 53
'検索するホスト名またはIPv4アドレス
Dim domainOrAddress As String = "microsoft.com"
'Dim domainOrAddress As String = "134.170.185.46"
'レコード種別
'A=1 NS=2 CNAME=5 PTR=12 MX=15 のみに対応
Dim qType As Byte = 1
'送信するデータを作成する
Dim req As Byte() = CreateRequestMessage(domainOr...
Console.WriteLine(BitConverter.ToString(req))
Dim res As Byte() = Nothing
Using udpc As New System.Net.Sockets.UdpClient(dn...
'UDPでリクエストメッセージを送信する
udpc.Send(req, req.Length)
'レスポンスを受信する
Dim ep As IPEndPoint = Nothing
res = udpc.Receive(ep)
End Using
Console.WriteLine(BitConverter.ToString(res))
'受信したデータから回答を取り出す
Dim answers As String() = GetAnswersFromResponse(...
'回答を表示する
Console.WriteLine("回答:")
For Each s As String In answers
Console.WriteLine(s)
Next
Console.ReadLine()
End Sub
'リクエストメッセージを作成する
Private Shared Function CreateRequestMessage( _
qName As String, qType As Byte) As Byte()
qName = qName.TrimEnd("."c)
Using ms As New System.IO.MemoryStream()
'Header section
'ID
ms.WriteByte(0)
ms.WriteByte(0)
'QR、Opcode、AA、TC、RD(RDのみ1)
ms.WriteByte(1)
'RA、Z、RCODE
ms.WriteByte(0)
'QDCOUNT(質問数)
ms.WriteByte(0)
ms.WriteByte(1)
'ANCOUNT(回答数)
ms.WriteByte(0)
ms.WriteByte(0)
'NSCOUNT
ms.WriteByte(0)
ms.WriteByte(0)
'ADCOUNT
ms.WriteByte(0)
ms.WriteByte(0)
'Question section
'QNAME を作成
Dim buf1 As String() = qName.Split("."c)
If qType = 12 Then
'PTRの時は、IPアドレスを逆に並べて、.in-a...
buf1 = New String() _
{buf1(3), buf1(2), buf1(1), buf1(0), ...
End If
For Each s As String In buf1
'文字列をバイト配列に変換
Dim bs1 As Byte() = Encoding.ASCII.GetByt...
'長さと文字列データを書き込む
ms.WriteByte(CByte(bs1.Length))
ms.Write(bs1, 0, bs1.Length)
Next
ms.WriteByte(0)
'QTYPE
ms.WriteByte(0)
ms.WriteByte(qType)
'QCLASS(Internetは1)
ms.WriteByte(0)
ms.WriteByte(1)
Return ms.ToArray()
End Using
End Function
'レスポンスメッセージから回答を取得する
Private Shared Function GetAnswersFromResponse( _
data As Byte(), startPos As Integer) As Strin...
'データの読み込み位置
Dim pos As Integer = 0
'RCODE (0=No error condition)
Dim resCode As Integer = data(3) And &HF
Console.WriteLine("Response Code:{0}", resCode)
'ANCOUNT(回答数)
pos = 6
Dim anCount As Integer = ConvertToShort(data, pos)
Console.WriteLine("Answers Count:{0}", anCount)
'NSCOUNT
Dim nsCount As Integer = ConvertToShort(data, pos)
'ARCOUNT
Dim arCount As Integer = ConvertToShort(data, pos)
'Questionを飛ばす
pos = startPos
Dim list As New List(Of String)()
'回答数だけ繰り返す
For i As Integer = 0 To anCount - 1
'ドメイン名を取り出す
Dim domainName As String = GetDomainName(data...
Console.WriteLine("Domain:{0}", domainName)
'TYPE
Dim ppType As Short = ConvertToShort(data, pos)
'CLASS、TTLを飛ばす
pos += 6
'RDLENGTH
Dim rdLength As Short = ConvertToShort(data, ...
Dim str As String = "???"
Select Case ppType
Case 1
'A
'IPアドレスを抜き出す
str = GetIPv4Address(data, pos)
list.Add(str)
Exit Select
Case 2, 5, 12
PTR:
'NS
'CNAME
'PTR
'ドメイン名を抜き出す
str = GetDomainName(data, pos)
list.Add(str)
Exit Select
Case 15
'MX
'Preference
Dim preference As Short = ConvertToSh...
Console.WriteLine("Preference:{0}", p...
'ドメイン名を取得する
GoTo PTR
End Select
Console.WriteLine(str)
Next
Return list.ToArray()
End Function
'データの指定位置からDomain名を取得する
Private Shared Function GetDomainName( _
data As Byte(), ByRef pos As Integer) As String
Dim sb As New StringBuilder()
While pos < data.Length
'labelの長さを取得
Dim len As Integer = data(pos)
pos += 1
'長さが0の時、終了
If len = 0 Then
Exit While
End If
If (len And &HC0) = &HC0 Then
'Message compressionの時
'新たな位置を取得
Dim newpos As Integer = _
ConvertToShort(CByte(len And &H3F), d...
pos += 1
'新たな位置から取得したDomainを追加
If sb.Length > 0 Then
sb.Append("."c)
End If
sb.Append(GetDomainName(data, newpos))
Exit While
End If
'byteを文字列に変換して、labelを取得し、追加...
If sb.Length > 0 Then
sb.Append("."c)
End If
sb.Append(Encoding.ASCII.GetString(data, pos,...
pos += len
End While
Return sb.ToString()
End Function
'データの指定位置からIPアドレスを取得する
Private Shared Function GetIPv4Address( _
data As Byte(), ByRef pos As Integer) As String
pos += 4
Return String.Format("{0}.{1}.{2}.{3}", _
data(pos - 4), data(pos - 3), data(pos - 2), ...
End Function
'2つのバイトからInt16を作成
Private Shared Function ConvertToShort(b1 As Byte, b2...
Return CShort(b1 << 8 Or b2)
End Function
Private Shared Function ConvertToShort( _
data As Byte(), ByRef pos As Integer) As Short
pos += 2
Return ConvertToShort(data(pos - 2), data(pos - 1))
End Function
End Class
}}
#code(csharp){{
using System;
using System.Net;
using System.Text;
using System.Collections.Generic;
class Program
{
//エントリポイント
public static void Main(string[] args)
{
//DNSのIPアドレスまたはホスト名
string dns = "8.8.8.8";
//DNSのポート番号
int dnsPort = 53;
//検索するホスト名またはIPv4アドレス
string domainOrAddress = "microsoft.com";
//string domainOrAddress = "134.170.185.46";
//レコード種別
//A=1 NS=2 CNAME=5 PTR=12 MX=15 のみに対応
byte qType = 1;
//送信するデータを作成する
byte[] req = CreateRequestMessage(domainOrAddress...
Console.WriteLine(BitConverter.ToString(req));
byte[] res = null;
using (System.Net.Sockets.UdpClient udpc =
new System.Net.Sockets.UdpClient(dns, dnsPort))
{
//UDPでリクエストメッセージを送信する
udpc.Send(req, req.Length);
//レスポンスを受信する
IPEndPoint ep = null;
res = udpc.Receive(ref ep);
}
Console.WriteLine(BitConverter.ToString(res));
//受信したデータから回答を取り出す
string[] answers = GetAnswersFromResponse(res, re...
//結果を表示する
Console.WriteLine("結果:");
foreach (string s in answers)
{
Console.WriteLine(s);
}
Console.ReadLine();
}
//リクエストメッセージを作成する
private static byte[] CreateRequestMessage(string qNa...
{
qName = qName.TrimEnd('.');
using (System.IO.MemoryStream ms = new System.IO....
{
//Header section
//ID
ms.WriteByte(0);
ms.WriteByte(0);
//QR、Opcode、AA、TC、RD(RDのみ1)
ms.WriteByte(1);
//RA、Z、RCODE
ms.WriteByte(0);
//QDCOUNT(質問数)
ms.WriteByte(0);
ms.WriteByte(1);
//ANCOUNT(回答数)
ms.WriteByte(0);
ms.WriteByte(0);
//NSCOUNT
ms.WriteByte(0);
ms.WriteByte(0);
//ADCOUNT
ms.WriteByte(0);
ms.WriteByte(0);
//Question section
//QNAME を作成
string[] buf1 = qName.Split('.');
if (qType == 12)
{
//PTRの時は、IPアドレスを逆に並べて、.in-...
buf1 = new string[] {
buf1[3], buf1[2], buf1[1], buf1[0], "...
}
foreach (string s in buf1)
{
//文字列をバイト配列に変換
byte[] bs1 = System.Text.Encoding.ASCII.G...
//長さと文字列データを書き込む
ms.WriteByte((byte)bs1.Length);
ms.Write(bs1, 0, bs1.Length);
}
ms.WriteByte(0);
//QTYPE
ms.WriteByte(0);
ms.WriteByte(qType);
//QCLASS(Internetは1)
ms.WriteByte(0);
ms.WriteByte(1);
return ms.ToArray();
}
}
//レスポンスメッセージから回答を取得する
private static string[] GetAnswersFromResponse(byte[]...
{
//データの読み込み位置
int pos = 0;
//RCODE (0=No error condition)
int resCode = data[3] & 0xF;
Console.WriteLine("Response Code:{0}", resCode);
//ANCOUNT(回答数)
pos = 6;
int anCount = ConvertToShort(data, ref pos);
Console.WriteLine("Answers Count:{0}", anCount);
//NSCOUNT
int nsCount = ConvertToShort(data, ref pos);
//ARCOUNT
int arCount = ConvertToShort(data, ref pos);
//Questionを飛ばす
pos = startPos;
List<string> list = new List<string>();
//回答数だけ繰り返す
for (int i = 0; i < anCount; i++)
{
//ドメイン名を取り出す
string domainName = GetDomainName(data, ref p...
Console.WriteLine("Domain:{0}", domainName);
//TYPE
short ppType = ConvertToShort(data, ref pos);
//CLASS、TTLを飛ばす
pos += 6;
//RDLENGTH
short rdLength = ConvertToShort(data, ref pos);
string str = "???";
switch (ppType)
{
case 1:
//A
//IPアドレスを抜き出す
str = GetIPv4Address(data, ref pos);
list.Add(str);
break;
case 2:
//NS
case 5:
//CNAME
case 12:
//PTR
//ドメイン名を抜き出す
str = GetDomainName(data, ref pos);
list.Add(str);
break;
case 15:
//MX
//Preference
short preference = ConvertToShort(dat...
Console.WriteLine("Preference:{0}", p...
//ドメイン名を取得する
goto case 2;
}
Console.WriteLine(str);
}
return list.ToArray();
}
//データの指定位置からDomain名を取得する
private static string GetDomainName(byte[] data, ref ...
{
StringBuilder sb = new StringBuilder();
while (pos < data.Length)
{
//labelの長さを取得
int len = data[pos++];
//長さが0の時、終了
if (len == 0) { break; }
if ((len & 0xC0) == 0xC0)
{
//Message compressionの時
//新たな位置を取得
int newpos = ConvertToShort((byte)(len & ...
pos++;
//新たな位置から取得したDomainを追加
if (sb.Length > 0) { sb.Append('.'); }
sb.Append(GetDomainName(data, ref newpos));
break;
}
//byteを文字列に変換して、labelを取得し、追加...
if (sb.Length > 0) { sb.Append('.'); }
sb.Append(Encoding.ASCII.GetString(data, pos,...
pos += len;
}
return sb.ToString();
}
//データの指定位置からIPアドレスを取得する
private static string GetIPv4Address(byte[] data, ref...
{
return string.Format("{0}.{1}.{2}.{3}",
data[pos++], data[pos++], data[pos++], data[p...
}
//2つのバイトからInt16を作成
private static short ConvertToShort(byte b1, byte b2)
{
return (short)(b1 << 8 | b2);
}
private static short ConvertToShort(byte[] data, ref ...
{
return ConvertToShort(data[pos++], data[pos++]);
}
}
}}
**補足説明 [#n4fbbed6]
上記サンプルについて、少し補足の説明をします。
CreateRequestMessageメソッドで、DNSサーバーに送信するデー...
GetAnswersFromResponseメソッドで、DNSサーバーから受信した...
Answer部分の解析は、NAME(ドメイン名)、TYPE(レコード種...
ConvertToShortメソッドでは、2つのバイト値から1つのInt16値...
**最後に [#hbed5db1]
皆様のおかげで、今年も一年無事に過ごすことができました。...
**コメント [#l631ec6a]
#comment
//これより下は編集しないでください
#pageinfo([[:Category/.NET]] [[:Category/ASP.NET]],2014-1...
ページ名:
▲
▼
[
トップ
] [
新規
|
子ページ作成
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]