xref: /plan9/sys/src/cmd/ip/wol.c (revision 14cc0f535177405a84c5b73603a98e5db6674719)
1 /* send wake-on-lan magic ethernet packet */
2 #include <u.h>
3 #include <libc.h>
4 #include <ip.h>
5 
6 enum {
7 	Eaddrlen = 6,	/* 48 bits */
8 };
9 
10 typedef struct Wolpack Wolpack;
11 struct Wolpack{
12 	uchar	magic[6];
13 	uchar	macs[16][Eaddrlen];
14 	char	pass[6+1];
15 };
16 
17 int verbose;
18 
19 void
usage(void)20 usage(void)
21 {
22 	fprint(2, "usage: wol [-v] [-a dialstr] [-c password] macaddr\n");
23 	exits("usage");
24 }
25 
26 void
fillmac(Wolpack * w,uchar * mac)27 fillmac(Wolpack *w, uchar *mac)
28 {
29 	int i;
30 
31 	for(i = 0; i < nelem(w->macs); i++)
32 		memmove(w->macs[i], mac, Eaddrlen);
33 }
34 
35 void
dumppack(Wolpack * w)36 dumppack(Wolpack *w)
37 {
38 	int i;
39 
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 
48 void
main(int argc,char * argv[])49 main(int argc, char* argv[])
50 {
51 	int fd, nw;
52 	char *argmac, *pass, *address;
53 	uchar mac[Eaddrlen];
54 	static Wolpack w = {
55 		.magic { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }
56 	};
57 
58 	address = pass = nil;
59 	fmtinstall('E', eipfmt);
60 
61 	ARGBEGIN{
62 	case 'a':
63 		address = EARGF(usage());
64 		break;
65 	case 'c':
66 		pass = EARGF(usage());
67 		break;
68 	case 'v':
69 		verbose++;
70 		break;
71 	default:
72 		usage();
73 	}ARGEND
74 
75 	if(argc != 1)
76 		usage();
77 	argmac = argv[0];
78 	if(verbose)
79 		print("mac is %s, pass is %s\n", argmac, pass);
80 
81 	parseether(mac, argmac);
82 	fillmac(&w, mac);
83 	if(pass){
84 		if(strlen(pass) > 6)
85 			sysfatal("password greater than 6 bytes");
86 		strcpy(w.pass, pass);
87 	}
88 	if(verbose)
89 		dumppack(&w);
90 
91 	if(!address)
92 		address = "udp!255.255.255.255!0";
93 
94 	fd = dial(address, nil, nil, nil);
95 	if(fd < 0)
96 		sysfatal("%s: %r", address);
97 	nw = write(fd, &w, sizeof w);
98 	if(nw != sizeof w)
99 		sysfatal("error sending: %r");
100 	exits(0);
101 }
102