Search code examples
javalinuxbusyboxwake-on-lanjamvm

java.io.IOException: Permission denied with Wake on Lan


I've written this code for implementing Wake On Lan:

InetAddress address = InetAddress.getByAddress(
        new byte[]{(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff});
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, 7);
socket.send(packet);

But I get this:

java.io.IOException: Permission denied
   at gnu.java.nio.VMChannel.send(Native Method)
   at gnu.java.nio.VMChannel.send(VMChannel.java:308)
   at gnu.java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:261)
   at java.net.DatagramSocket.send(DatagramSocket.java:659)
   at com.MyApp.wakeonlan(MyApp.java:685)

The problem seems the broadcast address, because if I change to any other address it does not give this error. How can I avoit it? I'm using linux busybox, with JamVM and GNU Classpath.


Solution

  • It's late but here is a patch for classpath 0.99:

    diff -aur a/native/jni/java-nio/gnu_java_nio_VMChannel.c b/native/jni/java-nio/gnu_java_nio_VMChannel.c
    --- a/native/jni/java-nio/gnu_java_nio_VMChannel.c  2007-12-28 18:49:56.000000000 +0100
    +++ b/native/jni/java-nio/gnu_java_nio_VMChannel.c  2012-08-14 08:49:38.000000000 +0200
    @@ -868,6 +868,17 @@
    
       elems = (*env)->GetByteArrayElements (env, addr, NULL);
    
    +  int n = 1;
    +
    +  if (*((uint32_t *) elems) == 0xFFFFFFFF)
    +  {
    +    if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *) &n, sizeof(n)) == -1)
    +    {
    +      JCL_ThrowException (env, IO_EXCEPTION, "unable to set broadcast option");
    +      return -1;
    +    }
    +  }
    +
       sockaddr.sin_family = AF_INET;
       sockaddr.sin_addr.s_addr = *((uint32_t *) elems);
       sockaddr.sin_port = htons (port);
    

    This solves the problem.