Search code examples
c#pcap.net

Automatically select a device in PcapDotNet?


Is there a way to select working device that sends http traffic automatically from this list?

List<NetworkInterface> Interfaces = new List<NetworkInterface>();
foreach (var nic in NetworkInterface.GetAllNetworkInterfaces())
{
    if (nic.OperationalStatus == OperationalStatus.Up)
    {
        Interfaces.Add(nic);
    }
}

Also how to sniff URLs instead of IPs? Sorry I'm new to PcapDotNet.

private static void PacketHandler(Packet packet)
{
    // print timestamp and length of the packet
    Console.WriteLine(packet.Timestamp.ToString("yyyy-MM-dd hh:mm:ss.fff") + " length:" + packet.Length);

    IpV4Datagram ip = packet.Ethernet.IpV4;
    UdpDatagram udp = ip.Udp;

    // print ip addresses and udp ports
    Console.WriteLine(ip.Source + ":" + udp.SourcePort + " -> " + ip.Destination + ":" + udp.DestinationPort);
}

Solution

  • Are you trying to find more information on a specific NIC? If you are trying to isolate traffic from a single interface, first find out which one it is. The code below will help you enumerate the available interfaces:

     var nics = from NetworkInterface a
                      in NetworkInterface.GetAllNetworkInterfaces()
                       where a.NetworkInterfaceType == NetworkInterfaceType.Ethernet &&
                       a.Supports(NetworkInterfaceComponent.IPv4)
                       select a;
    
        if (nics.Any())
        {
            var nic = nics.First();
            adapter = new NetworkAdapter();
            adapter.Name = nic.Name;
            adapter.Description = nic.Description;
            adapter.Id = nic.Id;
            var props = nic.GetIPProperties();
    
    
            var ipAddresses = from UnicastIPAddressInformation info
                              in props.UnicastAddresses
                              where info.PrefixOrigin == PrefixOrigin.Manual
                              select info;
    
            adapter.GatewayAddressList = nic.GetIPProperties().GatewayAddresses;
    
            adapter.Available = (nic.OperationalStatus == OperationalStatus.Up);
        }
    

    Also, If you are attempting to sniff URLs you are going to have to look at DNS packets. DNS is what helps convert a URL to an IP. Check out DNS. DNS searches will occur prior to any connection.

    EDIT: Here is a utility method that I use to enumerate the adapter IDs:

    DLL int GetAvailableAdapters()
    {
        pcap_if_t *alldevs;
        pcap_if_t *devs;
        char msgBuffer[LOG_SIZE];
        int index = 0;
        char* fullname;
        int namePtr;
        char* shortname;
        struct in_addr ip;
    
    
    // Retrieve the device list on the local machine
    if (-1 == pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, msgBuffer))
    {
        //error
        return 0;
    }
    
    // Cycle List, and make sure adapters are available/visable
    for(devs = alldevs; devs != NULL; devs = devs->next)
    {
        ++index;
    
        //
        // Print adapter description
        //
        sprintf(msgBuffer, "  [%d]:  %s", index, devs->description);
        gblLog(INFO, msgBuffer);
    
        //
        // Parse and Print adapters network info in dot-decimal notation
        //
        /*ip = ((struct sockaddr_in *)(devs->addresses->addr))->sin_addr;
        sprintf(msgBuffer, "        IPAddr:  %s ", inet_ntoa(ip));
        gblLog(INFO, msgBuffer);
        */
    
        //
        // Print the Registry Key Value from the substring of adapter name
        //
        fullname = devs->name;
        namePtr = strlen(fullname);
        shortname = fullname + namePtr;
    
        while(0 < namePtr && fullname[--namePtr] != '_');
        if(fullname[namePtr] == '_')
        {
            // Key is the string after "_" char, get the substring starting at that index.
            shortname = fullname + namePtr + 1;
            fullname[namePtr] = '\0';
    
            sprintf(msgBuffer, "        KeyVal:  %s\n", shortname);
            gblLog(INFO, msgBuffer);
        }       
        else
        {
            // Print full name if the "_" char was not found (odd formating...)
            sprintf(msgBuffer, "        KeyVal:  %s\n", fullname);
            gblLog(INFO, msgBuffer);
        }
    }
    
    if(index == 0)
    {
        gblLog(INFO, "FindAllDevs() returned null devices. No network adapters found!");
    }
    
    return index; // Total num of adapters enum
    }
    

    Using this method, along with the NetworkInterface, you should be able to associate an adapter with the index via its reg key. Once you find the proper adapter, open your pcap device using that index:

    if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
        {
            return -1; // error
        }
    
        // Cycle the devs until we reach the appropriate index
        for(d = alldevs, i = 0; (i < (index- 1)); d = d->next, i++);    
    
        // Open the device
        if ( (adhandle= pcap_open(d->name,              // HW name of the network device.
                                  65536,                // Portion of the packet to capture. 65536 max packet
                                  adapterFlags,         // See adapterFlags above
                                  1000,                 // 1sec timeout on idle. (We check for exit at this interval)
                                  NULL,                 // No authentication, 
                                  errbuf                // Error buffer
                                  )) == NULL)
        {
            //error opening
            pcap_freealldevs(alldevs);  // Free the device list
            return -1;
        }