wol.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /* send wake-on-lan magic ethernet packet */
  10. #include <u.h>
  11. #include <libc.h>
  12. #include <ip.h>
  13. enum {
  14. Eaddrlen = 6, /* 48 bits */
  15. };
  16. typedef struct Wolpack Wolpack;
  17. struct Wolpack{
  18. uint8_t magic[6];
  19. uint8_t macs[16][Eaddrlen];
  20. char pass[6+1];
  21. };
  22. int verbose;
  23. void
  24. usage(void)
  25. {
  26. fprint(2, "usage: wol [-v] [-a dialstr] [-c password] macaddr\n");
  27. exits("usage");
  28. }
  29. void
  30. fillmac(Wolpack *w, uint8_t *mac)
  31. {
  32. int i;
  33. for(i = 0; i < nelem(w->macs); i++)
  34. memmove(w->macs[i], mac, Eaddrlen);
  35. }
  36. void
  37. dumppack(Wolpack *w)
  38. {
  39. int i;
  40. print("packet: [\n");
  41. print("\t%E\n", w->magic);
  42. for(i = 0; i < nelem(w->macs); i++)
  43. print("\t%E\n", w->macs[i]);
  44. print("\t%6s\n", w->pass);
  45. print("]\n");
  46. }
  47. void
  48. main(int argc, char* argv[])
  49. {
  50. int fd, nw;
  51. char *argmac, *pass, *address;
  52. uint8_t mac[Eaddrlen];
  53. static Wolpack w = {
  54. .magic = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }
  55. };
  56. address = pass = nil;
  57. fmtinstall('E', eipfmt);
  58. ARGBEGIN{
  59. case 'a':
  60. address = EARGF(usage());
  61. break;
  62. case 'c':
  63. pass = EARGF(usage());
  64. break;
  65. case 'v':
  66. verbose++;
  67. break;
  68. default:
  69. usage();
  70. }ARGEND
  71. if(argc != 1)
  72. usage();
  73. argmac = argv[0];
  74. if(verbose)
  75. print("mac is %s, pass is %s\n", argmac, pass);
  76. parseether(mac, argmac);
  77. fillmac(&w, mac);
  78. if(pass){
  79. if(strlen(pass) > 6)
  80. sysfatal("password greater than 6 bytes");
  81. strcpy(w.pass, pass);
  82. }
  83. if(verbose)
  84. dumppack(&w);
  85. if(!address)
  86. address = "udp!255.255.255.255!0";
  87. fd = dial(address, nil, nil, nil);
  88. if(fd < 0)
  89. sysfatal("%s: %r", address);
  90. nw = write(fd, &w, sizeof w);
  91. if(nw != sizeof w)
  92. sysfatal("error sending: %r");
  93. exits(0);
  94. }