Using a Raspberry Pi as a Wake on Lan Forwarder
Author: The Man
Well I don’t have a Raspberry Pi yet but for $35 it’s a bargain and could be used as a WoL forwarder for those of you who don’t have a router that allow packet forwarding for Subnet Directed Broadcasts. This is a first draft of an app you can run.
1. Fire up your Raspberry Pi and download the developer tools, I am assuming your using a Debian based version of Linux. Simply type apt-get install build-essential
2. Copy the code below and place into a file e.g. nano wolf.c then save
3. Compile with gcc -o wolf wolf.c then run with ./wolf
* don’t forget to change to the name of your network interface #define ETHNAME “en1″ usually eth0 on Linux but en0 on a mac.
That’s basically all there is to it. I am going to look at running as a service and report back later.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | // // wolf.c // // Created by Brian on 12/05/2012. // Copyright (c) 2012 Depicus. All rights reserved. // #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <arpa/inet.h> #include <netdb.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <net/if.h> #include <sys/ioctl.h> #include <sys/types.h> #define ETHNAME "en1" #define BUFLEN 102 char myipaddress[16]; char str[1024]; enum { ADDRS_SIZE = 8 }; struct in_addr bcast; struct in_addr nmask; static char netcard[16]; char const *getadapteraddress(char adapter[5]) { int fd; struct ifreq ifr; u_char *addr; u_char *braddr; u_char *naddr; fd = socket (AF_INET, SOCK_DGRAM,0); if ((fd = socket(AF_INET,SOCK_DGRAM,0)) < 0) { fprintf(stderr,"Error: Unable to create socket\n"); perror("socket"); return "-1"; } memset (&ifr, 0, sizeof (struct ifreq)); strcpy (ifr.ifr_name, adapter); ifr.ifr_addr.sa_family = AF_INET; ioctl(fd, SIOCGIFADDR, &ifr); addr=(u_char*)&(((struct sockaddr_in * )&ifr.ifr_addr)->sin_addr); //printf("eth %s, addr %d.%d.%d.%d\n", ifr.ifr_name,addr[0],addr[1],addr[2],addr[3]); strcat(netcard,ifr.ifr_name); sprintf (myipaddress,"%d.%d.%d.%d",addr[0],addr[1],addr[2],addr[3]); memset (&ifr, 0, sizeof (struct ifreq)); strcpy (ifr.ifr_name, adapter); ifr.ifr_addr.sa_family = AF_INET; ioctl(fd, SIOCGIFBRDADDR, &ifr); braddr=(u_char*)&(((struct sockaddr_in * )&ifr.ifr_broadaddr)->sin_addr); //printf("eth broadcast %d.%d.%d.%d\n",braddr[0],braddr[1],braddr[2],braddr[3]); memcpy(&bcast, &(*(struct sockaddr_in *)&ifr.ifr_broadaddr).sin_addr, 4); memset (&ifr, 0, sizeof (struct ifreq)); strcpy (ifr.ifr_name, adapter); ifr.ifr_addr.sa_family = AF_INET; ioctl(fd, SIOCGIFNETMASK, &ifr); naddr=(u_char*)&(((struct sockaddr_in * )&ifr.ifr_broadaddr)->sin_addr); //printf("eth subnet %d.%d.%d.%d\n",braddr[0],braddr[1],braddr[2],braddr[3]); memcpy(&nmask, &(*(struct sockaddr_in *)&ifr.ifr_broadaddr).sin_addr, 4); close(fd); return myipaddress; } // Main section void sendWoLPacket(char mesg[101]) { int sendSocket; struct sockaddr_in wt; memset(&wt, 0, sizeof(wt)); wt.sin_family = AF_INET; wt.sin_port = htons(9); wt.sin_addr.s_addr = inet_addr(inet_ntoa(bcast)); //"192.168.43.255"); sendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); int udpflag = 1; int retval; retval = setsockopt(sendSocket, SOL_SOCKET, SO_BROADCAST, &udpflag, sizeof(udpflag)); if (retval < 0) { sprintf (str,"failed to setsockopt: %s",strerror(errno)); printf("%s\n",str); } int res; res = sendto(sendSocket,mesg,BUFLEN,0,(struct sockaddr *)&wt,sizeof(wt)); if (res < 0) { sprintf (str,"failed to send: %s",strerror(errno)); printf("%s\n", str); } else { printf("Resent WoL on port %i\n",9); } } int main(int argc, const char * argv[]) { printf("Starting WoLf:\n"); char const *cptr; cptr = getadapteraddress(ETHNAME); printf("%s: inet %s netmask %s broadcast %s \n",netcard,cptr,inet_ntoa(nmask),inet_ntoa(bcast)); int sendSocket,n; struct sockaddr_in servaddr,cliaddr; socklen_t len; char mesg[101]; //wol packet size is 102 so 0 to 101 //int bytes; sendSocket=socket(AF_INET,SOCK_DGRAM,0); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr=htonl(INADDR_ANY); servaddr.sin_port=htons(4343); bind(sendSocket,(struct sockaddr *)&servaddr,sizeof(servaddr)); for (;;) { len = sizeof(cliaddr); n = recvfrom(sendSocket,mesg,1000,0,(struct sockaddr *)&cliaddr,&len); sendto(sendSocket,mesg,n,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr)); printf("-------------------------------------------------------\n"); mesg[n] = 0; printf("\nPacket Received with length %i\n", n); //mesg[n] = 0; if (!n == 102) continue; printf("mac address: %02X:%02X:%02X:%02X:%02X:%02X \n",(unsigned char)mesg[6],(unsigned char)mesg[7],(unsigned char)mesg[8],(unsigned char)mesg[9],(unsigned char)mesg[10],(unsigned char)mesg[11]); char ffAddress[18] = ""; char mAddress[18] = ""; // check that the first six digits are FF sprintf (ffAddress,"%02X:%02X:%02X:%02X:%02X:%02X",(unsigned char)mesg[0],(unsigned char)mesg[1],(unsigned char)mesg[2],(unsigned char)mesg[3],(unsigned char)mesg[4],(unsigned char)mesg[5]); if (!strncmp(ffAddress,"FF:FF:FF:FF:FF:FF",17) == 0) { continue; } // check we have six repeating mac addresses int y; for (y = 0; y < 6; y++) { int mply = 6 * (y + 1); sprintf (mAddress,"%02X:%02X:%02X:%02X:%02X:%02X",(unsigned char)mesg[mply],(unsigned char)mesg[mply+1],(unsigned char)mesg[mply+2],(unsigned char)mesg[mply+3],(unsigned char)mesg[mply+4],(unsigned char)mesg[mply+5]); printf("%i %s \n",y, mAddress); if (y > 0) { if (!strncmp(mAddress,ffAddress,strlen(ffAddress)) == 0) { continue; } } stpcpy(ffAddress,mAddress); } //int y; //for (y = 0; y < sizeof(mesg); y++) //{ // printf("%i = %02X ",y,(unsigned char)mesg[y]); //} printf("End Packet\n"); sendWoLPacket(mesg); } printf("Fin\n"); return 0; } |







