vb.netdnspcap.net

How could I make a mDNS Query with Pcap.net?


Problem: I'm looking to make a mDNS packet, while having searching stackflow for options. I tried bonjour and some wrappers but had very limited success, especially when I requested a second time and get socket binding complaints (Which, of course, may have been my code not them).

Since VB.net didn't have a really editable dnsquery that I know of, I'm using the DNS layer in the build DNS packet in pcapdotnet and just kind of making the packet myself layer by layer. I'm thinking it's a good alternative, but I'm kind of lost on how I would do it.

Here's the question we want:

        q_name = new QuestionName("_axis-video._tcp.local"),
        q_type = QueryConstants.Question.QuestionType.PTR,
        q_class = QueryConstants.Question.QuestionClass.IN

Here's my edited BuildDNSPacket function from their standard:

Private Shared Function BuildDnsPacket(destmac As String, domainName As String) As Packet

    'get source MAC address of PC
    Dim nic = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
    Dim source As String = nic(0).GetPhysicalAddress().ToString
    Dim sourcearray As Byte() = System.Text.Encoding.ASCII.GetBytes(source)

    'format
    Dim sourceMacStr As String = ""
    For i As Integer = 0 To sourcearray.Count - 1 Step 2
        sourceMacStr += Chr(sourcearray(i)) & Chr(sourcearray(i + 1)) & ":"
    Next

    ' Will be filled automatically.
    Dim ethernetLayer As New EthernetLayer() With { _
         .Source = New MacAddress(sourceMacStr.Substring(0, 17)), _
          .Destination = New MacAddress(destmac), _
          .EtherType = EthernetType.None _
    }

    ' Will be filled automatically.
    Dim ipV4Layer As New IpV4Layer() With { _
          .Source = New IpV4Address("1.2.3.4"), _
          .CurrentDestination = New IpV4Address(destmac), _
          .Fragmentation = IpV4Fragmentation.None, _
          .HeaderChecksum = Nothing, _
          .Identification = 123, _
          .Options = IpV4Options.None, _
          .Protocol = Nothing, _
          .Ttl = 100, _
          .TypeOfService = 0 _
    }

    ' Will be filled automatically.
    Dim udpLayer As New UdpLayer() With { _
          .SourcePort = 5353, _
          .DestinationPort = 5353, _
          .Checksum = Nothing, _
          .CalculateChecksumValue = False _
    }

    Dim dnsLayer As New DnsLayer() With { _
          .Id = 0, _
          .IsResponse = False, _
          .OpCode = DnsOpCode.Query, _
          .IsAuthoritativeAnswer = False, _
          .IsTruncated = False, _
          .IsRecursionDesired = False, _
          .IsRecursionAvailable = False, _
          .FutureUse = False, _
          .IsAuthenticData = False, _
          .IsCheckingDisabled = False, _
          .ResponseCode = DnsResponseCode.NoError, _
          .Queries = {New DnsQueryResourceRecord(New DnsDomainName(domainName), DnsType.Ptr, DnsClass.Any)}, _
          .Answers = Nothing, _
          .Authorities = Nothing, _
          .Additionals = Nothing, _
          .DomainNameCompressionMode = DnsDomainNameCompressionMode.All _
    }


    Dim builder As New PacketBuilder(ethernetLayer, ipV4Layer, udpLayer, dnsLayer)

    Return builder.Build(DateTime.Now)
End Function

The main differences is my changing the DnsType to PTR and the port to 5353.

Question: What else should I add or change to make it mDNS? What could I put into the domainName? Should I vary the dnsclass?

All or any suggestions are definitely welcomed.


Solution

  • I am answering my question in case others who need to do mDNS in vb.net needs this:

    Solution: I didn't need to add anything to the DNS layer to make this work. I changed the DNS layer to below:

       Dim dnsLayer As New DnsLayer() With { _
              .Id = 0, _
              .IsResponse = False, _
              .OpCode = DnsOpCode.Query, _
              .IsAuthoritativeAnswer = False, _
              .IsTruncated = False, _
              .IsRecursionDesired = False, _
              .IsRecursionAvailable = False, _
              .FutureUse = False, _
              .IsAuthenticData = False, _
              .IsCheckingDisabled = False, _
              .ResponseCode = DnsResponseCode.NoError, _
              .Queries = {New DnsQueryResourceRecord(New DnsDomainName(domainName), DnsType.Ptr, DnsClass.Any)}, _
              .Answers = Nothing, _
              .Authorities = Nothing, _
              .Additionals = Nothing, _
              .DomainNameCompressionMode = DnsDomainNameCompressionMode.All _
        }
    

    I made the output address of the Ipv4 layer to be the multicast address of "224.0.0.251", changed my ports to 5353, and used the domain name of the question I listed above.

    Here's a wireshark to show the responses: enter image description here