···11-let () =
11+22+let send_wol mac port broadcast =
23 Eio_posix.run @@ fun env ->
33- let mac = "AA:BB:CC:DD:EE:FF" in
44- Wol.send ~net:env#net mac
44+ Wol.send ~net:env#net ~port ~broadcast mac
55+66+let () =
77+ let open Cmdliner in
88+ let mac_address =
99+ let doc = "The MAC address to send the magic packet to." in
1010+ Arg.(required & pos 0 (some string) None & info [] ~docv:"MAC_ADDRESS" ~doc)
1111+ in
1212+ let port =
1313+ let doc = "Port to send the packet too (default 9)." in
1414+ Arg.(value & opt int 9 & info ["p"; "port"] ~docv:"PORT" ~doc)
1515+ in
1616+ let broadcast =
1717+ let doc = "Address to send the packet too (default broadcast to 255.255.255.255)." in
1818+ Arg.(value & opt string "255.255.255.255" & info ["a"; "address"] ~docv:"ADDRESS" ~doc)
1919+ in
2020+ let cmd =
2121+ let term = Term.(const send_wol $ mac_address $ port $ broadcast) in
2222+ let doc = "Send a Wake-on-LAN magic packet with a specified MAC address." in
2323+ let info = Cmd.info "wol" ~doc in
2424+ Cmd.v info term
2525+ in
2626+ exit (Cmd.eval cmd)
+19-14
lib/wol.ml
···33 List.map (fun x -> int_of_string ("0x" ^ x)) (Str.split (Str.regexp ":") mac_str)
44 |> Array.of_list
5566-let construct_magic_packet mac =
77- let buf = Cstruct.create 102 in
88- for i = 0 to 5 do
99- Cstruct.set_uint8 buf i 0xFF
1010- done;
1111- for i = 0 to 15 do
1212- for j = 0 to 5 do
1313- Cstruct.set_uint8 buf (6 + i * 6 + j) mac.(j)
1414- done;
1515- done;
66+let mac_to_bytes mac =
77+ String.split_on_char ':' mac
88+ |> List.map (fun x -> int_of_string ("0x" ^ x))
99+1010+let repeat_list n list =
1111+ List.init n (fun _ -> list)
1212+ |> List.concat
1313+1414+let construct_magic_packet mac_str =
1515+ let prefix = [0xFF; 0xFF; 0xFF; 0xFF; 0xFF; 0xFF] in
1616+ let mac_bytes = mac_to_bytes mac_str in
1717+ let repeated_mac = repeat_list 16 mac_bytes in
1818+ let packet_data = prefix @ repeated_mac in
1919+ let buf = Cstruct.create (List.length packet_data) in
2020+ List.iteri (fun i byte -> Cstruct.set_uint8 buf i byte) packet_data;
1621 buf
17221818-let send ~net mac_str =
2323+let send ~net ?(port=9) ?(broadcast="255.255.255.255") mac_str =
1924 Eio.Switch.run @@ fun sw ->
2020- let addr = Ipaddr.V4.of_string_exn "255.255.255.255" |> Ipaddr.V4.to_octets |> Eio.Net.Ipaddr.of_raw in
2525+ let addr = Ipaddr.V4.of_string_exn broadcast |> Ipaddr.V4.to_octets |> Eio.Net.Ipaddr.of_raw in
2126 let sock =
2227 let proto =
2328 Eio.Net.Ipaddr.fold
···2732 in
2833 Eio.Net.datagram_socket ~sw net proto
2934 in
3030- let packet = construct_magic_packet (mac_of_string mac_str) in
3131- Eio.Net.send sock ~dst:(`Udp (addr, 9)) [ packet ]
3535+ let packet = construct_magic_packet mac_str in
3636+ Eio.Net.send sock ~dst:(`Udp (addr, port)) [ packet ]