Showing posts with label wake on lan. Show all posts
Showing posts with label wake on lan. Show all posts

Friday, January 15, 2010

WakeOnLan ported to C#

Paul Mutton wrote a great article on how to use Wake-On-Lan which includes a tutorial on how to create a Magic Packet sender in Java.  He even provides the source of his java implementation: http://www.jibble.org/wake-on-lan/

I took the liberty of converting it to C# with a few minor modifications.  It allows a user to specify a Port number manually.

WHY C#?  Well why not?  I'm using C# at work so it comes naturally.  Mono gives me the ability to run code on both Windows and Linux.  Yes, so does Java.  There are a variety of tools out there and I like to familiarize myself with a good number of them.  In this spirit, I am currently writing a small connection testing tool in Java using Swing.  Maybe I'll write another port of Wake-On-LAN in C++ for fun.

Here is the C# code below:


using System;
using System.Net;
using System.Net.Sockets;

namespace WakeOnLan
{
    class Program
    {       
        static void Main(string[] args)
        {
            string macAdd = "";
            string ip = "";
            string port = "9";
            int iPort = 0;

            if (args.Length < 2) {
                System.Console.WriteLine("Usage: wakeonlan <broadcast-ip> <mac-address> [<port>]");
                System.Console.WriteLine("Example: wakeonlan 192.168.0.255 00:0D:61:08:22:4A");
                System.Console.WriteLine("Example: wakeonlan 192.168.0.255 00-0D-61-08-22-4A");
                System.Environment.Exit(1);
            }

            ip = args[0];
            macAdd = args[1];
            if (args.Length > 2)           
                port = args[2];

            if (!IsNumeric(port))
            {
                System.Console.WriteLine("Port entered was not a number...");
                return; // quit
            }                     

            iPort = Int32.Parse(port);

            if (iPort > 65535 || iPort < 0)
            {
                System.Console.WriteLine("Port value is invalid");
                return;
            }

            byte[] mac = getMacBytes(macAdd);
            //byte[] mac = new byte[] { 0x00, 0x0F, 0x1F, 0x20, 0x2D, 0x35 };
            WakeUp(mac, iPort, ip);
        }

        ///
        /// Check whether string can be converted to a number value
        ///
        private static bool IsNumeric(string num)
        {
            try
            {
                double d = Double.Parse(num);
                return true;
            }
            catch
            {
                return false;
            }
        }

        ///
        /// Sends a Wake-On-Lan packet to the specified MAC address.
        ///
        private static void WakeUp(byte[] mac, Int32 iPort, string myIP)
        {
            //
            // WOL packet is sent over UDP 255.255.255.0:40000.
            //
            UdpClient client = new UdpClient();
            client.Connect(myIP, iPort);

            //
            // WOL packet contains a 6-bytes trailer and 16 times a 6-bytes sequence 
            // containing the MAC address.
            byte[] packet = new byte[17 * 6];

            //
            // Trailer of 6 times 0xFF.
            //
            for (int i = 0; i < 6; i++)
                packet[i] = 0xFF;

            //
            // Body of magic packet contains 16 times the MAC address.
            //
            for (int i = 1; i <= 16; i++)
                for (int j = 0; j < 6; j++)
                    packet[i * 6 + j] = mac[j];

            //
            // Submit WOL packet.
            //
            client.Send(packet, packet.Length);
            System.Console.WriteLine("Wake-on-LAN packet sent.");
        }
   
        private static byte[] getMacBytes(String macStr)
        {
            byte[] bytes = new byte[6];
            string[] hex = macStr.Split(new Char[] { ':', '-' });
            if (hex.Length != 6) {
                throw new ArgumentException("Invalid MAC address.");
            }
            try {
                for (int i = 0; i < 6; i++) {
                    Int32 intVal = Int32.Parse(hex[i], System.Globalization.NumberStyles.AllowHexSpecifier);
                    bytes[i] = (byte)intVal;
                }
            }
            catch (FormatException e) {
                throw new ArgumentException("Invalid hex digit in MAC address.");
            }
            return bytes;
        }
    }
}

Thursday, January 14, 2010

Enabling Wake On Lan on Fedora 16

April 18, 2012: Update - Many users are asking on various forums about WOL on Fedora 16.  My current Operating System is now Fedora 16 and the instructions below are perfectly functional.

Here are simple instructions to setup Wake On Lan on Fedora 14 and above or other versions of linux in general.

Wake-on-lan is a useful tool, but there are tricks to getting it to work correctly under Fedora. Enabling wake-on-lan manually on the network card does not suffice to allow my computer to be awaken remotely. (Lazy computer).

First check the current settings:

# ethtool eth0
Settings for eth0:
    ...
    Supports Wake-on: g
    Wake-on: d
    ...

'd' means wake-on-lan is currently disabled.

I can enable it manually by running the following command:

# ethtool -s eth0 wol g

Unfortunately a snag occurs during the shutdown process; wake-on-lan is disabled automatically.

In order to keep it active after shutdown I must create and use the following script: /etc/init.d/wol.sh

#!/bin/sh
# chkconfig: 0123456 55 10
ethtool -s eth0 wol g

Add execute permission to the file

# chmod +x /etc/init.d/wol.sh

Finally, add the script to my services configuration:

# chkconfig --add /etc/init.d/wol.sh

This allows wake-on-lan to remain active during the shutdown process.

NOTE: Verify the chkconfig priority settings as well as the runlevels that the script runs under as they may be slightly incorrect.

I would very much like to know if anyone can provide improvements to this solution, or even an alternate solution.