Options

Wake On Lan not working Over UDP

CodeBloxCodeBlox Member Posts: 1,363 ■■■■□□□□□□
I wrote two simple programs in C that send the magic pattern for WOL. One of the programs sends the magic packet straight over ethernet and that one works. The other sends it over UDP and I am using UDP port 9. I have tried several ports but the machine does not wake up using UDP. I know the packet is getting to the PC as I confirmed that with wireshark. It's a unicast datagram sent from my PC at work to my home PC. I know WOL should work over UPD according to research.

EDIT: I suspect that I know why it's not working... The packet should be port forwarded to the LAN broadcast address and my DLINK does not support that. I had it forwarding to the unicast address and the packet gets received whereas it doesn't when forwarding to the broadcast... Oh well :P
Currently reading: Network Warrior, Unix Network Programming by Richard Stevens

Comments

  • Options
    NovaHaxNovaHax Member Posts: 502 ■■■■□□□□□□
    I built a WOL tool that operates over TCP with Scapy (my c kung-fu is not so good). But it doesn't have to be sent to the broadcast address. My TCP function sends it directly to the host.

    I haven't tested it over UDP...but I see no reason why it wouldn't work. I'll try to modify mine tonight and let you know what I get. It will be way easier for me to modify my fairly short scapy script than for you to have to recode a C program.
  • Options
    About7NarwhalAbout7Narwhal Member Posts: 761
    Why not leave it at TCP if that works? Perhaps I am missing something?
  • Options
    NovaHaxNovaHax Member Posts: 502 ■■■■□□□□□□
    Is your home system on a public IP? Or are you using port forwarding to get to it?
  • Options
    CodeBloxCodeBlox Member Posts: 1,363 ■■■■□□□□□□
    Why not leave it at TCP if that works? Perhaps I am missing something?
    I'm not using TCP. Since NovaHax advises that it works using TCP, I think I might make revisions at some point tonight and try that out. My home PC gets natted to a public IP. What I have done is setup a port forward for the specific port to the PC. I can confirm that the packet gets to the PC using wireshark if its unicast.
    Currently reading: Network Warrior, Unix Network Programming by Richard Stevens
  • Options
    NovaHaxNovaHax Member Posts: 502 ■■■■□□□□□□
    Just looked back at my script and found that I was mistaken. I did use UDP port 7.

    Packet stack should be
    IP / UDP / Raw

    For IP, I used the public IP address of the host as the destination IP. I've only tested mine on public addresses (so you add an additional variable here).

    For UDP, I used the destination port of 7. I think most systems configured to respond to Wake-On-LAN will listen on both 7 and 9...so you should be good.

    For raw data, I included ('\xff'*6) and then 16 instances of the system's MAC address, hex-encoded.

    Hope that helps.
  • Options
    NovaHaxNovaHax Member Posts: 502 ■■■■□□□□□□
    Here it is in Python (this script assumes you have Scapy installed):

    from scapy.all import *
    import logging
    logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

    lay2addr = raw_input("Enter MAC address(Example - 000c2991e3b2): ")
    mac = lay2addr.decode("hex")
    ip = raw_input("Enter IP address (Example - 192.168.74.141): ")
    send(IP(dst=ip)/UDP(dport=7)/Raw(('\xff'*6)+(mac*16)))
  • Options
    networker050184networker050184 Mod Posts: 11,962 Mod
    Why not leave it at TCP if that works? Perhaps I am missing something?

    What would be the fun in that?!
    An expert is a man who has made all the mistakes which can be made.
  • Options
    NovaHaxNovaHax Member Posts: 502 ■■■■□□□□□□
    7 lines of code...which would probably amount to 100+ in C :-/
  • Options
    NovaHaxNovaHax Member Posts: 502 ■■■■□□□□□□
    But now I'm curious if it would work over TCP??? icon_scratch.gif

    images?q=tbn:ANd9GcSlD7PoMCAY3zhn2cU_6cHYuwLWsXohU4XUohisK-ohQZoGnJUjfw
  • Options
    CodeBloxCodeBlox Member Posts: 1,363 ■■■■□□□□□□
    haha... Here is my source code in C. I could do the same thing in Python with much less effort but I get so stuck in my ways of C. I like to keep my programs modular and the multiple files make it look longer than it really is. Not necessary, just my preference.

    wol.h
    
    #ifndef WOL_H
    #define WOL_H
    
    
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    #include <netinet/ether.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    
    
    
    
    #define MAC_ADDRSTRLEN 17
    #define WOL_DATA_LEN 102
    #define MAC_ADDR_LEN 6
    
    
    #define BROADCAST_STR "ff:ff:ff:ff:ff:ff"
    
    
    void get_params(char *, char *, char *, int, char **);
    void wol_err(char *);
    
    
    int wol_sock();
    
    
    
    
    
    
    #endif 
    




    get_params.c

    #include "wol.h"
    
    
    void get_params(char * inet_addr_str, char * mac_addr_str, char * port, int argc, char ** argv)
    {
      
      char optc;
    
    
      while((optc = getopt(argc, argv, "m:p:i:")) != -1)
        {
    
    
          switch(optc)
        {
    
    
        case 'm': 
          //memcpy(inet_addr, optarg, INET_ADDRSTRLEN);
          strncpy(mac_addr_str, optarg, MAC_ADDRSTRLEN);
          break;
        case 'i':
          strncpy(inet_addr_str, optarg, INET_ADDRSTRLEN);
          break;
        case 'p':
          //memcpy(mac_addr, optarg, MAC_ADDRSTRLEN);
          strncpy(port, optarg, 6);
          break;
        case '?':
          exit(EXIT_FAILURE);
        
        }
    
    
        }
    
    
    }
    
    
    






    wol.c



    #include "wol.h"
    
    
    int main(int argc, char ** argv)
    {
    
    
      int raw_sock, iteration = 0;
      struct ether_addr * mac_addr;
      char inet_addr_str[INET_ADDRSTRLEN], 
        mac_addr_str[MAC_ADDRSTRLEN], 
        port[6],
        data[WOL_DATA_LEN];
      
      struct sockaddr_in peer;
      
      if(argc == 7)
        get_params(inet_addr_str, mac_addr_str, port, argc, argv);
      else{
        printf("argc = %d\n", argc);
        wol_err("Usage: ./wol -i x.x.x.x -m xx[IMG]https://us.v-cdn.net/6030959/uploads/images/smilies/icon_mad.gif[/IMG]x[IMG]https://us.v-cdn.net/6030959/uploads/images/smilies/icon_mad.gif[/IMG]x[IMG]https://us.v-cdn.net/6030959/uploads/images/smilies/icon_mad.gif[/IMG]x[IMG]https://us.v-cdn.net/6030959/uploads/images/smilies/icon_mad.gif[/IMG]x[IMG]https://us.v-cdn.net/6030959/uploads/images/smilies/icon_mad.gif[/IMG]x -p xxxxxx");
      }
    
    
      raw_sock = wol_sock();
      
      peer.sin_family = AF_INET;
      peer.sin_port = htons(atoi(port));
      
      if(inet_pton(AF_INET, inet_addr_str, &peer.sin_addr) != 1)
        {
    
    
          wol_err("inet_pton:");
    
    
        }
    
    
    
    
      memcpy(data, (struct ether_addr *)ether_aton(BROADCAST_STR), MAC_ADDR_LEN);
    
    
      mac_addr = ether_aton(mac_addr_str);
     
      for(iteration = MAC_ADDR_LEN; iteration <= 96; iteration += MAC_ADDR_LEN)
        memcpy(data + iteration, mac_addr, MAC_ADDR_LEN);
    
    
      if(sendto(raw_sock, 
            data, 
            WOL_DATA_LEN, 
            0, 
            (struct sockaddr *)&peer,
            sizeof(peer)) == -1)
        {
    
    
          wol_err("sendto:");
    
    
        }
    
    
      return 0;
    
    
    }
    
    
    
    
    




    wol_err.c

    
    #include "wol.h"
    
    
    void wol_err(char * wol_err_str)
    {
    
    
      fprintf(stderr, "%s\n", wol_err_str);
      exit(EXIT_FAILURE);
    
    
    }
    

    wol_sock.c
    #include "wol.h"
    
    
    int wol_sock()
    {
      
      int wol_sock = 0;
    
    
      if((wol_sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        {
    
    
          wol_err("socket: ");
    
    
        }
      
      return wol_sock;
    
    
    }
    
    
    
    Currently reading: Network Warrior, Unix Network Programming by Richard Stevens
  • Options
    NovaHaxNovaHax Member Posts: 502 ■■■■□□□□□□
    God :-/...I envy and pity you at the same time, lol
  • Options
    CodeBloxCodeBlox Member Posts: 1,363 ■■■■□□□□□□
    I think I'll try coming up with a TCP implementation tonight or tomorrow which will require a raw socket and will cause me to have to craft the entire packet myself since a SOCK_STREAM socket must be "connect()'d" before it will be usable for read/writes. I'm interested in seeing how it plays out. I'm not really expecting the TCP implementation to work but who knows, I might be surprised.
    Currently reading: Network Warrior, Unix Network Programming by Richard Stevens
  • Options
    NovaHaxNovaHax Member Posts: 502 ■■■■□□□□□□
    Yeah...that's what's nice about scapy. It is very easy to defy conventional usage. **as opposed to Python's socket library**
Sign In or Register to comment.