How to send a WOL package(or anything at all) through a nic which has no IP address?
Asked Answered
M

4

7

I'm trying to send a WOL package on all interfaces in order to wake up the gateway(which is the DHCP server, so the machine won't have an IP yet).

And it seems that I can only bind sockets to IP and port pairs...

So the question is: How can a create a socket(or something else) that is bound to a NIC that has no IP? (Any languge is ok. c# is prefered)

@ctacke: I know that WOL is done by MAC address... My problem is that windows only sends UDP broadcasts on the NIC what Windows considers to be the primary NIC (which is not even the NIC with the default route on my Vista machine). And I can not seems to find a way to bind a socket to an interface which has no IP address. (like DHCP clients do this)

@Arnout: Why not? The clients know the MAC address of the gateway. I just want a send a WOL packet like a DHCP client does initially...(DHCP discover packets claim to come from 0.0.0.0) I don't mind if I have to construct the whole packet byte by byte...

Monitory answered 15/1, 2009 at 2:15 Comment(2)
So you want to wake up a DHCP server from a client that depends on that exact server to get an IP? I don't think that will be possible.Thiele
You're right -- I thought this was a kind of chicken-and-egg situation, but it is basically the same thing as a DHCP client looking for a server (as you stated). Good thing SO has no voting on comments :-)Thiele
M
8

It seems that I have found a solution. One can use winpcap to inject packets to any interface. And there is good wrapper for .net: http://www.tamirgal.com/home/dev.aspx?Item=SharpPcap

(I would have prefered a solution which requires no extra libraries to be installed...)

UPDATE: Here is what I came up for sending a WOL packet on all interfaces:

//You need SharpPcap for this to work

private void WakeFunction(string MAC_ADDRESS)
{
    /* Retrieve the device list */
    Tamir.IPLib.PcapDeviceList devices = Tamir.IPLib.SharpPcap.GetAllDevices();

    /*If no device exists, print error */
    if (devices.Count < 1)
    {
        Console.WriteLine("No device found on this machine");
        return;
    }

    foreach (NetworkDevice device in devices)
    {
        //Open the device
        device.PcapOpen();

        //A magic packet is a broadcast frame containing anywhere within its payload: 6 bytes of ones
        //(resulting in hexadecimal FF FF FF FF FF FF), followed by sixteen repetitions 

        byte[] bytes = new byte[120];
        int counter = 0;
        for (int y = 0; y < 6; y++)
            bytes[counter++] = 0xFF;
        //now repeat MAC 16 times
        for (int y = 0; y < 16; y++)
        {
            int i = 0;
            for (int z = 0; z < 6; z++)
            {
                bytes[counter++] =
                    byte.Parse(MAC_ADDRESS.Substring(i, 2),
                    NumberStyles.HexNumber);
                i += 2;
            }
        }

        byte[] etherheader = new byte[54];//If you say so...
        var myPacket = new Tamir.IPLib.Packets.UDPPacket(EthernetFields_Fields.ETH_HEADER_LEN, etherheader);

        //Ethernet
        myPacket.DestinationHwAddress = "FFFFFFFFFFFFF";//it's buggy if you don't have lots of "F"s... (I don't really understand it...)
        try { myPacket.SourceHwAddress = device.MacAddress; }
        catch { myPacket.SourceHwAddress = "0ABCDEF"; }//whatever
        myPacket.EthernetProtocol = EthernetProtocols_Fields.IP;

        //IP
        myPacket.DestinationAddress = "255.255.255.255";
        try { myPacket.SourceAddress = device.IpAddress; }
        catch { myPacket.SourceAddress = "0.0.0.0"; }
        myPacket.IPProtocol = IPProtocols_Fields.UDP;
        myPacket.TimeToLive = 50;
        myPacket.Id = 100;
        myPacket.Version = 4;
        myPacket.IPTotalLength = bytes.Length - EthernetFields_Fields.ETH_HEADER_LEN;           //Set the correct IP length
        myPacket.IPHeaderLength = IPFields_Fields.IP_HEADER_LEN;

        //UDP
        myPacket.SourcePort = 9;                
        myPacket.DestinationPort = 9;           
        myPacket.UDPLength = UDPFields_Fields.UDP_HEADER_LEN;


        myPacket.UDPData = bytes;
        myPacket.ComputeIPChecksum();
        myPacket.ComputeUDPChecksum();

        try
        {
            //Send the packet out the network device
            device.PcapSendPacket(myPacket);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }

        device.PcapClose();
    }
}
Monitory answered 15/1, 2009 at 16:24 Comment(4)
There are two issues with this comment. First, to pass the packet to all the computers on the network you need to enable IP broadcasting (255.255.255.255) on the router which is usually considered a bad idea security wise (because of added potential for internal network attacks like ping flooding. Second, you're using a version of SharpPcap that is years out of date. If you download the latest, it already contains a class for creating/parsing WOL packets. I know because I wrote it back in November/December as per a User's request.Settling
Here's the link to the SharpPcap project. sourceforge.net/projects/sharppcapSettling
re: DestinationHwAddress -- 12 Fs is the MAC equivalent of the broadcast IP address 255.255.255.255. You actually have 13 Fs. :)Photochromy
Sorry for the ambiguous comment there. I know that it's supposed to be 12, but it did not work with 12. It worked with 13. It is/was a bug somewhere in some lower layer, or who knows...Stinkstone
S
4

WOL is a very flexible protocol that can be implemented in multiple different ways.

The most common are:

  • Sending a WOL as the payload of an ethernet packet.
  • Sending a WOL as the payload of a UDP packet (for routing across the net).

Once it lands on the local network it's passes to all the hosts on the network using the broadcast MAC address.

For an Ethernet packet the structure is:

  • Destination MAC: FF:FF:FF:FF:FF:FF (Broadcast)
  • A Magic Packet Payload

For a UDP packet the structure is:

  • Destination MAC: FF:FF:FF:FF:FF:FF (Broadcast)
  • UDP Port: 9
  • A Magic Packet Payload

The Magic Payload consists of:

  • The Synchronization Stream: FFFFFFFFFFFF (that's 6 pairs or 6 bytes of FF)
  • 16 copies of the MAC of the computer you're signaling to WOL
  • An optional passphrase of 0, 4, or 6 bytes.

To receive WOL packets from the internet (through a firewall/router):

  • Configure router port 9 to forward to IP 255.255.255.255 (Broadcast IP)
  • Set the destination IP: The external IP of the router

Note: This can only be achieved using the UDP example because Ethernet packets lack the IP layer necessary for the packet to be routed through the internet. IE, Ethernet packets are the local-network-only option. The issue with sending WOL packets over UDP is security because you have to set the router to enable IP broadcasting (255.255.255.255). Enabling broadcasting over IP is usually considered a bad idea because of the added risk of internal attack within the network (Ping flooding, cache spoofing, etc...).

For more info on the protocol including a sample capture see this site.

If you want a quick-and-dirty command line tool that generates WOL packets (and you're running on a debian, linux mint, or Ubuntu) you can install a tool that already does this.

Just install using the command line with:

sudo apt-get install wakeonlan

Update:

Here's a working example that generates a WakeOnLan packet using the current version of SharpPcap.

using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using PacketDotNet;
using SharpPcap;

namespace SharpPcap.Test.Example9
{
    public class DumpTCP
    {
        public static void Main(string[] args)
        {
            // Print SharpPcap version
            string ver = SharpPcap.Version.VersionString;
            Console.WriteLine("SharpPcap {0}, Example9.SendPacket.cs\n", ver);

            // Retrieve the device list
            var devices = CaptureDeviceList.Instance;

            // If no devices were found print an error
            if(devices.Count < 1)
            {
                Console.WriteLine("No devices were found on this machine");
                return;
            }

            Console.WriteLine("The following devices are available on this machine:");
            Console.WriteLine("----------------------------------------------------");
            Console.WriteLine();

            int i = 0;

            // Print out the available devices
            foreach(var dev in devices)
            {
                Console.WriteLine("{0}) {1}",i,dev.Description);
                i++;
            }

            Console.WriteLine();
            Console.Write("-- Please choose a device to send a packet on: ");
            i = int.Parse( Console.ReadLine() );

            var device = devices[i];

            Console.Write("What MAC address are you sending the WOL packet to: ");
            string response = Console.ReadLine().ToLower().Replace(":", "-");

            //Open the device
            device.Open();

            EthernetPacket ethernet = new EthernetPacket(PhysicalAddress.Parse(
                "ff-ff-ff-ff-ff-ff"), PhysicalAddress.Parse("ff-ff-ff-ff-ff-ff"),
                EthernetPacketType.WakeOnLan);
            ethernet.PayloadPacket = new WakeOnLanPacket(
                PhysicalAddress.Parse(response));
            byte[] bytes = ethernet.BytesHighPerformance.Bytes;

            try
            {
                //Send the packet out the network device
                device.SendPacket(bytes);
                Console.WriteLine("-- Packet sent successfuly.");
            }
            catch(Exception e)
            {
                Console.WriteLine("-- "+ e.Message );
            }

            //Close the pcap device
            device.Close();
            Console.WriteLine("-- Device closed.");
            Console.Write("Hit 'Enter' to exit...");
            Console.ReadLine();
        }
    }
}

Note: This is a fully functional Wake-On-Lan packet sending console application built on the Example09 that can be found in the SharpPcap source.

The libraries used in this example that can't be found in the .NET framework are:

using PacketDotNet;

This library (.dll) comes packaged with SharpPcap. It is responsible for all of the packet construction and parsing within SharpPcap. This is where the WakeOnLan class resides.

Note: The packet construction/parsing code was originally bundled within SharpPcap.dll. It was migrated to its own lib because SharpPcap is meant to be a wrapper for winpcap. Many of its users deal with designing protocols and/or handling raw networking packets.

using SharpPcap;

SharpPcap contains all of the winpcap(windows)/libpcap(*nix) wrapper code. It's needed to select the interface and send the actual packets across the wire.

Settling answered 10/11, 2010 at 9:11 Comment(0)
A
2

WOL is done by MAC, not IP. Here's an example.

Arad answered 15/1, 2009 at 2:19 Comment(1)
I know that WOL is done by MAC address... My problem is that windows only sends UDP broadcasts on the NIC what Windows considers to be the primary NIC. And I can not seems to find a way to bind a socket to an interface which has no IP address. (like DHCP clients do this)Stinkstone
T
-1

.NET operates as a virtual machine (the CLR), so it abstracts away much of the underlying real machine. For example, it only provides interfaces for TCP and UDP networking, which is much higher in the network protocol stack that what you are discussing. You might be able to find a third-party component that provides access to a lower-level interface, but I would not count on it (I have looked in the past for .NET and Java).

For access to that low in the network protocol stack, you probably will need to code in C to the relevant OS system calls. You may find this easiest in Python, and you may find this functionality already implemented in Python's or third-party libraries. For example, I suggest taking a look at the Twisted networking libraries. That was one of the reasons that I switched to Python for much of my work.

Best wishes.

Thorny answered 15/1, 2009 at 16:22 Comment(1)
I did find one :) (We posted at the same time)Stinkstone

© 2022 - 2024 — McMap. All rights reserved.