views:

1097

answers:

3

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...

+2  A: 

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

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. 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)
Kalmi
+1  A: 

.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.

Rob Williams
I did find one :)(We posted at the same time)
Kalmi
+5  A: 

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();
    }
}
Kalmi
another c# example: http://www.codeproject.com/KB/IP/wolclass.aspx
cottsak